Home › Learn › MCP configuration

Tutorial · 10 min read · Claude Code · Codex · OpenCode

One MCP server in Claude Code, Codex and OpenCode, and how each one tells you it's broken

We connected the same public MCP server to all three runtimes, made one real tool call from each, then pointed each at a bad URL. The config files differ in small ways. How each runtime reports a broken server differs a lot, and that part is worth knowing before you rely on one.

The server

OpenAI runs a read-only MCP server for its documentation over streamable HTTP, with no key. Vendor docs It offered five tools when we connected: search_openai_docs, list_openai_docs, fetch_openai_doc, list_api_endpoints and get_openapi_spec. Observed We named the connection openaiDocs in every runtime, and asked each one to search for "Docs MCP" and give back the title of the first hit. All three answered "MCP servers | OpenAI API". Observed

Claude Code: .mcp.json

Run this in the project folder:

Terminal
claude mcp add --transport http --scope project openaiDocs https://developers.openai.com/mcp

It wrote this file at the project root: Observed

.mcp.json
{
  "mcpServers": {
    "openaiDocs": {
      "type": "http",
      "url": "https://developers.openai.com/mcp"
    }
  }
}

Without --scope project, the entry goes to ~/.claude.json instead, for you only. Vendor docs A project server has to be approved once, and until then claude mcp list shows it as ⏸ Pending approval (run `claude` to approve). Observed Starting claude in the folder asks you to approve it. Vendor docs

Print mode is the exception. claude -p connected the server without any approval while mcp list still said "Pending approval", which matches Anthropic's documentation. Observed So a script that runs claude -p in a repository you haven't reviewed will start whatever servers its .mcp.json lists.

Calling a tool

Tools appear as mcp__openaiDocs__search_openai_docs. Claude Code loads MCP tools on demand by default, so the model first has to find the tool with its tool-search step. Vendor docs With Haiku 4.5 that worked in one of two runs; in the other, the model decided it couldn't call MCP tools and never tried. Observed This command made the call directly, on the first turn:

Terminal
claude -p "Use the openaiDocs MCP server's search tool to search for 'Docs MCP' and quote the lvl1 title of the first hit. One line." \
  --strict-mcp-config --mcp-config .mcp.json --tools "" \
  --allowedTools "mcp__openaiDocs__*" < /dev/null

--strict-mcp-config keeps out every server except the ones in the file you pass, including any claude.ai connectors on your account, and --tools "" removes the built-in tools, so the MCP tools are all the model has. --allowedTools lets the calls run without asking. Without < /dev/null, print mode waited three seconds for input and printed a warning. Observed

Codex: config.toml

Codex reads MCP servers from ~/.codex/config.toml, and from .codex/config.toml in a project only when you have trusted that project. Vendor docs

~/.codex/config.toml
[mcp_servers.openaiDocs]
url = "https://developers.openai.com/mcp"

codex mcp add openaiDocs --url https://developers.openai.com/mcp writes the same table for you. Vendor docs In a project we hadn't trusted, Codex ignored the project file without any warning: the server was missing from codex mcp list, and the model said it had no such server. Trusting the project fixed both. Observed

To try a server without editing any file, pass the same key with -c:

Terminal
codex exec --json --sandbox read-only \
  -c 'mcp_servers.openaiDocs.url="https://developers.openai.com/mcp"' \
  "Use the openaiDocs MCP server's search_openai_docs tool to search for 'Docs MCP' and reply with only the hierarchy lvl1 title of the first hit." < /dev/null

With --json, each step is one JSON line, and the MCP call is easy to find. Codex didn't ask for approval before the call. Observed

One line of the output, shortened
{"type":"mcp_tool_call","server":"openaiDocs","tool":"search_openai_docs","arguments":{"query":"Docs MCP"},"status":"completed","error":null, …}

Before that call, Codex read a skill about OpenAI's docs that comes bundled with Codex, so yours may do the same. Observed

OpenCode: opencode.json

OpenCode lists servers under mcp, with type set to remote for a URL or local for a command. Vendor docs

opencode.json, at the project root
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "openaiDocs": {
      "type": "remote",
      "url": "https://developers.openai.com/mcp",
      "enabled": true
    }
  }
}

There was no trust or approval step. opencode mcp list connected to the server and printed ✓ openaiDocs connected. Observed

Tools are named <server>_<tool>, here openaiDocs_search_openai_docs. Observed Our first run went wrong twice. The model sent the limit argument as the string "10", and the server rejected it with MCP error -32602. The retry returned about 55 KB, which OpenCode replaced with a note and saved to a file under ~/.local/share/opencode/tool-output/. The model never read the file and gave a wrong title. Asking for one result, with the limit as a number, fixed both. Observed

When the server is broken

We changed the URL to https://developers.openai.com/mcp-nope, which returns 404, and ran the same commands. Observed

RuntimeThe list commandA real session
Claude CodeAfter approval: ✘ Failed to connect — MCP endpoint not found. Before approval it shows only "Pending approval" and doesn't try.claude -p exits 0 and the model answers anyway. The only sign is "status":"failed" for the server in the --output-format stream-json start-up event.
CodexShows enabled, exactly as for the working server. The column reports your config and never contacts the server.codex exec exits 0 and the model answers. Standard error gets two ERROR rmcp::transport::worker lines with HTTP 404.
OpenCode✗ badDocs failed with SSE error: Non-200 status code (404). It says SSE although the transport is streamable HTTP.opencode run exits 0 and says nothing about the server.

In all three, a broken optional server leaves a session that works but quietly lacks the tools. In scripts, check the list command first. In Codex, also set required = true on a server you can't do without. With it, codex exec stopped with exit status 1 and required MCP servers failed to initialize. Observed

Side by side

Claude CodeCodexOpenCode
Project file.mcp.json.codex/config.toml, trusted projects onlyopencode.json
Remote entry"type": "http", "url"url"type": "remote", "url"
Tool namemcp__openaiDocs__search_openai_docssearch_openai_docs on server openaiDocsopenaiDocs_search_openai_docs
Does the list command connect?Yes, once approvedNoYes
Approval before useOnce per project, except in -pNone in ~/.codex; a project file needs a trusted projectNone

Each row is what we saw with the versions above. Observed

What we haven't verified

  • The desktop apps. We ran all three runtimes in a terminal.
  • Servers that need OAuth or a key, and local servers started as a command.
  • Other models. Whether the model calls the tool at all varied between runs, and a stronger model may behave differently. Not verified

Last verified 2026-09-25 · review by 2026-10-25