Client or integration
Codex App
Provider or upstream service
Devin / Cognition cloud-direct (devin, model swe-2)
OpenCodex version
@bitkyc08/opencodex 2.52.0 and dev at dc33113a9
Endpoint or capability
/v1/responses streaming client tool calls with namespaced MCP tools
Current behaviour
The Devin adapter advertises every tool to Cognition as the local tool.name, dropping its Codex namespace. For a request that declares CUA as mcp__cua_repl__js, Cognition sees and returns js. runTurn forwards that bare name unchanged, while the Responses bridge authorizes the canonical request name. The fail-closed guard then terminates the turn with HTTP 502.
Redacted local observations on 2026-09-13 recorded 14 identical 502s across four conversations from devin/swe-2 between 12:28 and 12:33 KST.
Expected behaviour
When Devin returns a bare tool name that uniquely identifies one request tool, the adapter should restore the request's canonical wire identity before the shared Responses bridge validates and dispatches it. A bare name shared by multiple request tools must fail without choosing by declaration order. Unknown names must remain subject to the existing undeclared-tool guard.
Minimal redacted request or reproduction
# OpenCodex 2.52.0, Codex CLI/App 0.154.0
# Route a Codex task through devin/swe-2 with the CUA MCP tool declared as:
# namespace: mcp__cua_repl
# name: js
# Ask the model to continue a browser/UI task that requires that tool.
# The adapter sends Cognition the bare name "js" and returns the same bare name.
Actual response or error
stream disconnected before completion: routed provider emitted undeclared client tool "js"; only request-declared tools may be called
Upstream documentation
Cognition's cloud-direct Connect-RPC endpoint has no public tool-naming specification. The concrete client contract is the Responses request catalog: the client declared mcp__cua_repl__js, and OpenCodex must preserve that tool identity across an adapter that intentionally advertises its local name upstream.
Relevant source on dev: src/adapters/devin.ts maps tools with name: tool.name and emits event.name unchanged. The shared bridge uses namespacedToolName(namespace, name) as the authorized wire identity.
Suggested mapping or implementation notes
Build a request-scoped map from each advertised local name to namespacedToolName(tool.namespace, tool.name). Restore only uniquely owned names on tool_call_start. Represent collisions explicitly and emit a non-retryable adapter error before dispatch; preserve unknown names for the shared fail-closed guard.
Keep Cognition's current bare-name request contract and catalog nudge unchanged. This makes the response half symmetric without broadly authorizing bare aliases in the provider-independent bridge.
Additional context and attachments
Checks
Client or integration
Codex App
Provider or upstream service
Devin / Cognition cloud-direct (
devin, modelswe-2)OpenCodex version
@bitkyc08/opencodex2.52.0 anddevatdc33113a9Endpoint or capability
/v1/responsesstreaming client tool calls with namespaced MCP toolsCurrent behaviour
The Devin adapter advertises every tool to Cognition as the local
tool.name, dropping its Codex namespace. For a request that declares CUA asmcp__cua_repl__js, Cognition sees and returnsjs.runTurnforwards that bare name unchanged, while the Responses bridge authorizes the canonical request name. The fail-closed guard then terminates the turn with HTTP 502.Redacted local observations on 2026-09-13 recorded 14 identical 502s across four conversations from
devin/swe-2between 12:28 and 12:33 KST.Expected behaviour
When Devin returns a bare tool name that uniquely identifies one request tool, the adapter should restore the request's canonical wire identity before the shared Responses bridge validates and dispatches it. A bare name shared by multiple request tools must fail without choosing by declaration order. Unknown names must remain subject to the existing undeclared-tool guard.
Minimal redacted request or reproduction
Actual response or error
Upstream documentation
Cognition's cloud-direct Connect-RPC endpoint has no public tool-naming specification. The concrete client contract is the Responses request catalog: the client declared
mcp__cua_repl__js, and OpenCodex must preserve that tool identity across an adapter that intentionally advertises its local name upstream.Relevant source on
dev:src/adapters/devin.tsmaps tools withname: tool.nameand emitsevent.nameunchanged. The shared bridge usesnamespacedToolName(namespace, name)as the authorized wire identity.Suggested mapping or implementation notes
Build a request-scoped map from each advertised local name to
namespacedToolName(tool.namespace, tool.name). Restore only uniquely owned names ontool_call_start. Represent collisions explicitly and emit a non-retryable adapter error before dispatch; preserve unknown names for the shared fail-closed guard.Keep Cognition's current bare-name request contract and catalog nudge unchanged. This makes the response half symmetric without broadly authorizing bare aliases in the provider-independent bridge.
Additional context and attachments
Checks