Skip to content

feat: Add enabled field to plugin configuration to control plugin load #680

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions mcpgateway/plugins/framework/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ async def initialize(self) -> None:
loaded_count = 0

for plugin_config in plugins:
if plugin_config.mode != PluginMode.DISABLED:
if plugin_config.enabled and plugin_config.mode != PluginMode.DISABLED:
try:
plugin = await self._loader.load_and_instantiate_plugin(plugin_config)
if plugin:
Expand All @@ -441,7 +441,10 @@ async def initialize(self) -> None:
logger.error(f"Failed to load plugin {plugin_config.name}: {str(e)}")
raise ValueError(f"Unable to register and initialize plugin: {plugin_config.name}") from e
else:
logger.debug(f"Skipping disabled plugin: {plugin_config.name}")
if not plugin_config.enabled:
logger.debug(f"Skipping disabled plugin: {plugin_config.name} (enabled=false)")
else:
logger.debug(f"Skipping disabled plugin: {plugin_config.name} (mode=disabled)")
Copy link
Collaborator

@imolloy imolloy Aug 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe swap these? I think the mode is the coarser level of granularity and might take precedence for the debug statement.


self._initialized = True
logger.info(f"Plugin manager initialized with {loaded_count} plugins")
Expand Down
2 changes: 2 additions & 0 deletions mcpgateway/plugins/framework/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ class PluginConfig(BaseModel):
version (str): version of the plugin.
hooks (list[str]): a list of the hook points where the plugin will be called.
tags (list[str]): a list of tags for making the plugin searchable.
enabled (bool): whether the plugin is enabled and should be loaded.
mode (bool): whether the plugin is active.
priority (int): indicates the order in which the plugin is run. Lower = higher priority.
conditions (Optional[list[PluginCondition]]): the conditions on which the plugin is run.
Expand All @@ -130,6 +131,7 @@ class PluginConfig(BaseModel):
version: str
hooks: list[HookType]
tags: list[str]
enabled: bool = True # Default to enabled for backward compatibility
mode: PluginMode = PluginMode.ENFORCE
priority: int = 100 # Lower = higher priority
conditions: Optional[list[PluginCondition]] = None # When to apply
Expand Down
3 changes: 3 additions & 0 deletions plugins/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ plugins:
author: "Mihai Criveti"
hooks: ["prompt_pre_fetch", "prompt_post_fetch"]
tags: ["security", "pii", "compliance", "filter", "gdpr", "hipaa"]
enabled: true # true | false - whether plugin should be loaded
mode: "permissive" # enforce | permissive | disabled
priority: 50 # Lower number = higher priority (runs first)
conditions:
Expand Down Expand Up @@ -43,6 +44,7 @@ plugins:
author: "MCP Context Forge Team"
hooks: ["prompt_pre_fetch", "prompt_post_fetch"]
tags: ["plugin", "transformer", "regex", "search-and-replace", "pre-post"]
enabled: true # true | false - whether plugin should be loaded
mode: "enforce" # enforce | permissive | disabled
priority: 150
conditions:
Expand All @@ -63,6 +65,7 @@ plugins:
author: "MCP Context Forge Team"
hooks: ["prompt_pre_fetch"]
tags: ["plugin", "filter", "denylist", "pre-post"]
enabled: false # true | false - whether plugin should be loaded
mode: "enforce" # enforce | permissive | disabled
priority: 100
conditions:
Expand Down
12 changes: 6 additions & 6 deletions plugins/regex_filter/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Search Replace Plugin for MCP Gateway

> Author: Teryl Taylor
> Author: Teryl Taylor
> Version: 0.1.0

A native plugin for MCP Gateway that performs regex-based search and replace operations on prompt arguments and responses.
Expand Down Expand Up @@ -88,11 +88,11 @@ config:
# Replace email addresses with placeholder
- search: "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}"
replace: "[email]"

# Replace phone numbers
- search: "\\b\\d{3}-\\d{3}-\\d{4}\\b"
replace: "[phone]"

# Case-insensitive replacement
- search: "(?i)microsoft"
replace: "MS"
Expand Down Expand Up @@ -173,13 +173,13 @@ async def test_search_replace():
]
}
)

plugin = SearchReplacePlugin(config)
payload = PromptPrehookPayload(
name="test",
args={"message": "foo is foo"}
)

result = await plugin.prompt_pre_fetch(payload, context)
assert result.modified_payload.args["message"] == "bar is bar"
```
Expand Down Expand Up @@ -241,4 +241,4 @@ Apache-2.0

## Support

For issues or questions, please open an issue in the MCP Gateway repository.
For issues or questions, please open an issue in the MCP Gateway repository.
Loading