Client or integration
opencodex 2.55.0 (@bitkyc08/opencodex, Docker node:22-slim) running as the Responses→Chat translation proxy in front of the Command Code provider (api.commandcode.ai, openai-chat adapter). Client: Codex Desktop / codex-cli 0.153.x.
Summary
When a Codex client declares many MCP/app tools, namespace-tool-compat flattens namespaced tools to <namespace>__<name> for chat gateways. Some strict gateways cap function names at 64 characters. Command Code's AI gateway rejects the whole request before inference:
{"error":{"message":"`name` must be at most 64 characters, got 66","type":"invalid_request_error"}}
The 66-char name in that gateway error is mcp__codex_apps__codex_document_control___execute_document_command. Other real offenders (Codex Desktop built-in app tools — the user cannot exclude them from the bundle):
mcp__codex_apps__codex_document_control___get_document_tool_schemas (67)
mcp__codex_apps__safety_settings___prepare_parental_control_update (65)
This bites exactly on Responses-Lite catalogs (use_responses_lite: true), where the client bundles every declared tool into the additional_tools input item — there is no way to shrink the surface from config.
Reproduction
- Run opencodex 2.55.0 behind any client with the standard Codex Desktop tool set, routed to Command Code.
- Send any turn with
use_responses_lite: true.
- → 400
name must be at most 64 characters, got 66 from the gateway; the turn fails.
Suggested fix
A bounded, deterministic, reversible alias at the single point where wire names are produced — namespacedToolName() / dottedToolName() in src/types/tools.ts — so declarations, history replay, toolNsMap/declaredToolNames (built in server/responses/collaboration.ts) and the undeclared-tool guard all stay consistent, and provider echoes restore to the native {namespace, name} automatically:
// alias = flat.slice(0, 64 - 13) + "_" + sha256(`${ns ?? ""}\0${name}\0${attempt}`).slice(0, 12)
- stable across restarts (digest of the native identity, not declaration order);
- collision-safe loop (claimed-alias set,
attempt bump);
- no dotted spelling for a bounded alias (it is already at the limit);
- restore falls out for free because the bridge keys
toolNsMap by the same function's output.
Precedent: codex-router special-cases exactly this as BOUNDED_TOOL_NAME_PROVIDERS = {"commandcode", "commandcode-messages"} with BOUNDED_TOOL_NAME_LENGTH = 64 (src/chat-tool-surface.mjs + deterministic truncate+digest aliases in src/namespace-relay.mjs).
Version
opencodex 2.55.0 (@bitkyc08/opencodex npm).
Operating system
Linux (Docker, node:22-slim) for the proxy; macOS 26 arm64 for the Codex client.
A PR implementing the suggested fix is up and validated in production: #4715. A long-name tool round-trips (function_call returns with namespace: "mcp__codex_apps__safety_settings" restored), and a meta/muse-spark-1.3 root session spawned a deepseek-v4.1-flash subagent end-to-end through Command Code.
Client or integration
opencodex 2.55.0 (
@bitkyc08/opencodex, Dockernode:22-slim) running as the Responses→Chat translation proxy in front of the Command Code provider (api.commandcode.ai, openai-chat adapter). Client: Codex Desktop / codex-cli 0.153.x.Summary
When a Codex client declares many MCP/app tools,
namespace-tool-compatflattens namespaced tools to<namespace>__<name>for chat gateways. Some strict gateways cap function names at 64 characters. Command Code's AI gateway rejects the whole request before inference:{"error":{"message":"`name` must be at most 64 characters, got 66","type":"invalid_request_error"}}The 66-char name in that gateway error is
mcp__codex_apps__codex_document_control___execute_document_command. Other real offenders (Codex Desktop built-in app tools — the user cannot exclude them from the bundle):mcp__codex_apps__codex_document_control___get_document_tool_schemas(67)mcp__codex_apps__safety_settings___prepare_parental_control_update(65)This bites exactly on Responses-Lite catalogs (
use_responses_lite: true), where the client bundles every declared tool into theadditional_toolsinput item — there is no way to shrink the surface from config.Reproduction
use_responses_lite: true.name must be at most 64 characters, got 66from the gateway; the turn fails.Suggested fix
A bounded, deterministic, reversible alias at the single point where wire names are produced —
namespacedToolName()/dottedToolName()insrc/types/tools.ts— so declarations, history replay,toolNsMap/declaredToolNames(built inserver/responses/collaboration.ts) and the undeclared-tool guard all stay consistent, and provider echoes restore to the native{namespace, name}automatically:// alias = flat.slice(0, 64 - 13) + "_" + sha256(`${ns ?? ""}\0${name}\0${attempt}`).slice(0, 12)attemptbump);toolNsMapby the same function's output.Precedent: codex-router special-cases exactly this as
BOUNDED_TOOL_NAME_PROVIDERS = {"commandcode", "commandcode-messages"}withBOUNDED_TOOL_NAME_LENGTH = 64(src/chat-tool-surface.mjs+ deterministic truncate+digest aliases insrc/namespace-relay.mjs).Version
opencodex 2.55.0 (
@bitkyc08/opencodexnpm).Operating system
Linux (Docker,
node:22-slim) for the proxy; macOS 26 arm64 for the Codex client.A PR implementing the suggested fix is up and validated in production: #4715. A long-name tool round-trips (
function_callreturns withnamespace: "mcp__codex_apps__safety_settings"restored), and ameta/muse-spark-1.3root session spawned adeepseek-v4.1-flashsubagent end-to-end through Command Code.