Skip to content

[Provider compatibility] Qoder adapter cannot use Codex-owned MCP/tool calls #5270

Closed

Description

@juzijia

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

  1. Configure Qoder as the provider for /v1/responses.
  2. Send a Responses request containing at least one function/MCP tool.
  3. Use a prompt that requires that tool.
  4. 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

  1. changed the title [-][Provider compatibility] Qoder MCP tool calls require cold process/replay continuation[/-] [+][Provider compatibility] Qoder adapter cannot use Codex-owned MCP/tool calls[/+] on Sep 20, 2026
  2. added
    providerProvider adapters, OpenAI-compat presets, upstream API quirks
    toolstool_calls, MCP, web-search / sidecar tools
    on Sep 20, 2026
  3. Ingwannu commented on Sep 20, 2026

    @Ingwannu
    Owner

    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_call items, preserves call IDs across function_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.

  4. added
    priority: P2Medium: provider/client-specific bug with a workaround, bounded enhancement tied to a tracked issue,
    on Sep 24, 2026
  5. 1395490241lhj-code commented on Sep 28, 2026

    @1395490241lhj-code

    I can reproduce this in Codex Desktop with the current Qoder provider integration.

    I tested both:

    • Qoder · Qwen 3.8 Flash
    • Qoder · Qwen 3.8 Max

    When the model reaches a tool-required step, the Codex conversation sometimes renders the raw tool intent directly in the assistant message, for example:

    <tool_call>{"tool_calls":[{"name":"exec","arguments":{...}}]}</tool_call>
    

    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.swift had 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:

    Qoder tool intent
    → OpenCodex converts it into a structured Responses tool_call
    → Codex executes/approves the tool
    → function_call_output is returned
    → Qoder continues
    → raw tool-call JSON is never shown as normal assistant text
    

    I can provide screenshots showing the behavior in both Qwen 3.8 Flash and Qwen 3.8 Max.

  6. Ingwannu commented on Sep 28, 2026

    @Ingwannu
    Owner

    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:

    • the exact OpenCodex version or commit for each run;
    • whether Codex displayed an approval/tool-execution item before the file changed;
    • screenshot timestamps plus the file mtime or a minimal git diff --stat;
    • the content-free request/turn id from diagnostics, if available;
    • whether the raw block and edit occurred in the same turn.

    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.

  7. 1395490241lhj-code commented on Sep 29, 2026

    @1395490241lhj-code

    Follow-up evidence for the Qoder runs:

    • OpenCodex version: 2.69.0 (latest channel).
    • Reproduced on Qwen 3.8 Flash and Qwen 3.8 Max.
    • Flash run, about 2026-09-28 14:49 -0400: the same visible turn showed the raw Qoder tool-intent block and a Codex edit item for PlannerView.swift (about +39/-37). No separate approval prompt was visible between those two UI items in the screenshot.
    • Max run, about 2026-09-28 15:17 -0400: the raw Qoder tool-intent block appeared, but no corresponding execution/edit item followed; the turn stalled.
    • The file was later modified again by a different provider, so its current mtime no longer proves the earlier Qoder edit time. The later completed work was committed at 2026-09-28 16:54:53 -0400 as c772a36830396505cc04f4799b49410a069bcaeb.
    • I have not found a content-free request/turn ID yet.

    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.

  8. added a commit that references this issue on Oct 8, 2026
    6a7632d
  9. lidge-jun commented on Oct 8, 2026

    @lidge-jun
    Owner

    Fixed by #6289, merged into dev as 6a7632db2a. The Qoder adapter now gives Qoder a request-scoped stdio MCP catalog that holds only the Codex-owned tools selected for the request. Qoder's tool_use output comes back to Codex as Responses function_call / custom_tool_call items, and Codex keeps approval, sandboxing and execution. A store:false turn that ends in a tool call can be continued with previous_response_id and the tool output. Closing manually because PRs target dev; the change ships with the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: P2Medium: provider/client-specific bug with a workaround, bounded enhancement tied to a tracked issue,providerProvider adapters, OpenAI-compat presets, upstream API quirksprovider-compatibilityProvider compatibility reportstoolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions