{"record":{"id":"0124d8d14f9ad967","repo":"Hmbown/CodeWhale","slug":"source-contains-unsupported-oauth-fields","errorCode":null,"errorMessage":"Source contains unsupported OAuth fields","messagePattern":"Source contains unsupported OAuth fields","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp/external_import.rs","lineNumber":187,"sourceCode":"            \"disabled\",\n            \"enabled\",\n            \"required\",\n            \"enabled_tools\",\n            \"disabled_tools\",\n            \"headers\",\n            \"env_headers\",\n            \"env_http_headers\",\n            \"bearer_token_env_var\",\n            \"scopes\",\n            \"oauth\",\n            \"oauth_resource\",\n        ];\n        anyhow::ensure!(\n            fields.keys().all(|key| ALLOWED.contains(&key.as_str())),\n            \"Source contains unsupported MCP fields; review it at its source\"\n        );\n        if let Some(oauth) = fields.get(\"oauth\").filter(|v| !v.is_null()) {\n            anyhow::ensure!(\n                oauth\n                    .as_object()\n                    .is_some_and(|map| map.keys().all(|key| key == \"client_id\")),\n                \"Source contains unsupported OAuth fields\"\n            );\n        }\n        let server: McpServerConfig = serde_json::from_value(config)\n            .map_err(|_| anyhow::anyhow!(\"Invalid MCP entry; contents omitted\"))?;\n        anyhow::ensure!(\n            server.command.is_some() != server.url.is_some(),\n            \"MCP entry must have one target\"\n        );\n        if let Some(command) = &server.command {\n            anyhow::ensure!(\n                !command.trim().is_empty() && !command.chars().any(char::is_control),\n                \"Invalid MCP command\"\n            );\n        }","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/mcp/external_import.rs#L169-L205","documentation":"When discovering MCP servers from an external source file (Claude config, marketplace catalog), checked_source validates each server entry's fields against an allow-list before importing. If an entry declares an `oauth` object, only `client_id` is an accepted key; any other OAuth key causes this error and the whole source is rejected rather than partially imported.","triggerScenarios":"`discover` or `discover_from_json_file` reads a source JSON whose server entry has `oauth` containing keys other than `client_id` — e.g. {\"oauth\":{\"client_id\":\"x\",\"client_secret\":\"y\"}} or {\"oauth\":{\"auth_url\":\"...\"}}.","commonSituations":"Importing a config authored for another client that stores full OAuth client credentials (secret, redirect URI, scopes) in its MCP entry; hand-editing an oauth block with keys from a different tool's schema.","solutions":["Remove every key from the `oauth` object except `client_id`, keeping credentials in the environment instead","Move secret material (client_secret, tokens) out of the shared source file entirely","Re-export the source config using only fields from the tool's allowed set (command, args, env, url, oauth.client_id, etc.)"],"exampleFix":"// before\n{\"mcpServers\":{\"fs\":{\"command\":\"npx\",\"oauth\":{\"client_id\":\"abc\",\"client_secret\":\"zzz\"}}}}\n// after\n{\"mcpServers\":{\"fs\":{\"command\":\"npx\",\"oauth\":{\"client_id\":\"abc\"}}}}","handlingStrategy":"validation","validationCode":"const ALLOWED_OAUTH = new Set([\"client_id\"]);\nfunction oauthKeysOk(server) {\n  const o = server.oauth;\n  return o == null || (typeof o === \"object\" && !Array.isArray(o) && Object.keys(o).every(k => ALLOWED_OAUTH.has(k)));\n}","typeGuard":"function hasOnlyClientIdOAuth(v) {\n  return v == null || (typeof v === \"object\" && !Array.isArray(v) && Object.keys(v).every(k => k === \"client_id\"));\n}","tryCatchPattern":null,"preventionTips":["Keep OAuth secrets in environment variables, never in shared config files","Before sharing a config, inspect oauth blocks for keys other than client_id","Lint exported configs against the tool's field allow-list"],"tags":["mcp","oauth","config-validation","security"],"backgroundTag":"unsupported-config-value","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}