If your MCP server cannot connect to Claude Code, you are likely using an older version of pmcp that has a JSON-RPC compatibility issue.
Versions of pmcp prior to v1.4.0 used a custom message format that was incompatible with Claude Code and other standard MCP clients.
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": { ... }
}{
"id": 1,
"request": {
"Client": {
"Initialize": { ... }
}
}
}This caused:
- Connection timeouts with Claude Code
- "Invalid JSON" errors
- Complete inability to use Rust-based MCP servers
Upgrade to pmcp v1.4.1 or later, which includes full JSON-RPC 2.0 compatibility.
[dependencies]
pmcp = "1.4.1" # or latest versionIf you have custom JSON-RPC conversion code, remove it. The SDK now handles this automatically.
// Custom JSON-RPC to TransportMessage conversion
fn convert_jsonrpc_to_transport(json: Value) -> TransportMessage {
// Complex conversion logic
}// No conversion needed - SDK handles it internally
server.run_stdio().await?;cargo update
cargo clean
cargo build --release# Add your server to Claude Code
claude mcp add my-server ./target/release/my-mcp-server
# Test the connection
claude mcp test my-serverCause: Using pmcp < 1.4.0 with Claude Code
Solution: Upgrade to pmcp 1.4.1+
Cause: Server cannot parse JSON-RPC messages from Claude Code
Solution: Upgrade to pmcp 1.4.1+
Cause: Custom client using old pmcp message format
Solution: Upgrade both server and client to pmcp 1.4.1+
| pmcp Version | Claude Code | TypeScript SDK | Python SDK | Notes |
|---|---|---|---|---|
| < 1.4.0 | ❌ | ❌ | ❌ | Custom format only |
| 1.4.0 | ✅ | ✅ | ✅ | JSON-RPC 2.0 added |
| 1.4.1+ | ✅ | ✅ | ✅ | Recommended |
use pmcp::{Server, ServerCapabilities, ToolHandler};
use async_trait::async_trait;
struct MyTool;
#[async_trait]
impl ToolHandler for MyTool {
async fn handle(
&self,
args: serde_json::Value,
_extra: pmcp::RequestHandlerExtra
) -> Result<serde_json::Value, pmcp::Error> {
Ok(serde_json::json!({
"result": "Tool executed successfully"
}))
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let server = Server::builder()
.name("my-mcp-server")
.version("1.0.0")
.capabilities(ServerCapabilities::tools_only())
.tool("my_tool", MyTool)
.build()?;
// This now works with Claude Code!
server.run_stdio().await?;
Ok(())
}- Create a test script (
test_connection.sh):
#!/bin/bash
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | \
timeout 5 ./target/release/my-mcp-server- Expected output (successful connection):
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{...},"serverInfo":{...}}}If you maintain a library that depends on pmcp:
- Update your dependency to require pmcp 1.4.1+:
[dependencies]
pmcp = "^1.4.1"- Add a note in your README about Claude Code compatibility
- Consider adding a compatibility test
- Check the JSON-RPC compatibility tests
- See the compatibility documentation
- Open an issue if you encounter problems after upgrading
Remember: The compatibility issue is completely resolved in pmcp 1.4.1+. A simple version upgrade is all you need!