Skip to content

Commit 8ace6d3

Browse files
committed
release(v8.9.6): Codex MCP integration + stdio banner fix
Codex Desktop / CLI is now a fully supported MATHIR client, on par with Claude Code, OpenCode, and MiMoCode. Three independent layers each fixed end-to-end and documented with portable templates. **MCP server crash fix (root cause)** FastMCP 3.4.4 prints a 15-line colored ASCII banner on stdout at mcp.run(). For MCP-over-stdio, stdout is the JSON-RPC channel; the banner corrupted the framing and every MCP host reading JSON-RPC straight off stdout silently registered zero tools. Discovered live by Codex itself, patched with mcp.run(show_banner=False) in mathir_mcp_server.py:1490, then propagated to the repo per guardrail-sync-deployed-daemon. **Codex integration (3 layers)** A — MCP server: docs/CODEX_INTEGRATION.md walks through the absolute-path config.toml block, fixes the ~ expansion bug, fixes the missing-python- on-PATH bug, and adds startup_timeout_sec for parity with node_repl. B — auto-inject hook: ~/.codex/hooks.json reuses the existing claude_code_hook.py (zero changes needed; shared with Claude Code). C — transparent proxy: shell_environment_policy.set forwards OPENAI_BASE_URL=http://127.0.0.1:7339/v1 so Codex itself routes through the universal proxy (target=api.openai.com per the auto_start.bat fix). **Portable templates** (mathir_mcp/codex_templates/) - hooks.json — drop-in for ~/.codex/hooks.json (user replaces <YOU>). - config.toml.snippet — TOML blocks for ~/.codex/config.toml (user replaces <ABS_PYTHON> and <HOME>). - README.md — explains the placeholders + links to the integration guide. **Versioning** 8.9.5 -> 8.9.6 in: - pyproject.toml - mathir_mcp/__init__.py - mathir_mcp/mathir_lib/__init__.py Deployed copies synced per guardrail-sync-deployed-daemon. Daemon /health now reports version=8.9.6 live (config/mathir.json version field also bumped; daemon re-reads on every /health call so no restart required). **Hygiene** - .gitignore now ignores /hooks.json (root-level, machine-specific) and nul/NUL (Windows reserved-name artifact). - mathir_mcp/bin/auto_start.bat proxy target switched from anthropic.com -> openai.com so Codex, Cursor, Cline, Continue, and any other OpenAI-Chat-Completions-compat client works out of the box. Claude Code is unaffected (uses the UserPromptSubmit hook, not the proxy). - Two CHANGELOG.md bumps (top-level + sub-component) for [8.9.6]. - New docs/CODEX_INTEGRATION.md (16 KB, full setup + autostart + 3-layer troubleshooting walk-through + cheat sheet). - New mathir_mcp/docs/troubleshooting/codex-mcp-tools-invisible-three-layers.md (incident narrative cross-linked from the integration guide). - New mathir_mcp/docs/troubleshooting/codex-mcp-path-expansion.md (cause + fix + deliberate no-portable-alternative violation explained).
1 parent 27ccae1 commit 8ace6d3

14 files changed

Lines changed: 687 additions & 6 deletions

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,22 @@ daemon_*.txt
7878
# MiMoCode local state (plans, node_modules)
7979
.mimocode/
8080

81+
# Codex local settings (contains machine-specific python paths + hook commands).
82+
# Use mathir_mcp/codex_templates/ for the shareable templates instead.
83+
.codex/
84+
/hooks.json
85+
86+
# OpenCode plugin / config (machine-specific)
87+
# (already covered via .claude/ pattern elsewhere if needed)
88+
8189
# Superpowers (agent scratch dirs)
8290
.superpowers/
8391
superpowers/
8492

93+
# Windows PowerShell `> nul` artifact (reserved device name)
94+
nul
95+
NUL
96+
8597
# Editor
8698
.vscode/
8799
.idea/

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
88
99
---
1010

11+
## [8.9.6] — 2026-07-31 — CODEX MCP INTEGRATION + STDIO BANNER FIX
12+
13+
### Fixed
14+
- **Codex MCP stdio banner crash**`mathir_mcp/mathir_lib/mathir_mcp_server.py:1490`: `mcp.run()``mcp.run(show_banner=False)`. FastMCP 3.4.4 prints a large colored ASCII banner to **stdout** at startup; MCP-over-stdio uses stdout for JSON-RPC, so the banner corrupted the framing and Codex silently registered zero tools from this server. Full 3-layer failure walk-through in [`mathir_mcp/docs/troubleshooting/codex-mcp-tools-invisible-three-layers.md`](mathir_mcp/docs/troubleshooting/codex-mcp-tools-invisible-three-layers.md). See also [`docs/CODEX_INTEGRATION.md`](docs/CODEX_INTEGRATION.md) for the full Codex↔MATHIR setup guide (config + proxy + hook + autostart).
15+
16+
### Added
17+
- **Codex integration guide**[`docs/CODEX_INTEGRATION.md`](docs/CODEX_INTEGRATION.md): how to install, configure `~/.codex/config.toml` (MCP server + `OPENAI_BASE_URL` proxy + `[shell_environment_policy.set]` forwarding), wire the auto-inject hook, survive reboots via the scheduler tasks, and what to do when `mcp__mathir__*` tools don't appear.
18+
19+
---
20+
1121
## [8.9.5] — 2026-07-21 — AUTONOMOUS MAINTENANCE + HEADLESS GOD-MODE WORKERS
1222

