Skip to main content
Glama

qoder-as-subagent

An MCP server that exposes the local Qoder CN CLI (qoderclicn) as a subagent, for Codex to delegate review and implementation work to.

Built by copying cc-as-subagent and adapting it — the two CLIs share most of their command surface, so the architecture carried over. What did not carry over is isolation, and this server is weaker than the Claude Code one. Read the next two sections before using it.

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.

This CLI is missing three of the controls the other one has. Compared with cc-as-subagent:

Claude Code

Qoder CN

settings isolation (--setting-sources=user)

✓ measured working

✓ present, unverified here

MCP exclusion (--strict-mcp-config)

✓

✓

tool restriction (--tools / --disallowed-tools)

✓

✓

drop AGENTS.md / skills / plugins / hooks (--safe-mode)

✓

✗ no equivalent

turn ceiling (--max-turns)

✓

✗ does not exist

spend ceiling (--max-budget-usd)

✓

✗ does not exist

So: a workspace's AGENTS.md, skills, plugins and hooks load, and a run has no built-in ceiling on turns or cost. The server's timeout is the only bound. See SECURITY.md.

There is no OS-level sandbox underneath this on Windows.

Set default_tools_approval_mode = "prompt" in your Codex config (see examples/codex-config.toml). It is the only human checkpoint on this path, and it is off by default.

Related MCP server: Claude Code Bridge

What it does

Submits a task to qoderclicn 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

consult

Read, Grep, Glob

dont_ask

read and search; nothing that needs approval

execute

+ Edit, Write, Bash

auto

work inside the workspace, with a classifier reviewing anything risky

auto is what makes execute useful, and it is a classifier-backed mode, not a blanket approval. Nothing prompts; work inside the workspace proceeds; and an action that goes out of scope is handed to a reviewing model, which either allows it or blocks it with a stated reason. A write outside the workspace, for instance, comes back blocked as "Auto mode: action blocked by classifier — restricting file modifications to the workspace or explicitly trusted paths".

The layering is what makes this safe enough to default to: --tools decides which tools exist, --settings deny rules are deterministic and are evaluated first, and the classifier only sees what survives both. Measured — a denied command reports tool_denial_kind: "permission-rule", not "classifier".

consult stays on dont_ask and therefore fails closed: it is for reading, and it does not get the classifier.

Requirements

  • Node 18+ (developed on 24)

  • Qoder CN CLI installed and signed in. Verified against qoderclicn 1.1.64. Resolution order is QODER_BIN → PATH → ~/.qoder-cn/bin/qoderclicn/. The install path matters: qodercn on PATH is the IDE's launcher (qoder-cn.exe, which answers --diff and --install-extension), not this program, and resolving by name alone would run the wrong thing.

Install

npm install
npm run build
node scripts/selfcheck.mjs   # checks the assumptions against your CLI
npm run probe                # optional: MCP handshake smoke test

Configure Codex

Add the server to ~/.codex/config.toml — a working example is in examples/codex-config.toml.

[mcp_servers.qoder-as-subagent]
command = "node"
args = ["<abs path>/qoder-as-subagent/dist/index.js"]
default_tools_approval_mode = "prompt"

[mcp_servers.qoder-as-subagent.env]
QODER_AS_SUBAGENT_WORKSPACE_ROOTS = "C:\\code\\project-a;C:\\code\\project-b"

Tools

Tool

Arguments

Returns

qoder_run

tier, prompt, workspace, model?, reasoningEffort?, maxOutputTokens?, waitSeconds?

jobId, sessionId, status

qoder_status

jobId, cursor?, waitSeconds?

status, events, result, permissionDenials, cursor

qoder_reply

jobId, prompt, model?, reasoningEffort?, waitSeconds?

a new jobId on the same session

qoder_cancel

jobId

status

qoder_reply takes a job id, never a session id. The session id stays server-side, so a caller cannot aim --resume at an arbitrary transcript.

Poll with the cursor from the previous response to get only new events.

Configuration

Variable

Default

Purpose

QODER_AS_SUBAGENT_WORKSPACE_ROOTS

the server's own cwd

Path-delimiter-separated allowlist. A workspace outside every root is refused.

QODER_AS_SUBAGENT_STATE_DIR

%LOCALAPPDATA%\qoder-as-subagent

Where job state lives. Deliberately outside any workspace, and separate from cc-as-subagent's.

QODER_AS_SUBAGENT_PASSTHROUGH

(none)

Comma-separated variable names to pass through. Everything else is dropped.

QODER_BIN

resolved as above

Pin an exact CLI build.

Verified behaviour

