DynamoDB MCP for Codex
Codex can read your DynamoDB schema and query your tables once you give it an MCP server to call.
Codex configures MCP in TOML, and the table name is mcp_servers, snake_case: not
the mcpServers key Cursor uses. A camelCase key is the usual reason the server never
shows up.
This guide covers the config, the transport rule, login, the timeouts worth raising, and how to connect without putting AWS credentials in the agent's config. The DynamoDB MCP server overview compares all the options.
What Codex can do once it's connected
Through DynoTable, Codex reads your real schema (tables, key schema,
indexes, the attributes that appear in items) and runs PartiQL SELECT, GetItem and
item counts against live data.
It aggregates through Workbench SQL and stages edits for you to commit in the
staging area. There is no raw Query or Scan tool, and PartiQL
results come back capped to a small sample.
Before you start
- Install DynoTable: download it and add the AWS profile Codex should see.
- Expose that profile: its MCP section → Expose via MCP. The connection is bound to that profile's credentials and region; with nothing exposed, every connection is refused.
- Turn the MCP server on in Settings → MCP. Off by default, bound to
127.0.0.1.
Copy the endpoint and real port from the profile's MCP section.
Add the server to config.toml
Codex reads MCP servers from ~/.codex/config.toml:
[mcp_servers.dynotable-prod]
url = "http://127.0.0.1:<port>/mcp?profile=prod"Three details decide whether it works.
The table is mcp_servers, snake_case. Codex reads servers only from that table, so
a [mcpServers.dynotable-prod] table never registers a server. If your config looks
right and Codex sees nothing, check this first.
url selects the transport. command means a stdio server, url means streamable
HTTP. They are mutually exclusive: url, bearer_token_env_var and http_headers
can't sit in a table that also has command. DynoTable is HTTP, so url only.
?profile=prod is a hint, not authorization. It pre-selects the profile in
DynoTable's approval prompt; you still approve the connection in the app.
Timeouts worth raising
[mcp_servers.dynotable-prod]
url = "http://127.0.0.1:<port>/mcp?profile=prod"
startup_timeout_sec = 30
tool_timeout_sec = 300tool_timeout_sec defaults to 60 seconds per tool call. An aggregate over a large table
can take longer and surface as a tool error rather than as the slow read it is, so raise
it.
startup_timeout_sec (default 10 seconds) covers the initial connection; raise it if
Codex gives up while DynoTable is still starting.
enabled = false parks a server without deleting the block.
Project-scoped config
Codex also reads .codex/config.toml from a trusted project directory. Don't put a
loopback server there if the repo is shared: the port is per-machine and your
teammates don't run DynoTable. Keep it in ~/.codex/config.toml.
Log in and approve the connection
DynoTable's endpoint is OAuth-protected. Restart Codex after editing config.toml, then
run:
codex mcp login dynotable-prodYour browser should open and DynoTable show a consent prompt naming the client. Codex documents OAuth for streamable HTTP servers, but this login against DynoTable hasn't been run end to end yet. If it fails, connect through Claude Code instead. Grant Read only to start; the overview's scopes section covers Read & stage and Full access.
A grant can't be narrowed in place: Revoke in the MCP pane blocks the client's next request, and a different scope means revoking and approving the reconnect.
Without an active plan or trial, DynoTable clamps every connection to Read only and hides the Workbench SQL tool.
Verify it actually loaded
Codex reads config.toml at startup, so an edit mid-session changes nothing. After the
restart and login, run codex mcp list (or /mcp in the TUI) to see the active
servers. Then ask for something only your data answers: "list the tables in this
profile and their key schemas."
A hedged, generic answer means the tools never loaded.
Ask for the key schema before data questions, so the agent pins the partition key and its reads run as Queries rather than Scans. The cost section has the numbers and the other controls.
Why not give Codex AWS credentials?
A server that holds an AWS key hands the agent's process the full IAM power of that key.
An MCP tool result is untrusted input: a row, a document or a fetched page can carry instructions. That's prompt injection, and against write-capable credentials it can act on your tables.
Through DynoTable the agent gets no key over MCP and no write tool, so at Read & stage a steered agent can only stage a diff you review. The overview covers the full model.
DynoTable never passes your credentials to Codex, but they stay in ~/.aws, and Codex
runs shell commands as your user. A Codex permission profile (beta) can deny reads of
~/.aws for the commands it runs; see
OpenAI's permissions docs.
Without DynoTable: a read-only profile
For another DynamoDB MCP server, use a read-only AWS profile instead of keys: a role with
the managed AmazonDynamoDBReadOnlyAccess policy (the
overview shows the profile
block). Forward its name to the stdio server:
[mcp_servers.dynamodb-ro]
command = "<server command>"
args = ["<server args>"]
[mcp_servers.dynamodb-ro.env]
AWS_PROFILE = "dynamodb-readonly"The config holds a profile name, not a secret, and any write the agent attempts fails with an access-denied error.
Troubleshooting
Codex doesn't see the server at all. In order: is the table named mcp_servers
(snake_case), did you restart Codex after editing, and is the TOML valid?
Codex reports a config error for the server. Look for a command key in the same
table as url; they're mutually exclusive. Also confirm enabled isn't false.
The login ends in access denied. No profile is exposed in DynoTable, the MCP server
is off, or you denied the consent prompt. Expose a profile and run
codex mcp login dynotable-prod again.
Connects, then times out on queries. Raise tool_timeout_sec.
It can't stage. The connection was approved at Read only, or your plan lapsed and DynoTable clamped it to Read only.
No Workbench SQL or aggregates. Your plan or trial lapsed. A Read only grant keeps Workbench SQL.
Edits didn't change DynamoDB. They're staged. Commit them from the staging area.
FAQ
How do I connect Codex to DynamoDB?
In DynoTable, expose the profile you want (Expose via MCP) and turn the server on in
Settings → MCP. Add an [mcp_servers.dynotable-prod] table with that profile's url to
~/.codex/config.toml.
Restart Codex, run codex mcp login dynotable-prod, and approve the connection in
DynoTable.
Where does Codex configure MCP servers?
In ~/.codex/config.toml, one TOML table per server, such as
[mcp_servers.dynotable-prod]. Codex also reads .codex/config.toml in a trusted
project, but a loopback server belongs in the home-directory file: the port is
per-machine.
Why doesn't Codex see my MCP server in config.toml?
Most often the table name is wrong: it must be mcp_servers in snake_case, not
mcpServers. The next two causes are editing the file without restarting Codex, and
putting a url key in a table that also has command.
Does Codex use url or command for a remote MCP server?
Use url for a streamable HTTP server like DynoTable. Codex selects the transport from
which key is present (command means stdio, url means HTTP), and the two can't appear
in the same table.
Can Codex write to my DynamoDB tables?
Not directly through DynoTable: it can stage a change, which is written only when you commit it in the app. A server holding write-capable AWS credentials can write directly; a read-only IAM profile makes that write fail. The overview compares the servers.
Related
- DynamoDB MCP server: the options compared: scopes, the security model, read cost and the read-only path for any server.
- Same setup for Claude Code and Cursor.
- MCP server docs: full setup, consent and the security model.
- Staging: how proposed writes are reviewed and committed.
- DynamoDB Expression Builder: generate the
KeyConditionExpression/FilterExpressionin your browser, no agent involved. - Download DynoTable to connect Codex without handing it your keys.
Product names are trademarks of their respective owners; referenced for identification only. Codex config format verified 2026-10-09.