How do you set up MCP servers for a repository in Codex?
To set up MCP servers for one repository in Codex, create a .codex/config.toml file inside the repository and add one [mcp_servers.<name>] table per server. Codex loads that project file only when you trust the project. The Codex CLI, the IDE extension and the ChatGPT desktop app all read the same configuration.
Cite
CodeLifter Forum, "How do you set up MCP servers for a repository in Codex?", https://codelifter.com/forum/posts/how-do-you-set-up-mcp-servers-for-a-repository-in-codex/, accessed 2026-11-13.- CodeLifter editorsStaffStaff, CodeLifter ·
Where does Codex keep MCP settings?
Codex, OpenAI's coding agent, stores MCP server settings in TOML files, not in a separate JSON file. MCP (the Model Context Protocol) is the open standard that lets an agent call tools that a separate program, the MCP server, offers. OpenAI's Codex MCP page, read on 16 October 2026, says: "By default this is
~/.codex/config.toml, but you can also scope MCP servers to a project with.codex/config.toml(trusted projects only)."The basic configuration page gives the order Codex applies settings, highest first:
Layer File or source Applies to 1. CLI flags --configor-coverridesOne run 2. Project config .codex/config.toml, from the project root down to your working folder; "closest wins; trusted projects only"One repository or subfolder 3. Profile ~/.codex/profile-name.config.toml, chosen with--profileWhenever you pick it 4. User config ~/.codex/config.tomlEvery project on your machine 5. System config /etc/codex/config.tomlon UnixEvery user on the machine So a server defined in the repository's
.codex/config.tomlsits above your personal defaults, and a.codex/config.tomlin a subfolder beats one at the root when you start Codex inside that subfolder.Why does
codex mcp addnot create a project server?Because it writes to your user file. The Codex CLI source,
mcp_cmd.rs, describesaddas "add a server launcher entry to~/.codex/config.toml", and after it runs it printsAdded global MCP server '<name>'.Its usage line iscodex mcp add [OPTIONS] <NAME> (--url <URL> | -- <COMMAND>...). That is the right command for a server you want everywhere. For a server that belongs to one repository, write the project file by hand.How do you add a server to one repository?
- In the repository root, create a folder named
.codex. - Inside it, create
config.toml. This example adds a local server that Codex starts as a process (a stdio server) and a remote server reached by URL (a Streamable HTTP server):
# .codex/config.toml [mcp_servers.playwright] command = "npx" args = ["-y", "@playwright/mcp"] startup_timeout_sec = 20 [mcp_servers.github] url = "https://api.githubcopilot.com/mcp/" bearer_token_env_var = "GITHUB_PAT" default_tools_approval_mode = "prompt"- Set the token in your shell, not in the file:
export GITHUB_PAT=.... Thebearer_token_env_varkey names the variable; Codex reads its value and sends it in theAuthorizationheader. - Start Codex from inside the repository and trust the project when asked. The approvals and security page notes that Codex "may also start in
read-onlyuntil you explicitly trust the working directory (for example, via an onboarding prompt or/permissions)". An untrusted project's.codex/layer is skipped entirely. - In the Codex composer, type
/mcpto list the connected servers and check that both appear.
The server names, commands and URL above are examples; take the real install line from each server's own documentation. The CodeLifter MCP directory lists the install line and licence for each server it covers, including Playwright MCP.
Which settings can you put on a project server?
The MCP page lists these keys for every
[mcp_servers.<name>]table:Key What it does Default command,args,cwdStart a stdio server, with arguments and a working folder None env,env_varsSet variables for the server, or forward named variables from your shell None url,bearer_token_env_var,env_http_headersReach a remote server and authenticate from environment variables None startup_timeout_sec,tool_timeout_secTime limits for start-up and for each tool call 10 and 60 seconds enabled,requiredSwitch a server off without deleting it; make start-up fail if it cannot start Enabled, not required enabled_tools,disabled_toolsAllow list, then deny list applied after it All tools default_tools_approval_modeauto,prompt,writesorapprove;writes"prompts for tools that aren't marked read-only"Not set For a shared repository,
enabled_toolsis the useful one: list only the tools the project needs, so a teammate who pulls the repository does not get a server with write tools they never asked for. How hosts, clients and servers fit together is covered in the parts of an MCP setup thread.What should you commit, and what should stay out?
Commit
.codex/config.tomlonly if it holds no secrets. Usebearer_token_env_var,env_http_headersorenv_varsfor anything sensitive, because those keys store a variable name, not its value. Do not put a token inenv, which sets literal values, and do not runcodex mcp add --oauth-client-secretfor a project server: the MCP page says Codex then "saves the secret asmcp_servers.example.oauth.client_secretinconfig.toml." For the GitHub server, the token scopes thread explains how narrow the token can be.Remember that the file runs commands. A
commandline in a cloned repository is code that starts on your machine once you trust the project, so read.codex/config.tomlbefore you say yes, the same way you would read apackage.jsonscript.Short version
- Put repository servers in
.codex/config.tomlat the repository root, one[mcp_servers.<name>]table each. - Codex loads it only after you trust the project; check with
/mcp. codex mcp addwrites to~/.codex/config.toml, so it creates global servers, not project ones.- Keep tokens in environment variables and name them with
bearer_token_env_varorenv_vars. - Use
enabled_toolsanddefault_tools_approval_modeto keep a shared server narrow.
- In the repository root, create a folder named
Write something first.
Give people something to work with: at least 30 words on what happened and what you tried.
That is too long. Keep it under 6,000 characters.
Write the question as the title, 15 to 140 characters, no links.
Pick a category.
Add a name (2 to 40 characters, no links).
That email address does not look right.
That was quick. Read the thread, then try again.
The form expired. Reload the page and post again.
Something went wrong with the form. Reload and try again.
Please complete the check and post again.
Limit reached for now. Try again later.
This thread is closed to new replies.
This thread no longer accepts replies.
Something went wrong with the form. Reload and try again.
Post a reply or question first (name and email), then this browser can vote, edit and accept answers.
You cannot vote on your own post.
Only the author (within 30 days) or the forum team can do that.
That email already has an account. Use your sign-in link instead.
New accounts are paused for the moment. Try again later.
That was already posted.