npm test — 56 unit tests. node scripts/e2e.mjs — 13 checks against the real CLI: consult reads a workspace while being granted no write tool, execute writes, a resumed turn still carries the isolation stack, and the granted tool list is exactly the tier's six.

node scripts/selfcheck.mjs re-runs the security assumptions and writes a verdict to the state directory. Re-run it after a CLI upgrade.

One check reports skipped, and that is the honest result: I could not make the settings-injection probe fire on this CLI, so whether --setting-sources actually excludes a workspace's settings is unverified here. The flag is kept because it is the same flag with the same vocabulary as the CLI where the mechanism was measured, and it costs nothing — but it is defence, not a verified fix. Details in SECURITY.md.

Known limitations

See SECURITY.md for the reasoning.

  • No --safe-mode equivalent. A workspace's AGENTS.md, skills, plugins and hooks load. Hook activity is visible in a job's event stream.

  • No turn limit and no spend cap. A runaway run is bounded only by the server's 30-minute timeout.

  • --setting-sources is unverified on this CLI.

  • No OS sandbox on Windows.

  • Command deny rules are not a security boundary — they blunt a confused model, not a hostile one.

  • Reads inside the workspace are unrestricted.

License

MIT — see LICENSE.

Available Tools

5 tools
pingPingA
Read-onlyIdempotent

Liveness check. Reports the server version and the workspace roots it will accept. Never spawns the Qoder CLI.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and idempotentHint, so the safety profile is clear. The description adds valuable context beyond annotations, especially 'Never spawns the Qoder CLI,' which explains a meaningful behavioral guarantee that annotations alone do not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences that front-load the core purpose ('Liveness check') and then add the key behavioral details. No redundant or unnecessary wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-parameter, read-only, idempotent liveness tool, the description covers what it does, what it returns (server version and workspace roots), and what it avoids doing (spawning the CLI). Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there are no parameter semantics to document. The empty schema fully covers this, and the description correctly focuses on behavior rather than parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific purpose: a liveness check that reports server version and accepted workspace roots. It clearly distinguishes itself from the sibling tools, which are about canceling, running, statusing, and replying to Qoder operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: use this when you need a lightweight liveness/health check. It doesn't explicitly discuss alternatives or when not to use it, but for a tool this simple, the context is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

qoder_cancelCancel a jobA
Idempotent

Stop a running job and the process tree it started.

ParametersJSON Schema
NameRequiredDescriptionDefault
jobIdYes

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark readOnlyHint=false and idempotentHint=true, so mutation and idempotency are covered. The description adds valuable behavioral detail beyond those annotations by explicitly stating it stops the process tree the job started, which clarifies the destructive scope.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. Every word contributes to the core action and its scope.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter cancellation tool with no output schema, the description covers the main effect but omits details like whether cancellation is synchronous, what happens if the job is already finished, and what the agent should expect in the response. It is adequate but not fully specified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for the undocumented jobId parameter. It only says 'Stop a running job' without explaining the jobId format, where to obtain it, or whether it must reference a currently running job vs. any known job.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

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 the process tree it started'), so an agent can tell this is a cancellation tool. It does not explicitly compare itself to siblings like qoder_run or qoder_status, but the action is distinct enough to avoid confusion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'a running job' implies the tool is for jobs that are currently executing, which gives some usage context. However, it does not state when to prefer this over qoder_status or qoder_reply, nor does it mention exclusions such as completed or queued jobs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

qoder_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
jobIdYesA finished job whose session to continue.
modelNo
promptYes
waitSecondsNo
reasoningEffortNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare non-read, non-idempotent, open-world behavior; the description adds that the session id stays server-side, that the jobId must belong to a finished job, and that a new jobId is returned. This gives useful state-transition context without contradicting the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no filler; the action, precondition, and return value are front-loaded and each sentence adds a distinct piece of information. It is short but substantive.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core lifecycle (finished job -> follow-up jobId) and the server-side session behavior. It does not specify error behavior, whether waitSeconds is honored as a blocking wait, or how model/reasoningEffort affect execution, but for a tool with no output schema and existing annotations it is reasonably complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema documentation only covers jobId (20%), and the description enriches that by specifying it must come from a finished job. It does not explain the required `prompt` or the optional `model`, `waitSeconds`, and `reasoningEffort`, leaving those to be inferred from parameter names and sibling context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('start a follow-up turn') and a resource ('existing session'), and clarifies the key input-output relationship: a finished job's jobId produces a new jobId. This distinguishes it from siblings like qoder_run (new sessions) and qoder_status, so an agent can tell what the tool is for.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clear context is provided: use it when continuing an existing session with a follow-up turn, and the input must be a finished job. It does not explicitly name or exclude alternatives such as qoder_run or qoder_cancel, which weakens routing guidance, but the 'existing session' scope makes the intended use evident.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

