cc-as-subagent
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@cc-as-subagentreview the changes in C:\code\project-a and list any bugs"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
cc-as-subagent
An MCP server that exposes the local Claude Code CLI as a subagent, for Codex to delegate review and implementation work to.
Read this first
This server is a hole in your caller's policy, by construction. Codex's sandbox and approval settings do not govern MCP servers, and they do not govern anything an MCP server goes on to spawn. Approving this server means approving a path that runs
claudewith a policy you chose here, not one Codex chose.On native Windows there is no sandbox underneath it. Claude Code's
sandbox.enabledcovers macOS, Linux and WSL2 only. What confines a run here is a fixed permission tier plus the CLI's fail-closed behaviour when nothing can answer a prompt — not an OS boundary. A confused model is blunted; a hostile workspace is not defeated. See SECURITY.md.Set
default_tools_approval_mode = "prompt"in your Codex config (see examples/codex-config.toml). It is the only human checkpoint anywhere on this path, and it is off by default.
Related MCP server: Hydra
What it does
Submits a task to claude in a workspace and returns a job handle immediately.
The run continues in the background; you poll for the result. Submitting never
blocks, because a real review takes minutes and Codex's default tool timeout is
60 seconds.
Two permission tiers, chosen by the server — the caller names a tier, never a CLI flag:
Tier | Tools | Permission mode | Can |
|
|
| read and search; nothing that needs approval |
|
|
| edit files in the workspace, plus a small set of filesystem commands |
execute is narrower than it sounds. In a non-interactive run with nobody to
answer a prompt, anything that would ask is denied — so npm test,
git commit, cargo build and docker all fail. Only file edits and
mkdir/touch/mv/cp/sed inside the workspace proceed without asking.
Requirements
Node 18+ (developed on 24)
Claude Code CLI on
PATH, logged inClaude Code 2.1.227 or later; verified against 2.1.283.
--restricted(2.1.248+) is opt-in and off by default, viaCC_AS_SUBAGENT_RESTRICTED=1. It confines the built-in file tools to the working directory and loads only managed settings plus--settings— but that last part is also why it is off: it excludes user settings, so it breaks authentication wherever credentials come from there, and a sanitized environment has no fallback. Measured on 2.1.283: full environment works, sanitized environment fails withNot logged in. Turn it on only if your credentials come from the environment and you pass them through — see SECURITY.md.
Install
npm install
npm run build
node scripts/selfcheck.mjs # verifies the security assumptions against your CLI
npm run probe # optional: MCP handshake smoke testConfigure Codex
Add the server to ~/.codex/config.toml — a working example is in
examples/codex-config.toml.
[mcp_servers.cc-as-subagent]
command = "node"
args = ["<abs path>/cc-as-subagent/dist/index.js"]
default_tools_approval_mode = "prompt"
[mcp_servers.cc-as-subagent.env]
CC_AS_SUBAGENT_WORKSPACE_ROOTS = "C:\\code\\project-a;C:\\code\\project-b"default_tools_approval_mode = "prompt" makes Codex ask a human before each
call. Without it nothing on this path asks anyone.
Tools
Tool | Arguments | Returns |
|
|
|
|
|
|
|
| a new |
|
|
|
claude_reply takes a job id, never a session id. The session id stays
server-side, because --resume also accepts a path to a transcript file and a
caller-controlled value there would be a file-read primitive.
Poll with the cursor from the previous response to get only new events. If
the log was compacted while you were away, the response carries cursorResetTo
instead of silently skipping.
Configuration
Variable | Default | Purpose |
| the server's own cwd | Path-delimiter-separated allowlist. A workspace outside every root is refused. |
|
| Where job state lives. Deliberately outside any workspace. |
| (none) | Comma-separated variable names to pass to |
| off | Set to |
| off | Set to |
| resolved from | Pin an exact CLI build. |
Verified behaviour
npm test — 53 unit tests. node scripts/e2e.mjs — 13 checks against a real
CLI, including that a resumed turn still carries the isolation stack, that
consult can read a workspace while being granted no write tool, and that the
execute session is granted exactly its six tools — the CLI adds GetTask
to a Bash-capable session uninvited, so it is denied by name.
node scripts/selfcheck.mjs re-runs the security assumptions against whatever
CLI is installed and writes a verdict to the state directory. Re-run it after a
CLI upgrade.
Known limitations
Stated plainly rather than buried — see SECURITY.md for the full list and the reasoning.
No OS sandbox on Windows. The confinement is a permission tier plus fail-closed denial.
Command deny rules are not a security boundary. The CLI's own documentation says so. They blunt a confused model; they do not stop a deliberately crafted one.
Reads inside the workspace are unrestricted. Credentials sitting in a project directory are readable unless named in the deny list.
A workspace the user once trusted interactively carries its own
permissions.allowinto these runs.consultsessions are transcript-persisted unless you pass--no-session-persistence, which would also make them unresumable.
License
MIT — see LICENSE.
Available Tools
5 toolsclaude_cancelCancel a jobAIdempotent
Stop a running job and the process tree it started.
| Name | Required | Description | Default |
|---|---|---|---|
| jobId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate this is a mutating (readOnlyHint=false) and idempotent (idempotentHint=true) operation. The description adds meaningful behavioral detail beyond annotations by stating that the entire process tree started by the job is stopped, not just the job itself.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler. Every word adds value: 'Stop' states the action, 'running job' states the target, and 'process tree it started' states the scope.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter tool with no output schema, the description covers the essential behavior and side effect. It does not explain return values or error cases, but the idempotent annotation and simple schema make this acceptable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not mention jobId at all. While the parameter name is self-explanatory, the description provides no guidance on where to obtain the jobId, its format, or how it relates to the cancellation action, so it fails to compensate for the missing schema documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Stop') and a clear resource ('a running job'), and adds the precise scope 'the process tree it started.' This distinguishes it from siblings like claude_run (starting), claude_status (checking), and claude_reply (responding).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Stop a running job' provides clear context for when the tool should be used: when a job is actively running and needs to be terminated. It does not explicitly name alternatives or exclusions, but the running-job condition is a clear usage signal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
claude_replyContinue a sessionA
Start a follow-up turn in an existing session. Takes the jobId of a finished job — the session id stays server-side. Returns a new jobId for the follow-up.
| Name | Required | Description | Default |
|---|---|---|---|
| jobId | Yes | A finished job whose session to continue. | |
| model | No | ||
| effort | No | ||
| prompt | Yes | ||
| waitSeconds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false and idempotentHint=false, so the description doesn't need to repeat that. It adds useful context: the session id stays server-side (so the agent only needs jobId) and that the job must be finished. It also clarifies the return value (new jobId). No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core purpose. It includes the key input (jobId) and output (new jobId) without unnecessary verbosity. Every word adds value, and it is well-structured for quick scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has 5 parameters and no output schema, yet the description explains only the core flow. It omits guidance on optional parameters (model, effort, waitSeconds) and does not describe how to use the returned jobId (e.g., poll status). An agent would need to infer or look elsewhere for critical details, making it incomplete for reliable invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 20% (only jobId has a description). The tool description only mentions jobId and the return value, but does not explain prompt, model, effort, or waitSeconds. With such low schema coverage, the description must compensate, but it fails to clarify the purpose or constraints of the other parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: 'Start a follow-up turn in an existing session.' It specifies the resource (existing session via a finished job's jobId) and the outcome (returns a new jobId). It distinguishes itself from likely siblings like claude_run (which would start a new session) by emphasizing 'follow-up turn' and 'existing session.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear context: it takes the jobId of a finished job, implying it is for continuing completed work. However, it does not explicitly mention alternative tools or conditions for when not to use it. The guidance is sufficient for an agent to infer the appropriate scenario, but lacks explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
claude_runRun Claude CodeA
Start a new Claude Code session in a workspace. Returns a jobId immediately; the run continues in the background. Use claude_status to poll for the result. Tier "consult" is read-only; "execute" may edit files in the workspace.
| Name | Required | Description | Default |
|---|---|---|---|
| tier | Yes | Permission tier for the run. | |
| model | No | Model alias or full name; defaults to the CLI's. | |
| effort | No | Reasoning effort. | |
| prompt | Yes | The task for the subagent. | |
| maxTurns | No | ||
| workspace | Yes | Absolute path to an allowed workspace directory. | |
| waitSeconds | No | Block up to this long for the first result instead of returning at once. | |
| maxBudgetUsd | No | Spend ceiling for the run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey readOnlyHint=false, openWorldHint=true, and idempotentHint=false. The description adds valuable context beyond that: the asynchronous job/background behavior, the immediate jobId return, and the file-editing risk of the execute tier. It could further mention cancellation semantics, but it is not misleading and genuinely informs behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no wasted words. It front-loads the core operational fact (returns jobId, runs in background), states the polling dependency, and gives tier-based safety guidance. A slight improvement would be naming claude_cancel, but the current length is appropriate.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 8 parameters and no output schema, the description covers the most decision-critical context: async behavior, how to retrieve results, and the read-only vs mutation distinction. It does not describe cancellation via claude_cancel or error/timeout behavior, but the core invocation workflow is clearly captured.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 88% schema coverage, the schema already documents most parameters. The description adds meaning for the tier parameter by explicitly mapping 'consult' to read-only and 'execute' to potential file edits. It does not add details for model, effort, maxTurns, waitSeconds, or maxBudgetUsd, but the schema already handles those adequately.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies the tool with a specific verb ('Start a new Claude Code session'), names the workspace resource, and distinguishes it from siblings by explaining the jobId return value and background execution. It also explains the two tiers, which clarifies what the tool actually does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly directs the agent to use claude_status to poll for results, and it states when each tier is appropriate: 'consult' is read-only while 'execute' may edit files. This provides clear decision-making context relative to sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
claude_statusCheck a jobARead-onlyIdempotent
Poll a job for progress and its result. Pass the cursor from the previous call to receive only new events. Returns the final answer once the run completes.
| Name | Required | Description | Default |
|---|---|---|---|
| jobId | Yes | ||
| cursor | No | Last event sequence number seen. | |
| waitSeconds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds valuable behavioral context: it returns only new events when a cursor is passed, and it returns the final answer once the run completes. This goes beyond the annotations by explaining the incremental polling behavior and completion semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: the first states the core purpose, the second explains the cursor behavior, the third states the completion behavior. No fluff, no repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a polling tool with readOnly and idempotent annotations, the description covers the essential behavior: progress, result, incremental events, and final answer. It doesn't describe error cases or what happens on timeout, but the waitSeconds parameter and the polling pattern make those less critical. The lack of an output schema means the description could have said more about the return shape, but the core usage is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 33% (only cursor has a description). The description explains the cursor parameter's purpose ('Pass the cursor from the previous call to receive only new events'), which adds meaning. However, jobId and waitSeconds are not described in the schema or the description, so the agent must infer their semantics from names and constraints. The description partially compensates but doesn't fully cover the gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool polls a job for progress and result, with a specific verb ('Poll') and resource ('a job'). It distinguishes itself from siblings like claude_run (which presumably starts a job) and claude_cancel (which cancels one). The title 'Check a job' reinforces the purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains the polling mechanism and how to use the cursor for incremental updates, which implies the usage context (polling after starting a job). It doesn't explicitly name alternatives or state when not to use it, but the sibling list and the polling semantics make the usage clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pingPingARead-onlyIdempotent
Liveness check. Reports the server version and the workspace roots it will accept. Never spawns Claude Code.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds valuable behavioral context beyond these: it states the tool reports server version and workspace roots, and explicitly guarantees 'Never spawns Claude Code,' which is a meaningful side-effect disclosure absent from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, each earning its place: the first states the purpose, the second states the output and the key safety guarantee. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless, read-only, idempotent liveness check, the description fully covers what an agent needs: what it does, what it reports, and the crucial negative behavior (never spawns Claude Code). No output schema exists, but the described output is sufficient for a tool of this simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and schema coverage is 100%, so there is nothing for the description to clarify about parameters. The baseline of 4 applies because with no parameters, no additional parameter semantics are needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as a 'Liveness check' that reports server version and accepted workspace roots, giving a specific function and output. It is distinct from the claude_* siblings, though it does not explicitly name them or contrast with them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied: it is the tool to call for a liveness/status check, especially distinguished from claude_* tools that presumably run or manage Claude Code processes. However, there is no explicit 'when to use vs alternatives' guidance or exclusionary statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
claude_cancel - First observed
claude_reply - First observed
claude_run - First observed
claude_status - First observed
ping
TDQS
Scored across 5 tools
The tools are mostly distinct: ping is a liveness check, claude_run starts a job, claude_status polls it, claude_cancel stops it, and claude_reply continues a finished job. The only mild ambiguity is between claude_run and claude_reply, since both start work in a session, but the descriptions clarify that reply is specifically for follow-up turns on an existing session.
All tools use the claude_ prefix with a clear verb: cancel, ping, run, status, reply. This is a consistent and predictable pattern. The minor deviation is that ping is a noun/verb that doesn't fit the job lifecycle as directly as the others, but it is still clearly named.
Five tools is well-scoped for a subagent orchestration server: start, poll, cancel, reply, and health check. Each tool earns its place and there is no bloat.
The core lifecycle of running and managing a Claude Code session is covered: start, poll, cancel, and follow-up. A minor gap is the lack of a way to list active jobs or sessions, which could be useful for recovery, but agents can work around it by tracking jobIds.
Maintenance
Related MCP Connectors
No-data MCP handoff for local Claude Code to Codex harness moves. $49 lifetime.
Build and supervise fleets of agents from Claude Code, Codex or Cursor. Connects over OAuth.
A paid remote MCP for OpenAI Codex agent coordination MCP, built to return verdicts, receipts, usage
Source-checked CLI guides and model-aware planning for Claude Code, Codex, and Grok Build.
Related MCP Servers
- AlicenseCqualityFmaintenanceConnects AI assistants like Claude to the Codex CLI for code analysis, editing, and execution. Supports file references with @ syntax, sandboxed code execution with approval workflows, and structured code changes for automated refactoring and documentation.841 npm179MIT
- AlicenseNot gradedqualityBmaintenanceEnables Codex to delegate bounded engineering jobs to Claude Code CLI in isolated Git worktrees with strict security and allowance pacing.MIT
- AlicenseNot gradedqualityAmaintenanceLets Codex delegate coding and repository work to an installed Claude Code CLI with permission-aware inspect/write access, model and effort selection, resumable and cloud-attached sessions, and durable synchronous or asynchronous jobs.MIT
- AlicenseNot gradedqualityBmaintenanceEnables Claude Code to delegate bounded, read-only analysis and isolated patch proposals to the locally installed Codex CLI over MCP, with sanitized live status, revision-aware polling, and reviewable results.1MIT