toggleMcpServer() silently fails for SDK-injected MCP servers (only searches settings-based servers)
Bug Description
toggleMcpServer(serverName, false) fails with Server not found for MCP servers registered via the mcpServers option in query(). The toggle only works for servers defined in Claude Code settings files (.claude/settings.json, project/local settings).
This makes it impossible to implement lazy-loading for SDK-injected MCP servers, which is the primary use case for programmatic MCP server management via the Agent SDK.
Reproduction
import { query } from "@anthropic-ai/claude-agent-sdk";
const myMcpServer = createSomeMcpServer();
const q = query({
prompt: "Hello",
options: {
mcpServers: { "my-server": myMcpServer },
},
});
// This fails silently - server is not found
await q.toggleMcpServer("my-server", false);
// Error: Server not found: my-server
Root Cause
In cli.js, the mcp_toggle handler looks up servers via:
L1 = mR(P1) ?? q.find((a) => a.name === P1)?.config ?? null;
if (!L1) Y1(z1, `Server not found: ${P1}`);
mR()searches enterprise/user/project/local settings filesq.find()searches settings-based MCP clients
Neither searches the SDK-injected server collection (u.clients). SDK servers are registered through the mcp_set_servers subtype and stored separately, but the toggle handler doesn't know about them.
The mcp_reconnect handler has the same bug.
Interestingly, later in the toggle handler, when it actually disconnects a found server, it does search SDK servers: [...q,...B,...u.clients].find(...). But the initial existence check that gates the entire operation doesn't include them.
Impact
Any SDK consumer trying to implement lazy MCP server loading (register all servers at startup, toggle off unused ones, re-enable on demand) gets silent failures. The servers remain fully connected with all tools injected into every API call.
This was discovered while investigating context bloat from MCP tool schemas - directly related to #23508.
Environment
- SDK version:
@anthropic-ai/claude-agent-sdk@0.2.42 - Platform: Linux x86_64
- Node.js: v24.12.0
Evidence
Bot logs showing the failure:
[03:19:05.235] [agent] Failed to disable lazy server "discord": Error: Server not found: discord
[03:19:05.235] [agent] Disabled 1 lazy MCP servers: [discord]
The "Disabled" log is misleading because the .catch() handler swallows the error while Promise.all() resolves successfully.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