Hmbown/CodeWhale · error · anyhow::Error
Source has no supported MCP server map
Error message
Source has no supported MCP server map
What it means
After parsing, checked_source requires the JSON to contain an object under "mcpServers" or "servers", or to be a top-level array of server entries. Valid JSON lacking any of these shapes is rejected — there is no server map to import.
Solutions
- Wrap server entries under a "mcpServers" (or "servers") object in the source file, or use a top-level array of entries
- Verify you selected the right source file — one that actually exports MCP servers under a supported key
- Rename the root key in the source to mcpServers if the exporting tool used a custom key
Example fix
// before (valid JSON, no server map)
{ "myTools": { "fs": { "command": "npx" } } }
// after
{ "mcpServers": { "fs": { "command": "npx" } } } Defensive patterns
Strategy: validation
Validate before calling
fn has_supported_server_map(path: &std::path::Path) -> bool {
std::fs::read_to_string(path).ok()
.and_then(|s| serde_json::from_str::<serde_json::Value>(&s).ok())
.map(|v| v.get("mcpServers").or_else(|| v.get("servers"))
.is_some_and(|m| m.is_object()) || v.is_array())
.unwrap_or(false)
} Type guard
fn extract_server_map<'a>(v: &'a serde_json::Value) -> Option<&'a serde_json::Map<String, serde_json::Value>> {
v.get("mcpServers").or_else(|| v.get("servers"))?.as_object()
} Try / catch
match discover(&path) {
Err(e) if e.to_string().contains("no supported MCP server map") => {
eprintln!("source has no mcpServers/servers object and is not an array; fix the root shape");
}
r => r?,
} Prevention
- Confirm the exporting tool writes under mcpServers or servers before importing
- Wrap bare server objects in {"mcpServers": {...}} for import
- Check the root key name when a tool update changes its export format
- Prefer top-level arrays or mcpServers/servers objects — no other roots are accepted
When it happens
Trigger: discover / discover_from_json_file on a file that is valid JSON but has no mcpServers/servers object and is not an array — e.g. {"foo": 1}, a settings file with a different schema, or a JSONL/other format.
Common situations: Pointing the importer at the wrong tool's config that uses a different root key; importing a partial fragment like a single server object {"command": ...} without the wrapping map; Claude/Codex-style configs whose root key was renamed.
Related errors
- A managed, project or plugin connector already uses this…
- Codewhale session produced no inspectable events.
- Invalid MCP entry; contents omitted
- invalid MCP server definition list in key
- MCP config must be an object
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/2afc07c96635e7ed.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/mcp/external_import.rs:136
out
}
fn discover_from_json_file(path: &Path, kind: ExternalMcpSourceKind) -> Vec<ImportCandidate> {
checked_source(path, kind).unwrap_or_default()
}
fn checked_source(
path: &Path,
kind: ExternalMcpSourceKind,
) -> anyhow::Result<Vec<ImportCandidate>> {
super::validate_mcp_config_path(path)?;
let Some(raw) = super::read_mcp_config_file(path)? else {
return Ok(Vec::new());
};
let hash = hex_sha256(raw.as_bytes());
let value: Value = serde_json::from_str(&raw)
.map_err(|_| anyhow::anyhow!("Source is not valid JSON; contents omitted"))?;
anyhow::ensure!(
value
.get("mcpServers")
.or_else(|| value.get("servers"))
.is_some_and(Value::is_object)
|| value.is_array(),
"Source has no supported MCP server map"
);
let mut out = Vec::new();
for (name, mut config) in extract_servers_map(&value) {
anyhow::ensure!(
super::mcp_name_is_command_safe(&name) && name.len() <= 128,
"Source contains an unsupported server name"
);
if value.is_array()
&& let Some(map) = config.as_object_mut()
{
map.remove("name");
}View on GitHub (pinned to 73e0f67d83)