Support dynamic tool registration mid-query (tools added via setMcpServers not visible until next query())

Resolved 💬 1 comment Opened Apr 20, 2026 by pasch-ai Closed Apr 20, 2026

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

| Approach | Result |
|----------|--------|
| setMcpServers() from tool handler | Server connected, tools not visible |
| mcpServer.instance.tool() + auto sendToolListChanged() | Tool registered on server, notification sent, CLI doesn't re-query |
| Manual sendToolListChanged() after setMcpServers | Same — 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.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