Browser & Computer Use plugins silently unusable with a custom model_provider (no tool_search / dynamic tool discovery)

Open 💬 5 comments Opened Jul 9, 2026 by jay-tau
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

Codex supports custom model_provider endpoints (OpenAI-compatible /responses), but the Browser and Computer Use plugins silently do not work when a session uses one. Their required runtime tool (mcp__node_repl__js) is never exposed to the model. Switching the same machine/plugins to the official backend makes it work immediately. The differentiator is tool_search (dynamic tool discovery), which is not offered on custom providers.

Environment

  • Codex Desktop build 26.623.141536 (CLI 0.142.5), Windows 11
  • Plugins enabled: browser@openai-bundled, computer-use@openai-bundled
  • Model: gpt-5.5
  • Reproduced with a custom OpenAI-compatible model_provider (a local /responses endpoint). Not specific to any particular endpoint.

What works (so this is not an install/packaging problem)

  • [mcp_servers.node_repl] is registered; node_repl.exe starts cleanly (startup_complete=true, tool_count=3).
  • Native pipes are created (codex-computer-use-*, codex-browser-use-*); the browser-client.mjs SHA is in the node_repl trust allowlist.
  • Both plugin skills state that automation must run through mcp__node_repl__js.

Repro

  1. Configure a custom model_provider (any OpenAI-compatible /responses endpoint) and select it.
  2. Enable the Browser and/or Computer Use plugins; confirm node_repl starts (serves 3 tools).
  3. Ask the model to list its available tools.

Observed: the model's tool list contains no mcp__node_repl__js and no tool_search tool, so the runtime tool is unreachable and the plugins cannot control the in-app browser. [features].js_repl also resets to false on every launch and is not persistable via config.

Expected: the plugins' runtime tool is reachable, as it is on the official backend.

Official backend (same machine, same plugins) — works

  • tool_search.tool_search_tool is present; mcp__node_repl__js becomes discoverable via tool_search and the in-app browser can be driven end-to-end.

Apparent root cause (from investigation)

mcp__node_repl__js is a dynamic tool surfaced via tool_search, not a static tool. tool_search appears to be gated by a backend-delivered feature flag (anthropic_tool_search_enabled) tied to the official backend, so sessions on a custom model_provider never receive it — and therefore can never discover the plugins' runtime tool.

Request (any one of)

  1. Enable dynamic tool discovery (tool_search) for custom model_provider endpoints, or
  2. Provide a config option to expose MCP/plugin tools statically (bypassing tool_search), so Browser/Computer Use work without the dynamic-discovery layer, or
  3. Document that Browser & Computer Use require the official backend.

View original on GitHub ↗

5 Comments

github-actions[bot] contributor · 1 month ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #30523
  • #31628
  • #30486
  • #30562
  • #30904

Powered by Codex Action

SIMON-WORLD · 19 days ago

Verified workaround for custom model_provider sessions (Codex Desktop 26.803.5235.0, Windows):

Set "supports_search_tool": false in the model catalog JSON referenced by model_catalog_json in config.toml (with cc-switch: ~/.codex/cc-switch-model-catalog.json). When the field is true, plugin MCP tools (e.g. mcp__node_repl__js) are routed through tool_search dynamic discovery, which custom providers never receive; with false, the MCP tools appear directly in the session tool list.

After the change, a new conversation on the custom provider exposes mcp__node_repl__js and @Computer becomes invocable. On Windows 26.803 the helper then hits #37383's EnumWindows 0x80070003 sandbox regression, but tool exposure itself is fixed.

Eleven-is-cool · 17 days ago

Additional reproduction details from a custom-provider setup:

  • Codex Desktop: 26.803.61601
  • Bundled CLI: 0.147.0-alpha.6.5
  • macOS
  • Plugin: Browser
  • Model: a DeepSeek-compatible third-party model
  • Route: OpenCodex 2.11.1 → a local OpenAI-compatible Responses provider

Changing the model catalog entry to:

{
  "supports_search_tool": false,
  "tool_mode": null,
  "use_responses_lite": null
}

does expose the direct MCP tools, so this is a partial workaround for tool discovery. However, calls to the Browser plugin's node_repl.js tool still lose their actual output. The model only receives:

