Codex MCP Setup: Images and Video from One config.toml
Connect Codex CLI, the IDE extension and ChatGPT desktop to one MCP media server: config.toml with bearer_token_env_var, five real quirks, a Veo promo video for $0.70.
Bản gốc bằng en

An MCP server for Codex is an external toolbox OpenAI's coding agent can call from all three of its frontends at once: the CLI, the IDE extension, and the Codex tab in the ChatGPT desktop app. One TOML block, and an agent that normally edits code gains abilities its models don't ship with, image and video generation included. Codex refactors and runs tests all day, but no model behind it can hand you an MP4. Add a generation server and "make a promo clip for the release notes" becomes a terminal instruction that ends with a real file.
Here's the entire setup, if that's all you came for. Create an API key in your BananaBanana profile, then add this to ~/.codex/config.toml:
[mcp_servers.bananabanana]
url = "https://bananabanana.pro/api/mcp"
bearer_token_env_var = "BB_API_KEY"
Export BB_API_KEY=bb_live_YOUR_KEY in your environment and restart Codex. That's it: no local server process, no Google Cloud project, no subscription. Images bill from $0.03 off a prepaid balance, video from $0.10. The demo video further down was generated through this exact endpoint on a live key while I wrote the text, and the full $1.03 media bill for this article is itemized at the end.
Why one config file is the whole story here
Most MCP clients make you configure each surface separately. Codex doesn't, and that's the genuinely nice part. The official Codex MCP docs put it in one sentence: "The ChatGPT desktop app, Codex CLI, and IDE extension share this configuration." Paste the TOML block once and the same seven generation tools follow you from a terminal session into VS Code and into the desktop app's Codex tab.

