{"record":{"id":"567a0237fe8d45c2","repo":"ultraworkers/claw-code","slug":"mcp-bootstrap-transport-for-is-not-stdio-othe","errorCode":null,"errorMessage":"MCP bootstrap transport for {} is not stdio: {other:?}","messagePattern":"MCP bootstrap transport for (.+?) is not stdio: (.+?)","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"rust/crates/runtime/src/mcp_stdio.rs","lineNumber":1394,"sourceCode":"    }\n\n    async fn shutdown(&mut self) -> io::Result<()> {\n        if self.child.try_wait()?.is_none() {\n            match self.child.kill().await {\n                Ok(()) => {}\n                Err(error) if error.kind() == io::ErrorKind::InvalidInput => {}\n                Err(error) => return Err(error),\n            }\n        }\n        let _ = self.child.wait().await?;\n        Ok(())\n    }\n}\n\npub fn spawn_mcp_stdio_process(bootstrap: &McpClientBootstrap) -> io::Result<McpStdioProcess> {\n    match &bootstrap.transport {\n        McpClientTransport::Stdio(transport) => McpStdioProcess::spawn(transport),\n        other => Err(io::Error::new(\n            io::ErrorKind::InvalidInput,\n            format!(\n                \"MCP bootstrap transport for {} is not stdio: {other:?}\",\n                bootstrap.server_name\n            ),\n        )),\n    }\n}\n\nfn apply_env(command: &mut Command, env: &BTreeMap<String, String>) {\n    for (key, value) in env {\n        command.env(key, value);\n    }\n}\n\nfn encode_frame(payload: &[u8]) -> Vec<u8> {\n    let header = format!(\"Content-Length: {}\\r\\n\\r\\n\", payload.len());\n    let mut framed = header.into_bytes();","sourceCodeStart":1376,"sourceCodeEnd":1412,"githubUrl":"https://github.com/ultraworkers/claw-code/blob/08106b0c3771ef5b4a5aa176acccd460e88b7325/rust/crates/runtime/src/mcp_stdio.rs#L1376-L1412","documentation":"`spawn_mcp_stdio_process` (runtime/src/mcp_stdio.rs:1394) only knows how to spawn stdio servers: it matches `McpClientTransport::Stdio` and rejects everything else — Sse, Http, WebSocket, Sdk, ManagedProxy (mcp_client.rs:9) — with `InvalidInput` naming the configured server. Reaching it with a remote-style server means the caller routed a non-stdio config into the stdio spawner.","triggerScenarios":"An MCP config entry declared with a `url` (SSE/HTTP/WebSocket transport) passed to a code path that calls spawn_mcp_stdio_process; config migration renaming stdio fields so the entry no longer parses as Stdio; a managed-proxy/SDK entry fed to the generic spawn helper.","commonSituations":"Mixed MCP fleets (some `command:` servers, some `url:` servers) where the dispatcher assumes all are stdio; switching a server entry from `command/args` to `url` without updating the client path that consumed it.","solutions":["If the server should be stdio, change its config back to command/args (with env) form so it parses as McpClientTransport::Stdio.","If the server is genuinely remote, route it through the SSE/HTTP client path instead of the stdio spawner.","Dispatch on the transport enum before spawning so each transport reaches its own client."],"exampleFix":"# before (config uses a url, but this path only spawns stdio)\n[mcp.docs]\nurl = \"https://mcp.example.com/sse\"\n\n# after (either make it stdio)\n[mcp.docs]\ncommand = \"npx\"\nargs = [\"-y\", \"@mcp/docs-server\"]\n# ...or keep the url and use the SSE/HTTP MCP client instead of spawn_mcp_stdio_process","handlingStrategy":"type-guard","validationCode":"if !matches!(bootstrap.transport, McpClientTransport::Stdio(_)) {\n    // route to the SSE/HTTP/SDK client path instead of the stdio spawner\n}","typeGuard":"fn is_stdio_bootstrap(b: &McpClientBootstrap) -> bool {\n    matches!(b.transport, McpClientTransport::Stdio(_))\n}","tryCatchPattern":"match spawn_mcp_stdio_process(bootstrap) {\n    Err(e) if e.kind() == io::ErrorKind::InvalidInput\n        && e.to_string().contains(\"is not stdio\") => { /* dispatch remote transports to their own client */ }\n    other => other,\n}","preventionTips":["Dispatch on the McpClientTransport enum before spawning — only Stdio belongs in spawn_mcp_stdio_process","Keep config truth: command/args => stdio, url => remote transport","After editing MCP config, verify which transport each entry parses into"],"tags":["mcp","transport","config","invalid-input"],"backgroundTag":"transport-type-mismatch","analyzedSha":"08106b0c3771ef5b4a5aa176acccd460e88b7325","analyzedAt":"2026-08-18T00:29:38.590Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}