Hmbown/CodeWhale · error · anyhow::Error

Source contains unsupported MCP fields; review it at its…

Error message

Source contains unsupported MCP fields; review it at its source

What it means

Imported server entries may only contain a whitelist of fields (command, args, env, cwd, url, headers, env_http_headers, bearer_token_env_var, scopes, oauth, oauth_resource, etc.). If an entry has any key outside ALLOWED, checked_source refuses the import and tells you to review the source, because unknown fields could carry behavior the importer cannot safely translate.

Solutions

  1. Remove or rename unsupported keys in the source entry, keeping only whitelisted fields (command, args, env, cwd, url, headers, env_http_headers, bearer_token_env_var, scopes, oauth, oauth_resource)
  2. Re-express needed semantics with supported fields (e.g. map a transport type to command vs url) and re-run discovery
  3. Review the source at its origin as the message says — determine which tool wrote the extra fields and whether they matter before stripping them

Example fix

// before (unsupported field "timeout")
{ "fs": { "command": "npx", "timeout": 30 } }
// after
{ "fs": { "command": "npx" } }
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED: &[&str] = &["command","args","env","cwd","url","headers","env_http_headers","bearer_token_env_var","scopes","oauth","oauth_resource"];
fn entries_use_allowed_fields(path: &std::path::Path) -> bool {
    std::fs::read_to_string(path).ok()
        .and_then(|s| serde_json::from_str::<serde_json::Value>(&s).ok())
        .and_then(|v| v.get("mcpServers").or_else(|| v.get("servers")).cloned())
        .and_then(|m| m.as_object().cloned())
        .map(|m| m.values().all(|e| e.as_object()
            .map_or(false, |o| o.keys().all(|k| ALLOWED.contains(&k.as_str())))))
        .unwrap_or(false)
}

Type guard

fn only_allowed_fields(v: &serde_json::Value) -> bool {
    v.as_object().map_or(false, |o|
        o.keys().all(|k| ALLOWED.contains(&k.as_str())))
}

Try / catch

match discover(&path) {
    Err(e) if e.to_string().contains("unsupported MCP fields") => {
        eprintln!("strip non-whitelisted fields from the source entries and re-import");
    }
    r => r?,
}

Prevention

When it happens

Trigger: discover / discover_from_json_file where a server entry contains a key not in the ALLOWED list — e.g. "type", "disabled", "timeout", "transport", tool-specific vendor fields, or nested metadata added by another client.

Common situations: Importing configs from other MCP clients that store extra per-server options (type: "stdio", disabled flags, timeouts, prompts); a hand-added note or comment field; schema drift after the exporting tool updated its format.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/501ff56fe0ead8fe. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/mcp/external_import.rs:182

            "allow_private_network",
            "transport",
            "connect_timeout",
            "execute_timeout",
            "read_timeout",
            "disabled",
            "enabled",
            "required",
            "enabled_tools",
            "disabled_tools",
            "headers",
            "env_headers",
            "env_http_headers",
            "bearer_token_env_var",
            "scopes",
            "oauth",
            "oauth_resource",
        ];
        anyhow::ensure!(
            fields.keys().all(|key| ALLOWED.contains(&key.as_str())),
            "Source contains unsupported MCP fields; review it at its source"
        );
        if let Some(oauth) = fields.get("oauth").filter(|v| !v.is_null()) {
            anyhow::ensure!(
                oauth
                    .as_object()
                    .is_some_and(|map| map.keys().all(|key| key == "client_id")),
                "Source contains unsupported OAuth fields"
            );
        }
        let server: McpServerConfig = serde_json::from_value(config)
            .map_err(|_| anyhow::anyhow!("Invalid MCP entry; contents omitted"))?;
        anyhow::ensure!(
            server.command.is_some() != server.url.is_some(),
            "MCP entry must have one target"
        );
        if let Some(command) = &server.command {

View on GitHub (pinned to 73e0f67d83)