fix(tools): honor canonical MCP names in platform allowlists - #128141
Wenfengcheng wants to merge 1 commit into
Conversation
The fix is right and I'd approve it. Verified against base It works. One gap worth a follow-up — Same intent, opposite outcome — and user-reachable: Widen the membership test the same way: mcp_names = enabled_mcp | {f"mcp-{name}" for name in enabled_mcp}
if set(result) & mcp_names:
return resultKeep the union loop on bare Not blocking: |
|
@Enough1122 Thanks for verifying the platform allowlist fix. I checked the proposed cron follow-up against the actual diff of the still-open #108073: it already implements canonical-name recognition in |
JoaoMarcos44
left a comment
There was a problem hiding this comment.
@Wenfengcheng — I independently checked the reported selection mechanism and am documenting the bounded result here. This is a COMMENT review, not an approval or a request-changes verdict.
Scope and pins
Reviewed head: dc1d9229aa707c97cf6544bb8ad39f35aadc17a6; PR base: 5000e29936df69d5209f7cf2eea8e5776cb4cbb1. The executed production baseline was 20ae6087ffa5de9faf7e3b454b677a53a9e14856, not this PR's base. Native Windows, Python 3.14.7, pytest 9.1.1, using scripts/run_tests.sh.
Independently observed behavior
With three enabled synthetic MCP servers and platform_toolsets.cli: [hermes-cli, mcp-linear], the baseline platform resolver activates unrelated server names. I followed that through the real registry/alias machinery and model_tools.get_tool_definitions, rather than stopping at the config list: unrelated inert fixture schemas are model-visible. The bare linear selection exposes only the intended fixture schema.
Two contract assertions fail on the baseline. Replaying exactly the _merge_mcp_servers symbol from this head with the same baseline dependencies and the same schema-visibility contracts gives 2 passed, 0 failed. No MCP server was started, no handler was executed, and no credentials were used.
The controlling boundary is the bare-name-only intersection in the baseline _merge_mcp_servers, before the schema builder. Your change recognizes both spellings there while preserving the caller's spelling. This is preferable to a registry-only correction, which would arrive after the resolver had already widened the selection, or a save-time-only correction, which would miss existing/hand-written configuration.
Evidence limits and merge gates
This was an exact-symbol source probe, not your complete candidate-branch suite and not a full same-command branch RED/GREEN run. I inspected, but did not independently execute as a full branch suite, your portable-discovery, no_mcp, default-inclusion and disabled-server edge cases. The inspected MCP selection/schema functions have matching ASTs in subsequently observed main 79af3f6cea8067284a7ea5725078578b3f790adb; that is static identity evidence, not a test run on that later main.
Your existing PR owns the inspected platform fix; I am not proposing a duplicate or expanding it into the separate cron ownership boundary in #108073. The local result supports this mechanism, but full branch/current-base verification and the required CI/review gates remain separate conditions. An empty check rollup means no checks reported, not that CI never ran or passed.
This is a confirmed functional capability-selection defect in the baseline with security relevance. In-process tool selection is not OS containment under SECURITY.md, and schema visibility is not proof of credential use, exfiltration, or an official vulnerability.
Problem
Fixes #128017.
A saved
platform_toolsets.cli: [hermes-cli, mcp-linear]adds every enabled MCP server, whereas the bare aliaslinearcorrectly selects only that server.Root cause
_merge_mcp_serversrecognizes only enabled bare server names. Canonicalmcp-<server>names fall through as custom entries and leave the explicit MCP allowlist empty, activating the default-all branch.Change
Recognize both spellings in the existing merge function, preserving the caller's spelling.
no_mcpalso overrides canonical selections. No new configuration, discovery, or tools.Verification
Frozen base:
5000e29936df69d5209f7cf2eea8e5776cb4cbb1.scripts/run_tests.sh tests/hermes_cli/test_platform_mcp_allowlist.py -q --tb=short -j 1: 2 expected assertion failures, 6 passed (canonical selection broadens; canonical selection survivesno_mcp).scripts/run_tests.sh tests/hermes_cli/test_tools_config.py tests/hermes_cli/test_platform_mcp_allowlist.py -q --tb=short -j 1: 56 passed, 6 skipped. The first broader attempt lacked a source package in the sparse checkout; materializing the unchangedhermes_platformpackage resolved those setup errors.load_config()->_get_platform_tools()-> registered MCPresolve_toolset()output: PASS. Selected tool present, unrelated server absent, bare/canonical tool sets equal, andno_mcpexcludes both; no MCP process spawned.Scope / non-goals
The issue's enabled-server platform allowlist contract is covered. Existing bare-alias behavior and default inclusion policy remain unchanged. Per-job cron allowlists (#108073), server-side per-platform scope (#125393), config validation (#127978), and explicit empty lists (#107452) have separate implementations and are not changed.