@@ -9,7 +9,7 @@ The MCP Gateway Plugin Framework provides a standardized way to extend gateway f
99
1010- ** Content Filtering** - PII detection and masking
1111- ** AI Safety** - Integration with LLMGuard, OpenAI Moderation
12- - ** Security** - Input validation and output sanitization
12+ - ** Security** - Input validation and output sanitization
1313- ** Policy Enforcement** - Business rules and compliance
1414- ** Transformation** - Request/response modification
1515- ** Auditing** - Logging and monitoring
@@ -97,13 +97,13 @@ Plugins execute in priority order (ascending):
9797plugins :
9898 - name : " Authentication"
9999 priority : 10 # Runs first
100-
101- - name : " RateLimiter"
100+
101+ - name : " RateLimiter"
102102 priority : 50 # Runs second
103-
103+
104104 - name : " ContentFilter"
105105 priority : 100 # Runs third
106-
106+
107107 - name : " Logger"
108108 priority : 200 # Runs last
109109` ` `
@@ -144,23 +144,23 @@ from mcpgateway.plugins.framework.types import (
144144
145145class MyPlugin(Plugin):
146146 """Example plugin implementation."""
147-
147+
148148 def __init__(self, config: PluginConfig):
149149 super().__init__(config)
150150 # Initialize plugin-specific configuration
151151 self.my_setting = config.config.get("my_setting", "default")
152-
152+
153153 async def prompt_pre_fetch(
154- self,
155- payload: PromptPrehookPayload,
154+ self,
155+ payload: PromptPrehookPayload,
156156 context: PluginContext
157157 ) -> PromptPrehookResult:
158158 """Process prompt before retrieval."""
159-
159+
160160 # Access prompt name and arguments
161161 prompt_name = payload.name
162162 args = payload.args
163-
163+
164164 # Example: Block requests with forbidden words
165165 if "forbidden" in str(args.values()).lower():
166166 return PromptPrehookResult(
@@ -172,40 +172,40 @@ class MyPlugin(Plugin):
172172 details={"found_in": "arguments"}
173173 )
174174 )
175-
175+
176176 # Example: Modify arguments
177177 if "transform_me" in args:
178178 args["transform_me"] = args["transform_me"].upper()
179179 return PromptPrehookResult(
180180 modified_payload=PromptPrehookPayload(prompt_name, args)
181181 )
182-
182+
183183 # Allow request to continue unchanged
184184 return PromptPrehookResult()
185-
185+
186186 async def prompt_post_fetch(
187187 self,
188188 payload: PromptPosthookPayload,
189189 context: PluginContext
190190 ) -> PromptPosthookResult:
191191 """Process prompt after rendering."""
192-
192+
193193 # Access rendered prompt
194194 prompt_result = payload.result
195-
195+
196196 # Example: Add metadata to context
197197 context.metadata["processed_by"] = self.name
198-
198+
199199 # Example: Modify response
200200 for message in prompt_result.messages:
201201 message.content.text = message.content.text.replace(
202202 "old_text", "new_text"
203203 )
204-
204+
205205 return PromptPosthookResult(
206206 modified_payload=payload
207207 )
208-
208+
209209 async def shutdown(self):
210210 """Cleanup when plugin shuts down."""
211211 # Close connections, save state, etc.
@@ -221,17 +221,17 @@ async def prompt_pre_fetch(self, payload, context):
221221 # Store state for later use
222222 context.set_state("request_time", time.time())
223223 context.set_state("original_args", payload.args.copy())
224-
224+
225225 return PromptPrehookResult()
226226
227227async def prompt_post_fetch(self, payload, context):
228228 # Retrieve state from pre-hook
229229 elapsed = time.time() - context.get_state("request_time", 0)
230230 original = context.get_state("original_args", {})
231-
231+
232232 # Add timing metadata
233233 context.metadata["processing_time_ms"] = elapsed * 1000
234-
234+
235235 return PromptPosthookResult()
236236` ` `
237237
@@ -240,13 +240,13 @@ async def prompt_post_fetch(self, payload, context):
240240` ` ` python
241241class LLMGuardPlugin(Plugin):
242242 """Example external service integration."""
243-
243+
244244 def __init__(self, config: PluginConfig):
245245 super().__init__(config)
246246 self.service_url = config.config.get("service_url")
247247 self.api_key = config.config.get("api_key")
248248 self.timeout = config.config.get("timeout", 30)
249-
249+
250250 async def prompt_pre_fetch(self, payload, context):
251251 # Call external service
252252 async with httpx.AsyncClient() as client:
@@ -262,9 +262,9 @@ class LLMGuardPlugin(Plugin):
262262 },
263263 timeout=self.timeout
264264 )
265-
265+
266266 result = response.json()
267-
267+
268268 if result.get("blocked", False):
269269 return PromptPrehookResult(
270270 continue_processing=False,
@@ -275,7 +275,7 @@ class LLMGuardPlugin(Plugin):
275275 details=result
276276 )
277277 )
278-
278+
279279 except Exception as e:
280280 # Handle errors based on plugin settings
281281 if self.config.mode == PluginMode.ENFORCE:
@@ -288,7 +288,7 @@ class LLMGuardPlugin(Plugin):
288288 details={"error": str(e)}
289289 )
290290 )
291-
291+
292292 return PromptPrehookResult()
293293` ` `
294294
@@ -357,9 +357,9 @@ async def test_my_plugin():
357357 hooks=["prompt_pre_fetch"],
358358 config={"setting_one": "test_value"}
359359 )
360-
360+
361361 plugin = MyPlugin(config)
362-
362+
363363 # Test your plugin logic
364364 result = await plugin.prompt_pre_fetch(payload, context)
365365 assert result.continue_processing
@@ -378,11 +378,11 @@ async def prompt_pre_fetch(self, payload, context):
378378 pass
379379 except Exception as e:
380380 logger.error(f"Plugin {self.name} error: {e}")
381-
381+
382382 # In permissive mode, log and continue
383383 if self.mode == PluginMode.PERMISSIVE:
384384 return PromptPrehookResult()
385-
385+
386386 # In enforce mode, block the request
387387 return PromptPrehookResult(
388388 continue_processing=False,
@@ -408,17 +408,17 @@ class CachedPlugin(Plugin):
408408 super().__init__(config)
409409 self._cache = {}
410410 self._cache_ttl = config.config.get("cache_ttl", 300)
411-
411+
412412 async def expensive_operation(self, key):
413413 # Check cache first
414414 if key in self._cache:
415415 cached_value, timestamp = self._cache[key]
416416 if time.time() - timestamp < self._cache_ttl:
417417 return cached_value
418-
418+
419419 # Perform expensive operation
420420 result = await self._do_expensive_work(key)
421-
421+
422422 # Cache result
423423 self._cache[key] = (result, time.time())
424424 return result
0 commit comments