[BUG] In-process MCP servers bug in Claude Code TypeScript SDK
Resolved 💬 2 comments Opened Sep 7, 2025 by arthurgousset Closed Sep 9, 2025
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When I try to run the example in-process MCP server from the Claude Code TypeScript SDK documentation (https://docs.anthropic.com/en/docs/claude-code/sdk/sdk-typescript#creating-custom-tools), the query silently fails and doesn't yield.
What Should Happen?
Claude should run the query and use tools defined by the in-process MCP server.
Error Messages/Logs
No error logs, the `query` function fails silently and doesn't yield.
Steps to Reproduce
- Run the code from the Claude Code TypeScript SDK documentation (https://docs.anthropic.com/en/docs/claude-code/sdk/sdk-typescript#creating-custom-tools)
import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-code";
import { z } from "zod";
// Create an SDK MCP server with custom tools
const customServer = createSdkMcpServer({
name: "my-custom-tools",
version: "1.0.0",
tools: [
tool(
"calculate_compound_interest",
"Calculate compound interest for an investment",
{
principal: z.number().describe("Initial investment amount"),
rate: z.number().describe("Annual interest rate (as decimal, e.g., 0.05 for 5%)"),
time: z.number().describe("Investment period in years"),
n: z.number().default(12).describe("Compounding frequency per year")
},
async (args) => {
const amount = args.principal * Math.pow(1 + args.rate / args.n, args.n * args.time);
const interest = amount - args.principal;
return {
content: [{
type: "text",
text: `Final amount: $${amount.toFixed(2)}\nInterest earned: $${interest.toFixed(2)}`
}]
};
}
),
tool(
"fetch_user_data",
"Fetch user data from your application database",
{
userId: z.string().describe("The user ID to fetch"),
fields: z.array(z.string()).optional().describe("Specific fields to return")
},
async (args) => {
// Direct access to your application's data layer
const userData = await myDatabase.getUser(args.userId, args.fields);
return {
content: [{
type: "text",
text: JSON.stringify(userData, null, 2)
}]
};
}
)
]
});
// Use the custom tools in your query
for await (const message of query({
prompt: "Calculate compound interest for $10,000 at 5% for 10 years",
options: {
mcpServers: {
"my-custom-tools": customServer
},
maxTurns: 3
}
})) {
if (message.type === "result") {
console.log(message.result);
}
}
Claude Model
Not sure / Multiple models
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
1.0.108
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Warp
Additional Information
This bug is being discussed in the Claude Code Python SDK repo too: https://github.com/anthropics/claude-code-sdk-python/issues/147
A user found some information on the in-process MCP implementation in the Python SDK:
Hi! I did some digging with Claude Code and found some interesting details about what's happening with the in-process MCP servers. ### What I observed Claude Code was able to run the existing integration tests successfully, and MCP servers work perfectly when tested directly. However, when using thequery()function with SDK MCP servers, the tools aren't being discovered by Claude during actual conversations. ### Investigation findings 1. Import issue - Thetoolandcreate_sdk_mcp_serverfunctions aren't available via star imports because they were removed from__all__in commit e4feaf2 when the feature was marked unstable. 2. Initialization protocol - Theinitialize()method sends hooks configuration to the CLI but doesn't include SDK MCP server tool definitions. TheSDKControlInitializeRequesttype is missing ansdk_mcp_serversfield. 3. Tool discovery vs execution gap - Claude recognizes SDK tool names (shows "Tool used: X") but then reports the tool "is not available", suggesting a disconnect between tool discovery and execution routing. ### Local experiments I tried adding the missing initialization fields and exports locally. The SDK-side changes allow proper star imports and tool extraction from SDK servers during initialization, with all existing tests continuing to pass. However, even with Claude CLI v1.0.108, the streaming mode initialization encounters "ProcessTransport is not ready for writing" errors, and tools still aren't executable in practice. ### Current observation The behavior suggests that while the SDK can create and manage MCP servers internally, the communication protocol between the Python SDK and Claude CLI for in-process servers may need additional coordination. The CLI appears to receive some tool information (hence recognizing names) but can't complete the execution routing back to the SDK.
_Originally posted by @aoezdTchibo in #147_
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