[eric] agents: the three ungated meta MCP servers ride one process, cutting three idle interpreters per parked chat

This commit is contained in:
ciregenz
2026-08-08 09:41:45 -07:00
parent d60a99ddd1
commit 4d86b3377d
5 changed files with 107 additions and 43 deletions
@@ -0,0 +1,90 @@
#!/usr/bin/env python3
"""One stdio MCP process hosting the always-on, ungated meta tools that used to be three separate
python interpreters per agent CLI (MCPList/Search/Activate, SettingsRead/Write, CreateApp).
Why merge only these three: their tool NAMES are globally unique, none of them is referenced by
the non-bypassable permission gate (grep for `mcp__openswarm-mcp-meta__` etc. finds nothing in
build_effective_tool_lists / path_gate), and all three are registered unconditionally with the
same env. So collapsing them into one process is pure fan-out reduction with zero behavior change:
5 parked CLIs drop 15 idle interpreters to 5 (ENG-208). The gate-coupled servers (schedule, web,
browser-agent) and the conditional ones (skill, show-ui, spawn, invoke) stay separate on purpose.
We reuse each sub-server's own TOOLS + handle_tool_call; we own the stdio loop so their main() and
send_response never run. Sibling import (not backend.*) matches how these scripts are launched by
path in both dev and the packaged bundle."""
import json
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import apps_mcp_server as p_apps # noqa: E402
import mcp_meta_server as p_meta # noqa: E402
import settings_meta_server as p_settings # noqa: E402
P_SUBSERVERS = [p_meta, p_settings, p_apps]
TOOLS = []
P_ROUTE = {}
for p_mod in P_SUBSERVERS:
for p_tool in p_mod.TOOLS:
TOOLS.append(p_tool)
P_ROUTE[p_tool["name"]] = p_mod
def send_response(id_, result=None, error=None):
msg = {"jsonrpc": "2.0", "id": id_}
if error is not None:
msg["error"] = error
else:
msg["result"] = result
sys.stdout.write(json.dumps(msg) + "\n")
sys.stdout.flush()
def main():
for line in sys.stdin:
line = line.strip()
if not line:
continue
try:
msg = json.loads(line)
except json.JSONDecodeError:
continue
method = msg.get("method")
id_ = msg.get("id")
params = msg.get("params", {})
if method == "initialize":
send_response(id_, {
"protocolVersion": "2024-11-05",
"capabilities": {"tools": {}},
"serverInfo": {"name": "openswarm-core", "version": "1.0.0"},
})
elif method == "notifications/initialized":
pass
elif method == "tools/list":
send_response(id_, {"tools": TOOLS})
elif method == "tools/call":
tool_name = params.get("name", "")
arguments = params.get("arguments", {})
mod = P_ROUTE.get(tool_name)
if mod is None:
send_response(id_, {"content": [{"type": "text", "text": f"Unknown tool: {tool_name}"}], "isError": True})
continue
try:
send_response(id_, mod.handle_tool_call(tool_name, arguments))
except Exception as e:
send_response(id_, error={"code": -32000, "message": str(e)})
elif method in ("resources/list",):
send_response(id_, {"resources": []})
elif method in ("prompts/list",):
send_response(id_, {"prompts": []})
elif method == "ping":
send_response(id_, {})
elif id_ is not None:
send_response(id_, error={"code": -32601, "message": f"Method not found: {method}"})
if __name__ == "__main__":
main()
@@ -98,13 +98,14 @@ def register_builtin_mcp_servers(
"type": "stdio",
}
# Always-on meta-MCP server. Exposes MCPList / MCPSearch / MCPActivate so the model can discover and activate user MCPs at runtime. The activation gate (active_mcps filter in build_mcp_servers above) ensures the model cannot reach any other MCP server's tools without going through this layer first.
mcp_meta_server_path = os.path.join(
agents_dir, "mcp_meta_server.py"
)
mcp_servers["openswarm-mcp-meta"] = {
# Always-on core meta-MCP server: ONE process hosting the three ungated always-on servers that
# used to be three interpreters (MCP discovery MCPList/Search/Activate, SettingsRead/Write,
# CreateApp). None is referenced by the permission gate, so this is pure fan-out reduction
# (ENG-208). The activation gate still governs external MCPs exactly as before, via MCPActivate.
combined_meta_path = os.path.join(agents_dir, "combined_meta_mcp_server.py")
mcp_servers["openswarm-core"] = {
"command": sys.executable,
"args": [mcp_meta_server_path],
"args": [combined_meta_path],
"env": {
"OPENSWARM_PORT": os.environ.get("OPENSWARM_PORT", "8324"),
"OPENSWARM_AUTH_TOKEN": get_auth_token(),
@@ -134,34 +135,6 @@ def register_builtin_mcp_servers(
"type": "stdio",
}
# Always-on settings-meta server: SettingsRead / SettingsWrite let the agent read and edit its own OpenSwarm Settings autonomously. The backend (/api/settings-meta) enforces the only two guardrails: it can't disconnect the credential powering this run, and reads come back with secrets redacted. No activation gate, Settings is the agent's own house, not a third-party MCP.
settings_meta_server_path = os.path.join(
agents_dir, "settings_meta_server.py"
)
mcp_servers["openswarm-settings-meta"] = {
"command": sys.executable,
"args": [settings_meta_server_path],
"env": {
"OPENSWARM_PORT": os.environ.get("OPENSWARM_PORT", "8324"),
"OPENSWARM_AUTH_TOKEN": get_auth_token(),
"OPENSWARM_PARENT_SESSION_ID": session.id,
},
"type": "stdio",
}
# Always-on apps server: CreateApp lets ANY agent spin up a live App card on the canvas. This replaced the standalone App Builder page; the tool result carries the App Builder reference so no mode switch is needed.
apps_server_path = os.path.join(agents_dir, "apps_mcp_server.py")
mcp_servers["openswarm-apps"] = {
"command": sys.executable,
"args": [apps_server_path],
"env": {
"OPENSWARM_PORT": os.environ.get("OPENSWARM_PORT", "8324"),
"OPENSWARM_AUTH_TOKEN": get_auth_token(),
"OPENSWARM_PARENT_SESSION_ID": session.id,
},
"type": "stdio",
}
# ShowUI renders rich inline components from the tool_call input (display only, server just
# validates); AskUI renders an interactive component and BLOCKS on /api/ui-requests/wait until
# the user answers in the transcript. Gated on the ShowUI builtin perm.
+1 -1
View File
@@ -100,7 +100,7 @@ def test_headless_drops_the_renderer_bound_servers_and_tools(monkeypatch, no_ren
# The rest of the surface is untouched; headless prunes the renderer, it doesn't lobotomise the agent.
assert "Read" in allowed and "Bash" in allowed
assert "openswarm-invoke-agent" in mcp_servers
assert "openswarm-apps" in mcp_servers
assert "openswarm-core" in mcp_servers
def test_without_headless_every_one_of_them_is_offered(monkeypatch, no_renderer):
@@ -16,18 +16,18 @@ def test_registers_always_on_and_delegation_servers():
mcp_servers = {}
browser_tools, invoke_tools = register_builtin_mcp_servers(
mcp_servers, p_session(), {}, None, None)
# always-on
assert "openswarm-mcp-meta" in mcp_servers
assert "openswarm-settings-meta" in mcp_servers
assert "openswarm-apps" in mcp_servers
# always-on: the three ungated meta servers ride ONE combined process now (ENG-208)
assert "openswarm-core" in mcp_servers
assert "openswarm-mcp-meta" not in mcp_servers
assert "openswarm-settings-meta" not in mcp_servers
assert "openswarm-apps" not in mcp_servers
# delegation (not denied)
assert "openswarm-browser-agent" in mcp_servers
assert "openswarm-invoke-agent" in mcp_servers
assert browser_tools == ["CreateBrowserAgent", "BrowserAgent", "BrowserAgents", "AppAgent"]
assert invoke_tools == ["InvokeAgent"]
# Every registered server's script path must resolve to a file that ACTUALLY EXISTS. This is the assertion that catches a moved-caller resolving the wrong agents dir.
for name in ("openswarm-mcp-meta", "openswarm-settings-meta", "openswarm-apps",
"openswarm-browser-agent", "openswarm-invoke-agent"):
for name in ("openswarm-core", "openswarm-browser-agent", "openswarm-invoke-agent"):
script = mcp_servers[name]["args"][0]
assert os.path.isfile(script), f"{name} script does not exist on disk: {script}"
@@ -38,5 +38,4 @@ def test_fully_denied_delegation_servers_are_not_registered():
register_builtin_mcp_servers(mcp_servers, p_session(), perms, None, None)
assert "openswarm-browser-agent" not in mcp_servers # all browser tools denied -> skip
assert "openswarm-invoke-agent" not in mcp_servers
assert "openswarm-mcp-meta" in mcp_servers # always-on regardless
assert "openswarm-apps" in mcp_servers # always-on regardless
assert "openswarm-core" in mcp_servers # always-on regardless
@@ -288,9 +288,11 @@ const MCP_SERVER_BRAND: Record<string, string> = {
'stripe': 'Stripe',
'openswarm-browser-agent': 'browser',
'openswarm-invoke-agent': 'helper',
'openswarm-core': 'tools',
'openswarm-mcp-meta': 'tools',
'openswarm-outputs-meta': 'views',
'openswarm-settings-meta': 'settings',
'openswarm-apps': 'apps',
'openswarm-web': 'the web',
};