From 6f87eb0479018f0dd93db3f9f7b89902aebedb50 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Fri, 24 Apr 2026 00:17:43 -0700 Subject: [PATCH] Hide unsupported MCP bearer_token from config schema (#19294) ## Summary Fixes #19275. Codex runtime rejects inline MCP `bearer_token` config entries and asks users to configure `bearer_token_env_var` instead, but the generated config schema still advertised `mcp_servers..bearer_token` as a supported field. That made editor/schema validation disagree with runtime validation. This keeps `bearer_token` in `RawMcpServerConfig` so Codex can continue producing the targeted runtime error for recent or existing configs, but skips the field during schemars generation. The checked-in `core/config.schema.json` fixture now exposes `bearer_token_env_var` without exposing unsupported inline `bearer_token`. ## Verification - Added `config_schema_hides_unsupported_inline_mcp_bearer_token` to assert the generated schema hides `bearer_token` while preserving `bearer_token_env_var`. - Ran `cargo test -p codex-config`. - Ran `cargo test -p codex-core config_schema`. --- codex-rs/config/src/mcp_types.rs | 7 ++++++- codex-rs/core/config.schema.json | 5 +---- codex-rs/core/src/config/schema_tests.rs | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/codex-rs/config/src/mcp_types.rs b/codex-rs/config/src/mcp_types.rs index a276cd7070..d642d9fc57 100644 --- a/codex-rs/config/src/mcp_types.rs +++ b/codex-rs/config/src/mcp_types.rs @@ -176,7 +176,11 @@ pub struct McpServerConfig { pub tools: HashMap, } -/// Raw MCP config shape used for deserialization and JSON Schema generation. +/// Raw MCP config shape used for deserialization and supported-field JSON +/// Schema generation. +/// +/// Fields that are accepted only to produce targeted validation errors should +/// be skipped in the generated schema. /// /// Keep `TryFrom for McpServerConfig` exhaustively /// destructuring this struct so new TOML fields cannot be added here without @@ -200,6 +204,7 @@ pub struct RawMcpServerConfig { // streamable_http pub url: Option, + #[schemars(skip)] pub bearer_token: Option, pub bearer_token_env_var: Option, diff --git a/codex-rs/core/config.schema.json b/codex-rs/core/config.schema.json index 0673619971..a88cc21b82 100644 --- a/codex-rs/core/config.schema.json +++ b/codex-rs/core/config.schema.json @@ -1709,7 +1709,7 @@ }, "RawMcpServerConfig": { "additionalProperties": false, - "description": "Raw MCP config shape used for deserialization and JSON Schema generation.\n\nKeep `TryFrom for McpServerConfig` exhaustively destructuring this struct so new TOML fields cannot be added here without updating the validation/mapping logic that produces [`McpServerConfig`].", + "description": "Raw MCP config shape used for deserialization and supported-field JSON Schema generation.\n\nFields that are accepted only to produce targeted validation errors should be skipped in the generated schema.\n\nKeep `TryFrom for McpServerConfig` exhaustively destructuring this struct so new TOML fields cannot be added here without updating the validation/mapping logic that produces [`McpServerConfig`].", "properties": { "args": { "default": null, @@ -1718,9 +1718,6 @@ }, "type": "array" }, - "bearer_token": { - "type": "string" - }, "bearer_token_env_var": { "type": "string" }, diff --git a/codex-rs/core/src/config/schema_tests.rs b/codex-rs/core/src/config/schema_tests.rs index 31fabd64bd..dd67ead898 100644 --- a/codex-rs/core/src/config/schema_tests.rs +++ b/codex-rs/core/src/config/schema_tests.rs @@ -53,3 +53,23 @@ Run `just write-config-schema` to overwrite with your changes.\n\n{diff}" "fixture should match exactly with generated schema" ); } + +#[test] +fn config_schema_hides_unsupported_inline_mcp_bearer_token() { + let schema_json = config_schema_json().expect("serialize config schema"); + let schema_value: serde_json::Value = + serde_json::from_slice(&schema_json).expect("decode schema json"); + let properties = schema_value + .pointer("/definitions/RawMcpServerConfig/properties") + .expect("RawMcpServerConfig properties should exist") + .as_object() + .expect("RawMcpServerConfig properties should be an object"); + + assert_eq!( + ( + properties.contains_key("bearer_token"), + properties.contains_key("bearer_token_env_var"), + ), + (false, true), + ); +}