Seed Postgres From the Codex CLI With One MCP Command
By Mikhail Shytsko, Founder at Seedfast ·
My Codex CLI session is open and the migrations have run, but the schema behind my branch is still empty. Codex CLI database seeding handles that from inside the same session, once Seedfast is registered as an MCP server the agent can call by name, and it spares me the usual fallback of hand-written inserts from the model, which tend to satisfy the column types and break on the relationships between tables — the broader guide to generating test data with AI covers why.
TL;DR: One codex mcp add command registers the Seedfast MCP server in ~/.codex/config.toml. A plain-English prompt then calls seedfast_run, which works out insert order from the foreign keys in your live Postgres schema, so every child row it writes points at a real parent.
Codex CLI is OpenAI's open-source terminal coding agent, and it speaks the Model Context Protocol out of the box. One subcommand wires Seedfast into it.
codex mcp add seedfast --env SEEDFAST_API_KEY=sfk_live_your_api_key_here -- npx -y seedfast@latest mcp
That command writes the server into the global ~/.codex/config.toml, the TOML file Codex loads at startup. Open the file afterward and the new entry reads like this.
[mcp_servers.seedfast]
command = "npx"
args = ["-y", "seedfast@latest", "mcp"]
[mcp_servers.seedfast.env]
SEEDFAST_API_KEY = "sfk_live_your_api_key_here"
Run codex mcp list to confirm the registration, and once you are inside a session the /mcp command shows which servers are live. To check that the key authenticated, ask Codex to call seedfast_doctor, which verifies the install and confirms an sfk_live_... key is configured; keys come from the Seedfast dashboard. Because the server launches through npx, the machine needs Node.js 18 or later, and the flags codex mcp add accepts are documented in OpenAI's MCP configuration reference.
codex mcp add only ever writes the global file. To share the server through a repository, you add a project-scoped .codex/config.toml by hand and check it in. Codex loads those project layers only for projects you have trusted, walking from the project root down toward your working directory, and the file closest to where you are running takes precedence on any conflicting key. A handful of security-sensitive keys are refused at project level regardless.
Committing a config raises an obvious question about the API key sitting in it. Per OpenAI's config reference, Codex does not hand your whole shell environment to an MCP server, so a secret reaches the server one of two ways. You either hardcode it in the env table, where it then lives in the file, or you list the variable name under env_vars and let Codex forward it from its own environment at launch.
[mcp_servers.seedfast]
command = "npx"
args = ["-y", "seedfast@latest", "mcp"]
env_vars = ["SEEDFAST_API_KEY"]
Under env_vars, the file names SEEDFAST_API_KEY but never stores its value, which makes a project-scoped config safe to commit while each developer exports the key in their own shell. That forwarding is opt-in per variable, so don't assume the server can see anything else you exported; declare what it needs, one way or the other. The full set of layering and precedence rules lives in OpenAI's config reference, and the equivalent setup for other clients, including the Claude Code version of this job, is in the MCP setup guide.
Once the server is registered, the seed itself is one message to the agent. Say a test needs a small project tree to assert against.
Use seedfast_run to fill projects, tasks and comments. A handful of projects, a realistic spread of tasks each, a few comments where they fit.
Codex reads that and calls seedfast_run with the scope, handing off the relational work. Seedfast inspects the live PostgreSQL schema at that moment and sequences the inserts off the foreign-key graph before writing the first row, so a task lands only after the project it belongs to and a comment only after its task. The same call scales with the words you choose — "a handful" keeps a unit test quick while "a few thousand tasks" gives a query planner something to strain against. Codex picked up the GPT-5.6 family on launch day, which means the model parsing your scope may well be GPT-5.6 Sol; the ordering across tables still comes from the seeder, not the model.
When the run finishes, ask Codex for the summary, which reports how many tables succeeded and the total rows written, naming any table that failed; a SELECT count(*) gives you the same numbers from the database side. At Seedfast's default row volume even a full schema comes back populated inside a few minutes, and a scoped seed like the one above lands while you are still reading the test that needed it.
There is a fair worry under all of this, since you are giving an agent a write path into a database. Codex ships three sandbox modes (read-only, workspace-write, danger-full-access) with network access off until you enable it, and those govern the shell commands the agent itself runs. An MCP server sits outside that arrangement; Codex starts it as a separate, long-lived process, and in practice the sandbox does not confine it, though the docs don't spell this out. So the guardrail worth setting is the database connection you hand the server, which should belong to a dev or branch database. Codex does expose approval policies you can configure per server and per tool if you want a gate before a call runs, and because Seedfast composes every row from the schema alone, production data never enters the run.
codex mcp add stores the Seedfast entry globally, under an [mcp_servers.seedfast] table in ~/.codex/config.toml. Nothing project-local is created by the command; a repo-scoped .codex/config.toml has to be written by hand, and codex mcp list or the in-session /mcp command will confirm what actually registered.
Seedfast API keys stay out of a committed file when the variable is named under env_vars instead of written into the env table. OpenAI's config reference describes env_vars as a pass-through list, with Codex forwarding each named variable from its own environment when the server starts, so the committed file carries only the name SEEDFAST_API_KEY, never the value, and teammates supply their own keys locally. Hardcoding the key in env is fine for the global file in your home directory, but it doesn't belong in anything you push.
Codex CLI's sandbox is aimed at the agent's own shell commands, so in practice it does not restrict the Seedfast server, and nothing in the official docs places MCP processes inside that boundary. That leaves the choice of target database as the real limit on what a seed run can reach, with per-server and per-tool approval policies available on top when you want an explicit gate before a call.
Every seedfast_run call starts with a fresh look at the current Postgres schema, so a column added by this morning's migration shows up in the next batch of rows without any config change. Scope stays up to the prompt, and generated rows keep their references valid at any size because the foreign-key graph is rebuilt at the same time.
Codex CLI already sits where your migrations and tests run, and registering Seedfast means the same session can fill the schema they depend on. Keys come from the Seedfast dashboard, where the 30-day free trial starts without a card. Once /mcp shows the server live, every empty dev schema after that is one prompt away from being populated.