AnyRouter Spawn Agent
by wendou-chen
README.md
# AnyRouter Spawn Agent
Observable `spawn_agent` MCP fallback for Codex sessions that use `anyrouter.top` or other API providers where Codex App native Sub Agents are unavailable.
## What This Is
Codex has two different subagent paths:
1. **Codex App native Sub Agent**: preferred when the current Codex runtime exposes native Sub Agent tools and App sidebar integration.
2. **This MCP fallback**: a local MCP server that launches registered agents through detached `codex exec` child processes, then exposes job status through MCP tools.
Use native Sub Agents first. Use this repository when native Sub Agents are hidden or unavailable, for example when a session is routed through `https://anyrouter.top/v1` and the App native Sub Agent tool is not exposed to the model.
This fallback is intentionally honest about its limits:
- It does **not** create App sidebar-visible native Sub Agents.
- It does **not** fake native Sub Agent success.
- It starts real local `codex exec` child processes.
- It can observe queued/running/completed/failed/timed_out/cancelled fallback jobs through MCP.
## Tools
The MCP server exposes:
| Tool | Use |
| --- | --- |
| `spawn_agent` | Legacy synchronous one-shot fallback. Best for short fixed-response checks. |
| `spawn_agent_start` | Start an observable fallback job and return `run_id` immediately. |
| `spawn_agent_status` | Check status, pid, thread id, last activity, output tails, and `possibly_stalled`. |
| `spawn_agent_result` | Fetch final answer and metadata when ready. |
| `spawn_agent_list` | List recent jobs in the current MCP server process. |
| `spawn_agent_cancel` | Cancel queued/running jobs. On Windows it tries `taskkill /T /F /PID` before `child.kill()`. |
| `spawn_agent_issue_record` | Record a redacted diagnostic note/bug for later MCP improvement. |
| `spawn_agent_issue_list` | List recent diagnostic issues from the persistent journal. |
| `spawn_agent_issue_report` | Build a Markdown report from recent diagnostic issues. |
`possibly_stalled` becomes true after five minutes without stdout/stderr activity. It is a warning, not automatic failure.
## Diagnostic Journal
The MCP fallback now has a small persistent diagnostic journal for problems discovered while using fallback jobs.
Default location:
```text
$CODEX_HOME/spawn-agent-logs/issues.jsonl
$CODEX_HOME/spawn-agent-logs/events.jsonl
```
Set `SPAWN_AGENT_LOG_DIR` to place the journal somewhere else.
The journal is intentionally redacted by default. It stores metadata and short previews such as `run_id`, `agent_type`, `status`, `tool`, `error`, `timeout_ms`, `idle_ms`, and `message_preview`. It does not copy full parent prompts, final answers, stdout tails, or stderr tails unless a caller explicitly writes a short note.
Launch accounting is also written to `events.jsonl`. Every fallback subagent launch records a `fallback_launch_recorded` event:
- Observable `spawn_agent_start` launches record their real `run_id`.
- Legacy synchronous `spawn_agent` launches record `run_id: "legacy/no_run_id"` and keep the old response shape.
- The counter is derived from the persistent event journal, so it can survive MCP server restarts as long as the log files remain.
Every 20 fallback launches, `spawn_agent_start` returns `journal_review_due: true` plus `journal_review_recommended_tool: "spawn_agent_issue_report"` in `structuredContent`, and the response text includes `journal review due`. The main Agent should then inspect the issue journal and tell the human what recurring MCP issues were found and what changes are recommended.
## Tool Exposure Diagnostics
There are two different checks:
- Direct MCP `tools/list`: proves the local MCP server schema exposes tools.
- Active model tool surface: proves the current Codex session can actually call those tools.
The first can pass while the second fails. Codex may defer MCP tools behind tool search, a session may not have reloaded config, or the active provider/app surface may filter tools. For observable fallback work, the main Agent must see `spawn_agent_start`, `spawn_agent_status`, and `spawn_agent_result`, or prefixed names such as `mcp__spawn_agent__spawn_agent_start`.
If those tools are missing from the active model surface, do not silently downgrade long or parallel work to unobservable shell-launched `codex exec`. Run the diagnostic writer from the target project root:
```powershell
node "$env:USERPROFILE\.codex\skills\spawn-agent\scripts\diagnose_tool_exposure.js" --visible-tools <comma-separated-visible-tools> --write-issue --write-report
```
This records a redacted issue and writes `development/tool-exposure-diagnostic-report.md` for later MCP development.
After reporting to the human, the main Agent should persist the same redacted findings into this repository's development directory. Use the report writer script:
```powershell
node "$env:USERPROFILE\.codex\skills\spawn-agent\scripts\write_development_report.js" --limit 20 --output spawn-agent-diagnostic-report.md
```
The default output is:
```text
development/spawn-agent-diagnostic-report.md
```
The script can also write main-agent-authored Markdown from stdin:
```powershell
@'
# Spawn Agent Development Report
## Findings
- ...
## Recommended Changes
- ...
'@ | node "$env:USERPROFILE\.codex\skills\spawn-agent\scripts\write_development_report.js" --stdin-only --output journal-review.md
```
For safety, output paths must stay inside `development/` and must end in `.md`. The script redacts common bearer tokens, `sk-...` keys, GitHub PATs, and `token/api_key/password` assignments before writing.
Issues are recorded automatically for:
- `failed`, `timed_out`, and `cancelled` jobs.
- First observation of `possibly_stalled` for a run.
- Missing `run_id` lookups.
- Tool argument errors and unknown tool calls.
Use `spawn_agent_issue_record` manually when a fallback job behaved strangely but did not fail mechanically, for example partial research, unclear timeout behavior, missing capability, bad agent instructions, or a recurring workflow problem.
Example manual issue:
```json
{
"event": "manual_note",
"severity": "warning",
"title": "docs_researcher returned partial source list",
"run_id": "run_000004",
"agent_type": "docs_researcher",
"status": "timed_out",
"notes": "Retry with a narrower source request or longer timeout."
}
```
## Repository Layout
```text
agent-mcp/
spawn_agent_server.js
spawn_agent_server.test.js
agents/
explorer.toml
reviewer.toml
docs-researcher.toml
conversation-analyzer.toml
agent-evaluator.toml
spec-miner.toml
skills/
spawn-agent/
spawn-agent-observer/
examples/
config.spawn-agent.toml
AGENTS.spawn-agent.md
```
## Install
Clone the repo:
```powershell
git clone git@github.com:wendou-chen/anyrouter-spawn-agent.git
cd anyrouter-spawn-agent
```
Copy the files into your Codex home:
```powershell
$codexHome = "$env:USERPROFILE\.codex"
New-Item -ItemType Directory -Force -Path "$codexHome\agent-mcp", "$codexHome\agents", "$codexHome\skills" | Out-Null
Copy-Item -Recurse -Force .\agent-mcp\* "$codexHome\agent-mcp\"
Copy-Item -Recurse -Force .\agents\* "$codexHome\agents\"
Copy-Item -Recurse -Force .\skills\spawn-agent "$codexHome\skills\spawn-agent"
Copy-Item -Recurse -Force .\skills\spawn-agent-observer "$codexHome\skills\spawn-agent-observer"
```
Add the snippets from `examples/config.spawn-agent.toml` to `C:\Users\<you>\.codex\config.toml`, adjusting absolute paths if needed.
Add the rules from `examples/AGENTS.spawn-agent.md` to your global `C:\Users\<you>\.codex\AGENTS.md` or to a project-local `AGENTS.md`.
Restart Codex App or reload the session so MCP tools and skills are rediscovered.
## Agent Selection Rule
Use this decision flow:
1. Try Codex App native Sub Agent tools when they are visible and supported.
2. If native Sub Agents are unavailable, hidden by provider/API mode, or cannot be verified, use the MCP fallback tools from this repository.
3. For long-running, exploratory, research, review, or parallel work, use `spawn_agent_start` and keep the returned `run_id`.
4. Use `spawn_agent_status` while the job runs and `spawn_agent_result` when it completes.
5. Use legacy `spawn_agent` only for short one-shot requests where progress does not matter.
6. If the fallback mechanism misbehaves or produces a partial/failed result worth improving, call `spawn_agent_issue_record` or include the automatic issue in a `spawn_agent_issue_report`.
7. When a launch response says `journal_review_due: true`, call `spawn_agent_issue_report` and report the issue summary plus recommended fixes to the human.
8. Persist the same review findings with `node "$env:USERPROFILE\.codex\skills\spawn-agent\scripts\write_development_report.js" --stdin-only --output <name>.md` from the target project root so future MCP development inside that repository can read the Markdown report. In this repository, `npm run report:issues` is a no-argument shortcut.
9. If observable MCP tools are absent from the active model tool surface, run `diagnose_tool_exposure.js`, report the diagnosis, and stop unless the human explicitly accepts unobservable fallback.
## Example
Start an observable explorer job:
```json
{
"agent_type": "explorer",
"message": "Inspect the current configuration. Do not edit files.",
"timeout_ms": 900000
}
```
Then poll:
```json
{ "run_id": "run_000001" }
```
Report status from observed state, for example:
```text
explorer run_000001: running, pid 1234, thread_id pending, last activity 42s ago, not stalled.
docs_researcher run_000002: completed, thread_id 019..., result ready.
```
## Verify
Run the unit tests:
```powershell
npm test
```
Check the server schema directly:
```powershell
$messages = @(
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05"}}',
'{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
)
$messages | node .\agent-mcp\spawn_agent_server.js
```
Expected tools:
```text
spawn_agent
spawn_agent_start
spawn_agent_status
spawn_agent_result
spawn_agent_list
spawn_agent_cancel
spawn_agent_issue_record
spawn_agent_issue_list
spawn_agent_issue_report
```
## Notes
- Job state is in-memory only. If the MCP server restarts, historical `run_id` state is lost.
- Child timeouts default to 15 minutes and are capped at 30 minutes.
- Registered agents live in `[agents.*]` entries in `config.toml`; each `config_file` must stay inside `CODEX_HOME`.
- On API-key `codex exec` sessions, external MCP tools may not be available to the child. Put all required context in `message`.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues