mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
feat(tools): add "no_mcp" sentinel to exclude MCP servers per platform
Currently, MCP servers are included on all platforms by default. If a
platform's toolset list does not explicitly name any MCP servers, every
globally enabled MCP server is injected. There is no way to opt a
platform out of MCP servers entirely.
This matters for the API server platform when used as an execution
backend — each spawned agent session gets the full MCP tool schema
injected into its system prompt, dramatically inflating token usage
(e.g. 57K tokens vs 9K without MCP tools) and slowing response times.
Add a "no_mcp" sentinel value for platform_toolsets. When present in a
platform's toolset list, all MCP servers are excluded for that platform.
Other platforms are unaffected.
Usage in config.yaml:
platform_toolsets:
api_server:
- terminal
- file
- web
- no_mcp # exclude all MCP servers
The sentinel is filtered out of the final toolset — it does not appear
as an actual toolset name.
This commit is contained in:
parent
b9a5e6e247
commit
7fe6782a25
2 changed files with 48 additions and 3 deletions
|
|
@ -554,6 +554,7 @@ def _get_platform_tools(
|
|||
# MCP servers are expected to be available on all platforms by default.
|
||||
# If the platform explicitly lists one or more MCP server names, treat that
|
||||
# as an allowlist. Otherwise include every globally enabled MCP server.
|
||||
# Special sentinel: "no_mcp" in the toolset list disables all MCP servers.
|
||||
mcp_servers = config.get("mcp_servers") or {}
|
||||
enabled_mcp_servers = {
|
||||
name
|
||||
|
|
@ -561,10 +562,15 @@ def _get_platform_tools(
|
|||
if isinstance(server_cfg, dict)
|
||||
and _parse_enabled_flag(server_cfg.get("enabled", True), default=True)
|
||||
}
|
||||
explicit_mcp_servers = explicit_passthrough & enabled_mcp_servers
|
||||
enabled_toolsets.update(explicit_passthrough - enabled_mcp_servers)
|
||||
# Allow "no_mcp" sentinel to opt out of all MCP servers for this platform
|
||||
if "no_mcp" in toolset_names:
|
||||
explicit_mcp_servers = set()
|
||||
enabled_toolsets.update(explicit_passthrough - enabled_mcp_servers - {"no_mcp"})
|
||||
else:
|
||||
explicit_mcp_servers = explicit_passthrough & enabled_mcp_servers
|
||||
enabled_toolsets.update(explicit_passthrough - enabled_mcp_servers)
|
||||
if include_default_mcp_servers:
|
||||
if explicit_mcp_servers:
|
||||
if explicit_mcp_servers or "no_mcp" in toolset_names:
|
||||
enabled_toolsets.update(explicit_mcp_servers)
|
||||
else:
|
||||
enabled_toolsets.update(enabled_mcp_servers)
|
||||
|
|
|
|||
|
|
@ -72,6 +72,45 @@ def test_get_platform_tools_keeps_enabled_mcp_servers_with_explicit_builtin_sele
|
|||
assert "web-search-prime" in enabled
|
||||
|
||||
|
||||
def test_get_platform_tools_no_mcp_sentinel_excludes_all_mcp_servers():
|
||||
"""The 'no_mcp' sentinel in platform_toolsets excludes all MCP servers."""
|
||||
config = {
|
||||
"platform_toolsets": {"cli": ["web", "terminal", "no_mcp"]},
|
||||
"mcp_servers": {
|
||||
"exa": {"url": "https://mcp.exa.ai/mcp"},
|
||||
"web-search-prime": {"url": "https://api.z.ai/api/mcp/web_search_prime/mcp"},
|
||||
},
|
||||
}
|
||||
|
||||
enabled = _get_platform_tools(config, "cli")
|
||||
|
||||
assert "web" in enabled
|
||||
assert "terminal" in enabled
|
||||
assert "exa" not in enabled
|
||||
assert "web-search-prime" not in enabled
|
||||
assert "no_mcp" not in enabled
|
||||
|
||||
|
||||
def test_get_platform_tools_no_mcp_sentinel_does_not_affect_other_platforms():
|
||||
"""The 'no_mcp' sentinel only affects the platform it's configured on."""
|
||||
config = {
|
||||
"platform_toolsets": {
|
||||
"api_server": ["web", "terminal", "no_mcp"],
|
||||
},
|
||||
"mcp_servers": {
|
||||
"exa": {"url": "https://mcp.exa.ai/mcp"},
|
||||
},
|
||||
}
|
||||
|
||||
# api_server should exclude MCP
|
||||
api_enabled = _get_platform_tools(config, "api_server")
|
||||
assert "exa" not in api_enabled
|
||||
|
||||
# cli (not configured with no_mcp) should include MCP
|
||||
cli_enabled = _get_platform_tools(config, "cli")
|
||||
assert "exa" in cli_enabled
|
||||
|
||||
|
||||
def test_toolset_has_keys_for_vision_accepts_codex_auth(tmp_path, monkeypatch):
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
|
||||
(tmp_path / "auth.json").write_text(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue