Files
codex/codex-rs/ext/mcp/src/lib.rs
raquel-openai b58952b0fa fix: forward originator to Codex Apps MCP (#31481)
## Summary
- Forward Codexs canonical `originator` header on ChatGPT-hosted Apps
and plugin-runtime MCP requests.
- Preserve the configured `X-OpenAI-Product-Sku` header.
- Cover originator-only and originator-plus-SKU configurations.

## Why
Sites project creation is logged downstream of Apps MCP. Production
validation found `CODEX_UNKNOWN_DEFAULT` project-created threads that
matched `codex_surface=desktop_app` and `originator=Codex Desktop` in
`fact_codex_cli`
([query](https://kepler.gateway.data-1.internal.api.openai.org/permalink/H_mVoVPqLQ0)).

The hosted Apps MCP configuration forwarded the product SKU but not
Codexs canonical originator, so codex-backend could not derive
`CODEX_DESKTOP_APP` for those tool calls.

## Validation
- `just fmt`
- `CARGO_HOME=/private/tmp/codex-cargo-home
CARGO_TARGET_DIR=/private/tmp/codex-target just test -p codex-mcp` (106
passed)
- `CARGO_HOME=/private/tmp/codex-cargo-home
CARGO_TARGET_DIR=/private/tmp/codex-target just fix -p codex-mcp`
2026-07-09 16:51:44 +00:00

59 lines
1.9 KiB
Rust

use codex_core::config::Config;
use codex_extension_api::ExtensionFuture;
use codex_extension_api::ExtensionRegistryBuilder;
use codex_extension_api::McpServerContribution;
use codex_extension_api::McpServerContributionContext;
use codex_extension_api::McpServerContributor;
use codex_mcp::CODEX_APPS_MCP_SERVER_NAME;
use codex_mcp::hosted_plugin_runtime_mcp_server_config;
mod executor_plugin;
struct HostedPluginRuntimeExtension;
impl McpServerContributor<Config> for HostedPluginRuntimeExtension {
fn id(&self) -> &'static str {
"hosted_plugin_runtime"
}
fn contribute<'a>(
&'a self,
context: McpServerContributionContext<'a, Config>,
) -> ExtensionFuture<'a, Vec<McpServerContribution>> {
Box::pin(async move {
let config = context.config();
let name = CODEX_APPS_MCP_SERVER_NAME.to_string();
if !config.features.enabled(codex_features::Feature::Apps) {
return vec![McpServerContribution::Remove { name }];
}
vec![McpServerContribution::Set {
name,
config: Box::new(hosted_plugin_runtime_mcp_server_config(
&config.chatgpt_base_url,
config.apps_mcp_product_sku.as_deref(),
context.originator(),
)),
}]
})
}
}
pub fn install(builder: &mut ExtensionRegistryBuilder<Config>) {
builder.mcp_server_contributor(std::sync::Arc::new(HostedPluginRuntimeExtension));
}
/// Installs discovery for MCP servers declared by thread-selected executor plugins.
pub fn install_executor_plugins(
builder: &mut ExtensionRegistryBuilder<Config>,
environment_manager: std::sync::Arc<codex_exec_server::EnvironmentManager>,
) {
builder.mcp_server_contributor(std::sync::Arc::new(
executor_plugin::SelectedExecutorPluginMcpContributor::new(environment_manager),
));
}
#[cfg(test)]
#[path = "lib_tests.rs"]
mod tests;