That changes what the server is for. In Cursor or VS Code an image tool mostly serves the repo you have open. With Codex the terminal itself becomes a media console: you can ask for a video render from a plain shell, no editor involved, and check on it later from the desktop app. For someone who lives in tmux and treats GUI apps as an occasional guest, that's the difference between "a plugin I set up somewhere" and "a command I actually reach for."
The alternative, as usual, is running a local MCP server with your own Google API key, quotas and billing attached to your own cloud account. It works. It's also a process to babysit. The remote endpoint already runs on our side, on the same pipeline as the BananaBanana web generator, and your only credential is one revocable bb_live_ key.
How do you connect Codex to an MCP server?
Config details below are checked against the official Codex MCP documentation as of July 11, 2026 (OpenAI recently moved it from developers.openai.com to learn.chatgpt.com, so don't be surprised by the redirect).
First, register and open Profile → MCP API Keys. The key is shown once and stored hashed on our side, so copy it immediately. New accounts start with $0.10 on the balance, which covers three test images on the cheapest model.
Second, add the TOML block from the top of this article to ~/.codex/config.toml, creating the file if it doesn't exist. The [mcp_servers.bananabanana] table takes a url for any Streamable HTTP server and bearer_token_env_var for auth: Codex reads the named environment variable at startup and sends its value as the Authorization header. The key never touches the file, which means the file stays shareable, in dotfiles repos too. Our MCP server page keeps this snippet alongside a compatibility table for every client we've verified:

Third, export the variable and restart. In the CLI, codex will list the server's tools once it connects; ask it to "call list_models on bananabanana" and you should get back live prices for seven tools, list_models through list_generations. The IDE extension and the ChatGPT desktop app pick up the same config on their next launch with no extra steps.
A fair warning about the desktop app on macOS: a GUI application launched from the Dock doesn't read your .zshrc, so an export that works in the terminal can silently not exist for ChatGPT. If tools show up in the CLI but auth fails in the desktop app, that's almost always the cause. launchctl setenv BB_API_KEY bb_live_… fixes it, at the cost of feeling like a workaround, because it is one.
Can ChatGPT's own connectors use the same key?
Short answer: not yet, and it's worth being precise about why. ChatGPT has its own connectors system (Settings → Connectors, behind the developer mode toggle on paid plans) that adds MCP servers to regular chat rather than to Codex. Those connectors authenticate through OAuth flows. Our endpoint currently speaks Bearer keys only; OAuth 2.1 support is planned, and once it ships, plain ChatGPT chat becomes a supported client too. Until then the line is simple: Codex surfaces (CLI, IDE, the Codex tab in the desktop app) work today through config.toml, and the chat-side connectors don't. The compatibility table tracks this per client, with dates.
Use case: a product promo video without opening a single app
The scenario this article was built around: release day, your changelog needs a short promo clip, and you'd rather not leave the terminal. You ask Codex for a product-style video, it composes a cinematic prompt and calls generate_video. The tool never charges on the first call; it returns a quote, and the agent repeats the call accepting the exact amount. This is the real trace from my session:
→ generate_video {"prompt": "Cinematic product promo shot: matte pearl-white
wireless earbuds in an open charging case on a slowly rotating dark
pedestal, dramatic rim lighting in violet and warm amber, soft haze,
slow dolly-in from a slightly low angle, shallow depth of field,
premium tech commercial style", "model": "veo-3.1-fast",
"duration": 8, "resolution": "720p"}
← {"status": "confirmation_required", "quoted_cost_usd": 0.70,
"message": "This video costs $0.70. Nothing has been charged."}
→ generate_video {..., "confirm_cost": 0.70}
← {"job_id": "cmrgrpxgf0002mk7fvfepg82j", "status": "processing",
"cost_charged_usd": 0.70, "balance_remaining_usd": 1553.37}
→ get_result {"job_id": "cmrgrpxgf0002mk7fvfepg82j", "wait_seconds": 30}
← {"status": "completed", "files": [{"url": "https://…/api/files/…"}]}
Two minutes and fifteen seconds from confirmation to a finished 720p file. Here's that exact clip, generated by Veo 3.1 Fast, first take, no rerolls:
The prompt structure follows the pattern from our Veo 3.1 prompt guide: subject, action, lighting, camera move, lens behavior, style. Codex then pulls the file from the signed URL (valid for 24 hours; a fresh get_result reissues it) into the folder you name and can even write the <video> markup for your changelog page.
One honest caveat on the output: $0.70 buys the silent version. Native audio on the same clip costs $1.00, and Omni Flash with sound is a flat $1.00 too. For a muted autoplay loop on a landing page, silent is exactly what you want anyway; for a social cut you'll probably pay the extra thirty cents.
Images work the same way minus the confirmation step, since single images are cheap enough to just run: generate_image with a prompt returns a job id, get_result hands back the file plus a small inline preview Codex can look at.
Codex quirks worth knowing before you rely on it
Collected while testing the setup above, roughly in the order they'll bite you.

1. The CLI won't write this config for you. codex mcp add exists, but per the official docs it has no bearer-token option for HTTP servers; the command targets local stdio servers and OAuth logins (codex mcp login). For a key-authenticated remote server you edit ~/.codex/config.toml by hand. Thirty seconds of work, but if you expected the one-liner experience of claude mcp add --header, this is where Codex differs.
2. It's TOML, and the table is mcp_servers. Snake_case, square brackets, no JSON. Configs copied from Cursor or Claude docs (mcpServers, curly braces) won't parse, and TOML errors in this file tend to fail quietly rather than loudly. If the server never appears, run codex from a terminal and look at the startup output before suspecting anything else.
3. Secrets have one right field and one tempting wrong one. bearer_token_env_var keeps the key out of the file. The alternative http_headers map takes static values, which means a literal bb_live_ key sitting in plaintext in a file that dotfile-sync tools love to publish. There's also env_http_headers for custom headers from env vars. My rule: bearer_token_env_var always, http_headers never for anything secret.
4. The default tool timeout is 60 seconds, and that's fine, but only because of how polling works. Codex gives each tool call tool_timeout_sec = 60 by default. A video job takes one to ten minutes, which sounds like a conflict, except generate_video returns a job id instantly and get_result long-polls for at most 30 seconds per call. Each individual call stays comfortably under the limit; the agent just polls a few times. Don't "fix" this by raising the timeout to 600, you don't need it, and a genuinely hung server would then block the agent for ten minutes.
5. Approval behavior is configurable per server, and money deserves prompt. The default_tools_approval_mode field accepts auto, prompt, writes and approve values, per the docs. For a server where several tools spend real dollars per call, I'd keep prompting on and approve calls individually; the free tools (list_models, get_account, get_result) are the ones worth allowlisting if your setup supports per-tool decisions. Video has a second lock on our side regardless: nothing above a quote gets charged without an explicit confirm_cost.
What did this article's demo media cost?
Standard per-generation prices, the same numbers list_models reports to the agent, no staff discount:
| Asset | Model | Price |
|---|---|---|
| Promo video demo, via MCP on a live key | Veo 3.1 Fast, 720p, 8 s, silent | $0.70 |
| Cover + 2 editorial illustrations | Nano Banana Pro, 1K | $0.33 |
| Docs-page screenshot | browser, not a generation | $0.00 |
| Total | $1.03 |
The video landed on the first attempt, which I wouldn't bank on every time; product-style shots are forgiving, anything with hands or readable text is not. Budget a reroll for those.
If you already run this server in another client, the TOML block above is the only new part: same key, same balance, same generation history everywhere. Starting from zero, the Claude Code walkthrough covers four more use cases that transfer to Codex almost word for word. Create a key and ask Codex for your first render.
FAQ
Does Codex support remote MCP servers with Bearer authentication?
Yes, natively. A remote server is a [mcp_servers.<name>] table in ~/.codex/config.toml with a url field, and bearer_token_env_var names the environment variable whose value Codex sends as the Authorization header. Verified against the official Codex MCP docs on July 11, 2026. OAuth is also supported (it's the default auth mode for servers that offer it), but a static key setup needs nothing beyond those two lines.
Is the MCP config really shared between Codex CLI, the IDE extension and ChatGPT desktop?
Yes. The Codex documentation states that the ChatGPT desktop app, Codex CLI, and IDE extension share the config.toml configuration. In practice the one thing that doesn't automatically transfer is the environment variable: your shell exports are visible to the CLI, while a Dock-launched desktop app needs the variable set at the OS level (launchctl setenv on macOS) or it will fail auth with the exact same config.
Can I add the server with codex mcp add instead of editing the file?
Not for this kind of server. The docs offer no bearer-token flag on codex mcp add for HTTP servers, so a key-authenticated remote endpoint means editing ~/.codex/config.toml yourself. The upside of the manual edit is that the result is explicit and versionable; the block is three lines, and the key stays in the environment rather than in the file.
Why doesn't my bb_live_ key work in ChatGPT's Connectors settings?
Because that's a different integration surface. Connectors in ChatGPT chat (web and desktop, behind the developer mode toggle) authenticate MCP servers through OAuth, not pasted API keys, so a Bearer-only endpoint can't finish that flow today. Codex surfaces read config.toml instead and work fine with the key. Once our OAuth 2.1 support ships, chat-side connectors become a supported path too; the client table tracks the current state.
Can Codex generate video, and what does it cost?
Yes, with a mandatory cost confirmation. generate_video always returns a USD quote first and charges nothing; the agent repeats the call with confirm_cost matching the quoted amount to start the render. Prices run from $0.10 for a 4-second silent 720p Veo 3.1 Lite clip, through $0.70 for the 8-second Veo 3.1 Fast demo in this article, up to $4.40 for a top-end 4K Veo 3.1 render with audio; Omni Flash with sound is a flat $1.00. Failed generations are refunded automatically.