codex-mcp is a small terminal UI for organizing Codex CLI MCP servers into
native Codex configuration profiles and launching Codex with one of those
profiles.
I've slopped this because the other tools weren't as minimal as I wanted / didn't work with codex cli. Judge me as you like lol
It does not introduce another profile format. Codex loads its base
$CODEX_HOME/config.toml and overlays
$CODEX_HOME/<profile>.config.toml; this tool reads the same files and only
edits the native TOML definitions and each MCP server's profile-level
enabled value. See the official
Codex profile documentation
and configuration reference.
Rust 1.85 or newer is required.
cargo install --path .Ensure both codex-mcp and codex are available on PATH.
codex-mcp
codex-mcp -- -C /path/to/project
codex-mcp --codex-home /path/to/another/codex-home
codex-mcp --codex-bin /path/to/codex -- "start with this prompt"Arguments after -- are passed to Codex unchanged. Do not pass -p or
--profile; the selected row determines the profile.
The Base row launches Codex without a profile. Selecting a named profile
launches:
codex --profile <name> <forwarded arguments>The current directory and environment are preserved.
Profile picker:
Enter: launch the selected rown: create a profilee: edit MCP statesr: rename a profiled: move a profile to the recovery directorym: open the MCP server inventoryi: inspect the selected Base or profile file as native TOMLj/kor arrow keys: navigateqorEsc: quit
Profile editor:
Space: cycleInherited,Enabled, andDisableds: saveEsc: discard the in-memory changes
MCP inventory:
n: add a local stdio or remote HTTP servere: edit the selected server's guided fieldsi: inspect only the selected server's native TOML tablev: ask Codex to validate the current configurationEsc: return to profiles
Source inspector:
j/k, arrow keys,PageUp, orPageDown: scroll vertically- Left/right arrows or
h/l: scroll long lines horizontally Home/End: jump to the beginning or endqorEsc: return to the originating screen
The add-server flow collects a safe name and transport, then opens the same sectioned form used for editing existing servers. The form includes:
- Connection fields: local executable, shell-style arguments, optional working directory, and inherited environment-variable names; or a remote HTTP URL and optional bearer-token environment-variable name
- Runtime fields:
required,startup_timeout_sec, andtool_timeout_sec - Tool-policy fields:
default_tools_approval_mode,enabled_tools, anddisabled_tools - Profiles in which a newly created server should be enabled
Server form keys:
j/kor arrow keys: navigate fieldsEnter: edit an input field or open a tool listSpaceor left/right: cycle optional boolean and approval-mode valuesDeleteorBackspace: unset the selected optional fields: validate and save the formEsc: discard the in-memory changes
While editing text, left/right arrows move the cursor, Home/End jump to
either edge, Backspace removes the character before the cursor, and Delete
removes the character under it. Long values scroll horizontally to keep the
cursor visible. Ctrl-U clears the complete field.
Inside an enabled/disabled tool list, a adds a tool, Enter or e edits
one, and d or Delete removes one. Space toggles between an unset list and
an explicit empty list; those have different meanings and are preserved
separately.
New definitions are always written to config.toml with enabled = false.
The tool then writes explicit enabled = true overrides only to the profiles
selected in the wizard. This prevents a newly added server from silently
appearing in Base or unrelated profiles.
The server editor keeps the existing name, transport, and Base enablement.
Existing values are prefilled; use Ctrl-U to clear a text input before
replacing it. Only fields changed in the form are written. A legacy
startup_timeout_ms value is displayed in seconds but remains stored in
milliseconds until that field is edited; editing it writes the canonical
startup_timeout_sec field.
Inherited means the profile has no enabled override for that server. The
effective state then comes from config.toml; if neither layer contains an
enabled value, Codex's default is enabled.
- Existing commands, arguments, URLs, headers, and environment values are never rendered by inventory or profile screens. Inspecting TOML or loading an existing server into the editor requires an explicit sensitive-data confirmation.
- The wizard accepts environment-variable names rather than secret values.
HTTP bearer tokens should use
bearer_token_env_var; stdio servers should inherit named variables throughenv_vars. - Profile changes preserve unrelated settings and TOML comments.
- Adding a server preserves unrelated base settings and comments and uses the same atomic-write protections as profile edits.
- Editing a server changes only fields marked dirty in the form. Base
enablement, comments, headers, nested environment tables, and other advanced
TOML fields are preserved. Structured
env_varsvalues that cannot be represented by the simple name list appear read-only, without preventing edits to the other supported fields. - Saves use a same-directory temporary file and atomic rename. A save is rejected if another process changed the Base config or profile after it was opened.
- New profile files use user-only permissions on Unix.
- Deleted profiles are moved to
$CODEX_HOME/.codex-mcp-trash/, not permanently removed. - Malformed profiles are shown as invalid and cannot be edited or launched by the manager until repaired externally.
Renaming, removing, or changing the transport of existing server definitions,
and performing OAuth login/logout, remain the responsibility of codex mcp.
Plugin-bundled MCP servers and native Windows are outside the initial release.
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test