Intermediate6 min read

DynamoDB MCP for Codex

Codex can read your DynamoDB schema and query your tables once you give it an 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

  1. Install DynoTable: download it and add the AWS profile Codex should see.
  2. 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.
  3. 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 = 300

tool_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-prod

Your 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 , 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.

Product names are trademarks of their respective owners; referenced for identification only. Codex config format verified 2026-10-09.

By Dmitriy · Updated