Repository navigation
[Provider compatibility] Qoder adapter cannot use Codex-owned MCP/tool calls #5270
Description
Client or integration
Codex CLI
Provider or upstream service
Qoder
OpenCodex version
2.59.0 (134c92a01b120162f00c7275189cc47858720379)
Endpoint or capability
/v1/responses — tool calls / MCP tools
Current behaviour
The upstream Qoder adapter launches Qoder in a single-shot, tools-disabled mode.
Its argument list includes:
--tools ""
--strict-mcp-config
--max-turns 1
--no-session-persistence
Because tools are disabled, tools supplied by the Codex/Responses request are not exposed to Qoder. A request that requires a Codex-owned tool cannot enter the normal tool-call continuation flow through the Qoder adapter.
Expected behaviour
Qoder should be able to request tools supplied by Codex/OpenCodex while Codex remains responsible for approval, sandboxing, and actual tool execution.
The expected flow is:
Qoder requests tool
→ OpenCodex returns a tool_call
→ Codex executes the tool
→ function_call_output is sent back
→ Qoder continues
→ final response
Minimal redacted request or reproduction
- Configure Qoder as the provider for
/v1/responses. - Send a Responses request containing at least one function/MCP tool.
- Use a prompt that requires that tool.
- Observe that the upstream Qoder adapter starts the CLI with
--tools ""and--strict-mcp-config, so the supplied tool is unavailable to Qoder.
Actual response or error
There is no required HTTP error.
The failure is capability-level: the Qoder adapter disables tools, so a tool-required request cannot produce and complete the normal Codex-owned tool_call → function_call_output → continuation flow.
Upstream documentation
No public specification was found for Qoder's internal host/control protocol.
The OpenCodex 2.59.0 Qoder adapter itself documents and implements the current single-shot, tools-disabled behavior.
Suggested mapping or implementation notes
A local proof-of-concept can bridge Qoder tool intent back to Codex while keeping Codex as the actual tool executor, including multi-tool continuation.
That proof-of-concept is local work and is not being proposed here as the final architecture. This issue only tracks the base Qoder tool-compatibility gap.
Additional context and attachments
A separate architecture discussion can cover lifecycle and performance trade-offs after the base compatibility problem is established.
Checks
- I searched existing provider and compatibility issues.
- The request and response were redacted.
- The expected behaviour is based on a concrete client requirement.
Activity
[-][Provider compatibility] Qoder MCP tool calls require cold process/replay continuation[/-][+][Provider compatibility] Qoder adapter cannot use Codex-owned MCP/tool calls[/+]Ingwannu commentedon Sep 20, 2026
Confirmed against current
dev: this is a real capability gap, but it is currently an intentional limitation rather than a regression. The Qoder adapter explicitly launches the vendor CLI with--tools "",--strict-mcp-config,--max-turns 1, and no session persistence, and the registry/scaffold contract describes that route as text/reasoning-only.We should keep the issue open because Codex-owned tool execution would be valuable. The safe implementation cannot simply re-enable Qoder built-in tools: it needs a bounded bridge that converts Qoder tool intent into Responses
tool_callitems, preserves call IDs acrossfunction_call_output, supports multi-tool continuation, and leaves approval/sandbox/execution entirely with Codex. It also needs child-process timeout/cleanup coverage and must not place prompts, tool schemas, credentials, or results in argv. With no public Qoder control-protocol specification, we should require an exact CLI-version fixture or documented protocol evidence before making this a shipped capability.1395490241lhj-code commentedon Sep 28, 2026
I can reproduce this in Codex Desktop with the current Qoder provider integration.
I tested both:
When the model reaches a tool-required step, the Codex conversation sometimes renders the raw tool intent directly in the assistant message, for example:
or a JSON block containing:
{"tool_calls":[{"name":"exec", ...}]}This happens consistently with both Qwen 3.8 Flash and Qwen 3.8 Max, so it does not appear model-specific.
In at least one run, Codex also showed that
PlannerView.swifthad actually been edited while the raw tool-call payload was still rendered in the conversation. So the current behavior can be confusing: the user cannot reliably tell whether the tool call was only emitted as text, partially bridged, or actually executed.Expected behavior would be:
I can provide screenshots showing the behavior in both Qwen 3.8 Flash and Qwen 3.8 Max.
Ingwannu commentedon Sep 28, 2026
Thanks — this narrows the issue from a theoretical capability gap to a user-visible ambiguity on both Qwen 3.8 routes. The raw
<tool_call>/ JSON appearing as assistant text is consistent with the current tools-disabled Qoder contract; the reported file edit needs a separate execution-timeline check before we conclude that this adapter partially bridged it.Please add, with prompts/credentials/tool arguments redacted:
git diff --stat;Do not post tokens, full prompts, tool schemas, file contents, or raw request bodies. I am keeping this open at P2. The implementation still needs a bounded structured continuation bridge; parsing arbitrary assistant prose as executable tool intent would be unsafe and is not an acceptable shortcut.
1395490241lhj-code commentedon Sep 29, 2026
Follow-up evidence for the Qoder runs:
So, on the same OpenCodex version, I observed both: (1) raw tool intent plus an edit item in the same visible turn, and (2) raw tool intent with no execution item, after which the turn stopped.
feat(qoder): bridge Codex-owned tools through MCP (#6289)
lidge-jun commentedon Oct 8, 2026
Fixed by #6289, merged into
devas6a7632db2a. The Qoder adapter now gives Qoder a request-scoped stdio MCP catalog that holds only the Codex-owned tools selected for the request. Qoder'stool_useoutput comes back to Codex as Responsesfunction_call/custom_tool_callitems, and Codex keeps approval, sandboxing and execution. Astore:falseturn that ends in a tool call can be continued withprevious_response_idand the tool output. Closing manually because PRs targetdev; the change ships with the next release.