{"execution_duration_ms": 0}

The expected content payload is missing. In the same session, js_reset and js_add_node_module_dir return text normally, so the failure seems specific to serialization/forwarding of the direct MCP node_repl.js result through the custom Responses provider path.

Should direct MCP function_call_output preserve both content and structuredContent for custom Responses providers? Is there an additional provider capability/configuration required beyond supports_search_tool: false?

WillSuo-Github · 16 days ago

Adding data that narrows this down: on my machine the lost-output half of this report reproduces without any custom provider, so the tool-result forwarding failure appears to be independent of supports_search_tool / tool_search.

Environment

  • Codex Desktop 26.803.61601, bundled CLI 0.147.0-alpha.6.5, macOS (arm64)
  • Plugins: computer-use@openai-bundled, browser@openai-bundled

What I measured

I parsed all 401 local rollout sessions in ~/.codex/sessions and paired every mcp_tool_call_end with the function_call_output Codex actually forwards to the model. 746 MCP calls returned a non-empty content[] text block:

| structuredContent present | content[] text reached the model | count |
| --- | --- | --- |
| no | yes | 697 |
| yes | no | 49 |

Correlation is 100% with zero exceptions: whenever a CallToolResult carries both content[] and structuredContent, only structuredContent is forwarded and the text block is dropped. Same behaviour as #10334, observed here on the app/plugin path.

The part that rules out the custom provider

Three of the 49 dropped calls are from 2026-07-26, about two weeks before I installed any routing proxy. That session's session_meta records:

{"originator":"Codex Desktop","cli_version":"0.146.0-alpha.3.1","model_provider":"openai"}

Native OpenAI backend, no proxy, no custom model_provider, no catalog override, and the content[] text was dropped identically:

MCP returned  content[0].text  : "InvalidInputException: Repository not found: <redacted>"
              structuredContent: {"error":"InvalidInputException: ...","error_code":"UNKNOWN"}
Codex -> model                 : {"error":"InvalidInputException: ...","error_code":"UNKNOWN"}

So supports_search_tool: false fixes tool discovery (as @SIMON-WORLD and @Eleven-is-cool found), but the output loss looks like a separate, provider-independent defect.

Direct repro on the Computer Use path

const fs = await import("node:fs/promises");
await fs.writeFile("/tmp/probe.txt", "executed at " + new Date().toISOString());
nodeRepl.write("wrote file");
  • /tmp/probe.txt is created, so the code really ran.
  • The session log shows the MCP server returned content: [{"type":"text","text":"wrote file"}] plus structuredContent: {"execution_duration_ms":1}.
  • The model received only {"execution_duration_ms":1}.

A useful control: when the submitted code throws, the result carries no structuredContent, and the error text arrives intact (I saw Identifier 'fs' has already been declared). That matches @Eleven-is-cool's observation that js_reset and js_add_node_module_dir return text normally, since those results also carry no structuredContent. The discriminator is the presence of structuredContent, not the tool or the transport.

Not limited to node_repl

Distinct tools affected in my logs:

  • node_repl/js
  • codex_apps/figma.get_metadata, codex_apps/figma.download_assets
  • codex_apps/github.search_branches, codex_apps/github.get_repo, codex_apps/github.fetch_file

Why this makes the plugin look unused rather than broken

Computer Use itself is fully functional here: through @oai/sky I enumerated 53 apps and captured a Finder screenshot successfully. But the model only ever receives {"execution_duration_ms": N} with no app list, no accessibility tree, and no screenshot. Given no usable feedback from the first call, the model falls back to shell commands, which presents as "the model won't use Computer Use" when the actual cause is that every result comes back empty.

Images are affected on the same path: nodeRepl.emitImage(...) output does not reach the model, though writing the screenshot to disk and reading it back works as a workaround.

Question

Should function_call_output preserve content[] whenever structuredContent is present, either concatenated or with content[] taking precedence? As it stands, any MCP tool returning both, which includes the bundled Computer Use / Browser runtime and several connectors, is effectively mute to the model on official and custom providers alike.

aohan237 · 11 days ago

this should be addressed
@tibo-openai