Skip to main content
An MCP server is a separate program or web service that gives the model extra tools, such as access to an issue tracker, a database, or a docs site. o4 speaks the Model Context Protocol (MCP), so you can connect any MCP server over stdio, Streamable HTTP, or the older SSE transport. Add an MCP server when you want the model to use a system that o4’s built-in tools can’t reach.

Add a server

The quickest way to add a server is the MCP browser. In a session, run:
Choose Add server and follow the steps: pick a transport (stdio or sse), give the server a name, enter the command and arguments or the URL, add any environment variables or headers (one KEY=value per line; press Shift+Enter for a new line), choose the scope, and confirm. o4 splits the arguments the way a shell does, so quote an argument that contains spaces. o4 starts the server right away and the model can use its tools in the same session. If the server fails to connect, o4 shows the error and doesn’t save the entry. In the steps, Enter or Tab moves on, Backspace in an empty field goes back a step, and Esc cancels. To add a Streamable HTTP server, edit the config file. You can also edit the config file yourself. For a server that runs as a local command, create .o4/.mcp.json in your project:
o4 reads the config files when a session starts. If you edit a file while a session is running, start a new session to pick up the change, or change the server from /mcp with Edit config, which reloads the file when you close your editor.
Servers in a project’s .o4/.mcp.json only load after you trust the workspace. See Project servers need workspace trust.

Where servers are configured

o4 reads MCP servers from two files. Both use the same format. If both files define a server with the same name, the project entry wins. When you add a server through Add server in /mcp, the scope step starts on global. o4 mcp add and /mcp add <name> write to the project file unless you pass --global to the CLI command. o4 writes these files with owner-only permissions, and refuses to read a config file that is a symlink or larger than 4 MiB. Plugins can also provide MCP servers. Those servers are never written to .mcp.json, and a server with the same name in your own config takes precedence over the plugin’s. See Plugins and marketplaces.

Config format

Each entry under mcpServers is keyed by the server name. The name also prefixes the server’s tools: a tool called search on a server named docs reaches the model as docs__search.

Local servers (stdio)

o4 starts the command as a child process and talks to it over standard input and output. transport defaults to stdio, so you can leave it out.
The child process does not inherit your full environment. o4 passes only a small safe set of variables (PATH, HOME, USER, LOGNAME, SHELL, TERM, TMPDIR, TZ, LANG, PWD, and the LC_* locale variables), so API keys in your shell don’t leak to MCP servers. To give a server more, set values in env or name variables to copy from your environment in pass_env. A value in env wins over one from pass_env. LD_PRELOAD and DYLD_* variables are never passed through pass_env.

Remote servers (HTTP and SSE)

For a server reached over the network, set transport and url:
The URL must start with http:// or https://. o4 rejects URLs that point at localhost, loopback, private-network, or link-local addresses, so you can’t use a remote transport for a server running on your own machine. Run local servers with stdio instead. o4 includes a test switch for this: start o4 with O4_ALLOW_LOCALHOST=1 and it accepts loopback and private-network addresses too. Link-local addresses, such as the cloud metadata address 169.254.169.254, stay blocked.

All server fields

string
default:"stdio"
stdio, sse, http, streamable_http, or streamable-http. You can write type instead of transport.
string
The program to run. Required for stdio.
string[]
Arguments for command.
object
Environment variables to set for a stdio server.
string[]
Names of variables to copy from o4’s environment into a stdio server, when they are set.
string
The server endpoint. Required for sse and HTTP transports.
object
HTTP headers to send, written into the config as plain text. You can write httpHeaders instead of headers.
string
The name of an environment variable that holds a token. o4 reads it when it connects and sends Authorization: Bearer with the token. HTTP and SSE only. You can’t combine it with an Authorization entry in headers.
object
Headers whose values come from environment variables, as "Header-Name": "VARIABLE_NAME". HTTP and SSE only. A header can’t appear in both headers and env_http_headers.
boolean
default:"true"
Set to false to keep the entry but not start the server.
integer
Seconds to wait for the server to finish its startup handshake and list its tools. The default is 10 seconds, or 30 seconds for /mcp restart <name> and for servers a subagent starts. /mcp restart without a name gives each server at most 10 seconds, even when you set this higher.
integer
default:"30"
Seconds to wait for a single tool call. Must be more than 0.
string[]
Only these tools are shown to the model. Use the tool names without the server prefix.
string[]
Tools hidden from the model. A tool listed in both enabled_tools and disabled_tools is hidden.
boolean
default:"false"
In print mode, a required server that fails to start stops the run with an error. In an interactive session, the failure is listed on the Errors tab of /mcp as “Required MCP server failed to start” and the session continues.
o4 checks each entry when it loads the file. An invalid entry, such as a stdio server without command or a blocked URL, is skipped and a warning is written to the log. The other servers still load.

