fix(mcp): default Apps product SKU to codex (#31803)

## Motivation

Host-owned Apps MCP requests currently omit `X-OpenAI-Product-Sku`
unless `apps_mcp_product_sku` is explicitly configured. Codex requests
should identify themselves with the `codex` product SKU by default.

## Changes

- Default `X-OpenAI-Product-Sku` to `codex`.
- Preserve explicitly configured SKU values.
- Add coverage for both default and configured behavior.

## Impact

Codex Apps MCP requests now include the expected product identity
without requiring local configuration. Existing explicit SKU overrides
are unchanged.

## Testing

- `just test -p codex-mcp
codex_apps_server_config_sets_product_sku_header`
- `just fix -p codex-mcp`
- `just fmt`
This commit is contained in:
Alec Barber
2026-07-09 16:04:02 +01:00
committed by GitHub
parent 091b2ada94
commit 23a09eb3c3
2 changed files with 24 additions and 19 deletions
+6 -3
View File
@@ -51,6 +51,7 @@ use crate::runtime::McpRuntimeContext;
use crate::server::EffectiveMcpServer;
pub const CODEX_APPS_MCP_SERVER_NAME: &str = "codex_apps";
const DEFAULT_CODEX_APPS_MCP_PRODUCT_SKU: &str = "codex";
const MCP_TOOL_NAME_PREFIX: &str = "mcp";
const MCP_TOOL_NAME_DELIMITER: &str = "__";
const CODEX_CONNECTORS_TOKEN_ENV_VAR: &str = "CODEX_CONNECTORS_TOKEN";
@@ -523,9 +524,11 @@ fn mcp_server_config_for_url(
apps_mcp_product_sku: Option<&str>,
auth_mode: McpServerAuth,
) -> McpServerConfig {
let http_headers = apps_mcp_product_sku.map(|product_sku| {
HashMap::from([("X-OpenAI-Product-Sku".to_string(), product_sku.to_string())])
});
let product_sku = apps_mcp_product_sku.unwrap_or(DEFAULT_CODEX_APPS_MCP_PRODUCT_SKU);
let http_headers = Some(HashMap::from([(
"X-OpenAI-Product-Sku".to_string(),
product_sku.to_string(),
)]));
McpServerConfig {
transport: McpServerTransportConfig::StreamableHttp {
+18 -16
View File
@@ -263,25 +263,27 @@ fn codex_apps_server_config_uses_legacy_codex_apps_path() {
}
#[test]
fn codex_apps_server_config_forwards_configured_product_sku_header() {
let config = codex_apps_mcp_server_config("https://chatgpt.com", Some("tpp"));
fn codex_apps_server_config_sets_product_sku_header() {
for (configured_product_sku, expected_product_sku) in [(None, "codex"), (Some("tpp"), "tpp")] {
let config = codex_apps_mcp_server_config("https://chatgpt.com", configured_product_sku);
match &config.transport {
McpServerTransportConfig::StreamableHttp {
http_headers,
env_http_headers,
..
} => {
assert_eq!(
match &config.transport {
McpServerTransportConfig::StreamableHttp {
http_headers,
&Some(HashMap::from([(
"X-OpenAI-Product-Sku".to_string(),
"tpp".to_string(),
)]))
);
assert!(env_http_headers.is_none());
env_http_headers,
..
} => {
assert_eq!(
http_headers,
&Some(HashMap::from([(
"X-OpenAI-Product-Sku".to_string(),
expected_product_sku.to_string(),
)]))
);
assert!(env_http_headers.is_none());
}
other => panic!("expected streamable http transport, got {other:?}"),
}
other => panic!("expected streamable http transport, got {other:?}"),
}
}