codex_start
Initiate a background codex task and receive an immediate job ID to track progress without blocking or timeout.
Instructions
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.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | Yes | The task description to pass to codex. | |
| cwd | Yes | Absolute path to the working directory for codex. | |
| approval_policy | No | One of 'suggest', 'auto-edit', 'full-auto'. Default: 'suggest'. | suggest |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/codex_async_mcp/server.py:9-21 (handler)The MCP tool handler function for 'codex_start'. Decorated with @mcp.tool(), accepts prompt, cwd, and optional approval_policy, and delegates to start_job().
def codex_start(prompt: str, cwd: str, approval_policy: str = "suggest") -> dict: """ 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. Args: prompt: The task description to pass to codex. cwd: Absolute path to the working directory for codex. approval_policy: One of 'suggest', 'auto-edit', 'full-auto'. Default: 'suggest'. """ return start_job(prompt, cwd, approval_policy) - src/codex_async_mcp/server.py:8-8 (registration)Registration of the tool via the @mcp.tool() decorator on the codex_start function.
@mcp.tool() - The start_job() helper function that implements the actual logic: creates a job_id, spawns a subprocess, writes metadata, and returns the job_id/status.
def start_job(prompt: str, cwd: str, approval_policy: str = DEFAULT_APPROVAL_POLICY) -> dict: job_id = uuid.uuid4().hex[:8] job_dir = _job_dir(job_id) job_dir.mkdir(parents=True, exist_ok=True) output_path = job_dir / "output.txt" # Map legacy approval_policy values to codex exec flags (v0.125.0+) approval_flags = { "suggest": ["-s", "read-only"], "auto-edit": ["--full-auto"], "full-auto": ["--dangerously-bypass-approvals-and-sandbox"], } flags = approval_flags.get(approval_policy, ["--full-auto"]) cmd = [CODEX_BIN, "exec"] + flags + [prompt] with open(output_path, "w") as out_file: proc = subprocess.Popen( cmd, stdin=subprocess.DEVNULL, stdout=out_file, stderr=subprocess.STDOUT, cwd=cwd, ) meta = { "job_id": job_id, "status": "running", "prompt": prompt, "cwd": cwd, "approval_policy": approval_policy, "pid": proc.pid, "started_at": datetime.now(timezone.utc).isoformat(), "finished_at": None, "exit_code": None, } _write_meta(job_id, meta) with _lock: _active_procs[job_id] = proc t = threading.Thread(target=_monitor, args=(job_id, proc), daemon=True) t.start() return {"job_id": job_id, "status": "running", "pid": proc.pid} - src/codex_async_mcp/config.py:1-7 (schema)Configuration constants used by the tool, including JOBS_DIR, DEFAULT_APPROVAL_POLICY, CODEX_BIN, and limits.
from pathlib import Path JOBS_DIR = Path.home() / ".codex-async" / "jobs" DEFAULT_APPROVAL_POLICY = "suggest" CODEX_BIN = "codex" JOB_TAIL_LINES = 100 MAX_OUTPUT_CHARS = 8000