{"record":{"id":"9c3b0aa6685580c6","repo":"Hmbown/CodeWhale","slug":"failed-to-find-mcp-server-server-name","errorCode":null,"errorMessage":"Failed to find MCP server: {server_name}","messagePattern":"Failed to find MCP server: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp.rs","lineNumber":2669,"sourceCode":"            .map(|conn| conn.is_ready())\n            .unwrap_or(false);\n        if is_ready {\n            return self\n                .connections\n                .get_mut(server_name)\n                .ok_or_else(|| anyhow::anyhow!(\"MCP connection disappeared for {server_name}\"));\n        }\n\n        self.drop_connection(server_name, \"reconnect\");\n\n        // Check static config first, then dynamic servers\n        let server_config = self\n            .config\n            .servers\n            .get(server_name)\n            .cloned()\n            .or_else(|| self.dynamic_servers.read().get(server_name).cloned())\n            .ok_or_else(|| anyhow::anyhow!(\"Failed to find MCP server: {server_name}\"))?;\n\n        if !server_config.is_enabled() {\n            anyhow::bail!(\"Failed to connect MCP server '{server_name}': server is disabled\");\n        }\n\n        let mut connection = McpConnection::connect_with_policy(\n            server_name.to_string(),\n            server_config,\n            &self.config.timeouts,\n            self.network_policy.as_ref(),\n        )\n        .await?;\n        connection.catalog_generation = self.catalog_generation.load(Ordering::SeqCst);\n\n        self.connections.insert(server_name.to_string(), connection);\n        self.connections\n            .get_mut(server_name)\n            .ok_or_else(|| anyhow::anyhow!(\"Failed to store MCP connection for {server_name}\"))","sourceCodeStart":2651,"sourceCodeEnd":2687,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/mcp.rs#L2651-L2687","documentation":"get_or_connect resolves a server by looking in static config (config.servers) first and then the dynamic runtime registry (dynamic_servers); if neither contains the name it fails with this error before attempting any connection. It means the server is not configured at all — distinct from being configured-but-disabled or configured-but-failed.","triggerScenarios":"Calling a tool/resource/prompt API with a server name that is misspelled, refers to a server removed from the config after the last reload, or a dynamic server that was never registered or was unregistered.","commonSituations":"Typos in server names from hand-written tool arguments; stale catalogs where the model or UI remembers a server deleted from .mcp config; referencing a dynamically added server before its registration completes; case-sensitive name mismatches (GitHub vs github).","solutions":["Check the exact server key in the MCP config file (JSON keys are case-sensitive) and correct the caller.","If the server was recently added or removed, force a reload (reload_if_config_changed already runs lazily — verify the file was actually saved) or reconnect.","For dynamic servers, confirm registration happened before dispatching to the name.","List configured servers (config keys + dynamic_servers) in logs to compare against the requested name."],"exampleFix":"# before (.mcp.json)\n{\"servers\": {\"github\": {\"command\": \"gh-mcp\"}}}\n# caller asks for 'Github' -> Failed to find MCP server: Github\n\n# after\n{\"servers\": {\"github\": {\"command\": \"gh-mcp\"}}}\n# caller uses 'github' exactly","handlingStrategy":"validation","validationCode":"// Rust: confirm the name resolves before use\nfn server_exists(pool: &McpPool, name: &str) -> bool {\n    pool.config().servers.contains_key(name)\n        || pool.dynamic_server_names().contains(&name.to_string())\n}\nif !server_exists(&pool, name) {\n    bail!(\"server '{name}' is not configured; check .mcp.json keys (case-sensitive)\");\n}","typeGuard":null,"tryCatchPattern":"// Rust: catch and translate for the model/UI\nmatch pool.get_or_connect(name).await {\n    Err(e) if e.to_string().contains(\"Failed to find MCP server\") => {\n        let known: Vec<_> = pool.config().servers.keys().cloned().collect();\n        bail!(\"unknown server '{name}'; configured servers: {}\", known.join(\", \"))\n    }\n    o => o,\n}","preventionTips":["Always source server names from the live config/catalog, never hard-code them.","Remember names are case-sensitive JSON keys.","After editing config, save the file so the lazy mtime-based reload sees it."],"tags":["mcp","config","lookup","naming"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}