Codex keeps MCP servers in a config.toml file, by default in a .codex folder in your home directory. Each server can have an allow list and a deny list of tools, timeouts and an approval mode. For a security tool, start with a short allow list and prompts on, then widen it as you verify behavior.
Where the configuration lives
OpenAI's Codex documentation says MCP settings are stored in config.toml, by default at ~/.codex/config.toml. A project can add its own .codex/config.toml, but only in trusted projects. The ChatGPT desktop app, the command line tool and the IDE extension share the same configuration. Each server is a table named mcp_servers followed by the server name.
That sharing matters for review. A server you add from the command line also appears in the other surfaces, so one approval covers more places than you might expect.
Two kinds of server
| Kind | Key fields | Typical use |
|---|---|---|
| STDIO | command, args, env, cwd | A local helper that runs on your machine |
| Streamable HTTP | url, auth, bearer_token_env_var, headers | A remote service such as a security platform |
For HTTP servers the default authentication is OAuth, started with a login command for that server. Alternatively you can name an environment variable that holds a bearer token. The documentation warns that if no credential source resolves, Codex connects without authentication. For a security connector, that is a reason to test that an unauthenticated connection is refused by the server.
Controls per server
The documentation lists these options, each worth a conscious decision.
- enabled: switches a server off without deleting it, which is useful during an incident.
- required: makes startup fail if the server cannot initialize.
- enabled_tools and disabled_tools: an allow list and a deny list, with the deny list applied after the allow list.
- startup_timeout_sec and tool_timeout_sec: defaults are 10 and 60 seconds.
- default_tools_approval_mode: one of auto, prompt, writes or approve, with per tool overrides.
- output_token_limit: a per tool budget on how much output enters the conversation.
A worked example
This example is illustrative. A team adds a remote vulnerability platform. The platform exposes fourteen tools, of which four can change data.
- The engineer adds the server with its URL and signs in with the login command, so access follows the person, not a shared key.
- In config.toml, the engineer sets an allow list of the six read tools the pilot needs.
- The approval mode is set to prompt, so every call asks first.
- A per tool override sets a lower output limit on the findings list tool, so one question cannot pull thousands of rows into the conversation.
- After a week the log shows that two read tools were called constantly with predictable results. The engineer changes their mode to auto and leaves everything else on prompt.
- The four write tools stay off until someone writes a reason to enable one.
Step by step checklist
- Decide local or remote, using the same reasoning as for any MCP client.
- Add the server, preferring OAuth over a pasted token.
- Write the allow list before the first real question.
- Set approval to prompt.
- Set timeouts you can live with, and a per tool output limit.
- Commit project level config only if it contains no secrets, and only for trusted projects.
- Record the server in your connector register.
Warnings from the documentation
If you register a pre-configured OAuth client secret on the command line, it is saved in plaintext in config.toml, so keep the file private and out of version control. Callback addresses must match what you registered with the provider. The page also notes that local servers and transports may not be available in cloud containers, and that MCP hooks do not provide a complete audit trail through the Compliance API, so plan your own logging.
Common mistakes
- Leaving no allow list, so every tool the server ever adds becomes available.
- Setting the approval mode to approve everything because prompts feel slow.
- Pasting a token directly into the file rather than naming an environment variable.
- Forgetting that the same file serves several Codex surfaces.
What to ask the vendor
Does the connector work with OAuth for each user? Which tools can write? Can the server return less data per call, so that a low output limit does not cut answers short?
Reviewing the file as a team
Treat config.toml like any other file that can start programs. For a stdio server, the command field is a program that runs with your privileges, so read it before you save it. For HTTP servers, read the URL and confirm it belongs to the operator you intended. Ask each engineer to share the server tables, with secrets removed, in a pull request or a ticket, so a second person sees what was added.
Keep a standard snippet for approved servers, with the allow list and approval mode already set. New users copy the snippet rather than starting from a blank file, which prevents the common case of a server added with no allow list at all.
Where Safeguard fits
Safeguard offers an MCP Guardrail for policy on the tools agents can call, which sits above any one client's configuration file. A free scan at gold.safeguard.sh/scan lets you see typical findings first. The Safeguard CLI, installed with a curl or PowerShell installer, can also write code, and the download page lists a Local agent and a Cloud agent as available.
Try it yourself
Click through it at your own pace, or open it full screen.
Look at the tools the server exposes and mark which ones you would put on an allow list.
Quick check
Can I keep a server installed but unused?
Yes. The documentation describes an enabled option that switches a server off without deleting it.
Does the deny list override the allow list?
The documentation says the deny list is applied after the allow list, so a tool on both lists is denied.
Is a project config file safe to commit?
Only if it contains no secrets, and Codex reads project config only in trusted projects. Keep tokens in environment variables.
Sources
Last reviewed: 19 October 2026.