zai-org / zai-org/feedback

[Bug] Mid-session MCP tools never reach the tool catalog; intended call silently executes as another tool

Open
#551 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

priority: P2
Dominant language
No language data
Stars
22
Forks
1
PR merge metrics
No merged PRs in 30d

Description

Summary: an MCP server that finishes connecting after session start never gets its tools into the running session's tool catalog, and an intended call to a missing tool silently executes as a different MCP server's tool instead of returning an "unknown tool" error.

Environment

  • ZCode CLI 0.16.5, Windows 11 Pro (10.0.26200 x64)
  • Provider: builtin:zai-coding-plan, model GLM-5.3-Flash (anthropic-compatible endpoint)
  • MCP servers configured: serena (stdio via uvx, serena-agent 1.7.0, startup ~15–18 s), v8-pulsar (HTTP localhost:8010), rlm (HTTP localhost:8201), plus plugin servers (computer-use, node_repl, image_search)

Summary

Two related defects, recurring for about a month across multiple sessions and different MCP servers (the repro below uses serena because it has the slowest startup):

  1. Stale tool catalog in a live session. When an MCP server finishes connecting after the session started, its tools never appear in the catalog of that session's subsequent turns. The host even logs a successful connect, but every later model request still goes out without those tools. Waiting / doing a neutral turn (tried 75 s) does not help. Only opening a new session picks the tools up.
  2. No guard against unknown tool names → wrong tool executes. When the agent intends to call a tool that is missing from the current catalog, the call is not rejected with an "unknown tool" error result; instead a different MCP server's tool silently executes, and the model reads that tool's output as if it were the intended tool's answer. This is a correctness and safety problem: any MCP tool can effectively be swapped for another one with real side effects.

Steps to reproduce

  1. Configure an MCP server with a slow startup (e.g. serena over stdio/uvx, ~15–18 s) alongside fast servers. Start a ZCode session; the slow server connects in parallel, a few turns later.
  2. Instruct the agent (via project instructions) to start code work with mcp__serena__initial_instructions.
  3. Observe that mcp__serena__* tools are absent from the turn's catalog (evidence below); the intended call ends up executing as mcp__v8-pulsar__list_sessions or mcp__computer-use__list_apps — no "tool not found" error is ever produced.
  4. Pause / do a neutral turn (75 s tested): the catalog is still not refreshed.
  5. Start a new session: all 23 mcp__serena__* tools are present and everything works.

Evidence (one repro, 2026-09-06, timestamps UTC)

From host log zcode-2026-09-06.jsonl and model-I/O rollout model-io-sess_bdacc918-…jsonl of session sess_bdacc918:

  • 13:01:46, 13:53:38, 13:54:47mcp.server.connected, server serena, transport stdio, toolCount: 23 (same session; reconnected after a config fix)
  • 13:54:4913:59:19 — six consecutive model requests in that session: the tools array contains 127 entries (54 mcp__v8-pulsar__*, 30 mcp__computer-use__*, 18 mcp__rlm__*, 3 node_repl, 1 image_search, 21 built-ins) and 0 mcp__serena__* — 4.5 minutes after the successful connect
  • 13:55:49 and 13:58:34 — the agent narrates and intends to call mcp__serena__initial_instructions, but the recorded/executed tool call is mcp__v8-pulsar__list_sessions; in a second session (sess_1a0f5a1e) the same intended call dispatched to mcp__computer-use__list_apps. Three wrong-tool executions in one hour total.
  • 14:00:58 — first request of a new session (sess_7aa27408): 129 tools, including all 23 mcp__serena__* → works normally

So the server connects successfully (the host logs it), but the running session's catalog never refreshes, and a call naming a tool outside the catalog is not rejected — it lands on another server's tool. Whether the name substitution happens in the model output, the anthropic-compatible adapter, or the dispatcher is for you to pinpoint; from the outside it looks like "I called tool X, tool Y ran".

Expected behavior

  1. After mcp.server.connected, newly registered tools must be included in the catalog of subsequent turns of the same session (or provide an explicit catalog-refresh mechanism).
  2. A tool_use whose name is not in the current catalog must return an explicit error as tool_result ("unknown tool: …") — never dispatch, map or alias it to another registered tool.
  3. If any tool-name mapping happens in the provider adapter, it must be logged and surfaced to the user instead of being silent.

Impact

  • Silent wrong-tool execution. In our case a read-only code-analysis call executed list_sessions against a live 1C server-monitoring MCP; both the user and the model believed the intended tool had run. With other tool sets this pattern can trigger arbitrary side effects.
  • Any MCP server slower than the first turn is unusable for the whole session. Our team's code workflow (Serena for C#/BSL static analysis) was blocked several times over the last month; each time the only fix was restarting the session.

Suggested test

  1. Register stub MCP server A (fast) and server B with ≥15 s startup delay; start a session.
  2. After the first turn and B's connect, ask the model to call B__tool1, and also to call a non-existent name B__nope.
  3. Expect: B__tool1 is available in the next turn's catalog (or after an explicit refresh); B__nope returns an "unknown tool" error result and never executes another server's tool.

Happy to provide full host logs and model-I/O rollouts if needed.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the mcp.server.connected event into the running session's tool catalog, then follow tool-name validation and dispatch using the cited host logs and model-I/O rollouts. Add the suggested delayed-server test for a newly connected tool and an unknown name; done means same-session visibility and an explicit unknown-tool error without another tool executing.

Written by the indexing model from the issue text.

Assessment

Domain
cli, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.