1323
**mathir_mcp package work — full detail in [mathir_mcp/CHANGELOG.md](mathir_mcp/CHANGELOG.md#895--2026-07-21--autonomous-maintenance--headless-god-mode-workers).**

docs/CODEX_INTEGRATION.md

Lines changed: 351 additions & 0 deletions
Large diffs are not rendered by default.

mathir_mcp/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# MATHIR Changelog
22

3+
## [8.9.6] — 2026-07-31 — CODEX MCP STDIO BANNER FIX + INTEGRATION GUIDE
4+
5+
### Fixed
6+
- **`mathir_mcp_server.py:1490`**`mcp.run()``mcp.run(show_banner=False)`. FastMCP 3.4.4 prints a large colored ASCII banner to **stdout** at startup; for MCP-over-stdio this corrupts JSON-RPC framing and any MCP host reading JSON-RPC straight off stdout silently fails to register any tool (Codex, in particular). stderr is unaffected, so daemon `logging` and 3-layer cache logs still appear. First symptom reported live: "MCP server `mathir` is configured but `mcp__mathir__*` tools never appear in Codex's tool list." Discovered and patched by Codex's own session, then propagated to source repo per `guardrail-sync-deployed-daemon`.
7+
8+
### Notes
9+
- This is the **third** layer of three separate MCP-server-for-Codex failures
10+
encountered on 2026-07-31 (the other two were `~` not expanded in MCP env
11+
vars, and Codex's child process not inheriting `python` on PATH).
12+
- Documentation: `docs/troubleshooting/codex-mcp-tools-invisible-three-layers.md`.
13+
314
## [8.9.5] — 2026-07-21 — AUTONOMOUS MAINTENANCE + HEADLESS GOD-MODE WORKERS
415

516
### Added

mathir_mcp/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
Console scripts (after ``pip install -e .``):
1515
mathir-daemon, mathir-mcp, mathir-client, mathir-watchdog
1616
"""
17-
__version__ = "8.9.5"
17+
__version__ = "8.9.6"
1818

1919
__all__ = ["__version__"]

mathir_mcp/bin/auto_start.bat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ REM ---- Launch universal proxy detached (best-effort, non-fatal) -------------
9191
REM Missing script or missing flask/waitress must never block the daemon
9292
REM launch above — this section only ever adds capability, never breaks it.
9393
if exist "%PROXY_PATH%" (
94-
start "MATHIR_PROXY" /B "%PYTHON_PATH%" "%PROXY_PATH%" --port %PROXY_PORT% --target https://api.anthropic.com >> "%PROXY_LOG_PATH%" 2>&1
95-
echo [%date% %time%] Proxy launch requested (port %PROXY_PORT%, see mathir_proxy.log) >> "%LOG_PATH%"
94+
start "MATHIR_PROXY" /B "%PYTHON_PATH%" "%PROXY_PATH%" --port %PROXY_PORT% --target https://api.openai.com >> "%PROXY_LOG_PATH%" 2>&1
95+
echo [%date% %time%] Proxy launch requested (port %PROXY_PORT%, target=api.openai.com, see mathir_proxy.log) >> "%LOG_PATH%"
9696
)
9797

9898
endlocal & exit /b 0
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Codex Templates
2+
3+
Portable templates for connecting Codex Desktop / CLI to MATHIR.
4+
5+
## Files
6+
7+
- **`hooks.json`** — drop-in replacement for `~/.codex/hooks.json`. Replace `<YOU>` with your username (Windows) or `<USER>` (macOS/Linux), or use the dedicated `claude_code_hook.py` path from your install.
8+
9+
- **`config.toml.snippet`** — TOML blocks to merge into your existing `~/.codex/config.toml`. Replace the placeholders:
10+
- `<ABS_PYTHON>` — the absolute path of the Python interpreter that should run the MCP server. Verify with `where.exe python` (Windows) or `which python3` (macOS/Linux). If you use a conda/venv, point at that interpreter specifically.
11+
- `<HOME>` — your home directory as a Windows backslash path on Windows (`C:\\Users\\<YOU>`) or POSIX path on macOS/Linux (`/Users/<USER>` or `/home/<USER>`).
12+
13+
## Why a template and not a copy?
14+
15+
The Codex `config.toml` and `hooks.json` accept **absolute paths only** because Codex (Electron) does not shell-expand `~` in MCP env vars and does not always inherit `PATH`. Hardcoding any user's path in the template would be misleading.
16+
17+
The official setup guide ([docs/CODEX_INTEGRATION.md](../../../docs/CODEX_INTEGRATION.md)) walks through the substitutions and the three layers of integration.
18+
19+
## What lives where after install
20+
21+
| Template field | Resolves to (after substitution) |
22+
|---|---|
23+
| `<ABS_PYTHON>` | `C:\Users\<YOU>\miniconda3\python.exe` (or wherever `where.exe python` finds first) |
24+
| `<HOME>\.config\MATHIR\mathir_mcp\mathir_lib\mathir_mcp_server.py` | the deployed mathir_mcp_server.py |
25+
| `<HOME>\.config\MATHIR\config\mathir.json` | the daemon runtime config |
26+
| `<HOME>\.config\MATHIR\mathir_mcp\mathir_lib` | the deployed mathir_lib directory (PYTHONPATH for the MCP server) |
27+
| `<HOME>\.config\MATHIR\mathir_mcp\bin\claude_code_hook.py` | the auto-inject hook shared with Claude Code |
28+
29+
## Related docs
30+
31+
- [`../../../docs/CODEX_INTEGRATION.md`](../../../docs/CODEX_INTEGRATION.md) — full setup guide (config + autostart + troubleshooting, all 3 layers).
32+
- [`../troubleshooting/codex-mcp-tools-invisible-three-layers.md`](../troubleshooting/codex-mcp-tools-invisible-three-layers.md) — incident narrative for the 3-layer failure that broke Codex MCP until `mcp.run(show_banner=False)`.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# ============================================================================
2+
# Codex MCP + auto-inject + proxy configuration for MATHIR
3+
# ----------------------------------------------------------------------------
4+
# This is a TEMPLATE — every line that needs a per-user substitution uses the
5+
# placeholder `<YOU>` (Windows) or `<USER>` (macOS/Linux).
6+
#
7+
# How to use this on a fresh box:
8+
# 1. Find your Python interpreter:
9+
# Windows : `where.exe python`
10+
# macOS : `which python3` (or use a venv interpreter)
11+
# Then replace `<ABS_PYTHON>` below with that absolute path.
12+
# 2. Replace every `<YOU>` / `<USER>` with your username.
13+
# 3. Merge this into your existing `~/.codex/config.toml` (do not overwrite).
14+
# 4. Quit Codex fully (not just close the chat) and relaunch.
15+
# 5. Verify by asking Codex "liste tes outils MCP" — you should see
16+
# mcp__mathir__memory_recall, mcp__mathir__memory_save, etc.
17+
#
18+
# Troubleshooting: see ../../../docs/CODEX_INTEGRATION.md
19+
# and troubleshooting/codex-mcp-tools-invisible-three-layers.md
20+
# ============================================================================
21+
22+
# ---------------------------------------------------------------------------
23+
# Layer A — MCP server (the 27 tools)
24+
# ---------------------------------------------------------------------------
25+
[mcp_servers.mathir]
26+
# IMPORTANT: use ABSOLUTE python path. Codex (Electron) does not always
27+
# inherit your shell's PATH for MCP child processes, so `command = "python"`
28+
# silently resolves to nothing and 0 tools show up.
29+
command = "<ABS_PYTHON>"
30+
args = ["<HOME>\\.config\\MATHIR\\mathir_mcp\\mathir_lib\\mathir_mcp_server.py"]
31+
startup_timeout_sec = 30
32+
33+
[mcp_servers.mathir.env]
34+
MATHIR_EMBEDDING_DIM = "384"
35+
MATHIR_PORT = "7338"
36+
MATHIR_DAEMON_URL = "http://127.0.0.1:7338"
37+
# IMPORTANT: absolute paths in env vars, NOT `~/.config/...`. Codex does NOT
38+
# shell-expand `~` in MCP env vars before passing them to Python. If you use
39+
# `~`, `from mathir_paths import CONFIG_PATH` crashes silently and you get 0 tools.
40+
MATHIR_CONFIG = "<HOME>\\.config\\MATHIR\\config\\mathir.json"
41+
PYTHONPATH = "<HOME>\\.config\\MATHIR\\mathir_mcp\\mathir_lib"
42+
43+
# ---------------------------------------------------------------------------
44+
# Layer B — auto-inject hook (prompt-time context)
45+
# ---------------------------------------------------------------------------
46+
# Drop hooks.json from this same directory into `~/.codex/hooks.json` (full
47+
# template also provided). No TOML changes needed for this.
48+
49+
# ---------------------------------------------------------------------------
50+
# Layer C — transparent OpenAI proxy (optional)
51+
# ---------------------------------------------------------------------------
52+
# Adds `OPENAI_BASE_URL` to Codex's env forwarding. `/v1` is mandatory:
53+
# OpenAI SDK adds `/chat/completions` to your base_url, and its default
54+
# already includes `/v1` (per guardrail-base-url-v1-convention).
55+
[shell_environment_policy.set]
56+
OPENAI_BASE_URL = "http://127.0.0.1:7339/v1"
57+
MATHIR_PROXY_PORT = "7339"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"hooks": {
3+
"UserPromptSubmit": [
4+
{
5+
"hooks": [
6+
{
7+
"type": "command",
8+
"command": "python \"C:\\Users\\<YOU>\\.config\\MATHIR\\mathir_mcp\\bin\\claude_code_hook.py\""
9+
}
10+
]
11+
}
12+
]
13+
}
14+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Codex MCP Server Path Expansion Pitfall (Windows) — 2026-07-31
2+
3+
## Symptom
4+
Codex says "I see MCP servers in settings but the mathir tools aren't exposed" — the
5+
configured MCP server silently fails to start (no error visible in Codex UI).
6+
7+
## Root cause (verified by reproducing)
8+
The previous config used shell-style `~` expansion in MCP env vars:
9+
10+
```toml
11+
[mcp_servers.mathir.env]
12+
MATHIR_CONFIG = "~/.config/MATHIR/config/mathir.json"
13+
PYTHONPATH = "~/.config/MATHIR/mathir_mcp/mathir_lib"
14+
```
15+
16+
On Windows, **Codex's MCP spawn does NOT expand `~` before passing env vars to the child
17+
process**. Python then interprets `~/.config/MATHIR/...` literally:
18+
- `sys.path` contains `'D:\\...\\~\\.config\\MATHIR\\mathir_mcp\\mathir_lib'` (joined to CWD)
19+
- `from mathir_paths import CONFIG_PATH``ModuleNotFoundError`
20+
- The MCP server exits before its first stdio handshake → Codex sees "no tools"
21+
22+
Verified empirically:
23+
```bash
24+
$ PYTHONPATH='~/.config/MATHIR/mathir_mcp/mathir_lib' python -c \
25+
"from mathir_paths import CONFIG_PATH"
26+
# ModuleNotFoundError: No module named 'mathir_paths'
27+
$ PYTHONPATH='C:\\Users\\princ\\.config\\MATHIR\\mathir_mcp\\mathir_lib' python -c \
28+
"from mathir_paths import CONFIG_PATH"
29+
# OK — CONFIG_PATH = C:\Users\princ\.config\MATHIR\config\mathir.json
30+
```
31+
32+
## Fix applied
33+
Replaced `~/.config/MATHIR/...` with `C:\\Users\\princ\\.config\\MATHIR\\...` (absolute
34+
Win path with escaped backslashes) in `~/.codex/config.toml` `[mcp_servers.mathir.env]`.
35+
Also added `MATHIR_DAEMON_URL = "http://127.0.0.1:7338"` for consistency.
36+
37+
## IMPORTANT VIOLATION (acceptable for Codex only)
38+
This is a deliberate violation of `guardrail-mcp-config-no-hardcoded-user` because
39+
Codex's MCP env-vars do not expand `%USERPROFILE%` (cmd.exe feature, not a Node.js
40+
process-env feature) NOR `~` (shell feature, not a Python expanduser feature at the
41+
env-var level). All other MATHIR scripts/files stay portable — only `~/.codex/config.toml`
42+
bears the hardcoded `C:\Users\princ` because there is no portable alternative for
43+
Codex MCP env vars on Windows.
44+
45+
## Action required from user
46+
Open a NEW Codex task to pick up the env change (Codex doesn't hot-reload MCP servers).
47+
Confirm by asking Codex to list MCP tools — should see 27 (mathir_dashboard etc.).
48+
49+
## Related
50+
- Codex binary: `C:\Users\princ\AppData\Local\OpenAI\Codex\bin\*\codex.exe`
51+
- Codex config: `C:\Users\princ\.codex\config.toml`
52+
- Codex hooks: `C:\Users\princ\.codex\hooks.json` (uses `python ...claude_code_hook.py`,
53+
works fine since path is absolute)
54+
- Pre-existing bak: `config.toml.mathir-bad-inject-20260730-2335.bak` (17784 bytes —
55+
earlier failed injection attempt — unrelated, keep as-is)
56+
- New backup made during this fix: `config.toml.bak.codex-mcp-fix-20260731`

0 commit comments

Comments
 (0)