claude-code - 💡(How to fix) Fix Support dynamic tool registration mid-query (tools added via setMcpServers not visible until next query())

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

Root cause (from SDK investigation)

Fix Action

Fix / Workaround

Attempted workarounds

Code Example

const coreServer = sdk.createSdkMcpServer({
    name: "core",
    tools: [
        sdk.tool("loadMode", "Load a capability mode", { mode: z.string() },
            async ({ mode }) => {
                // Connect a new server with additional tools
                await queryRef.setMcpServers({
                    core: coreServer,
                    [mode]: modeServers.get(mode)!,
                });
                // Server is connected (confirmed via logs + response.added),
                // but model cannot see its tools until next query()
                return { content: [{ type: "text", text: `Mode ${mode} loaded` }] };
            },
        ),
    ],
});

const stream = sdk.query({ prompt, options: { mcpServers: { core: coreServer } } });
queryRef = stream;

---

p = [...G, ...P, ...x.tools]          // snapshot of tools
for await (let RA of w09({ tools: p, ... }))  // fixed for entire loop
RAW_BUFFERClick to expand / collapse

Problem

When using setMcpServers() to connect a new MCP server mid-query (from within a tool handler), the server connects successfully but its tools are not visible to the model until the next query() call. This prevents implementing progressive tool disclosure — a pattern where an agent starts with minimal tools and gains more as it discovers what capabilities it needs.

Reproduction

const coreServer = sdk.createSdkMcpServer({
    name: "core",
    tools: [
        sdk.tool("loadMode", "Load a capability mode", { mode: z.string() },
            async ({ mode }) => {
                // Connect a new server with additional tools
                await queryRef.setMcpServers({
                    core: coreServer,
                    [mode]: modeServers.get(mode)!,
                });
                // Server is connected (confirmed via logs + response.added),
                // but model cannot see its tools until next query()
                return { content: [{ type: "text", text: `Mode ${mode} loaded` }] };
            },
        ),
    ],
});

const stream = sdk.query({ prompt, options: { mcpServers: { core: coreServer } } });
queryRef = stream;

After setMcpServers resolves successfully (new server appears in response.added), the model's next agentic turn within the same query() does not include the new server's tool schemas. The tools only appear on the next query() call.

Root cause (from SDK investigation)

In cli.js, the tool list is assembled once per user turn and passed by value to the agentic loop generator:

p = [...G, ...P, ...x.tools]          // snapshot of tools
for await (let RA of w09({ tools: p, ... }))  // fixed for entire loop

setMcpServers correctly triggers v() which updates P (the MCP tool registry), but p is already captured. The w09 generator uses the stale snapshot for all remaining API calls in the loop.

Attempted workarounds

ApproachResult
setMcpServers() from tool handlerServer connected, tools not visible
mcpServer.instance.tool() + auto sendToolListChanged()Tool registered on server, notification sent, CLI doesn't re-query
Manual sendToolListChanged() after setMcpServersSame — notification received but tool list already frozen

Requested behavior

When setMcpServers() adds a new server mid-query, its tools should be included in the next API call within the same agentic loop. This could be implemented by:

  1. Having w09 re-read the tool registry on each API call instead of using the snapshot, or
  2. Providing an explicit refreshTools() method on the Query object that rebuilds the tool list for subsequent API calls

Use case

Progressive disclosure for domain-specific agents. Our agent starts with 8 general tools (~800 tokens of schemas). When the user asks about chip design, the agent loads "design mode" which should make 4 additional design tools available immediately. Without mid-query refresh, the agent loads the mode but can't use the tools until the user sends another message — breaking the conversational flow.

extent analysis

TL;DR

To fix the issue, the w09 generator should be modified to re-read the tool registry on each API call instead of using a stale snapshot, or a refreshTools() method should be added to the Query object to rebuild the tool list for subsequent API calls.

Guidance

  • The root cause of the issue is that the tool list is assembled once per user turn and passed by value to the agentic loop generator, which uses a stale snapshot of tools for all remaining API calls in the loop.
  • To verify the issue, check if the new server's tools are visible to the model after the next query() call, but not within the same query() call after setMcpServers() is called.
  • One possible workaround is to modify the w09 generator to re-read the tool registry on each API call, instead of using the snapshot.
  • Another possible solution is to provide an explicit refreshTools() method on the Query object that rebuilds the tool list for subsequent API calls.

Example

// Example of how the w09 generator could be modified to re-read the tool registry
for await (let RA of w09({ tools: [...G, ...P, ...x.tools], ... }))  // re-read tool registry on each API call

Notes

  • The issue is specific to the implementation of the w09 generator and the setMcpServers() method, and may not be applicable to other parts of the codebase.
  • The requested behavior is to include the new server's tools in the next API call within the same agentic loop, which requires modifying the w09 generator or adding a refreshTools() method.

Recommendation

Apply workaround: Modify the w09 generator to re-read the tool registry on each API call, or add a refreshTools() method to the Query object to rebuild the tool list for subsequent API calls. This will allow the new server's tools to be included in the next API call within the same agentic loop.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Support dynamic tool registration mid-query (tools added via setMcpServers not visible until next query())