Skip to main content
Glama
codex-async-mcp

codex-async-mcp

by benzkittisak

agent-async-mcp

Local MCP server that runs Codex, Cursor, and Gemini CLI tasks asynchronously — returns a job_id immediately instead of blocking, so the orchestrating agent never hits the MCP 60-second timeout.

How it works

Claude (orchestrator)
  │
  ├─ codex_start(prompt, cwd)  →  job_id (instant)
  │
  └─ codex_wait(job_id)        →  blocks up to 50 s, returns result
                                   loop again on timeout

A sequential queue ensures only one agent process runs at a time. Jobs are persisted in SQLite so the queue survives server restarts.


Related MCP server: codex-mcp-bridge

Install

curl -fsSL https://raw.githubusercontent.com/benzkittisak/claude-codex-mcp/master/install.sh | bash

The installer will:

  • Clone this repo to ~/.local/share/agent-async-mcp/

  • Create an isolated Python venv

  • Symlink agent-async to ~/.local/bin/

  • Detect Claude Code, Codex, Cursor, Claude Desktop and ask which to register

Uninstall:

curl -fsSL https://raw.githubusercontent.com/benzkittisak/claude-codex-mcp/master/install.sh | bash -s uninstall
# or, if already installed:
agent-async uninstall

CLI

agent-async list-agents              # show detected / registered agents
agent-async add-agent claude-code    # register with Claude Code CLI
agent-async add-agent codex          # register with Codex CLI
agent-async add-agent cursor         # register with Cursor IDE
agent-async add-agent claude-desktop # register with Claude Desktop
agent-async remove-agent <agent>     # unregister
agent-async status                   # open real-time job monitor
agent-async update                   # pull latest + reinstall
agent-async check-update             # check without installing
agent-async enable-auto-update       # schedule daily auto-update (09:00)
agent-async disable-auto-update      # remove scheduled auto-update
agent-async uninstall                # remove everything

Requirements

  • Python 3.11+

  • One or more agent CLIs: codex, cursor, gemini (optional — only needed for the tools you use)

  • Claude Code CLI (recommended orchestrator)


MCP Tools (13 total)

Codex

Tool

Description

codex_start(prompt, cwd, approval_policy?, context_files?)

Queue a Codex task → returns job_id instantly

codex_wait(job_id, timeout_seconds=50)

Block until done; loop on {"status":"timeout"}

codex_await_any(timeout_seconds=50)

Block until ANY queued job completes

Cursor

Tool

Description

cursor_start(prompt, cwd, approval_policy?, context_files?)

Queue a Cursor headless task → job_id

cursor_wait(job_id, timeout_seconds=50)

Block until done

Gemini

Tool

Description

gemini_start(prompt, cwd, approval_policy?, context_files?)

Queue a Gemini CLI task → job_id

gemini_wait(job_id, timeout_seconds=50)

Block until done

gemini_confluence_start(title, cwd, ...)

Ask Gemini to draft/publish a Confluence page

gemini_pr_start(cwd, pr_goal, ...)

Ask Gemini to draft/publish a PR

Shared / Queue

Tool

Description

job_list(limit=20)

List recent jobs (all agents), newest first

job_cancel(job_id)

Cancel running or pending job

queue_status()

{"busy": bool, "pending_count": int}

agent_notify_done(job_id, summary?)

Called BY an agent to signal completion

approval_policy values

Value

Behavior

full-auto

No prompts, no sandbox (use for automation)

auto-edit

Auto-applies edits

suggest

Read-only — pauses for interactive input (avoid in automation)


Permissions (settings.local.json)

Add to your Claude Code project's .claude/settings.local.json:

{
  "permissions": {
    "allow": [
      "mcp__agent-async__codex_start",   "mcp__agent-async__codex_wait",
      "mcp__agent-async__cursor_start",  "mcp__agent-async__cursor_wait",
      "mcp__agent-async__gemini_start",  "mcp__agent-async__gemini_wait",
      "mcp__agent-async__queue_status",  "mcp__agent-async__job_list",
      "mcp__agent-async__job_cancel",    "mcp__agent-async__agent_notify_done",
      "mcp__agent-async__codex_await_any"
    ]
  }
}

Usage pattern

# Start a job (returns immediately)
result = codex_start(
    prompt="In app/services/foo.rb line 42, change X to Y. Do not change anything else.",
    cwd="/path/to/repo",
    approval_policy="full-auto"
)
job_id = result["job_id"]

# Wait in a loop (each call blocks up to 50 s)
while True:
    result = codex_wait(job_id, timeout_seconds=50)
    if result["status"] == "timeout":
        continue
    break  # "done" | "error" | "cancelled"

Job data

Jobs are persisted in ~/.agent-async/:

~/.agent-async/
  queue.db          ← SQLite: job metadata, status, token usage
  jobs/<job_id>/
    output.txt      ← stdout + stderr from the agent process

Troubleshooting

agent-async: command not found

~/.local/bin not in PATH. Run:

source ~/.zshrc   # or ~/.bashrc

Or open a new terminal. The installer adds it automatically.

status: "error" immediately after *_start

The agent CLI failed to start. Check output:

cat ~/.agent-async/jobs/<job_id>/output.txt

Message

Fix

command not found: codex

Install codex: npm install -g @openai/codex

command not found: gemini

Install gemini CLI from github.com/google-gemini/gemini-cli

permission denied

cwd doesn't exist or is inaccessible

status: "running" forever

The subprocess is hung. Most common cause: approval_policy="suggest" waiting for interactive input. Always use "full-auto" for automation.

agent-async status   # open monitor to see live state

Cancel a stuck job:

job_cancel(job_id="<job_id>")

Old jobs filling up disk

find ~/.agent-async/jobs -maxdepth 1 -type d -mtime +7 -exec rm -rf {} +

Project structure

agent-async-mcp/
├── install.sh
├── mcp-monitor.py
├── pyproject.toml
└── src/
    └── agent_async_mcp/
        ├── server.py       # MCP entry point, tool definitions
        ├── job_manager.py  # queue, spawn, wait, cancel
        ├── db.py           # SQLite schema + helpers
        ├── config.py       # paths, timeouts, agent binaries
        └── cli.py          # agent-async CLI

Development

git clone https://github.com/benzkittisak/claude-codex-mcp
cd claude-codex-mcp
pip install -e ".[dev]"
pytest tests/ -v

Available Tools

4 tools
codex_cancelA

Cancel a running codex job by sending SIGTERM to the subprocess.

Inputs: job_id (required). Returns: object

codex_listA

List recent codex jobs with their status and prompt summaries.

Inputs: limit. Returns: result

codex_pollA

Poll the status and output of a running (or finished) codex job.

Inputs: job_id (required), tail_lines. Returns: object

codex_startA

Start a codex task asynchronously in the background.

Returns a job_id immediately — does not block or timeout. Use codex_poll(job_id) to check progress.

Inputs: prompt (required), cwd (required), approval_policy. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.2/5.0

    Scored across 4 tools

    Disambiguation5/5

    Each tool has a distinct purpose: start, list, poll, and cancel. There is no overlap in functionality, and the descriptions clearly differentiate them.

    Naming Consistency5/5

    All tools follow a consistent 'codex_verb' pattern using snake_case, making it predictable for an agent to infer tool behavior from the name.

    Tool Count5/5

    Four tools cover the essential operations for managing async jobs (start, list, poll, cancel) without redundancy or missing critical actions.

    Completeness5/5

    The tool set covers the full lifecycle of an async job: initiating (start), monitoring (poll, list), and termination (cancel). No obvious gaps are present.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers