Skip to main content
Glama
tksfjt1024

codex-cli-mcp-slim

by tksfjt1024

codex-cli-mcp-slim

A thin, auditable MCP server wrapping the Codex CLI (codex exec).

PyPI version Python versions License: MIT CI

Why

codex mcp-server, the command that let other MCP clients call Codex, is deprecated, and its removal has been merged upstream (openai/codex#42993): releases up to 0.153.x still ship it, later ones will not. Its replacement, the Codex app server, speaks its own JSON-RPC protocol rather than MCP. This server keeps the old integration point alive: it exposes the same two tools, codex and codex-reply, and runs codex exec underneath. codex exec is the Codex CLI's non-interactive mode: one prompt in, the agent works on its own, one final message out.

When you add an MCP server to your AI coding tool, every prompt and code snippet you send flows through that wrapper. Most CLI-wrapping MCP servers are small, individually maintained packages, and recent supply-chain incidents (xz-utils, postmark-mcp, the npm chalk/debug compromise) show that "small and useful" is not the same as "safe to trust blindly."

This project takes the opposite stance: instead of asking you to trust it, it tries to be easy to audit.

  • Single file — the whole server is src/codex_cli_mcp_slim/server.py, readable end-to-end in one sitting

  • One third-party dependency (mcp) — minimal supply-chain surface

  • Faithful CLI mapping — every typed parameter mirrors a real codex exec flag by name, so it is obvious which flags an invocation actually sets

  • Prompt over stdin — the prompt never appears in the process list and is not bounded by the argv size limit

  • Forward-compatible — any new or uncommon codex exec flag is reachable via extra_args without touching this server

  • Configurable binary path$CODEX_CMD lets you swap or wrap the codex binary

  • Transparent — every invocation logs the exact argv to stderr

Read server.py before you install. That is the point.

Related MCP server: codex-cli-mcp

Prerequisites

  • The codex CLI installed and on $PATH (or pointed to via $CODEX_CMD). See the official Codex CLI repository. This server always passes --json and reads the prompt from stdin (codex exec -), both of which codex exec documents.

  • codex already authenticated — this wrapper does not manage login; it surfaces codex's own error output if the CLI is not ready.

Installation

# Run directly without installing
uvx codex-cli-mcp-slim

# Install from PyPI
pip install codex-cli-mcp-slim

# Run from GitHub HEAD
uvx --from git+https://github.com/tksfjt1024/codex-cli-mcp-slim codex-cli-mcp-slim

Usage as an MCP server

Claude Code

claude mcp add codex uvx codex-cli-mcp-slim

Or manually in ~/.claude.json:

{
  "mcpServers": {
    "codex": {
      "type": "stdio",
      "command": "uvx",
      "args": ["codex-cli-mcp-slim"]
    }
  }
}

If codex is not on the launching process's $PATH, point $CODEX_CMD at it:

{
  "mcpServers": {
    "codex": {
      "type": "stdio",
      "command": "uvx",
      "args": ["codex-cli-mcp-slim"],
      "env": { "CODEX_CMD": "/absolute/path/to/codex" }
    }
  }
}

Replacing codex mcp-server

An entry that used to launch codex mcp-server keeps its server name and its tool names; only command and args change. Before:

{
  "mcpServers": {
    "codex": {
      "type": "stdio",
      "command": "codex",
      "args": ["mcp-server"]
    }
  }
}

After:

{
  "mcpServers": {
    "codex": {
      "type": "stdio",
      "command": "uvx",
      "args": ["codex-cli-mcp-slim"]
    }
  }
}

Parameter names differ from the old server where codex exec names the flag differently: cwd is now cd (the -C/--cd flag), and codex-reply takes thread_id instead of threadId. The result's structuredContent field keeps the shape the old server returned, {"threadId": ..., "content": ...}.

Other MCP clients

Any MCP-compatible client can launch the server via stdio:

uvx codex-cli-mcp-slim

Server-level flags

Everything on the server's own command line is placed right after codex exec on every invocation. One MCP-client entry can therefore pin a reasoning effort, a model or a working directory for all of its calls. Two entries that differ only in reasoning effort look like this:

{
  "mcpServers": {
    "codex-medium": {
      "type": "stdio",
      "command": "uvx",
      "args": ["codex-cli-mcp-slim", "-c", "model_reasoning_effort=medium"]
    },
    "codex-high": {
      "type": "stdio",
      "command": "uvx",
      "args": ["codex-cli-mcp-slim", "-c", "model_reasoning_effort=high"]
    }
  }
}

A call to codex-high runs codex exec -c model_reasoning_effort=high [per-call flags] --json -. Per-call flags come after the server-level ones, and -c may repeat with the last one winning, so a per-call config entry overrides a server-level -c. Single-value flags such as -m and -C may not repeat: codex rejects the second one, and the tool result carries that error. Keep server-level flags and per-call parameters disjoint for those.

Tool: codex

Runs a single non-interactive Codex session (codex exec). codex is an agentic assistant: it reads and, depending on the sandbox, edits files in the working directory to fulfil the request, then prints its final message.

The tool returns that final message followed by one metadata line:

[codex] thread_id=019a2b3c-1d4e-7f60-8a9b-0c1d2e3f4a5b status=completed input_tokens=13894 cached_input_tokens=11904 output_tokens=612

thread_id and status are always present; the token fields appear when the run reported them. isError is the flag on an MCP tool result that tells the client a call failed. This server sets it when codex exited non-zero, when the subprocess timed out, and when the turn itself failed. The last case matters because codex exec exits 0 after a failure inside the model API; the tool result then carries the error text instead of coming back as a successful call:

[ERROR] codex failed

returncode=0

errors:
Unsupported value: 'none' is not supported with the ... model.

[codex] thread_id=019a2b3c-... status=failed

argv: ['codex', 'exec', '--json', '-']

Pass the thread_id to codex-reply to continue the same session.

Parameter

Type

Description

prompt (required)

string

Prompt sent verbatim to codex on stdin

cd

string

Pass -C <DIR>: the working directory; defaults to the server's own

model

string

Pass -m <MODEL>

config

string[]

key=value overrides; each maps to one -c (repeatable, last wins)

sandbox

string

Pass --sandbox: read-only, workspace-write or danger-full-access. See note below

add_dir

string[]

Extra writable directories; each maps to one --add-dir (repeatable, not comma-joined)

profile

string

Pass -p <PROFILE>

ephemeral

bool

Pass --ephemeral (do not write the session transcript codex keeps under $CODEX_HOME/sessions)

skip_git_repo_check

bool

Pass --skip-git-repo-check (allow a working directory outside a git repository)

extra_args

string[]

Raw CLI flags appended verbatim. Do not pass --json or a prompt; the server adds both

env

object

Extra environment variables for the codex subprocess

timeout_seconds

int

Hard wall-clock timeout for the subprocess, 30 to 3600 (default 1800)

Unknown parameters are refused rather than ignored, so a call that still uses the old server's cwd gets an error naming cd instead of running in the wrong directory.

Security note: sandbox

codex exec reads its sandbox mode from its own configuration file (~/.codex/config.toml by default) unless --sandbox is given. danger-full-access removes the filesystem and network sandbox entirely; workspace-write makes the working directory (and any add_dir) writable. --sandbox overrides only the mode; whether workspace-write gets network access still follows the [sandbox_workspace_write] section of config.toml. The parameter mirrors the flag so that whichever mode a call runs under is visible in the arguments and in the logged argv. This server does not pass --dangerously-bypass-approvals-and-sandbox; reach it via extra_args if you really mean it.

Tool: codex-reply

Continues a previous session (codex exec resume <THREAD_ID>) with a follow-up prompt and returns the new final message. Only the flags codex exec resume accepts are exposed, so cd, sandbox, add_dir and profile are refused here. The working directory and sandbox of a reply come from the current configuration, that is, the server-level flags and config.toml, not from the original session.

Parameter

Type

Description

thread_id (required)

string

The thread_id from a previous result's [codex] line

prompt (required)

string

Follow-up prompt, sent on stdin

model

string

Pass -m <MODEL>

config

string[]

key=value overrides; each maps to one -c

ephemeral

bool

Pass --ephemeral

skip_git_repo_check

bool

Pass --skip-git-repo-check

extra_args

string[]

Raw CLI flags appended verbatim

env

object

Extra environment variables for the codex subprocess

timeout_seconds

int

Hard wall-clock timeout for the subprocess, 30 to 3600 (default 1800)

Timeout configuration

timeout_seconds is this wrapper's hard wall-clock limit (default 1800, or $CODEX_CLI_MCP_SLIM_TIMEOUT). On timeout, the wrapper kills the subprocess's whole process group and then waits up to 20 additional seconds to collect any buffered output and reap the process, so the effective ceiling is timeout_seconds + 20. A timed-out call is flagged isError and carries whatever codex had printed so far.

Forward-compatibility example

If a future codex exec release adds a new flag (say --super-mode), use it immediately without updating this server:

{
  "name": "codex",
  "arguments": {
    "prompt": "...",
    "extra_args": ["--super-mode"]
  }
}

Configuration

Environment variable

Default

Purpose

CODEX_CMD

codex

Path to the codex CLI binary

CODEX_CLI_MCP_SLIM_TIMEOUT

1800

Default subprocess timeout in seconds

CODEX_CLI_MCP_SLIM_LOG_LEVEL

INFO

Logging level for stderr diagnostics

codex itself reads its configuration file and credentials from $CODEX_HOME (~/.codex by default), so an MCP-client entry can point a server at a dedicated configuration directory through its env block.

Development

# Install dev dependencies
pip install -e ".[test,dev]"

# Lint
ruff check .

# Test
pytest

License

MIT © tksfjt1024

Available Tools

2 tools
codexB

Run a single non-interactive Codex session (codex exec) with the given prompt and return its final message. codex is an agentic coding assistant that reads and, depending on the sandbox, edits files inside the working directory. Forward-compatible: unknown CLI flags can be passed via extra_args. The codex binary path is configurable via $CODEX_CMD.

ParametersJSON Schema
NameRequiredDescriptionDefault
cdNoPass -C <DIR>: the working directory codex runs in. Defaults to this server's own working directory.
envNoExtra environment variables for the codex subprocess.
modelNoPass -m <MODEL>: the model slug for this call, overriding config.toml.
configNoConfiguration overrides as key=value strings, one per element. Each entry maps to a separate codex -c flag (for example "model_reasoning_effort=high"). Values are parsed as TOML by codex, so quote strings that are not bare words.
promptYesPrompt sent verbatim to codex on stdin. codex runs its full agentic loop and this server returns the final agent message.
add_dirNoExtra writable directories. Each entry maps to a separate codex --add-dir flag (repeatable, not comma-joined).
profileNoPass -p <PROFILE>: the config.toml profile to load.
sandboxNoPass --sandbox <MODE>: read-only, workspace-write or danger-full-access. Overrides sandbox_mode from config.toml; network access still follows the [sandbox_workspace_write] section there.
ephemeralNoPass --ephemeral: do not persist the session's rollout file to disk.
extra_argsNoRaw CLI flags appended verbatim (one token per element). Use to reach new or uncommon codex exec flags without updating this server. Do not pass --json or a prompt: the server adds both.
timeout_secondsNoHard wall-clock timeout for the codex subprocess in seconds (default 1800).
skip_git_repo_checkNoPass --skip-git-repo-check: allow running in a directory that is not inside a git repository. Without it codex refuses such a working directory.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose meaningful behavior: non-interactive single session, agentic file reads/edits, sandbox-dependent side effects, and return of the final message. It omits other important traits such as authentication requirements, cost/latency expectations, and the default 1800s timeout (which is only in the schema).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, tightly written and front-loaded with the core action before the explanatory and extensibility details. Nothing is padded, though the codex-agent explanation sentence is arguably the weakest link.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter, no-annotation, no-output-schema tool, the description covers purpose and some behavior but leaves gaps: no differentiation from `codex-reply`, no auth/prerequisite note, and no sense of cost or duration. Adequate but incomplete for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents every parameter, making 3 the baseline. The description adds only marginal value beyond the schema (the $CODEX_CMD and extra_args notes), so there is no reason to score higher.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: running a single non-interactive `codex exec` session and returning its final message. It also defines what codex is (an agentic coding assistant that reads/edits files), which helps an agent understand the tool. However, it never contrasts itself with the sibling `codex-reply`, so an agent must guess which one to pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use or when-not-to-use guidance, and no mention of the `codex-reply` sibling that presumably continues a session. The closest thing to guidance is the `extra_args` forward-compatibility note, which is a usage hint for extensibility rather than routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

codex-replyA

Continue a previous Codex session (codex exec resume <THREAD_ID>) with a follow-up prompt and return the new final message. Only the flags codex exec resume accepts are exposed; the working directory and sandbox come from the current configuration (this server's own flags and config.toml), not from the original session.

ParametersJSON Schema
NameRequiredDescriptionDefault
envNoExtra environment variables for the codex subprocess.
modelNoPass -m <MODEL>: the model slug for this call, overriding config.toml.
configNoConfiguration overrides as key=value strings, one per element. Each entry maps to a separate codex -c flag (for example "model_reasoning_effort=high"). Values are parsed as TOML by codex, so quote strings that are not bare words.
promptYesPrompt sent verbatim to codex on stdin. codex runs its full agentic loop and this server returns the final agent message.
ephemeralNoPass --ephemeral: do not persist the session's rollout file to disk.
thread_idYesThe thread to continue: the thread_id from a previous result's [codex] line. Maps to codex exec resume <THREAD_ID>.
extra_argsNoRaw CLI flags appended verbatim (one token per element). Use to reach new or uncommon codex exec flags without updating this server. Do not pass --json or a prompt: the server adds both.
timeout_secondsNoHard wall-clock timeout for the codex subprocess in seconds (default 1800).
skip_git_repo_checkNoPass --skip-git-repo-check: allow running in a directory that is not inside a git repository. Without it codex refuses such a working directory.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does meaningful work: it discloses that working directory and sandbox come from the current server configuration rather than the original session, and that it returns the new final message. It omits auth requirements and other runtime caveats, but the config-inheritance note is exactly the kind of non-obvious behavior an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, behavior-first, with the CLI mapping inline and the configuration caveat front-loaded second. No redundant restatement of parameters or boilerplate.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 9-parameter subprocess-invoking tool with no annotations and no output schema, the description covers the key semantics (session continuation, config inheritance, return value). Remaining gaps around error/exit behavior are minor given how fully the schema describes each flag.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all nine parameters thoroughly. The description reiterates the thread_id mapping and prompt behavior but adds no syntax or format detail beyond the schema, which is the expected baseline when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (continue) and resource (a previous Codex session) and maps directly to the underlying `codex exec resume <THREAD_ID>` command. The scoping to continuation clearly separates it from the `codex` sibling that starts a fresh run.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes clear this resumes an existing session and requires a thread_id, implying the alternative (the `codex` sibling) is for new sessions. It stops short of explicitly naming the sibling or stating when not to use this tool, so it lands at a strong 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.1.0
    • First observedcodex
    • First observedcodex-reply

TDQS

A3.7/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct purposes: `codex` starts a non-interactive Codex session, while `codex-reply` resumes an existing session by THREAD_ID. Agents can easily choose between initial execution and continuation without overlap.

Naming Consistency4/5

Both names share the `codex` prefix and use kebab-case, making the relationship obvious. However, the first tool is a bare noun while the second appends an action-like suffix, so it is not a uniform verb_noun convention.

Tool Count4/5

Two tools is slightly under the typical 3-15 range, but for a deliberately slim CLI wrapper it is well-scoped. Each tool earns its place: one starts a session, one continues it.

Completeness4/5

The set covers the core Codex session lifecycle: start a session and continue it with a follow-up prompt. It lacks broader session management such as listing, cancelling, or checking status, but these are minor gaps given the slim wrapper scope.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    C
    quality
    D
    maintenance
    Bridges MCP clients with local Codex CLI to execute autonomous coding tasks, manage threads, and inspect history via SQLite state.
    13
    577 npm
    4
    Apache 2.0
  • A
    license
    A
    quality
    C
    maintenance
    Enables MCP-compatible coding agents to execute the local Codex CLI as a coding agent, including code reviews, session resume/fork, and CLI diagnostics.
    9
    94 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A local stdio MCP server that lets any MCP client start a Codex thread and continue it by opaque thread ID through the codex and codex-reply tools, with fail-closed sandboxing and approval policies. It restores the removed Codex CLI MCP integration by bridging clients like OpenCode to the official Codex SDK.
    MIT