From 1bfabb21fe56e21adce3aed945ab74aff27b67d2 Mon Sep 17 00:00:00 2001 From: Angad Singh Date: Wed, 19 Aug 2026 18:29:59 +0000 Subject: [PATCH] Raise the MCP tool name limit to 128 bytes (#39594) ## Why The Responses API accepts tool names up to 128 bytes, but MCP tool name normalization limited model-visible names to 64 bytes. ## What changed - Preserve MCP tool names up to the 128-byte Responses API limit. - Continue shortening and hashing names that exceed the limit so generated names remain bounded and unique. ## Testing - Cover names at the 128-byte boundary and immediately above it. - Verify distinct long names remain 128 bytes and code-mode compatible. GitOrigin-RevId: 75544d00e75dd0e9328b3e2ac763d26f9cc99a48 --- .../codex-mcp/src/connection_manager_tests.rs | 37 ++++++++++++++----- codex-rs/codex-mcp/src/tools.rs | 4 +- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/codex-rs/codex-mcp/src/connection_manager_tests.rs b/codex-rs/codex-mcp/src/connection_manager_tests.rs index fac9f6731b..a33ddf3323 100644 --- a/codex-rs/codex-mcp/src/connection_manager_tests.rs +++ b/codex-rs/codex-mcp/src/connection_manager_tests.rs @@ -1440,19 +1440,38 @@ fn test_normalize_tools_duplicated_names_skipped() { ); } +#[test] +fn test_normalize_tools_respects_responses_api_name_length_boundaries() { + let namespace = "mcp__codex_apps"; + let namespace_len = namespace.len() + "__".len(); + + for total_len in [128, 129] { + let tool_name = "a".repeat(total_len - namespace_len); + let model_tools = normalize_tools_for_model_with_prefix( + vec![create_test_tool("codex_apps", &tool_name)], + /*prefix_mcp_tool_names*/ true, + &[], + ); + let model_name = model_tools[0].canonical_tool_name(); + + assert_eq!(model_tool_name_len(&model_name), 128); + if total_len == 128 { + assert_eq!(model_name, ToolName::namespaced(namespace, tool_name)); + } else { + assert_ne!(model_name.name, tool_name); + } + } +} + #[test] fn test_normalize_tools_long_names_same_server() { let server_name = "my_server"; + let first_name = "a".repeat(128); + let second_name = "b".repeat(128); let tools = vec![ - create_test_tool( - server_name, - "extremely_lengthy_function_name_that_absolutely_surpasses_all_reasonable_limits", - ), - create_test_tool( - server_name, - "yet_another_extremely_lengthy_function_name_that_absolutely_surpasses_all_reasonable_limits", - ), + create_test_tool(server_name, &first_name), + create_test_tool(server_name, &second_name), ]; let model_tools = @@ -1462,7 +1481,7 @@ fn test_normalize_tools_long_names_same_server() { let names = model_tool_names(&model_tools); - assert!(names.iter().all(|name| model_tool_name_len(name) == 64)); + assert!(names.iter().all(|name| model_tool_name_len(name) == 128)); assert!( names .iter() diff --git a/codex-rs/codex-mcp/src/tools.rs b/codex-rs/codex-mcp/src/tools.rs index a7ae51925d..51d3f05aac 100644 --- a/codex-rs/codex-mcp/src/tools.rs +++ b/codex-rs/codex-mcp/src/tools.rs @@ -106,7 +106,7 @@ pub(crate) fn filter_tools(tools: Vec, filter: &ToolFilter) -> Vec String { if !prefix_mcp_tool_names || namespace.starts_with(LEGACY_MCP_TOOL_NAME_PREFIX) {