From 2f3b5ed81ac939db908fb8ca2aeb80c42e8e7600 Mon Sep 17 00:00:00 2001 From: colby-oai <228809017+colby-oai@users.noreply.github.com> Date: Mon, 27 Apr 2026 20:42:10 -0400 Subject: [PATCH] disallow fileparams metadata for custom mcps (#19836) ## Summary Disallow fileParams metadata for custom MCPs Restricts Codex openai/fileParams handling to the first-party codex_apps MCP server. Custom MCP servers may still advertise the metadata, but Codex now ignores it for upload rewriting, preventing non-Apps tools from receiving signed OpenAI file refs for local paths. Added a regression test for the allowed and denied cases. --- codex-rs/core/src/mcp_tool_call.rs | 16 +++++++++++++--- codex-rs/core/src/mcp_tool_call_tests.rs | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/codex-rs/core/src/mcp_tool_call.rs b/codex-rs/core/src/mcp_tool_call.rs index b6646a338..efa50b2b4 100644 --- a/codex-rs/core/src/mcp_tool_call.rs +++ b/codex-rs/core/src/mcp_tool_call.rs @@ -1194,13 +1194,23 @@ pub(crate) async fn lookup_mcp_tool_metadata( .and_then(|meta| meta.get(MCP_TOOL_CODEX_APPS_META_KEY)) .and_then(serde_json::Value::as_object) .cloned(), - openai_file_input_params: Some(declared_openai_file_input_param_names( + // Disallow custom MCPs from uploading files via fileParams. + openai_file_input_params: openai_file_input_params_for_server( + server, tool_info.tool.meta.as_deref(), - )) - .filter(|params| !params.is_empty()), + ), }) } +fn openai_file_input_params_for_server( + server: &str, + meta: Option<&serde_json::Map>, +) -> Option> { + (server == CODEX_APPS_MCP_SERVER_NAME) + .then_some(declared_openai_file_input_param_names(meta)) + .filter(|params| !params.is_empty()) +} + fn get_mcp_app_resource_uri( meta: Option<&serde_json::Map>, ) -> Option { diff --git a/codex-rs/core/src/mcp_tool_call_tests.rs b/codex-rs/core/src/mcp_tool_call_tests.rs index 8b3f22770..5ab2c6c4e 100644 --- a/codex-rs/core/src/mcp_tool_call_tests.rs +++ b/codex-rs/core/src/mcp_tool_call_tests.rs @@ -183,6 +183,23 @@ fn mcp_app_resource_uri_reads_known_tool_meta_keys() { ); } +#[test] +fn openai_file_params_are_only_honored_for_codex_apps() { + let meta = serde_json::json!({ + "openai/fileParams": ["file"], + }); + let meta = meta.as_object(); + + assert_eq!( + openai_file_input_params_for_server(CODEX_APPS_MCP_SERVER_NAME, meta), + Some(vec!["file".to_string()]) + ); + assert_eq!( + openai_file_input_params_for_server("minimaltest", meta), + None + ); +} + #[test] fn approval_required_when_read_only_false_and_destructive() { let annotations = annotations(Some(false), Some(true), /*open_world*/ None);