Skip to content

Connect the exchange-rate API as an MCP server

A few of your transactions are in euros and pounds, stored at whatever rate you eyeballed when you entered them. The monthly report treats those numbers as gospel, so your real spend is off by however much the rate has drifted. The fix is obvious — convert at the actual rate — but Codex can’t do it, because the rate lives at an external HTTP API the agent has no way to call. It can reason about currency all day; it just can’t fetch the number.

That gap is the exact signal for an MCP server. The Model Context Protocol is an open standard for connecting an agent to an external tool or data source; an MCP server is one such connection. Wire the rate API up as a server and Codex gets a new tool — convert one currency to another — that it reaches for on its own, the way it already reaches for shell or file edits. The API stops being something you look up and paste in, and becomes something the agent touches directly.

Codex configures MCP servers in config.toml, under a [mcp_servers.<name>] table. The common shape is a stdio server — a process Codex spawns on your machine and talks to over stdin/stdout. You give it a command and its args:

# ~/.codex/config.toml (or .codex/config.toml in the repo)
[mcp_servers.fx]
command = "npx"
args = ["-y", "your-exchange-rate-mcp-server", "--api-url", "https://<your-rate-api-endpoint>"]

Use the real package and endpoint your rate provider publishes — the values above are placeholders, not a server that exists. The table name (fx here) becomes the prefix on every tool the server exposes, so the model sees something like fx.convert and never collides with another server’s tools.

Servers that live out on the network are reached as a remote server instead, by giving a url in place of command/args. The transport is chosen by which key is present; the official syntax for both shapes, plus auth via named environment variables rather than secrets pasted into the file, is on the Codex MCP docs.

You don’t have to hand-edit the file. The codex mcp subcommand manages servers from the CLI:

codex mcp add fx -- npx -y your-exchange-rate-mcp-server --api-url https://<your-rate-api-endpoint>
codex mcp list # what's registered, connected, or failed
codex mcp get fx # inspect one server
codex mcp remove fx

Read the add form carefully: the bare -- separates the server name from the command Codex will spawn. Everything before it is the name; everything after is the process. Inside a session, /mcp shows the same connection status without leaving the agent.

Now you ask Codex to use it — and on a fresh budgetcli setup, it fails:

> recompute the EUR and GBP transactions at the current rate
● fx.convert { from: "EUR", to: "USD", amount: 4200 }
✗ network error: connection refused
The rate server is registered but I can't reach the network to
call it — the sandbox is blocking the outbound request.

Nothing is wrong with the server. This is the same wall you met back in approvals & sandbox: in workspace-write, network access is off by default. A stdio MCP server runs as a child process inside that sandbox, so when it tries to reach the rate API, the sandbox refuses the connection — exactly as it would refuse the agent’s own curl.

The fix is the one from that chapter: enable network for this workspace deliberately, knowing what you’re opening.

[sandbox_workspace_write]
network_access = true

This is worth sitting with rather than reflexively flipping on. Registering an MCP server does not by itself grant the agent the network — the sandbox still governs reach. That separation is a feature: you decide, per project, whether the convenience of a live API is worth the wider blast radius, instead of a connection silently becoming a hole. For budgetcli, a single read-only rate lookup is an easy yes — but it’s you saying yes, not the server assuming it.

With the network open, the same request goes through, and the copy-paste loop collapses:

> recompute the EUR and GBP transactions at the current rate
● fx.convert { from: "EUR", to: "USD", amount: 4200 }
→ 4557
● fx.convert { from: "GBP", to: "USD", amount: 1899 }
→ 2402
Converted both at the live rate and stored the results as integer
cents, per the AGENTS.md money rule. The March report total drops
by $38 once the stale rates are replaced.

Notice what changed. You asked one question in plain language; Codex called the rate tool twice on its own, applied the cents-not-floats rule from AGENTS.md without being reminded, and reasoned across the result. Nothing was pasted. A live external system is now part of the agent’s working context.

One discipline before you add more servers: every connected server injects its full tool description into context at session start, whether or not you use it. Two or three useful servers cost little; a dozen “might need it someday” servers spend your context budget on capability descriptions before you’ve typed a word. Connect for a concrete gap — the rate API is one — not on spec.

You’ve now given Codex reach in one direction: out to an external system. There’s a second direction worth knowing about — Codex itself standing in as a server that another agent calls. That’s the next lesson.