Authentication

o4 does not run an OAuth sign-in flow for MCP servers. For a server that needs a token, keep the token in an environment variable and point the config at it with bearer_token_env_var or env_http_headers:
o4 reads the variables when it connects to the server and doesn’t write their values to disk or to the log. If a variable is missing or empty, that server fails to start with an error that names the variable. Start o4 from a shell where the variable is set:
For stdio servers, pass credentials with env or pass_env instead.

Manage servers in a session

/mcp opens the MCP browser. It has three tabs:
  • Configured: your servers with their status, scope, transport, and tool count. Select a server to restart it, enable or disable it, remove it, open its config file in your editor ($EDITOR, then $VISUAL, then vi), or view its tools.
  • Registry: search the MCP registry and add a server from the results.
  • Errors: servers that failed to start, and failed MCP actions such as a registry search or a restart, with the error message.
Disabling a server sets enabled to false in its config file and removes its tools from the session. Edit config opens the file that defines the server; when you close the editor, o4 reloads the config and restarts that server. While the model is working, you can still open the browser and search the registry, but adding, removing, enabling, disabling, restarting or editing a server is refused: o4 closes the browser and shows Wait for the current turn to finish before making this change. The typed commands that change servers, such as /mcp add <name> and /mcp remove <name>, wait for the turn to finish instead. In the browser, Up and Down move between rows, and Tab and Shift+Tab (or Right and Left) switch tabs. Type to filter the Configured list; Backspace deletes a character and Ctrl+U clears the filter. On the Registry tab, type a query and press Enter on Search registry. Enter opens a server’s details or runs the selected action, Backspace goes back from the details, and Esc closes the browser. See Keyboard shortcuts. You can also go straight to an action: The MCP tab in /config (run /config mcp to go straight to it) has one row, Open MCP browser. It opens the same MCP browser as /mcp.

Manage servers from the command line

The o4 mcp commands work outside a session, which is useful in scripts. o4 mcp list only reads the config files, and skips the project file in an untrusted workspace. It doesn’t start the servers, so the Status column always shows stopped and Tools shows ?:
o4 mcp remove removes the server from the project config if it’s there, and otherwise from the global config. o4 mcp restart exists, but servers only run inside a session, so it exits with “Server restart is only available within an interactive session”. Use /mcp restart in a session instead.
In o4 0.2.74, registry lookups fail. o4 queries https://registry.modelcontextprotocol.io/servers, which the registry no longer serves, so o4 mcp search exits with “Registry search failed with status 404 Not Found”, and o4 mcp add <name> reports that the server was not found. The Registry tab and /mcp add <name> use the same lookup. Until this is fixed, add servers with Add server in /mcp or by editing .mcp.json.

Project servers need workspace trust

An MCP server entry can run any program on your machine, so o4 ignores a project’s .o4/.mcp.json until you trust that workspace. When you open an untrusted workspace that has project servers, o4 offers to trust the workspace and load them. To trust it from the command line, review the checkout and run this from the workspace root:
Trust also covers the folders inside the trusted one. o4 untrust revokes it. Setting O4_TRUST_WORKSPACE=1 trusts every workspace for that o4 process, so use it only for automation that already vets the repository. o4 mcp add without --global refuses to write to an untrusted workspace. See Workspace trust for everything trust controls.

How the model uses MCP tools

Each MCP tool reaches the model as <server>__<tool>, with the description and input schema the server reports. If your built-in and MCP tools together come to more than 64, o4 doesn’t send the MCP tools up front. The model finds them with the tool_search tool and loads the ones it needs. MCP tool calls go through the same checks as built-in tools:
  • In the default ask permission mode, the first call to a server’s tools asks for approval. After you approve, other calls to that server’s tools don’t ask again for the rest of the session.
  • Permission rules that match the tool name, such as docs__search, can allow, deny, or always ask for a tool. See Permissions.
  • PreToolUse hooks run before each call and can block it. See Hooks.
  • Plan mode blocks MCP tools. See Plan mode.

Resources

Some MCP servers also expose resources, such as files or records the model can read. The model has two built-in tools for them:
  • list_mcp_resources lists a server’s resources. It doesn’t ask for approval.
  • read_mcp_resource reads one resource by its URI. It asks for approval each time.

MCP in print mode and evals

Print mode (o4 -p) loads the same MCP servers as an interactive session, including project servers when the workspace is trusted. If a server fails to start, o4 prints an [mcp error] line to standard error and the run continues, unless the server is marked "required": true, in which case the run stops with an error. See Print mode and scripting. o4 eval runs don’t load MCP servers unless you pass --enable-mcp. See Evaluations.