@leo000001/codex-mcp 0.2.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,40 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Breaking Changes
11
+
12
+ - `approvalPolicy`, `sandbox`, and `effort` are now **required** parameters in the `codex` tool — callers must explicitly set based on their own permission level and task complexity
13
+ - `effort` parameter promoted from `advanced.effort` to top-level parameter in the `codex` tool
14
+ - `codex_reply` parameter `sandboxPolicy` renamed to `sandbox`
15
+
16
+ ### Changed
17
+
18
+ - All MCP-visible text (tool descriptions, parameter descriptions, resource descriptions) streamlined for conciseness
19
+ - `effort` description now suggests adjusting based on task complexity
20
+ - `replyToSession` now persists successful `model` / `approvalPolicy` / `sandbox` / `cwd` overrides to session metadata
21
+ - Process `exit` / `error` paths now emit terminal `result` payloads so `codex_check(action=\"poll\")` always includes a terminal `result` in error states
22
+ - `SessionManager` now deduplicates concurrent `cancelSession` calls and prevents terminal sessions from re-entering `waiting_approval` on late server requests
23
+ - Approval and user-input timeout timers now call `.unref()` to avoid blocking process exit
24
+ - Documentation aligned with implementation details for event eviction and e2e guidance
25
+ - Tool input defaults are now defined in schema (`cursor`, `maxEvents`, `includeSensitive`, `advanced.approvalTimeoutMs`) and client-facing text avoids duplicated default descriptions
26
+
27
+ ## [0.1.0] - 2026-02-15
28
+
29
+ ### Added
30
+
31
+ - Initial release
32
+ - 4 MCP tools: `codex`, `codex_reply`, `codex_session`, `codex_check`
33
+ - Async non-blocking session management
34
+ - Three-layer permission model (approval policy, sandbox, async approval)
35
+ - Cursor-based event polling with pin-protected buffer
36
+ - Session lifecycle: create, reply, cancel, interrupt, fork
37
+ - Command execution and file change approval flow
38
+ - User input request handling
39
+ - Automatic session cleanup (idle/running/terminal timeouts)
40
+ - Zero-config startup via `~/.codex/config.toml` inheritance
@@ -0,0 +1,26 @@
1
+ # Code of Conduct
2
+
3
+ This project is committed to providing a welcoming and harassment-free experience for everyone.
4
+
5
+ ## Our Standards
6
+
7
+ Examples of behavior that contributes to a positive environment include:
8
+ - Being respectful and considerate in language and actions
9
+ - Giving and accepting constructive feedback
10
+ - Focusing on what is best for the community and project
11
+
12
+ Examples of unacceptable behavior include:
13
+ - Harassment, insults, or personal attacks
14
+ - Trolling, deliberate intimidation, or sustained disruption
15
+ - Publishing others' private information without explicit permission
16
+
17
+ ## Scope
18
+
19
+ This Code of Conduct applies within all project spaces, including issues, pull requests, and discussions.
20
+
21
+ ## Enforcement
22
+
23
+ If you experience or witness unacceptable behavior, please report it via the contact in `SECURITY.md`.
24
+
25
+ Project maintainers may remove, edit, or reject contributions that are not aligned with this Code of Conduct.
26
+
@@ -0,0 +1,43 @@
1
+ # Contributing to codex-mcp
2
+
3
+ Thanks for your interest in contributing!
4
+
5
+ ## Getting Started
6
+
7
+ ```bash
8
+ git clone https://github.com/xihuai18/codex-mcp.git
9
+ cd codex-mcp
10
+ npm install
11
+ npm run build
12
+ ```
13
+
14
+ ## Development Workflow
15
+
16
+ ```bash
17
+ npm run typecheck # Type check
18
+ npm run build # Build
19
+ npm test # Run tests
20
+ npm run lint # Lint (ESLint)
21
+ npm run format:check # Check formatting (Prettier)
22
+ ```
23
+
24
+ ## Pull Requests
25
+
26
+ 1. Fork the repo and create a branch from `master` (or the repository default branch)
27
+ 2. Make your changes
28
+ 3. Ensure `npm run typecheck` and `npm run build` pass
29
+ 4. Submit a PR with a clear description
30
+
31
+ ## Reporting Issues
32
+
33
+ Use [GitHub Issues](https://github.com/xihuai18/codex-mcp/issues). Include:
34
+ - Steps to reproduce
35
+ - Expected vs actual behavior
36
+ - Node.js and Codex CLI versions
37
+
38
+ ## Code Style
39
+
40
+ - TypeScript strict mode
41
+ - ESM modules
42
+ - Prefer `as const` tuples for shared constants
43
+ - Keep tool handlers thin — delegate to SessionManager
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 xihuai18
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,354 @@
1
+ # codex-mcp
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@leo000001/codex-mcp.svg)](https://www.npmjs.com/package/@leo000001/codex-mcp)
4
+ [![license](https://img.shields.io/npm/l/@leo000001/codex-mcp.svg)](https://github.com/xihuai18/codex-mcp/blob/master/LICENSE)
5
+ [![node](https://img.shields.io/node/v/@leo000001/codex-mcp.svg)](https://nodejs.org)
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.
8
+
9
+ ## Features
10
+
11
+ - **4 tools, full capability** — `codex`, `codex_reply`, `codex_session`, `codex_check`
12
+ - **Async non-blocking** — sessions run in background, poll for results
13
+ - **Complete permission management** — three-layer model: approval policy, sandbox isolation, async approval arbitration
14
+ - **Zero config** — inherits your local `~/.codex/config.toml` automatically
15
+ - **Session management** — list, inspect, cancel, interrupt, fork sessions
16
+ - **Event streaming** — cursor-based pagination with pin-protected event buffer
17
+ - **Static read-only resources** — `codex-mcp:///server-info`, `codex-mcp:///compat-report`, `codex-mcp:///config`, `codex-mcp:///gotchas`, `codex-mcp:///quickstart`, `codex-mcp:///errors`
18
+
19
+ ## Prerequisites
20
+
21
+ - [Node.js](https://nodejs.org) >= 18
22
+ - [OpenAI Codex CLI](https://github.com/openai/codex) installed and configured (`codex` in PATH)
23
+
24
+ ## Quick Start
25
+
26
+ ### npx (no install)
27
+
28
+ ```bash
29
+ npx @leo000001/codex-mcp
30
+ ```
31
+
32
+ ### Global install
33
+
34
+ ```bash
35
+ npm install -g @leo000001/codex-mcp
36
+ codex-mcp
37
+ ```
38
+
39
+ ### Windows shell wrapper (if needed)
40
+
41
+ ```powershell
42
+ pwsh -NoProfile -Command "npx -y @leo000001/codex-mcp"
43
+ ```
44
+
45
+ ### MCP Client Configuration
46
+
47
+ Add to your MCP client config (e.g. Claude Desktop, Cursor, etc.):
48
+
49
+ ```json
50
+ {
51
+ "mcpServers": {
52
+ "codex": {
53
+ "command": "npx",
54
+ "args": ["-y", "@leo000001/codex-mcp"]
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ ### OpenAI Codex CLI
61
+
62
+ ```bash
63
+ codex mcp add codex-mcp -- npx -y @leo000001/codex-mcp
64
+ ```
65
+
66
+ Or add to `~/.codex/config.toml`:
67
+
68
+ ```toml
69
+ [mcp_servers.codex-mcp]
70
+ command = "npx"
71
+ args = ["-y", "@leo000001/codex-mcp"]
72
+ ```
73
+
74
+ ## STDIO Guard Modes
75
+
76
+ `codex-mcp` includes a startup preflight guard for stdout contamination risk.
77
+
78
+ - `CODEX_MCP_STDIO_MODE=auto` (default): run with warnings when risk is elevated
79
+ - `CODEX_MCP_STDIO_MODE=strict`: fail fast on blocking risks (e.g. TTY stdio), keep heuristic risks as warnings
80
+ - `CODEX_MCP_STDIO_MODE=off`: disable the preflight guard
81
+
82
+ Examples:
83
+
84
+ ```bash
85
+ CODEX_MCP_STDIO_MODE=strict npx -y @leo000001/codex-mcp
86
+ ```
87
+
88
+ ```powershell
89
+ $env:CODEX_MCP_STDIO_MODE = "strict"; npx -y @leo000001/codex-mcp
90
+ ```
91
+
92
+ ## Tools
93
+
94
+ ### `codex` — Start a new session
95
+
96
+ Start a Codex agent session asynchronously. Returns immediately with `sessionId`.
97
+
98
+ | Parameter | Type | Required | Description |
99
+ | ---------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------- |
100
+ | `prompt` | string | Yes | Task or question for the Codex agent |
101
+ | `approvalPolicy` | string | Yes | Approval policy: `untrusted`, `on-failure`, `on-request`, `never` — caller must set based on its own permission level |
102
+ | `sandbox` | string | Yes | Sandbox mode: `read-only`, `workspace-write`, `danger-full-access` — caller must set based on its own permission level |
103
+ | `effort` | string | No | Reasoning effort: `none`, `minimal`, `low`, `medium`, `high`, `xhigh`. Default: `low`; increase/decrease based on task complexity |
104
+ | `cwd` | string | No | Working directory. Default: server cwd |
105
+ | `model` | string | No | Model override. Default: from `~/.codex/config.toml` |
106
+ | `profile` | string | No | `config.toml` profile name (passed as `codex app-server -p`) |
107
+ | `advanced` | object | No | Low-frequency options (see below) |
108
+
109
+ <details>
110
+ <summary><code>advanced</code> object parameters (9 low-frequency parameters)</summary>
111
+
112
+ | Parameter | Type | Description |
113
+ | -------------------------------- | -------- | ----------------------------------------------------------------------------------------------- |
114
+ | `advanced.baseInstructions` | string | Replace default instructions (thread-level) |
115
+ | `advanced.developerInstructions` | string | Developer instructions (thread-level) |
116
+ | `advanced.personality` | string | Personality: `none`, `friendly`, `pragmatic` (default: from `~/.codex/config.toml`) |
117
+ | `advanced.summary` | string | Reasoning summary: `auto`, `concise`, `detailed`, `none` (default: from `~/.codex/config.toml`) |
118
+ | `advanced.config` | object | Override `config.toml` values (passed as `codex app-server -c key=value`) |
119
+ | `advanced.ephemeral` | boolean | Don't persist thread. Default: `false` |
120
+ | `advanced.outputSchema` | object | JSON Schema for structured output |
121
+ | `advanced.images` | string[] | Local image paths (adds `localImage` inputs) |
122
+ | `advanced.approvalTimeoutMs` | number | Auto-decline timeout (ms) for pending approvals. Default: `60000` |
123
+
124
+ </details>
125
+
126
+ **Returns:** `{ sessionId, threadId, status: "running" | "idle", pollInterval }`
127
+
128
+ ```json
129
+ {
130
+ "prompt": "Fix the failing tests in src/",
131
+ "approvalPolicy": "on-request",
132
+ "sandbox": "workspace-write",
133
+ "effort": "high",
134
+ "cwd": "/path/to/project",
135
+ "model": "o4-mini"
136
+ }
137
+ ```
138
+
139
+ ### Resources
140
+
141
+ If your MCP client supports resources, this server exposes a few **read-only** resources:
142
+
143
+ - `codex-mcp:///server-info` (JSON): static server metadata (version/platform/runtime)
144
+ - `codex-mcp:///compat-report` (JSON): capability summary for cross-backend adapter compatibility
145
+ - `codex-mcp:///config` (Markdown): config mapping guide, including how to use `codex.advanced.config`
146
+ - `codex-mcp:///gotchas` (Markdown): practical limits/gotchas
147
+ - `codex-mcp:///quickstart` (Markdown): minimal workflow examples
148
+ - `codex-mcp:///errors` (Markdown): error code catalog + recovery hints
149
+
150
+ ### `codex_reply` — Continue a session
151
+
152
+ Send a follow-up message to an existing session.
153
+
154
+ | Parameter | Type | Required | Description |
155
+ | ---------------- | ------ | -------- | ------------------------------------------------------------------------------- |
156
+ | `sessionId` | string | Yes | Session ID from `codex` |
157
+ | `prompt` | string | Yes | Follow-up message |
158
+ | `model` | string | No | Override model for this turn |
159
+ | `approvalPolicy` | string | No | Override approval policy |
160
+ | `effort` | string | No | Override reasoning effort (`none`, `minimal`, `low`, `medium`, `high`, `xhigh`) |
161
+ | `summary` | string | No | Override reasoning summary (`auto`, `concise`, `detailed`, `none`) |
162
+ | `personality` | string | No | Override personality (`none`, `friendly`, `pragmatic`) |
163
+ | `sandbox` | string | No | Override sandbox (`read-only`, `workspace-write`, `danger-full-access`) |
164
+ | `cwd` | string | No | Override working directory |
165
+ | `outputSchema` | object | No | JSON Schema for structured output |
166
+
167
+ **Returns:** `{ sessionId, threadId, status: "running" | "idle", pollInterval }`
168
+
169
+ ```json
170
+ {
171
+ "sessionId": "sess_abc123",
172
+ "prompt": "Now add error handling for the edge cases"
173
+ }
174
+ ```
175
+
176
+ ### `codex_session` — Manage sessions
177
+
178
+ List, inspect, cancel, interrupt, or fork sessions.
179
+
180
+ | Parameter | Type | Required | Description |
181
+ | ------------------ | ------- | ----------------------------- | ---------------------------------------------------------------------- |
182
+ | `action` | string | Yes | `"list"`, `"get"`, `"cancel"`, `"interrupt"`, or `"fork"` |
183
+ | `sessionId` | string | For get/cancel/interrupt/fork | Target session ID |
184
+ | `includeSensitive` | boolean | No | Include `cwd`/`profile`/`config`/`threadId` in `get`. Default: `false` |
185
+
186
+ **Returns:**
187
+ - `action="list"` → `{ sessions: PublicSessionInfo[] }`
188
+ - `action="get"` → `PublicSessionInfo` (or `SensitiveSessionInfo` when `includeSensitive=true`)
189
+ - `action="cancel"|"interrupt"` → `{ success: true, message }`
190
+ - `action="fork"` → `{ sessionId, threadId, status: "idle", pollInterval }`
191
+
192
+ ```json
193
+ { "action": "list" }
194
+ { "action": "get", "sessionId": "sess_abc123", "includeSensitive": true }
195
+ { "action": "cancel", "sessionId": "sess_abc123" }
196
+ { "action": "interrupt", "sessionId": "sess_abc123" }
197
+ { "action": "fork", "sessionId": "sess_abc123" }
198
+ ```
199
+
200
+ ### `codex_check` — Poll events & respond
201
+
202
+ Query a running session for events, respond to approval requests, or answer user input.
203
+
204
+ | Parameter | Type | Required | Description |
205
+ | --------------------- | -------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
206
+ | `action` | string | Yes | `"poll"`, `"respond_permission"`, `"respond_approval"` (deprecated alias), or `"respond_user_input"` |
207
+ | `sessionId` | string | Yes | Target session ID |
208
+ | `cursor` | number | No | Event cursor for incremental polling (`action="poll"`). For `respond_*`, codex-mcp applies monotonic cursor progression: `max(cursor, sessionLastCursor)`. |
209
+ | `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). |
210
+ | `responseMode` | string | No | Response shaping mode: `minimal` (default), `delta_compact`, `full` |
211
+ | `pollOptions` | object | No | Optional controls: `includeEvents` (default `true`), `includeActions` (default `true`), `includeResult` (default `true`), `maxBytes` (default unlimited) |
212
+ | `requestId` | string | For respond_permission/user_input | Request ID from `actions[]` |
213
+ | `decision` | string | For respond_permission | For command approvals: `"accept"`, `"acceptForSession"`, `"acceptWithExecpolicyAmendment"`, `"decline"`, `"cancel"`; for file changes: `"accept"`, `"acceptForSession"`, `"decline"`, `"cancel"` |
214
+ | `execpolicyAmendment` | string[] | For acceptWithExecpolicyAmendment | Exec policy amendment list (required when `decision="acceptWithExecpolicyAmendment"`) |
215
+ | `denyMessage` | string | No | Internal note on deny (not sent to app-server) |
216
+ | `answers` | object | For respond_user_input | For `respond_user_input`: `questionId -> { answers: string[] }` |
217
+
218
+ **Returns (poll and respond_*):** `{ sessionId, status, pollInterval?, cursorResetTo?, events, nextCursor, actions?, result? }`
219
+
220
+ ```json
221
+ { "action": "poll", "sessionId": "sess_abc123", "cursor": 0 }
222
+ {
223
+ "action": "respond_permission",
224
+ "sessionId": "sess_abc123",
225
+ "requestId": "req_xyz",
226
+ "decision": "accept"
227
+ }
228
+ {
229
+ "action": "respond_user_input",
230
+ "sessionId": "sess_abc123",
231
+ "requestId": "req_abc",
232
+ "answers": { "question_id": { "answers": ["choice_1"] } }
233
+ }
234
+ ```
235
+
236
+ ## Event Polling Semantics
237
+
238
+ `codex_check(action="poll")` returns an append-only event stream with cursor pagination:
239
+
240
+ - `cursor`: the first event id you want (use the previous `nextCursor`)
241
+ - `nextCursor`: pass this back on the next poll
242
+ - `cursorResetTo`: when present, older events were evicted; restart from this cursor to avoid gaps
243
+ - `maxEvents`: max events returned per call
244
+ - If `cursor` is omitted, codex-mcp continues from that session's last consumed cursor.
245
+ - If `responseMode` is omitted, codex-mcp uses `minimal`.
246
+ - `pollOptions.includeEvents/includeActions/includeResult` default to `true`.
247
+ - `pollOptions.maxBytes` is optional and enforces best-effort payload truncation (`truncated`, `truncatedFields`).
248
+ - `respond_*` defaults to compact ACK (`events: []`, no cursor advance) unless you explicitly pass `maxEvents`.
249
+ - `poll` defaults to `maxEvents=1` to keep payloads small; increase temporarily (for example `10-20`) when you need to catch up faster.
250
+ - If `poll` is called with `maxEvents=0`, codex-mcp treats it as `1` to avoid no-op polling loops.
251
+ - For `respond_*`, prefer `maxEvents=0` instead of `1`: `0` keeps approval ACK minimal and avoids consuming/replaying stream events in the same call. Use `1-5` only when you explicitly need immediate events.
252
+ - For `poll`, keep windows small to reduce payload spikes and context pressure.
253
+
254
+ Event types include `output`, `progress`, `approval_request`, `approval_result`, `result`, `error`.
255
+ Approvals/results/errors are pinned to reduce eviction risk.
256
+
257
+ ## Approvals & User Input
258
+
259
+ When the agent requests approval or user input, `poll` includes an `actions[]` list. Respond with:
260
+
261
+ - `respond_permission`: `decision` is one of `accept`, `acceptForSession`, `decline`, `cancel`.
262
+ - For command approvals, `acceptWithExecpolicyAmendment` is supported and requires `execpolicyAmendment`.
263
+ - `respond_approval` is still accepted as a deprecated alias for `respond_permission`.
264
+ - `respond_user_input`: send `answers` keyed by `questionId`.
265
+
266
+ Pending approvals auto-decline after `advanced.approvalTimeoutMs`.
267
+
268
+ ## Session Lifecycle & Cleanup
269
+
270
+ Sessions auto-clean up in the background:
271
+
272
+ - `idle` > 30 minutes → cancelled
273
+ - `running`/`waiting_approval` > 4 hours → cancelled
274
+ - `cancelled`/`error` > 5 minutes → removed from memory
275
+
276
+ ## Error Model
277
+
278
+ Tools return errors as:
279
+
280
+ ```json
281
+ { "content": [{ "type": "text", "text": "Error [CODE]: message" }], "isError": true }
282
+ ```
283
+
284
+ Common codes include `INVALID_ARGUMENT`, `SESSION_NOT_FOUND`, `SESSION_BUSY`, `SESSION_NOT_RUNNING`, `REQUEST_NOT_FOUND`, `CANCELLED`, `INTERNAL`.
285
+
286
+ ## Client compatibility notes
287
+
288
+ - Tool responses follow `@modelcontextprotocol/sdk`'s `CallToolResult` contract: `content` (JSON text for wide compatibility), optional `structuredContent` (the canonical object), and `isError`. `structuredContent` is always object-shaped; when a tool returns a scalar/array, codex-mcp wraps it as `{ "value": ... }`. Claude Desktop and other clients tend to surface the `content` text directly, which shows the raw JSON blob, so they should fall back to `structuredContent` when they want typed data (Cursor already does this automatically whenever structured output is available).
289
+ - When an operation fails we set `isError: true` and return `Error [CODE]: message` in the `content` array instead of raising an MCP transport error. This keeps the STDIO channel healthy so Claude, Cursor, and other MCP clients stay connected even when a tool reports a problem.
290
+ - `codex-mcp` uses the MCP stdio transport (`src/index.ts`), so stdout is reserved for newline-delimited JSON and all diagnostics go to stderr. Anything else on stdout—including shell/profile banners (e.g., PowerShell's oh-my-posh warning) or CLI wrappers that print prompts—will break the MCP handshake for Claude/Cursor. Run `pwsh -NoProfile`, disable profile banners, or wrap the command so stdout stays quiet before piping it into the client.
291
+ - Windows command execution inside `codex app-server` may still inherit PowerShell profile side effects in some environments. This cannot be filtered by codex-mcp once emitted on stdout; if command turns are noisy or fail with profile errors, clean your PowerShell profile and prefer `approvalPolicy="on-failure"` / `"never"` to reduce approval churn.
292
+ - If Windows command output shows mojibake, enforce UTF-8 in the shell (`chcp 65001` and `$OutputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()`).
293
+ - Startup guard behavior is controlled by `CODEX_MCP_STDIO_MODE` (`auto`/`strict`/`off`). Use `strict` in CI or hardened environments to fail fast on blocking contamination risks (while still surfacing heuristic risk warnings).
294
+ - Retryable transport/API interruptions are emitted as `progress` events with `data.method="codex-mcp/reconnect"` and `willRetry=true`, so clients can surface reconnect state without treating it as terminal failure.
295
+ - Approval/user-input flows rely on the `actions[]` array returned by `codex_check(action="poll")`. Claude and Cursor render approval buttons from this payload, so they need to poll at `pollInterval`, honour `cursorResetTo`, and reply within `approvalTimeoutMs` to avoid automatic declines.
296
+
297
+ ## Typical Workflow
298
+
299
+ ```
300
+ 1. codex(prompt="Fix bug X") → { sessionId, threadId, status: "running" }
301
+ 2. codex_check(action="poll", ...) → events[], status, actions[]
302
+ 3. codex_check(action="respond_permission", decision="accept") (if needed)
303
+ 4. codex_check(action="poll", ...) → result when status="idle"
304
+ 5. codex_reply(prompt="Also add tests") → new turn starts
305
+ 6. codex_check(action="poll", ...) → poll until done
306
+ ```
307
+
308
+ ## Permission Model
309
+
310
+ Three layers of protection:
311
+
312
+ | Layer | Mechanism | Options |
313
+ | ----- | --------------- | ---------------------------------------------------------- |
314
+ | 0 | Approval Policy | `never`, `on-failure`, `on-request`, `untrusted` |
315
+ | 1 | Sandbox | `read-only`, `workspace-write`, `danger-full-access` |
316
+ | 2 | Async Approval | Command execution + file change approval via `codex_check` |
317
+
318
+ ## Architecture
319
+
320
+ > **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.
321
+
322
+ ```
323
+ MCP Client ←stdio→ codex-mcp server ←stdio→ codex app-server ←→ Codex Agent
324
+ (same machine, stdio transport)
325
+ ```
326
+
327
+ 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.
328
+
329
+ ## Development
330
+
331
+ ```bash
332
+ git clone https://github.com/xihuai18/codex-mcp.git
333
+ cd codex-mcp
334
+ npm install
335
+ npm run build
336
+ npm run typecheck
337
+ npm test
338
+ npm run check:stdio
339
+ npm run check:stdio:strict
340
+ ```
341
+
342
+ End-to-end local test plan (after installing/configuring in an MCP client):
343
+ - Full guide (LLM operator handbook): `docs/E2E_LOCAL_TEST_PLAN.md`
344
+ - 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`.
345
+
346
+ ## Project Policies
347
+
348
+ - [Contributing](CONTRIBUTING.md)
349
+ - [Security](SECURITY.md)
350
+ - [Code of Conduct](CODE_OF_CONDUCT.md)
351
+
352
+ ## License
353
+
354
+ [MIT](LICENSE)
package/SECURITY.md ADDED
@@ -0,0 +1,28 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ | Version | Supported |
6
+ |---------|-----------|
7
+ | 0.1.x | Yes |
8
+ | < 0.1.0 | No |
9
+
10
+ Only the latest released minor line receives security fixes. Critical fixes are backported to the latest two patch releases in that supported minor line.
11
+
12
+ ## Reporting a Vulnerability
13
+
14
+ If you discover a security vulnerability, please report it responsibly:
15
+
16
+ 1. **Do not** open a public issue
17
+ 2. Use GitHub's private vulnerability reporting (Security Advisories → "Report a vulnerability")
18
+ 3. Include a description of the vulnerability and steps to reproduce
19
+
20
+ You should receive a response within 48 hours.
21
+
22
+ ## Security Considerations
23
+
24
+ - codex-mcp assumes the MCP client and server run on the same machine (stdio transport, shared filesystem). It is not designed for remote/cross-machine deployment.
25
+ - codex-mcp spawns `codex app-server` child processes that can execute commands on your system
26
+ - Always use appropriate `approvalPolicy` and `sandbox` settings
27
+ - The `danger-full-access` sandbox mode grants unrestricted system access — use with caution
28
+ - Approval requests auto-decline after 60 seconds by default
@@ -0,0 +1,2 @@
1
+
2
+ export { }