Power Your Software Testing with AI Agents and Cloud
The Native AI-Agentic Cloud Platform to Supercharge Quality Engineering. Test Intelligently and Ship Faster.
- TestMu AI (Formerly LambdaTest)
- /
- Blog
- /
- Codex MCP: Setup, Per-Repo Config, and Tool Approvals
Codex MCP: Setup, Per-Repo Config, and Tool Approvals
Codex MCP setup for the CLI, IDE and app: add servers, scope them per repo, sign in with OAuth, set tool approvals, and see what 88 MCP tools cost in context.
Published on:
A study of MCP servers found MCP-specific tool poisoning in 5.5% of 1,899 open-source servers and general vulnerabilities in 7.2% of them.
Codex MCP is how servers like those reach Codex: register one once, and the CLI, the IDE extension and the ChatGPT desktop app can all call its tools. So the controls matter as much as the setup: which servers load, how they sign in and which tools run without asking.
The examples below connect Codex CLI 0.166.0 to TestMu AI's hosted MCP server, a real server with 88 tools, to show the setup, what those tools cost in context, and which approval settings let a call through in codex exec.
TL;DR
Codex MCP is the Model Context Protocol support in OpenAI's Codex CLI, IDE extension and ChatGPT desktop app, which share one config.toml of MCP servers. It exists so Codex can call tools outside your repository, such as a test platform's logs, during a task. Codex connects to MCP servers but no longer runs as one.
Codex MCP Settings That Matter
- Adding a server: codex mcp add <name> -- <command> registers a local STDIO server, and codex mcp add <name> --url <url> registers a remote Streamable HTTP server. codex mcp list then shows each server's status and whether it still needs an OAuth login.
- Per-repository servers: Yes, supported. A .codex/config.toml in the repository adds servers for that project only, and Codex reads it only after the project is trusted. An untrusted clone's servers are left out of codex mcp list without a warning.
- Context cost: No upfront cost by default. Connected to TestMu AI's 88-tool MCP server, Codex CLI 0.166.0 sent a 13,733-token first request, identical to a run with no server, because it looked tools up on demand.
- Approvals in codex exec: No prompts are possible. codex exec blocks any MCP call that needs approval, destructive tools included, and still exits 0, so set approval modes in config.toml before running Codex in CI.
- codex mcp-server: No longer available. OpenAI removed the command and the codex-mcp-server binary, and its replacement, the Codex app server, speaks its own JSON-RPC protocol instead of MCP.
What Is Codex MCP?
Codex MCP is Model Context Protocol support in OpenAI's Codex: an MCP server describes its tools, and Codex calls them during a task the same way it runs a shell command. It lets the agent read a ticket, a design file or a test run that never lands in your repository.
Per OpenAI's Codex MCP docs, the ChatGPT desktop app, Codex CLI and IDE extension share one MCP configuration per Codex host, so a server added in one client works in the others. Codex also reads each server's instructions field and treats the first 512 characters as the part that has to stand on its own.
- STDIO servers - A local process Codex starts from a command, such as npx -y @upstash/context7-mcp, with environment variables passed through.
- Streamable HTTP servers - A remote URL, signed in with a bearer token, custom headers or OAuth.
- ChatGPT on the web - Uses remote MCP tools through plugins and does not read your local Codex configuration, so the setup below applies to the desktop app, the CLI and the IDE extension.
Codex is the client in this setup. For installing Codex itself and choosing sandbox modes, see Codex CLI, and for the same protocol in Anthropic's agent, see Claude MCP.
How Do You Add an MCP Server to Codex?
Run codex mcp add from any terminal. It writes the server to ~/.codex/config.toml, which the ChatGPT desktop app and the IDE extension read as well.
# STDIO server: Codex starts the process
codex mcp add context7 -- npx -y @upstash/context7-mcp
# Streamable HTTP server: Codex connects to a URL, then you sign in with OAuth
codex mcp add mcp-lambdatest --url https://mcp.lambdatest.com/mcp
codex mcp login mcp-lambdatest
# confirm what Codex will load
codex mcp list
codex mcp get mcp-lambdatestUntil the OAuth sign-in finishes, codex mcp list shows the HTTP server as enabled but not logged in. Check that column first when a server's tools fail:
Name Url Bearer Token Env Var Status Auth
mcp-lambdatest https://mcp.lambdatest.com/mcp - enabled Not logged incodex mcp add writes a plain TOML table, so you can also add the same server by hand:
# ~/.codex/config.toml
[mcp_servers.mcp-lambdatest]
url = "https://mcp.lambdatest.com/mcp"- ChatGPT desktop app - Open Settings, then MCP servers, then Add server. Choose STDIO or Streamable HTTP, save, and select Restart. Type /mcp in the composer to see connected servers.
- IDE extension - Open the gear menu, then MCP servers, then Add server, and select Restart extension after saving. The list marks servers that still need Authenticate.
- Codex terminal UI - Type /mcp to see the servers active in the current session.
TestMu AI's MCP server is a good one to learn on because it is hosted and large. One URL exposes tool families for HyperExecute, automation sessions, native app automation, SmartUI, accessibility scans and Test Manager, and sign-in is OAuth, so no access key sits in config.toml.
Ask Codex to analyze a project and create a HyperExecute YAML file, and it calls generateHyperExecuteYAML. Ask it to triage a failed test, and it pulls that session's command, network and console logs. The HyperExecute tools generate configuration and read job state, while running the job stays with the HyperExecute CLI.
Client-by-client setup steps are in the TestMu AI MCP server docs. This demo shows the automation triage flow, from a failed test to its likely root cause:
Note: Point Codex at TestMu AI's MCP server, sign in once with codex mcp login, and ask it to triage your last failed test from that session's command, network and console logs. Start free to connect your account.
How Do You Set Up MCP for Each Repository With Codex?
Create .codex/config.toml at the repository root. Codex adds those servers to your user configuration for that project only, so everyone who clones the repository gets the same tool surface without running codex mcp add.
# .codex/config.toml at the repository root
[mcp_servers.testmu]
url = "https://mcp.lambdatest.com/mcp"
enabled_tools = ["automationQuery", "getAutomationTestCommandLogs", "getAutomationTestBrowserConsoleLogs"]
default_tools_approval_mode = "writes"Codex reads the project file only in a trusted project. In an untrusted clone, codex mcp list run from the repository leaves the project's server out, with no warning that a file was skipped:
# untrusted clone: the project's server is left out
$ codex mcp list
Name Url Bearer Token Env Var Status Auth
mcp-lambdatest https://mcp.lambdatest.com/mcp - enabled Not logged in
# after the project is trusted
$ codex mcp list
Name Url Bearer Token Env Var Status Auth
mcp-lambdatest https://mcp.lambdatest.com/mcp - enabled Not logged in
testmu https://mcp.lambdatest.com/mcp - enabled Not logged inTrust is a projects entry in your user configuration, keyed by the repository path:
# ~/.codex/config.toml
[projects.'/home/dev/checkout-service']
trust_level = "trusted"- Keep secrets out of the file - Reference them with bearer_token_env_var, env_http_headers or env_vars, so each developer's token stays in their own environment. An OAuth server needs no secret in the file at all.
- Pin the tool surface - An enabled_tools allow list in the repository file means a server update that adds tools does not change what Codex can call in this project.
- Set approvals next to the server - default_tools_approval_mode = "writes" lets read-only tools run and asks before anything else.
- Never commit an OAuth client secret - codex mcp add --oauth-client-secret saves the secret as mcp_servers.<name>.oauth.client_secret in config.toml, so add pre-registered clients to your user file only.
A cloned repository can bring its own servers, which is how a poisoned tool description would reach you, and why the trust gate matters. Read a repository's .codex/config.toml before you trust the project, the same way you would review a new dependency, and see MCP security for tool poisoning and how to test a server before you add it.
How Does Codex Sign In to Remote MCP Servers?
For a Streamable HTTP server, Codex sends a configured bearer token or authorization headers first, then stored OAuth credentials. When none of them resolves, it connects without authentication, which is why a server can list its tools and still refuse every call.
TestMu AI's server behaves that way before login. It answers the handshake and lists its tools, then rejects each tool call with a 401 and an OAuth challenge, which Codex hands back to the model inside the tool result:
{"type": "mcp_tool_call", "server": "mcp-lambdatest", "tool": "getOrgConcurrency",
"result": {"content": [{"type": "text", "text": "Authentication required"}],
"_meta": {"mcp/www_authenticate": ["Bearer realm=\"MCP Server\", resource_metadata=\"https://mcp.lambdatest.com/.well-known/oauth-protected-resource/mcp\""]}},
"status": "failed"}- codex mcp login <name> - Opens a browser for the OAuth sign-in and stores the credentials. On a machine without a local browser, add --no-browser, open the printed URL elsewhere, and paste the full redirect URL back into the terminal.
- Client registration - Codex uses an OAuth Client ID Metadata Document when the authorization server advertises support, and Dynamic Client Registration otherwise. TestMu AI's authorization server advertises a registration endpoint and PKCE with S256, so Codex registers itself and there is no client ID to configure.
- Pre-registered clients - Pass --oauth-client-id, plus --oauth-client-secret for a confidential client, to codex mcp add, then register the exact callback URL the command prints.
- Scopes - Set mcp_servers.<name>.scopes, or override them for one login with codex mcp login <name> --scopes read,write.
- Static tokens - For servers that issue an API token instead of OAuth, bearer_token_env_var names the environment variable Codex reads the token from.
OAuth also keeps a long-lived key out of the agent's configuration. TestMu AI documents OAuth as the sign-in for its MCP server, so the token Codex holds belongs to your account session rather than to a shared access key.
How Much Context Do MCP Tools Use in Codex?
Less than the tool count suggests. By default Codex keeps a server's tool definitions out of the first request and looks them up when the model needs one.
The Codex configuration reference names three surfaces a server's tools can sit on, direct initial tools, deferred tool search and Code Mode scripts, and it compacts any tool input schema larger than 5,000 bytes.
To measure the effect, Codex CLI 0.166.0 with GPT-6.1 Sol ran the same one-word prompt against TestMu AI's server in four setups. Two of them forced the server's tools into the first request with omit_tools_from = ["code_mode", "deferred"] and mcp_optional_startup_grace_ms = 0.
| Setup | MCP tools in the first request | Input tokens, first request |
|---|---|---|
| No MCP server | None | 13,733 |
| TestMu AI server, default settings | None, looked up on demand | 13,733 |
| All 88 tools forced into the first request | 88 | 26,723 |
| Six-tool allow list forced into the first request | 6 | 14,927 |
- Upfront cost - Forcing all 88 definitions into the request added 12,990 tokens, about 148 per tool. The six-tool allow list added 1,194.
- On-demand lookups - In default mode, asking Codex which tool runs an accessibility report took four model requests and 76,225 input tokens, 51,519 of them cached, because one broad catalog search returned a result that Codex truncated from 43,948 tokens.
- Large schemas - The tool list TestMu AI's server returns is 99,242 bytes of JSON. One tool, generateHyperExecuteYAML, has a 6,128-byte input schema, above the 5,000-byte default, so Codex compacts it unless you raise tool_input_schema_max_bytes for that server.
- Slow servers - With the default 1,000 ms grace for optional servers, a forced-direct run still sent 13,733 tokens. The server's handshake took 3.5 to 3.8 seconds in five timed runs, so its tools missed the first request entirely.
Allow lists still pay off. They shrink what an on-demand search can return and fix the tool surface per project, so keep each one to the tools a task needs, such as the automation triage tools in a test-debugging repository.
How Do You Control Which MCP Tools Codex Can Call?
Tool lists decide which MCP tools Codex can see at all: enabled_tools is an allow list, and disabled_tools is a deny list applied after it. Approval settings then decide which of those run without asking: default_tools_approval_mode for the whole server, and tools.<tool>.approval_mode for one tool.
The modes are auto, prompt, writes and approve. In writes mode, Codex asks only before tools that the server does not mark read-only.
[mcp_servers.mcp-lambdatest]
url = "https://mcp.lambdatest.com/mcp"
default_tools_approval_mode = "writes"
disabled_tools = ["deleteBuild", "deleteSession", "deleteUploadedApps"]
[mcp_servers.mcp-lambdatest.tools.getAccessibilityReport]
approval_mode = "approve"Whether a tool counts as read-only comes from the server's tool annotations, and TestMu AI's server annotates every tool:
- Read-only - 53 of the 88 tools, such as automationQuery and getAutomationTestCommandLogs, run without a prompt in writes mode.
- Destructive - 19 tools, including deleteBuild, stopTunnel and tm_update_test_case, carry a destructive annotation, and Codex wants approval for them even in the default mode.
- Other writes - The remaining 16, such as getAccessibilityReport and tm_create_test_case, are neither, so writes mode asks before each call unless a per-tool setting says otherwise.
How Approvals Work in codex exec
codex exec cannot ask anyone, so it runs with an approval policy of never. Any MCP call that needs approval fails before it reaches the server, and codex exec still exits with code zero.
These runs used a connection without a sign-in, so a call that got through came back Authentication required and nothing changed on any account:
| Tool and annotation | Setting | What codex exec did |
|---|---|---|
| getOrgConcurrency, read-only | Default | Sent the call |
| getOrgConcurrency, read-only | default_tools_approval_mode = "prompt" | Blocked: MCP tool call requires approval, but approval policy is never |
| getOrgConcurrency, read-only | default_tools_approval_mode = "writes" | Sent the call |
| deleteSession, destructive | Default | Blocked with the same message |
| deleteSession, destructive | tools.deleteSession.approval_mode = "approve" | Sent the call |
- Exit codes - Every run in the table exited 0, so a CI job has to read the codex exec --json events and fail on mcp_tool_call items whose status is failed.
- Narrow pre-approval - approve lets even a destructive tool through, as the deleteSession run shows. Set it per tool for the calls a pipeline needs, and never as the default for a server that has delete tools.
This check fails the job when any MCP call in the run was blocked or rejected:
codex exec --json "Find the last failed automation test and summarize its console errors" > codex-events.jsonl
node -e 'const bad=require("fs").readFileSync("codex-events.jsonl","utf8").split("\n").filter(Boolean).map(JSON.parse).filter(e=>e.type==="item.completed"&&e.item.type==="mcp_tool_call"&&e.item.status==="failed");bad.forEach(e=>console.error("MCP call failed:",e.item.server+"/"+e.item.tool));process.exit(bad.length?1:0)'Calling MCP Tools From Hooks
Codex hooks can call an MCP tool directly with a handler of type mcp_tool that names an already-connected server, a tool and an input template filled from the hook event. The handler's timeout defaults to 600 seconds.
OpenAI's example sends every patch to a scanner server after Codex writes or edits files:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "mcp_tool",
"server": "scanner",
"tool": "scan_patch",
"input": { "patch": "${tool_input.command}" },
"timeout": 30,
"statusMessage": "Scanning edited files"
}
]
}
]
}
}- Existing connections only - A hook uses a server Codex already connected and never starts or reconnects one.
- Blocking - A hook blocks the operation only when the tool returns a blocking decision. Errors, missing servers and unavailable tools let the operation continue.
- No approval step - MCP tool hooks run synchronously and skip tool approval, so point them at read-only tools.
- SessionEnd - This event does not support MCP tool hooks.
Can Codex Run as an MCP Server?
No. According to OpenAI's Codex MCP server removal notice, the codex mcp-server command and the standalone codex-mcp-server binary are gone, and integrations that launch either one must migrate before upgrading Codex.
On Codex CLI 0.166.0 the subcommand no longer exists, so Codex reads mcp-server as a prompt for the interactive CLI. An MCP client that spawns it without a terminal gets an error instead of a server:
$ codex mcp-server
Error: stdin is not a terminal
$ codex --help
Commands:
exec Run Codex non-interactively [aliases: e]
mcp Manage external MCP servers for Codex
app-server [experimental] Run the app server or related tooling
...- Codex app server - OpenAI's replacement for integrations that need sign-in, conversation history, approvals and streamed agent events. It speaks its own JSON-RPC protocol, is not an MCP server, and OpenAI labels it experimental and not supported for production workloads.
- codex exec --json - For an orchestrator that hands Codex one task at a time, run it as a subprocess and read the JSON event stream, the same output the CI check above parses.
- External MCP servers - Unchanged. codex mcp still manages the servers Codex connects to.
How Do You Troubleshoot Codex MCP Servers?
Start with /mcp in the terminal UI or codex mcp list, which separate a server that never loaded from one that loaded but cannot sign in. If the server loads and still misbehaves, test it on its own with MCP Inspector before changing your Codex config.
| Symptom | Likely cause | Fix |
|---|---|---|
| Server missing from codex mcp list inside a repository | The project is not trusted, so Codex skips .codex/config.toml | Mark the project trusted in your user config |
| Server listed, but its tools never reach the first turn | Startup took longer than the 1,000 ms Codex waits for optional servers | Set required = true on the server, or mcp_optional_startup_grace_ms = 0 |
| A STDIO server fails to start | The command ran past the 10-second default, often during an npx download | Raise startup_timeout_sec for that server |
| Tool result says Authentication required | No OAuth sign-in for that server | Run codex mcp login <name> |
| Long tool calls get cut off | The tool ran past the 60-second default | Raise tool_timeout_sec for that server |
| MCP tool call requires approval, but approval policy is never | codex exec cannot show an approval prompt | Set approval_mode for that tool in config.toml |
| Command not found: npx in the app or IDE | The client cannot find Node.js on its PATH | Use the full path to npx in the server's command |
| Codex ignores rules from the server's instructions | Codex treats only the first 512 characters of instructions as self-contained | If you own the server, put rules that apply to every tool first |
If you build MCP servers for Codex users, how to build an MCP server covers the protocol side, and MCP server instructions shows how to test the instructions field that Codex reads.
Conclusion
Start with one Codex MCP server and a narrow config: add it with codex mcp add, set default_tools_approval_mode = "writes" and an enabled_tools list, and confirm the result with codex mcp get before Codex runs it in CI.
To have Codex also check its own changes in a real browser, the Kane CLI with AI coding agents guide installs the Kane CLI skill for Codex CLI with npx @testmuai/kane-cli-skill.
Testing from the terminal? Kane CLI by TestMu AI lets SDETs and developers plan, write, run and debug tests from the command line.
Author
Saurabh Prakash is an Engineering Manager at TestMu AI, where he leads engineering on agentic AI development and scalable system architecture for the quality engineering platform. He has also contributed to Test at Scale, the company's open-source test intelligence platform. He brings over 9 years of experience across Node.js, Java, Spring, MVC, data structures, algorithms, and scalable system design, with earlier roles as SDE 2 at Zomato, Senior Software Engineer at LogicHub, and Software Development Engineer at Directi. Saurabh holds a B.Tech in Computer Science and Engineering from Delhi Technological University.
Reviewer
Srinivasan Sekar is Director of Engineering at TestMu AI, where he leads engineering and open-source initiatives behind the Selenium and Appium automation grid and owns TestMu AI's MCP Server. A committer to Appium and a contributor to Selenium, WebdriverIO, Taiko, and AppiumTestDistribution, he brings over 15 years of experience in quality engineering and open-source technologies. He is the author of the Apress book 'The MCP Standard: A Developer's Guide to Building Universal AI Tools with the Model Context Protocol,' a Certified Kubernetes and Cloud Native Associate, and an international conference speaker. Before TestMu AI he spent over eight years at Thoughtworks as a Principal Consultant and Quality Architect. Srinivasan holds a B.Tech in Information Technology from Anna University.
Codex MCP FAQs
Did you find this page helpful?
More Related Blogs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance
- Advanced access controls
- Advanced data retention rules
- Advanced Local Testing
- Premium Support options
- Early access to beta features
- Private Slack Channel
- Unlimited Manual Accessibility DevTools Tests






