@leo000001/codex-mcp 2.1.0 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![license](https://img.shields.io/npm/l/@leo000001/codex-mcp.svg)](https://github.com/xihuai18/codex-mcp/blob/master/LICENSE)
5
5
  [![node](https://img.shields.io/node/v/@leo000001/codex-mcp.svg)](https://nodejs.org)
6
6
 
7
- MCP server that wraps [OpenAI Codex](https://github.com/openai/codex) `app-server` — start coding agents, poll their progress, and manage permissions from any MCP client.
7
+ MCP server that wraps [OpenAI Codex](https://github.com/openai/codex) — start coding agents, poll their progress, and manage permissions from any MCP client. Supports both `app-server` (full capability) and `exec` (fallback for codex variants without app-server) modes.
8
8
 
9
9
  ## Features
10
10
 
@@ -19,7 +19,7 @@ MCP server that wraps [OpenAI Codex](https://github.com/openai/codex) `app-serve
19
19
  ## Prerequisites
20
20
 
21
21
  - [Node.js](https://nodejs.org) >= 18
22
- - [OpenAI Codex CLI](https://github.com/openai/codex) installed and configured (`codex` in PATH)
22
+ - [OpenAI Codex CLI](https://github.com/openai/codex) installed and configured (`codex` or `codex-internal` in PATH)
23
23
 
24
24
  ## Quick Start
25
25
 
@@ -76,6 +76,52 @@ Or add to `~/.claude/settings.json`:
76
76
  }
77
77
  ```
78
78
 
79
+ ## Codex Executable Configuration
80
+
81
+ By default, codex-mcp auto-detects the Codex CLI by searching PATH for `codex`, then `codex-internal`. You can override this with environment variables.
82
+
83
+ Resolution priority:
84
+
85
+ - `CODEX_MCP_PATH`
86
+ - `CODEX_MCP_COMMAND`
87
+ - auto-detect from PATH: `codex`, then `codex-internal`
88
+
89
+ | Variable | Description | Example |
90
+ | ------------------- | ------------------------------------------------------ | ------------------------------- |
91
+ | `CODEX_MCP_COMMAND` | Bare command name (resolved from PATH) | `codex-internal` |
92
+ | `CODEX_MCP_PATH` | Absolute or relative filesystem path to the executable | `/usr/local/bin/codex-internal` |
93
+
94
+ - `CODEX_MCP_PATH` and `CODEX_MCP_COMMAND` are mutually exclusive.
95
+ - When none are set, codex-mcp tries `codex` then `codex-internal` on PATH automatically.
96
+
97
+ Examples:
98
+
99
+ ```bash
100
+ # Use codex-internal instead of codex
101
+ CODEX_MCP_COMMAND=codex-internal npx -y @leo000001/codex-mcp
102
+ ```
103
+
104
+ ```bash
105
+ # Use an explicit path
106
+ CODEX_MCP_PATH=/opt/codex/bin/codex npx -y @leo000001/codex-mcp
107
+ ```
108
+
109
+ MCP client config with env override:
110
+
111
+ ```json
112
+ {
113
+ "mcpServers": {
114
+ "codex": {
115
+ "command": "npx",
116
+ "args": ["-y", "@leo000001/codex-mcp"],
117
+ "env": {
118
+ "CODEX_MCP_COMMAND": "codex-internal"
119
+ }
120
+ }
121
+ }
122
+ }
123
+ ```
124
+
79
125
  ## STDIO Guard Modes
80
126
 
81
127
  `codex-mcp` includes a startup preflight guard for stdout contamination risk.
@@ -84,6 +130,27 @@ Or add to `~/.claude/settings.json`:
84
130
  - `CODEX_MCP_STDIO_MODE=strict`: fail fast on blocking risks (e.g. TTY stdio), keep heuristic risks as warnings
85
131
  - `CODEX_MCP_STDIO_MODE=off`: disable the preflight guard
86
132
 
133
+ ## Exec Fallback Mode
134
+
135
+ When the codex binary does not support `app-server` (e.g. internal variants like `codex-internal`), codex-mcp automatically falls back to `codex exec --json` mode.
136
+
137
+ | Env Var | Default | Description |
138
+ | ------------------- | ----------- | -------------------------------------------------------------------------------------- |
139
+ | `CODEX_MCP_COMMAND` | `codex` | Command name used to select the Codex executable; lower priority than `CODEX_MCP_PATH` |
140
+ | `CODEX_MCP_MODE` | auto-detect | Force `app-server` or `exec` mode (skip detection) |
141
+
142
+ If you need an explicit path-based override, use `CODEX_MCP_PATH` from the executable configuration section above.
143
+
144
+ **Exec mode supports multi-turn context** via `codex exec resume`. First turn uses `codex exec`, subsequent turns use `codex exec resume <threadId>`.
145
+
146
+ **Exec mode limitations:**
147
+
148
+ - No approval/user-input interactions
149
+ - `threadFork`/`threadResume` throw `EXEC_NOT_SUPPORTED`
150
+ - `sandbox`/`profile`/`cwd`/`outputSchema` overrides only apply on the first turn (exec resume does not support these flags)
151
+
152
+ Check `codex-mcp:///server-info` `clientMode` field to detect which mode is active.
153
+
87
154
  Examples:
88
155
 
89
156
  ```bash
@@ -182,13 +249,14 @@ Send a follow-up message to an existing session.
182
249
 
183
250
  List, inspect, cancel, interrupt, fork sessions, or clean background terminals.
184
251
 
185
- | Parameter | Type | Required | Description |
186
- | ------------------ | ------- | ----------------------------- | ---------------------------------------------------------------------- |
187
- | `action` | string | Yes | `"list"`, `"get"`, `"cancel"`, `"interrupt"`, `"fork"`, or `"clean_background_terminals"` |
188
- | `sessionId` | string | For get/cancel/interrupt/fork/clean_background_terminals | Target session ID |
189
- | `includeSensitive` | boolean | No | Include `cwd`/`profile`/`config`/`threadId` in `get`. Default: `false` |
252
+ | Parameter | Type | Required | Description |
253
+ | ------------------ | ------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
254
+ | `action` | string | Yes | `"list"`, `"get"`, `"cancel"`, `"interrupt"`, `"fork"`, or `"clean_background_terminals"` |
255
+ | `sessionId` | string | For get/cancel/interrupt/fork/clean_background_terminals | Target session ID |
256
+ | `includeSensitive` | boolean | No | Include `cwd`/`profile`/`config`/`threadId` in `get`. Default: `false` |
190
257
 
191
258
  **Returns:**
259
+
192
260
  - `action="list"` → `{ sessions: PublicSessionInfo[] }`
193
261
  - `action="get"` → `PublicSessionInfo` (or `SensitiveSessionInfo` when `includeSensitive=true`)
194
262
  - `action="cancel"|"interrupt"` → `{ success: true, message }`
@@ -208,21 +276,21 @@ List, inspect, cancel, interrupt, fork sessions, or clean background terminals.
208
276
 
209
277
  Query a running session for events, respond to approval requests, or answer user input.
210
278
 
211
- | Parameter | Type | Required | Description |
212
- | --------------------- | -------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
213
- | `action` | string | Yes | `"poll"`, `"respond_permission"`, or `"respond_user_input"` |
214
- | `sessionId` | string | Yes | Target session ID |
215
- | `cursor` | number | No | Event cursor for incremental polling (`action="poll"`). For `respond_*`, codex-mcp applies monotonic cursor progression: `max(cursor, sessionLastCursor)`. |
216
- | `maxEvents` | number | No | Keep this small. `poll` default: `1` (minimum `1`; increase only for catch-up). `respond_*` default: `0` (recommended; compact ACK, no event replay). |
217
- | `responseMode` | string | No | Response shaping mode: `minimal` (default), `delta_compact`, `full` |
218
- | `pollOptions` | object | No | Optional controls: `includeEvents` (default `true`), `includeActions` (default `true`), `includeResult` (default `true`), `maxBytes` (default unlimited) |
219
- | `requestId` | string | For respond_permission/user_input | Request ID from `actions[]` |
220
- | `decision` | string | For respond_permission | For command approvals: `"accept"`, `"acceptForSession"`, `"acceptWithExecpolicyAmendment"`, `"decline"`, `"cancel"`; for file changes: `"accept"`, `"acceptForSession"`, `"decline"`, `"cancel"` |
279
+ | Parameter | Type | Required | Description |
280
+ | ---------------------- | -------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
281
+ | `action` | string | Yes | `"poll"`, `"respond_permission"`, or `"respond_user_input"` |
282
+ | `sessionId` | string | Yes | Target session ID |
283
+ | `cursor` | number | No | Event cursor for incremental polling (`action="poll"`). For `respond_*`, codex-mcp applies monotonic cursor progression: `max(cursor, sessionLastCursor)`. |
284
+ | `maxEvents` | number | No | Keep this small. `poll` default: `1` (minimum `1`; increase only for catch-up). `respond_*` default: `0` (recommended; compact ACK, no event replay). |
285
+ | `responseMode` | string | No | Response shaping mode: `minimal` (default), `delta_compact`, `full` |
286
+ | `pollOptions` | object | No | Optional controls: `includeEvents` (default `true`), `includeActions` (default `true`), `includeResult` (default `true`), `maxBytes` (default unlimited) |
287
+ | `requestId` | string | For respond_permission/user_input | Request ID from `actions[]` |
288
+ | `decision` | string | For respond_permission | For command approvals: `"accept"`, `"acceptForSession"`, `"acceptWithExecpolicyAmendment"`, `"decline"`, `"cancel"`; for file changes: `"accept"`, `"acceptForSession"`, `"decline"`, `"cancel"` |
221
289
  | `execpolicy_amendment` | string[] | For acceptWithExecpolicyAmendment | Exec policy amendment list (required when `decision="acceptWithExecpolicyAmendment"`) |
222
- | `denyMessage` | string | No | Internal note on deny (not sent to app-server) |
223
- | `answers` | object | For respond_user_input | For `respond_user_input`: `question-id -> { answers: string[] }` |
290
+ | `denyMessage` | string | No | Internal note on deny (not sent to app-server) |
291
+ | `answers` | object | For respond_user_input | For `respond_user_input`: `question-id -> { answers: string[] }` |
224
292
 
225
- **Returns (poll and respond_*):** `{ sessionId, status, pollInterval?, cursorResetTo?, events, nextCursor, actions?, result? }`
293
+ **Returns (poll and respond\_\*):** `{ sessionId, status, pollInterval?, cursorResetTo?, events, nextCursor, actions?, result? }`
226
294
 
227
295
  ```json
228
296
  { "action": "poll", "sessionId": "sess_abc123", "cursor": 0 }
@@ -329,11 +397,12 @@ Three layers of protection:
329
397
  > **Same-platform assumption**: codex-mcp assumes the MCP client and server run on the same machine. All communication uses stdio (local IPC), child processes share the local filesystem and `~/.codex/config.toml`, and `cwd` paths refer to the local filesystem.
330
398
 
331
399
  ```
332
- MCP Client ←stdio→ codex-mcp server ←stdio→ codex app-server ←→ Codex Agent
400
+ MCP Client ←stdio→ codex-mcp server ←stdio→ codex app-server ←→ Codex Agent (app-server mode)
401
+ MCP Client ←stdio→ codex-mcp server ←stdio→ codex exec --json ←→ Codex Agent (exec fallback)
333
402
  (same machine, stdio transport)
334
403
  ```
335
404
 
336
- Each session spawns an independent `codex app-server` child process. The MCP server translates between MCP tool calls and the app-server's JSON-RPC protocol.
405
+ Each session spawns an independent child process. In app-server mode, it uses the JSON-RPC protocol over stdio. In exec fallback mode, it uses `codex exec --json` JSONL output with `codex exec resume` for multi-turn context.
337
406
 
338
407
  ## Development
339
408
 
@@ -349,6 +418,7 @@ npm run check:stdio:strict
349
418
  ```
350
419
 
351
420
  End-to-end local test plan (after installing/configuring in an MCP client):
421
+
352
422
  - Full guide (LLM operator handbook): `docs/E2E_LOCAL_TEST_PLAN.md`
353
423
  - Quick English checklist: run `codex` → poll with `codex_check(action="poll")` → respond via `respond_permission`/`respond_user_input` if `actions[]` appears → continue polling until `status` is `idle`/`error`/`cancelled`.
354
424