codex-cli-mcp-slim 0.1.0__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 tksfjt1024
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.
@@ -0,0 +1,354 @@
1
+ Metadata-Version: 2.4
2
+ Name: codex-cli-mcp-slim
3
+ Version: 0.1.0
4
+ Summary: A thin, auditable MCP server wrapping the Codex CLI (codex exec). Same tools as the deprecated `codex mcp-server`; forward-compatible with future CLI flags via extra_args passthrough.
5
+ Author-email: tksfjt1024 <tksfjt1024@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/tksfjt1024/codex-cli-mcp-slim
8
+ Project-URL: Repository, https://github.com/tksfjt1024/codex-cli-mcp-slim
9
+ Project-URL: Issues, https://github.com/tksfjt1024/codex-cli-mcp-slim/issues
10
+ Keywords: mcp,model-context-protocol,codex,codex-cli,openai,claude,anthropic,ai,llm,coding-agent
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: POSIX
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Topic :: Utilities
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.10
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: mcp<3,>=2.0.0
29
+ Provides-Extra: test
30
+ Requires-Dist: pytest>=8.0; extra == "test"
31
+ Requires-Dist: pytest-asyncio>=0.23; extra == "test"
32
+ Provides-Extra: dev
33
+ Requires-Dist: ruff>=0.6; extra == "dev"
34
+ Dynamic: license-file
35
+
36
+ # codex-cli-mcp-slim
37
+
38
+ A thin, auditable [MCP](https://modelcontextprotocol.io) server wrapping the [Codex CLI](https://github.com/openai/codex) (`codex exec`).
39
+
40
+ [![PyPI version](https://img.shields.io/pypi/v/codex-cli-mcp-slim.svg)](https://pypi.org/project/codex-cli-mcp-slim/)
41
+ [![Python versions](https://img.shields.io/pypi/pyversions/codex-cli-mcp-slim.svg)](https://pypi.org/project/codex-cli-mcp-slim/)
42
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
43
+ [![CI](https://github.com/tksfjt1024/codex-cli-mcp-slim/actions/workflows/ci.yml/badge.svg)](https://github.com/tksfjt1024/codex-cli-mcp-slim/actions/workflows/ci.yml)
44
+
45
+ ## Why
46
+
47
+ `codex mcp-server`, the command that let other MCP clients call Codex, is
48
+ deprecated, and its removal has been merged upstream
49
+ ([openai/codex#42993](https://github.com/openai/codex/pull/42993)): releases up
50
+ to 0.153.x still ship it, later ones will not. Its replacement, the Codex app
51
+ server, speaks its own JSON-RPC protocol rather than MCP. This server keeps the old
52
+ integration point alive: it exposes the same two tools, `codex` and
53
+ `codex-reply`, and runs `codex exec` underneath. `codex exec` is the Codex CLI's
54
+ non-interactive mode: one prompt in, the agent works on its own, one final
55
+ message out.
56
+
57
+ When you add an MCP server to your AI coding tool, every prompt and code snippet
58
+ you send flows through that wrapper. Most CLI-wrapping MCP servers are small,
59
+ individually maintained packages, and recent supply-chain incidents
60
+ (`xz-utils`, `postmark-mcp`, the npm `chalk`/`debug` compromise) show that
61
+ "small and useful" is not the same as "safe to trust blindly."
62
+
63
+ This project takes the opposite stance: instead of asking you to trust it, it
64
+ tries to be **easy to audit**.
65
+
66
+ - **Single file** — the whole server is `src/codex_cli_mcp_slim/server.py`,
67
+ readable end-to-end in one sitting
68
+ - **One third-party dependency** (`mcp`) — minimal supply-chain surface
69
+ - **Faithful CLI mapping** — every typed parameter mirrors a real `codex exec`
70
+ flag by name, so it is obvious which flags an invocation actually sets
71
+ - **Prompt over stdin** — the prompt never appears in the process list and is
72
+ not bounded by the argv size limit
73
+ - **Forward-compatible** — any new or uncommon `codex exec` flag is reachable via
74
+ `extra_args` without touching this server
75
+ - **Configurable binary path** — `$CODEX_CMD` lets you swap or wrap the `codex`
76
+ binary
77
+ - **Transparent** — every invocation logs the exact argv to stderr
78
+
79
+ Read `server.py` before you install. That is the point.
80
+
81
+ ## Prerequisites
82
+
83
+ - The `codex` CLI installed and on `$PATH` (or pointed to via `$CODEX_CMD`). See
84
+ the [official Codex CLI repository](https://github.com/openai/codex). This server
85
+ always passes `--json` and reads the prompt from stdin (`codex exec -`), both of
86
+ which `codex exec` documents.
87
+ - `codex` already **authenticated** — this wrapper does not manage login; it
88
+ surfaces `codex`'s own error output if the CLI is not ready.
89
+
90
+ ## Installation
91
+
92
+ ```bash
93
+ # Run directly without installing
94
+ uvx codex-cli-mcp-slim
95
+
96
+ # Install from PyPI
97
+ pip install codex-cli-mcp-slim
98
+
99
+ # Run from GitHub HEAD
100
+ uvx --from git+https://github.com/tksfjt1024/codex-cli-mcp-slim codex-cli-mcp-slim
101
+ ```
102
+
103
+ ## Usage as an MCP server
104
+
105
+ ### Claude Code
106
+
107
+ ```bash
108
+ claude mcp add codex uvx codex-cli-mcp-slim
109
+ ```
110
+
111
+ Or manually in `~/.claude.json`:
112
+
113
+ ```json
114
+ {
115
+ "mcpServers": {
116
+ "codex": {
117
+ "type": "stdio",
118
+ "command": "uvx",
119
+ "args": ["codex-cli-mcp-slim"]
120
+ }
121
+ }
122
+ }
123
+ ```
124
+
125
+ If `codex` is not on the launching process's `$PATH`, point `$CODEX_CMD` at it:
126
+
127
+ ```json
128
+ {
129
+ "mcpServers": {
130
+ "codex": {
131
+ "type": "stdio",
132
+ "command": "uvx",
133
+ "args": ["codex-cli-mcp-slim"],
134
+ "env": { "CODEX_CMD": "/absolute/path/to/codex" }
135
+ }
136
+ }
137
+ }
138
+ ```
139
+
140
+ ### Replacing `codex mcp-server`
141
+
142
+ An entry that used to launch `codex mcp-server` keeps its server name and its
143
+ tool names; only `command` and `args` change. Before:
144
+
145
+ ```json
146
+ {
147
+ "mcpServers": {
148
+ "codex": {
149
+ "type": "stdio",
150
+ "command": "codex",
151
+ "args": ["mcp-server"]
152
+ }
153
+ }
154
+ }
155
+ ```
156
+
157
+ After:
158
+
159
+ ```json
160
+ {
161
+ "mcpServers": {
162
+ "codex": {
163
+ "type": "stdio",
164
+ "command": "uvx",
165
+ "args": ["codex-cli-mcp-slim"]
166
+ }
167
+ }
168
+ }
169
+ ```
170
+
171
+ Parameter names differ from the old server where `codex exec` names the flag
172
+ differently: `cwd` is now `cd` (the `-C/--cd` flag), and `codex-reply` takes
173
+ `thread_id` instead of `threadId`. The result's `structuredContent` field keeps
174
+ the shape the old server returned, `{"threadId": ..., "content": ...}`.
175
+
176
+ ### Other MCP clients
177
+
178
+ Any MCP-compatible client can launch the server via stdio:
179
+
180
+ ```bash
181
+ uvx codex-cli-mcp-slim
182
+ ```
183
+
184
+ ## Server-level flags
185
+
186
+ Everything on the server's own command line is placed right after `codex exec`
187
+ on every invocation. One MCP-client entry can therefore pin a reasoning effort, a
188
+ model or a working directory for all of its calls. Two entries that differ only
189
+ in reasoning effort look like this:
190
+
191
+ ```json
192
+ {
193
+ "mcpServers": {
194
+ "codex-medium": {
195
+ "type": "stdio",
196
+ "command": "uvx",
197
+ "args": ["codex-cli-mcp-slim", "-c", "model_reasoning_effort=medium"]
198
+ },
199
+ "codex-high": {
200
+ "type": "stdio",
201
+ "command": "uvx",
202
+ "args": ["codex-cli-mcp-slim", "-c", "model_reasoning_effort=high"]
203
+ }
204
+ }
205
+ }
206
+ ```
207
+
208
+ A call to `codex-high` runs
209
+ `codex exec -c model_reasoning_effort=high [per-call flags] --json -`. Per-call
210
+ flags come after the server-level ones, and `-c` may repeat with the last one
211
+ winning, so a per-call `config` entry overrides a server-level `-c`. Single-value
212
+ flags such as `-m` and `-C` may not repeat: `codex` rejects the second one, and
213
+ the tool result carries that error. Keep server-level flags and per-call
214
+ parameters disjoint for those.
215
+
216
+ ## Tool: `codex`
217
+
218
+ Runs a single non-interactive Codex session (`codex exec`). `codex` is an
219
+ agentic assistant: it reads and, depending on the sandbox, edits files in the
220
+ working directory to fulfil the request, then prints its final message.
221
+
222
+ The tool returns that final message followed by one metadata line:
223
+
224
+ ```
225
+ [codex] thread_id=019a2b3c-1d4e-7f60-8a9b-0c1d2e3f4a5b status=completed input_tokens=13894 cached_input_tokens=11904 output_tokens=612
226
+ ```
227
+
228
+ `thread_id` and `status` are always present; the token fields appear when the
229
+ run reported them. `isError` is the flag on an MCP tool result that tells the
230
+ client a call failed. This server sets it when `codex` exited non-zero, when the
231
+ subprocess timed out, and when the turn itself failed. The last case matters
232
+ because `codex exec` exits 0 after a failure inside the model API; the tool
233
+ result then carries the error text instead of coming back as a successful call:
234
+
235
+ ```
236
+ [ERROR] codex failed
237
+
238
+ returncode=0
239
+
240
+ errors:
241
+ Unsupported value: 'none' is not supported with the ... model.
242
+
243
+ [codex] thread_id=019a2b3c-... status=failed
244
+
245
+ argv: ['codex', 'exec', '--json', '-']
246
+ ```
247
+
248
+ Pass the `thread_id` to `codex-reply` to continue the same session.
249
+
250
+ | Parameter | Type | Description |
251
+ | --------------------- | -------- | ---------------------------------------------------------------------------------------------------- |
252
+ | `prompt` (required) | string | Prompt sent verbatim to `codex` on stdin |
253
+ | `cd` | string | Pass `-C <DIR>`: the working directory; defaults to the server's own |
254
+ | `model` | string | Pass `-m <MODEL>` |
255
+ | `config` | string[] | `key=value` overrides; each maps to one `-c` (repeatable, last wins) |
256
+ | `sandbox` | string | Pass `--sandbox`: `read-only`, `workspace-write` or `danger-full-access`. See note below |
257
+ | `add_dir` | string[] | Extra writable directories; each maps to one `--add-dir` (repeatable, not comma-joined) |
258
+ | `profile` | string | Pass `-p <PROFILE>` |
259
+ | `ephemeral` | bool | Pass `--ephemeral` (do not write the session transcript codex keeps under `$CODEX_HOME/sessions`) |
260
+ | `skip_git_repo_check` | bool | Pass `--skip-git-repo-check` (allow a working directory outside a git repository) |
261
+ | `extra_args` | string[] | Raw CLI flags appended verbatim. Do not pass `--json` or a prompt; the server adds both |
262
+ | `env` | object | Extra environment variables for the `codex` subprocess |
263
+ | `timeout_seconds` | int | Hard wall-clock timeout for the subprocess, 30 to 3600 (default 1800) |
264
+
265
+ Unknown parameters are refused rather than ignored, so a call that still uses
266
+ the old server's `cwd` gets an error naming `cd` instead of running in the
267
+ wrong directory.
268
+
269
+ ### Security note: `sandbox`
270
+
271
+ `codex exec` reads its sandbox mode from its own configuration file
272
+ (`~/.codex/config.toml` by default) unless `--sandbox` is given.
273
+ `danger-full-access` removes the filesystem and network sandbox entirely;
274
+ `workspace-write` makes the working directory (and any `add_dir`) writable.
275
+ `--sandbox` overrides only the mode; whether `workspace-write` gets network
276
+ access still follows the `[sandbox_workspace_write]` section of `config.toml`.
277
+ The parameter mirrors the flag so that whichever mode a call runs
278
+ under is visible in the arguments and in the logged argv. This server does not
279
+ pass `--dangerously-bypass-approvals-and-sandbox`; reach it via `extra_args` if
280
+ you really mean it.
281
+
282
+ ## Tool: `codex-reply`
283
+
284
+ Continues a previous session (`codex exec resume <THREAD_ID>`) with a follow-up
285
+ prompt and returns the new final message. Only the flags `codex exec resume`
286
+ accepts are exposed, so `cd`, `sandbox`, `add_dir` and `profile` are refused
287
+ here. The working directory and sandbox of a reply come from the current
288
+ configuration, that is, the server-level flags and `config.toml`, not from the
289
+ original session.
290
+
291
+ | Parameter | Type | Description |
292
+ | ----------------------- | -------- | ----------------------------------------------------------------- |
293
+ | `thread_id` (required) | string | The `thread_id` from a previous result's `[codex]` line |
294
+ | `prompt` (required) | string | Follow-up prompt, sent on stdin |
295
+ | `model` | string | Pass `-m <MODEL>` |
296
+ | `config` | string[] | `key=value` overrides; each maps to one `-c` |
297
+ | `ephemeral` | bool | Pass `--ephemeral` |
298
+ | `skip_git_repo_check` | bool | Pass `--skip-git-repo-check` |
299
+ | `extra_args` | string[] | Raw CLI flags appended verbatim |
300
+ | `env` | object | Extra environment variables for the `codex` subprocess |
301
+ | `timeout_seconds` | int | Hard wall-clock timeout for the subprocess, 30 to 3600 (default 1800) |
302
+
303
+ ## Timeout configuration
304
+
305
+ `timeout_seconds` is this wrapper's hard wall-clock limit (default 1800, or
306
+ `$CODEX_CLI_MCP_SLIM_TIMEOUT`). On timeout, the wrapper kills the subprocess's
307
+ whole process group and then waits up to 20 additional seconds to collect any
308
+ buffered output and reap the process, so the effective ceiling is
309
+ `timeout_seconds + 20`. A timed-out call is flagged `isError` and carries
310
+ whatever `codex` had printed so far.
311
+
312
+ ## Forward-compatibility example
313
+
314
+ If a future `codex exec` release adds a new flag (say `--super-mode`), use it
315
+ immediately without updating this server:
316
+
317
+ ```jsonc
318
+ {
319
+ "name": "codex",
320
+ "arguments": {
321
+ "prompt": "...",
322
+ "extra_args": ["--super-mode"]
323
+ }
324
+ }
325
+ ```
326
+
327
+ ## Configuration
328
+
329
+ | Environment variable | Default | Purpose |
330
+ | ------------------------------ | ------- | ---------------------------------------- |
331
+ | `CODEX_CMD` | `codex` | Path to the `codex` CLI binary |
332
+ | `CODEX_CLI_MCP_SLIM_TIMEOUT` | `1800` | Default subprocess timeout in seconds |
333
+ | `CODEX_CLI_MCP_SLIM_LOG_LEVEL` | `INFO` | Logging level for stderr diagnostics |
334
+
335
+ `codex` itself reads its configuration file and credentials from `$CODEX_HOME`
336
+ (`~/.codex` by default), so an MCP-client entry can point a server at a
337
+ dedicated configuration directory through its `env` block.
338
+
339
+ ## Development
340
+
341
+ ```bash
342
+ # Install dev dependencies
343
+ pip install -e ".[test,dev]"
344
+
345
+ # Lint
346
+ ruff check .
347
+
348
+ # Test
349
+ pytest
350
+ ```
351
+
352
+ ## License
353
+
354
+ [MIT](./LICENSE) © tksfjt1024
@@ -0,0 +1,319 @@
1
+ # codex-cli-mcp-slim
2
+
3
+ A thin, auditable [MCP](https://modelcontextprotocol.io) server wrapping the [Codex CLI](https://github.com/openai/codex) (`codex exec`).
4
+
5
+ [![PyPI version](https://img.shields.io/pypi/v/codex-cli-mcp-slim.svg)](https://pypi.org/project/codex-cli-mcp-slim/)
6
+ [![Python versions](https://img.shields.io/pypi/pyversions/codex-cli-mcp-slim.svg)](https://pypi.org/project/codex-cli-mcp-slim/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+ [![CI](https://github.com/tksfjt1024/codex-cli-mcp-slim/actions/workflows/ci.yml/badge.svg)](https://github.com/tksfjt1024/codex-cli-mcp-slim/actions/workflows/ci.yml)
9
+
10
+ ## Why
11
+
12
+ `codex mcp-server`, the command that let other MCP clients call Codex, is
13
+ deprecated, and its removal has been merged upstream
14
+ ([openai/codex#42993](https://github.com/openai/codex/pull/42993)): releases up
15
+ to 0.153.x still ship it, later ones will not. Its replacement, the Codex app
16
+ server, speaks its own JSON-RPC protocol rather than MCP. This server keeps the old
17
+ integration point alive: it exposes the same two tools, `codex` and
18
+ `codex-reply`, and runs `codex exec` underneath. `codex exec` is the Codex CLI's
19
+ non-interactive mode: one prompt in, the agent works on its own, one final
20
+ message out.
21
+
22
+ When you add an MCP server to your AI coding tool, every prompt and code snippet
23
+ you send flows through that wrapper. Most CLI-wrapping MCP servers are small,
24
+ individually maintained packages, and recent supply-chain incidents
25
+ (`xz-utils`, `postmark-mcp`, the npm `chalk`/`debug` compromise) show that
26
+ "small and useful" is not the same as "safe to trust blindly."
27
+
28
+ This project takes the opposite stance: instead of asking you to trust it, it
29
+ tries to be **easy to audit**.
30
+
31
+ - **Single file** — the whole server is `src/codex_cli_mcp_slim/server.py`,
32
+ readable end-to-end in one sitting
33
+ - **One third-party dependency** (`mcp`) — minimal supply-chain surface
34
+ - **Faithful CLI mapping** — every typed parameter mirrors a real `codex exec`
35
+ flag by name, so it is obvious which flags an invocation actually sets
36
+ - **Prompt over stdin** — the prompt never appears in the process list and is
37
+ not bounded by the argv size limit
38
+ - **Forward-compatible** — any new or uncommon `codex exec` flag is reachable via
39
+ `extra_args` without touching this server
40
+ - **Configurable binary path** — `$CODEX_CMD` lets you swap or wrap the `codex`
41
+ binary
42
+ - **Transparent** — every invocation logs the exact argv to stderr
43
+
44
+ Read `server.py` before you install. That is the point.
45
+
46
+ ## Prerequisites
47
+
48
+ - The `codex` CLI installed and on `$PATH` (or pointed to via `$CODEX_CMD`). See
49
+ the [official Codex CLI repository](https://github.com/openai/codex). This server
50
+ always passes `--json` and reads the prompt from stdin (`codex exec -`), both of
51
+ which `codex exec` documents.
52
+ - `codex` already **authenticated** — this wrapper does not manage login; it
53
+ surfaces `codex`'s own error output if the CLI is not ready.
54
+
55
+ ## Installation
56
+
57
+ ```bash
58
+ # Run directly without installing
59
+ uvx codex-cli-mcp-slim
60
+
61
+ # Install from PyPI
62
+ pip install codex-cli-mcp-slim
63
+
64
+ # Run from GitHub HEAD
65
+ uvx --from git+https://github.com/tksfjt1024/codex-cli-mcp-slim codex-cli-mcp-slim
66
+ ```
67
+
68
+ ## Usage as an MCP server
69
+
70
+ ### Claude Code
71
+
72
+ ```bash
73
+ claude mcp add codex uvx codex-cli-mcp-slim
74
+ ```
75
+
76
+ Or manually in `~/.claude.json`:
77
+
78
+ ```json
79
+ {
80
+ "mcpServers": {
81
+ "codex": {
82
+ "type": "stdio",
83
+ "command": "uvx",
84
+ "args": ["codex-cli-mcp-slim"]
85
+ }
86
+ }
87
+ }
88
+ ```
89
+
90
+ If `codex` is not on the launching process's `$PATH`, point `$CODEX_CMD` at it:
91
+
92
+ ```json
93
+ {
94
+ "mcpServers": {
95
+ "codex": {
96
+ "type": "stdio",
97
+ "command": "uvx",
98
+ "args": ["codex-cli-mcp-slim"],
99
+ "env": { "CODEX_CMD": "/absolute/path/to/codex" }
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ ### Replacing `codex mcp-server`
106
+
107
+ An entry that used to launch `codex mcp-server` keeps its server name and its
108
+ tool names; only `command` and `args` change. Before:
109
+
110
+ ```json
111
+ {
112
+ "mcpServers": {
113
+ "codex": {
114
+ "type": "stdio",
115
+ "command": "codex",
116
+ "args": ["mcp-server"]
117
+ }
118
+ }
119
+ }
120
+ ```
121
+
122
+ After:
123
+
124
+ ```json
125
+ {
126
+ "mcpServers": {
127
+ "codex": {
128
+ "type": "stdio",
129
+ "command": "uvx",
130
+ "args": ["codex-cli-mcp-slim"]
131
+ }
132
+ }
133
+ }
134
+ ```
135
+
136
+ Parameter names differ from the old server where `codex exec` names the flag
137
+ differently: `cwd` is now `cd` (the `-C/--cd` flag), and `codex-reply` takes
138
+ `thread_id` instead of `threadId`. The result's `structuredContent` field keeps
139
+ the shape the old server returned, `{"threadId": ..., "content": ...}`.
140
+
141
+ ### Other MCP clients
142
+
143
+ Any MCP-compatible client can launch the server via stdio:
144
+
145
+ ```bash
146
+ uvx codex-cli-mcp-slim
147
+ ```
148
+
149
+ ## Server-level flags
150
+
151
+ Everything on the server's own command line is placed right after `codex exec`
152
+ on every invocation. One MCP-client entry can therefore pin a reasoning effort, a
153
+ model or a working directory for all of its calls. Two entries that differ only
154
+ in reasoning effort look like this:
155
+
156
+ ```json
157
+ {
158
+ "mcpServers": {
159
+ "codex-medium": {
160
+ "type": "stdio",
161
+ "command": "uvx",
162
+ "args": ["codex-cli-mcp-slim", "-c", "model_reasoning_effort=medium"]
163
+ },
164
+ "codex-high": {
165
+ "type": "stdio",
166
+ "command": "uvx",
167
+ "args": ["codex-cli-mcp-slim", "-c", "model_reasoning_effort=high"]
168
+ }
169
+ }
170
+ }
171
+ ```
172
+
173
+ A call to `codex-high` runs
174
+ `codex exec -c model_reasoning_effort=high [per-call flags] --json -`. Per-call
175
+ flags come after the server-level ones, and `-c` may repeat with the last one
176
+ winning, so a per-call `config` entry overrides a server-level `-c`. Single-value
177
+ flags such as `-m` and `-C` may not repeat: `codex` rejects the second one, and
178
+ the tool result carries that error. Keep server-level flags and per-call
179
+ parameters disjoint for those.
180
+
181
+ ## Tool: `codex`
182
+
183
+ Runs a single non-interactive Codex session (`codex exec`). `codex` is an
184
+ agentic assistant: it reads and, depending on the sandbox, edits files in the
185
+ working directory to fulfil the request, then prints its final message.
186
+
187
+ The tool returns that final message followed by one metadata line:
188
+
189
+ ```
190
+ [codex] thread_id=019a2b3c-1d4e-7f60-8a9b-0c1d2e3f4a5b status=completed input_tokens=13894 cached_input_tokens=11904 output_tokens=612
191
+ ```
192
+
193
+ `thread_id` and `status` are always present; the token fields appear when the
194
+ run reported them. `isError` is the flag on an MCP tool result that tells the
195
+ client a call failed. This server sets it when `codex` exited non-zero, when the
196
+ subprocess timed out, and when the turn itself failed. The last case matters
197
+ because `codex exec` exits 0 after a failure inside the model API; the tool
198
+ result then carries the error text instead of coming back as a successful call:
199
+
200
+ ```
201
+ [ERROR] codex failed
202
+
203
+ returncode=0
204
+
205
+ errors:
206
+ Unsupported value: 'none' is not supported with the ... model.
207
+
208
+ [codex] thread_id=019a2b3c-... status=failed
209
+
210
+ argv: ['codex', 'exec', '--json', '-']
211
+ ```
212
+
213
+ Pass the `thread_id` to `codex-reply` to continue the same session.
214
+
215
+ | Parameter | Type | Description |
216
+ | --------------------- | -------- | ---------------------------------------------------------------------------------------------------- |
217
+ | `prompt` (required) | string | Prompt sent verbatim to `codex` on stdin |
218
+ | `cd` | string | Pass `-C <DIR>`: the working directory; defaults to the server's own |
219
+ | `model` | string | Pass `-m <MODEL>` |
220
+ | `config` | string[] | `key=value` overrides; each maps to one `-c` (repeatable, last wins) |
221
+ | `sandbox` | string | Pass `--sandbox`: `read-only`, `workspace-write` or `danger-full-access`. See note below |
222
+ | `add_dir` | string[] | Extra writable directories; each maps to one `--add-dir` (repeatable, not comma-joined) |
223
+ | `profile` | string | Pass `-p <PROFILE>` |
224
+ | `ephemeral` | bool | Pass `--ephemeral` (do not write the session transcript codex keeps under `$CODEX_HOME/sessions`) |
225
+ | `skip_git_repo_check` | bool | Pass `--skip-git-repo-check` (allow a working directory outside a git repository) |
226
+ | `extra_args` | string[] | Raw CLI flags appended verbatim. Do not pass `--json` or a prompt; the server adds both |
227
+ | `env` | object | Extra environment variables for the `codex` subprocess |
228
+ | `timeout_seconds` | int | Hard wall-clock timeout for the subprocess, 30 to 3600 (default 1800) |
229
+
230
+ Unknown parameters are refused rather than ignored, so a call that still uses
231
+ the old server's `cwd` gets an error naming `cd` instead of running in the
232
+ wrong directory.
233
+
234
+ ### Security note: `sandbox`
235
+
236
+ `codex exec` reads its sandbox mode from its own configuration file
237
+ (`~/.codex/config.toml` by default) unless `--sandbox` is given.
238
+ `danger-full-access` removes the filesystem and network sandbox entirely;
239
+ `workspace-write` makes the working directory (and any `add_dir`) writable.
240
+ `--sandbox` overrides only the mode; whether `workspace-write` gets network
241
+ access still follows the `[sandbox_workspace_write]` section of `config.toml`.
242
+ The parameter mirrors the flag so that whichever mode a call runs
243
+ under is visible in the arguments and in the logged argv. This server does not
244
+ pass `--dangerously-bypass-approvals-and-sandbox`; reach it via `extra_args` if
245
+ you really mean it.
246
+
247
+ ## Tool: `codex-reply`
248
+
249
+ Continues a previous session (`codex exec resume <THREAD_ID>`) with a follow-up
250
+ prompt and returns the new final message. Only the flags `codex exec resume`
251
+ accepts are exposed, so `cd`, `sandbox`, `add_dir` and `profile` are refused
252
+ here. The working directory and sandbox of a reply come from the current
253
+ configuration, that is, the server-level flags and `config.toml`, not from the
254
+ original session.
255
+
256
+ | Parameter | Type | Description |
257
+ | ----------------------- | -------- | ----------------------------------------------------------------- |
258
+ | `thread_id` (required) | string | The `thread_id` from a previous result's `[codex]` line |
259
+ | `prompt` (required) | string | Follow-up prompt, sent on stdin |
260
+ | `model` | string | Pass `-m <MODEL>` |
261
+ | `config` | string[] | `key=value` overrides; each maps to one `-c` |
262
+ | `ephemeral` | bool | Pass `--ephemeral` |
263
+ | `skip_git_repo_check` | bool | Pass `--skip-git-repo-check` |
264
+ | `extra_args` | string[] | Raw CLI flags appended verbatim |
265
+ | `env` | object | Extra environment variables for the `codex` subprocess |
266
+ | `timeout_seconds` | int | Hard wall-clock timeout for the subprocess, 30 to 3600 (default 1800) |
267
+
268
+ ## Timeout configuration
269
+
270
+ `timeout_seconds` is this wrapper's hard wall-clock limit (default 1800, or
271
+ `$CODEX_CLI_MCP_SLIM_TIMEOUT`). On timeout, the wrapper kills the subprocess's
272
+ whole process group and then waits up to 20 additional seconds to collect any
273
+ buffered output and reap the process, so the effective ceiling is
274
+ `timeout_seconds + 20`. A timed-out call is flagged `isError` and carries
275
+ whatever `codex` had printed so far.
276
+
277
+ ## Forward-compatibility example
278
+
279
+ If a future `codex exec` release adds a new flag (say `--super-mode`), use it
280
+ immediately without updating this server:
281
+
282
+ ```jsonc
283
+ {
284
+ "name": "codex",
285
+ "arguments": {
286
+ "prompt": "...",
287
+ "extra_args": ["--super-mode"]
288
+ }
289
+ }
290
+ ```
291
+
292
+ ## Configuration
293
+
294
+ | Environment variable | Default | Purpose |
295
+ | ------------------------------ | ------- | ---------------------------------------- |
296
+ | `CODEX_CMD` | `codex` | Path to the `codex` CLI binary |
297
+ | `CODEX_CLI_MCP_SLIM_TIMEOUT` | `1800` | Default subprocess timeout in seconds |
298
+ | `CODEX_CLI_MCP_SLIM_LOG_LEVEL` | `INFO` | Logging level for stderr diagnostics |
299
+
300
+ `codex` itself reads its configuration file and credentials from `$CODEX_HOME`
301
+ (`~/.codex` by default), so an MCP-client entry can point a server at a
302
+ dedicated configuration directory through its `env` block.
303
+
304
+ ## Development
305
+
306
+ ```bash
307
+ # Install dev dependencies
308
+ pip install -e ".[test,dev]"
309
+
310
+ # Lint
311
+ ruff check .
312
+
313
+ # Test
314
+ pytest
315
+ ```
316
+
317
+ ## License
318
+
319
+ [MIT](./LICENSE) © tksfjt1024