qoder_runRun Claude CodeA

Start a new Claude Code session in a workspace. Returns a jobId immediately; the run continues in the background. Use qoder_status to poll for the result. Tier "consult" is read-only; "execute" may edit files in the workspace.

ParametersJSON Schema
NameRequiredDescriptionDefault
tierYesPermission tier for the run.
modelNoModel alias or full name; defaults to the CLI's.
promptYesThe task for the subagent.
workspaceYesAbsolute path to an allowed workspace directory.
waitSecondsNoBlock up to this long for the first result instead of returning at once.
maxOutputTokensNoCap on one response. This is the only brake available: the CLI has no turn limit and no spend cap, so it does not bound the whole run.
reasoningEffortNoReasoning effort. Falls back to the model's own default.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are present (readOnlyHint=false, openWorldHint=true, idempotentHint=false), so the bar is lowered. Description adds critical context: returns jobId immediately, runs in background, and clarifies that 'execute' tier may edit files while 'consult' is read-only. This goes beyond annotations and covers key behaviors.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences front-load the core purpose and async nature, then immediately reference qoder_status and tier semantics. Zero fluff, each sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 7 parameters and no output schema, the description covers the critical use case: starting a run, getting jobId, polling for result. Schema documents all parameters, so the description needn't repeat them. The description is missing explicit mention of failure modes or limits, but given the async pattern and schema richness, it is sufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds semantic value by explaining tier meaning (consult read-only, execute may edit) directly, which supplements the schema's simple 'Permission tier' description. It also clarifies async behavior tied to the jobId return.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Start a new Claude Code session') with a clear resource ('workspace'), and explicitly differentiates from siblings by mentioning async jobId return and qoder_status for polling. The tier semantics (consult vs execute) further disambiguate the tool's scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance to use qoder_status for polling results, and clarifies tier meaning. Does not explicitly list when not to use it or name alternatives beyond qoder_status, but the context is clear enough for the primary flow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

qoder_statusCheck a jobA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
jobIdYes
cursorNoLast event sequence number seen.
waitSecondsNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds useful behavioral detail beyond the annotations: events are incremental via cursor, and the final answer is returned when the run completes. It aligns with readOnlyHint=true and idempotentHint=true and adds meaningful context about how polling behaves.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise sentences, each with a distinct job: state the purpose, explain cursor behavior, and describe the completion result. No wasted words, and the most important information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple polling tool with no output schema, the description covers the core behavior: progress, result, incremental events, and final answer. It does not detail event shape or error behavior, but given the annotations and simple parameter set, it is reasonably complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%, but the description clarifies the cursor's purpose beyond the schema's 'Last event sequence number seen.' jobId is self-evident, and waitSeconds is weakly inferable by name, but its exact polling semantics are not described.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb and resource: 'Poll a job for progress and its result.' It is specific about the tool's role but does not explicitly differentiate it from siblings like qoder_reply or qoder_run, so it stops short of a full 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the usage context well: it is for polling after a job has been started, and 'Pass the cursor from the previous call' indicates repeated polling. It does not explicitly name alternatives or exclusion conditions, but the context is clear enough.

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.

  1. 5 tool updatesv0.1.0
    • First observedping
    • First observedqoder_cancel
    • First observedqoder_reply
    • First observedqoder_run
    • First observedqoder_status

TDQS

A4.2/5.0

Scored across 5 tools

Disambiguation5/5

Each tool covers a distinct lifecycle action: liveness, start, poll, cancel, and follow-up. The descriptions make the boundaries clear, especially qoder_run (new session) vs qoder_reply (existing session).

Naming Consistency4/5

The four main tools follow a consistent qoder_<verb/noun> pattern, but ping breaks the prefix convention. Minor deviation, easily predictable overall.

Tool Count5/5

Five tools is well-scoped for a subagent orchestration server. Each tool serves a necessary step in the job lifecycle with no redundancy.

Completeness5/5

The tool surface covers the full lifecycle: discover workspace via ping, start a job, poll progress/results, continue with follow-up turns, and cancel if needed. No obvious dead ends or missing operations for the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Lets 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
  • A
    license
    A
    quality
    A
    maintenance
    Enables Claude Code to delegate coding tasks—investigation, review, long-running background jobs, and optional file edits—to a locally installed OpenAI Codex CLI, with the model and reasoning effort chosen per task and read-only execution by default. Follow-up requests reuse Codex's existing context, and write-enabled delegations can be confined to a managed git worktree so the user's own checkout stays untouched.
    8
    204 npm
    MIT