Codex DSH MCP
# Codex DSH MCP
> A cost-aware MCP bridge that lets Codex delegate routine, context-heavy work to DeepSeek Harness—while Codex keeps architecture, review, and final verification under control.
`Codex DSH MCP` runs each DeepSeek worker in an isolated Git worktree created from committed `HEAD`. It never applies changes to the main workspace automatically: Codex and the human reviewer receive a compact result, a Markdown report, and a patch to inspect first.
## Why use it?
- Offload repository exploration, routine implementation, refactors, tests, and ordinary fixes to DeepSeek.
- Keep high-risk architecture, security, final review, and acceptance with Codex.
- Retry an eligible non-timeout failure at most once; timeouts consume the total budget and escalate immediately.
- Track calls, duration, success rate, and clearly labeled estimated/reported token usage per project.
- Keep the main checkout protected: workers operate only in isolated worktrees.
## Quick start
1. Clone this repository and open its folder in Windows Explorer.
2. Double-click `install-windows.bat` (or run `install-windows.ps1` in PowerShell).
3. Merge `config.toml.example` into `%USERPROFILE%\.codex\config.toml` and update the bridge path.
4. Merge `AGENTS.md` into your global or project-level Codex instructions.
5. Restart Codex and confirm the `deepseek` MCP server exposes five tools.
## What it exposes
- `deepseek_explore` — read-only repository exploration/search.
- `deepseek_task` — normal implementation/refactor/test work in an isolated worktree.
- `deepseek_fix` — bug/failing-test diagnose-edit-test loop in an isolated worktree.
- `deepseek_review` — read-only focused review.
- `deepseek_stats` — read-only bridge statistics (totals, tool counts, success rate, average duration, last 10 task metadata).
## How routing works
`AGENTS.md` tells Codex to choose `DIRECT_CODEX` for small, critical, architectural, security-sensitive, destructive, or already-escalated work. It chooses `DELEGATE_DEEPSEEK` for broad exploration and routine work—especially when more than about three files must be read, more than about two files changed, or an edit/test/fix loop is likely. Codex does not scan the repository first just to make this choice.
```text
User
↓
Codex Router
├── Small / Critical ──→ Codex
│
└── Delegatable
↓
DeepSeek
↓
┌─────┴─────┐
Success Failure
↓ ↓
Review Retry once
↓
Failure again
↓
Codex
```
The retry is a focused bug-fix attempt using the same task ID. It is available only for eligible non-timeout failures and only while total time remains. A timeout or second failure returns `ESCALATED_TO_CODEX`; Codex takes over.
## Long-running delegations
Codex estimates a duration range before launching DSH work:
- Up to 10 minutes: use the synchronous MCP tools and keep the task in the current turn.
- More than 10 minutes, or an estimate that crosses 10 minutes: start the isolated DSH batch in detached mode, record its run directory and expected completion window, then check status near the estimated time instead of continuously waiting.
Long runs are status-first: unchanged state does not trigger repeated log reads or chat updates. Reports, patches, and detailed logs are reviewed only at completion, failure, staleness, or a meaningful checkpoint. This preserves Codex context while retaining the same isolation, one-retry, and human-review guarantees.
The bundled controller enforces the deadline itself, emits 15-second heartbeats, terminates timed-out worker process trees, and finalizes `status.json` plus Markdown reports before returning. `status` also reconciles legacy `running` records when their heartbeat and processes are stale. Headless launches sharing one `DSH_HOME` are serialized across runs to avoid profile-startup races; Windows batches are additionally clamped to one active worker.
## Requirements
- Windows 10/11 (the bridge also has a POSIX path).
- Node.js 20+.
- Codex with MCP support.
- DeepSeek Harness available as `dsh` and already configured/authenticated for the DeepSeek model/service you intend to use.
## Install on Windows
Open PowerShell in this folder:
```powershell
Set-ExecutionPolicy -Scope Process Bypass
.\install-windows.ps1
```
Or double-click `install-windows.bat`; it is a thin Windows wrapper around the same installer. The installer also updates the bundled `dsh-batch-subagents` skill under `%USERPROFILE%\.codex\skills`.
Then verify DeepSeek Harness independently before involving Codex:
```powershell
dsh --profile headless "Reply with exactly READY"
```
If that does not work, fix `dsh` first. The MCP bridge intentionally does not manage DeepSeek credentials itself.
## Configure Codex
Merge `config.toml.example` into `%USERPROFILE%\.codex\config.toml`, and replace the example path:
```toml
[mcp_servers.deepseek]
command = "node"
args = ["C:/tools/codex-deepseek-bridge/src/index.mjs"]
startup_timeout_sec = 20
tool_timeout_sec = 7200
[mcp_servers.deepseek.env]
DSH_BATCH_CONTROLLER = "C:/Users/Administrator/.codex/skills/dsh-batch-subagents/scripts/dsh-batch-agents.mjs"
DSH_COMMAND = "dsh"
DSH_TIMEOUT_MS = "1800000"
DSH_MAX_OUTPUT_CHARS = "6000"
DSH_AUTO_RETRY = "true"
DSH_MAX_RETRIES = "1"
DSH_STATS_ENABLED = "true"
DSH_TOKEN_STATS = "true"
DEEPSEEK_ALLOWED_ROOT = "D:/Projects"
```
Restart Codex. In Codex TUI, `/mcp` should show the `deepseek` MCP server and five tools.
## Install the delegation prompt
For one repository, put `AGENTS.md` at the repository root (or merge the DeepSeek delegation section into an existing `AGENTS.md`).
For a global personal policy, merge the contents into `%USERPROFILE%\.codex\AGENTS.md`. Project-specific instructions can still override it.
## Suggested first test
In a disposable Git repository, ask Codex:
> Find where the CLI arguments are parsed. Use DeepSeek for repository exploration and report the relevant files. Do not modify anything.
Then try a harmless write task:
> Add a small unit test for an existing pure helper. Delegate the implementation to DeepSeek, then inspect the diff and run the focused test yourself before reporting success.
Then verify stats:
> Run deepseek_stats to check bridge usage and token savings.
## Environment variables
### Core
| Variable | Description | Default |
|---|---|---|
| `DSH_BATCH_CONTROLLER` | Absolute path to the isolated-worktree controller | _(required)_ |
| `DSH_COMMAND` | `dsh`, or an absolute DSH JavaScript launcher module passed safely to the controller | `dsh` |
| `DSH_TIMEOUT_MS` | Total wall-clock budget for one delegation, including any retry; clamped 10 s – 2 h | `1800000` (30 min) |
| `DSH_MAX_OUTPUT_CHARS` | Max chars returned to Codex context | `6000` |
| `DEEPSEEK_ALLOWED_ROOT` | Optional root; restricts which directories DeepSeek can access | _(none)_ |
### Auto-retry
| Variable | Description | Default |
|---|---|---|
| `DSH_AUTO_RETRY` | Whether to auto-retry eligible non-timeout failures while budget remains | `true` |
| `DSH_MAX_RETRIES` | Max focused retries; a timeout is never retried automatically | `1` |
### Statistics
| Variable | Description | Default |
|---|---|---|
| `DSH_STATS_ENABLED` | Enable stats persistence | `true` |
| `DSH_STATS_FILE` | Path to stats file; absolute or relative to workspace | `.codex-deepseek/stats.json` |
| `DSH_TOKEN_STATS` | Enable token usage tracking | `true` |
## Result format
Every delegation tool returns a compact structured JSON object with:
| Field | Description |
|---|---|
| `status` | `success`, `failed`, or `escalated_to_codex` |
| `tool` | The tool name (e.g. `deepseek_task`) |
| `task_id` | Unique ID: `ds_YYYYMMDD_shortid` |
| `attempt` | Current attempt number |
| `attempts` | Actual number of attempts completed |
| `max_attempts` | Configured maximum (initial + retries) |
| `duration_ms` | Wall-clock duration of this attempt |
| `exit_code` | Exit code from the batch controller |
| `changed_files` | Array of file paths that were changed |
| `tests` | `{ ran, passed, summary }` |
| `usage` | Token usage with `source` (`reported`/`estimated`) and `estimated` boolean |
| `summary` | Short description of what was done |
| `artifact_paths` | `{ run_dir, report, patch }` |
| `failure_type` | `timeout`, `controller_error`, `malformed_output`, `unable_to_complete`, `test_failure`, `no_changes`, or `null` |
| `retry_recommended` | Whether this failure type qualifies for retry |
| `will_retry` | Whether another attempt will actually run under the configured limit |
| `escalated` | Boolean; `true` when all attempts exhausted |
| `escalation_marker` | `"ESCALATED_TO_CODEX"` when exhausted |
### Escalation flow
```
Tool call → attempt 1 (eligible non-timeout failure) → one retry within the original budget → failure → escalated_to_codex
Tool call → timeout → controller finalizes artifacts → escalated_to_codex (no retry)
```
When a delegation returns `status: "escalated_to_codex"`, Codex should investigate the root cause and decide on next steps. The bridge **never** calls the Codex API.
## Token Statistics
Token usage is parsed from DeepSeek/Harness output when a usage JSON block is available (`source: "reported"`, `estimated: false`). Otherwise, it is approximated from prompt/result character counts at about one token per four characters (`source: "estimated"`, `estimated: true`). Reported usage is provider data; estimated usage is only a fallback approximation.
The project-level `.codex-deepseek/stats.json` records bounded metadata for at most 100 attempts and is written through a temporary file followed by rename. It never stores the complete task Prompt, result summary, diff, changed-file paths, or artifact paths. `deepseek_stats` returns totals, success rate, average duration, per-tool counts, and the most recent 10 metadata entries.
`estimated_codex_tokens_avoided` uses the amount of context handled by DeepSeek as a rough proxy for context Codex did not have to process. It is always marked `estimate_only: true`. It is **not** an OpenAI or Codex quota measurement and should be used only to judge whether delegation is directionally worthwhile.
## Security model
`deepseek_task` and `deepseek_fix` allow DeepSeek Harness to edit only an isolated Git worktree. Reports and patches are kept outside the repository for Codex and human review. Nothing is merged or applied automatically.
`deepseek_explore` and `deepseek_review` also run in isolated worktrees. Their read-only behavior remains a prompt-level policy, but accidental writes cannot touch the main workspace.
`deepseek_stats` is read-only and accesses only the stats file.
## Why this saves Codex usage
The expensive loop is usually repository search → many file reads → implementation → tests → failure analysis → retry. The bridge moves that loop into a separate DeepSeek Harness session. Only DeepSeek's compact structured result returns to Codex; Codex can then inspect the resulting diff and perform targeted verification.
## Author
Created and maintained by [@sakurameishi](https://github.com/sakurameishi).
## License
[MIT](LICENSE) © 2026 sakurameishi.
TDQS
Scored across 5 tools
Each tool has a clearly distinct purpose: task delegation, bug fixing, exploration, review, and statistics. The descriptions explicitly differentiate read-only operations and the action types, leaving no ambiguity.
All tools follow the identical `deepseek_` prefix with a verb indicating the action (task, fix, explore, review, stats). This consistent pattern makes the API predictable and easy to navigate.
With only 5 tools, the set is tightly scoped to the core operations of the DeepSeek Harness bridge. Each tool serves a distinct necessary function without redundancy or bloat.
The tools cover the primary workflows (delegation, fixing, exploration, review, and stats). A minor gap is the lack of explicit task status or cancellation tools, though the stats tool implicitly provides an overview. The surface is otherwise well-rounded.