Skip to content

fix(mcp): hide server-beta-only tools from worker-runtime tools/list (closes #3064)#3065

Open
rodboev wants to merge 2 commits into
thedotmack:mainfrom
rodboev:fix/3064-mcp-tools-runtime-filter
Open

fix(mcp): hide server-beta-only tools from worker-runtime tools/list (closes #3064)#3065
rodboev wants to merge 2 commits into
thedotmack:mainfrom
rodboev:fix/3064-mcp-tools-runtime-filter

Conversation

@rodboev

@rodboev rodboev commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Worker runtime currently advertises observation_* and memory_* MCP tools that only run when CLAUDE_MEM_RUNTIME=server-beta, so clients can discover a tool that is guaranteed to fail in the active runtime. This change makes tools/list runtime-aware: worker mode hides the eight server-beta-only tool names, while server-beta keeps the current full observation and memory surface.

The handler registry stays intact, and requireServerBetaForObservationTool() still rejects direct worker-mode calls as defense in depth. The main proof is a focused runtime-visibility regression test on the production filtering logic, plus the existing schema and alias guards. The shipped plugin bundles were then regenerated through the normal build so installed MCP clients pick up the same filtered surface.

A follow-up CI rerun also required one debug-level logger call inside the new visibility helper. src/servers/* files are covered by the repo's logger-standards guard, so the helper now carries the same observability contract as the rest of the MCP server surface without changing the advertised tool set.

Why

requireServerBetaForObservationTool() already rejects the observation_* path outside server-beta at src/servers/mcp-server.ts:240-245, which means the implementation already knows those handlers are not worker-capable. The problem is earlier in the flow: the top-level registry at src/servers/mcp-server.ts:429-667 includes those server-beta-only tools unconditionally, and ListToolsRequestSchema at src/servers/mcp-server.ts:902-909 advertises that full registry without checking runtime.

This PR fixes the advertised MCP contract rather than adding worker stubs. CallToolRequestSchema stays on the full registry so the same actionable wrong-runtime error remains in place if a client bypasses discovery and calls one of those tools directly.

Issue analysis and the direct MCP transcript in #3064 identified the worker-runtime list surface as the bug; related PR #3044 stays out of scope because it adds a separate worker write tool instead of filtering discovery.

Scope

  • Keeps scope to runtime-aware MCP advertisement only.
  • Does not make worker runtime implement the server-beta observation or memory endpoints.
  • Does not change worker auto-start behavior or generated hook artifacts.

Risk

The only semantic change to the MCP contract is which tool names tools/list advertises in worker mode. Server-beta keeps the existing tool exposure, and the handler-level guard remains unchanged. The logger follow-up is debug-only instrumentation inside the helper. The real regression risk is hiding a worker-capable tool by mistake, which is why the proof centers on worker-vs-server-beta visibility behavior rather than source-string inspection alone.

Verification

  • bun test tests/servers/mcp-runtime-tool-visibility.test.ts tests/servers/mcp-tool-schemas.test.ts - pass (15/15)
  • bun test tests/logger-usage-standards.test.ts -t "should have logger coverage in high-priority files" - pass
  • npm.cmd run typecheck:root - pass
  • npm run build - pass, shipped bundles regenerated
  • npm run lint:hook-io - pass
  • npm run lint:spawn-env - pass
  • npm run strip-comments:check - current repo snapshot still reports Changed: 329 (check mode, no writes)
  • Manual: compared worker vs server-beta advertised sets in the focused runtime test, and kept compatibility with schema and alias tests

Closes #3064

@greptile-apps

greptile-apps Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR makes MCP tool discovery aware of the selected runtime. The main changes are:

  • Filters server-beta-only observation_* and memory_* tools from worker-mode tools/list responses.
  • Keeps server-beta discovery unchanged and leaves direct tool calls on the full registry with existing runtime guards.
  • Adds tests for worker versus server-beta tool visibility and core worker tool preservation.
  • Regenerates the shipped plugin bundles.

Confidence Score: 5/5

The runtime-aware filtering is narrowly scoped to tool discovery and preserves the existing direct-call guard behavior.

Focused tests cover worker versus server-beta visibility, schema compatibility, and preservation of worker-capable tools; the generated bundles were rebuilt from the source changes.

T-Rex T-Rex Logs

What T-Rex did

  • Compared the pre- and post-artifact tools/list results to verify how server-beta visibility changes and which items are exposed on the head and server-beta endpoints.
  • Observed that observation_search_advertised_in_tools_list changed from true to false and confirmed the direct tools/call still returns isError true due to the runtime guard, showing discovery filtering did not remove the call handler registry path.
  • Collected evidence artifacts detailing the command, working directory, commit, runtime sections, and exit statuses, concluding the blocker is runtime non-response from the generated bundle to the MCP stdio probe, not a source-only issue.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (2): Last reviewed commit: "fix(mcp): satisfy logger coverage for th..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant