anthropics / anthropics/claude-agent-sdk-typescript

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

Open
#292 1 comment 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Shell
Stars
1.8k
Forks
226
PR merge metrics
No merged PRs in 30d

Description

## 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

```ts
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:

```js
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.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.