Skip to content

Commit f80f913

Browse files
committed
Improve Claude autodiscovery for Codex subagents
1 parent 91b7f49 commit f80f913

9 files changed

Lines changed: 437 additions & 42 deletions

File tree

.claude-plugin/mcp.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
{
22
"mcpServers": {
33
"codex-subagents": {
4-
"command": "${CLAUDE_PLUGIN_ROOT}/dist/index.js",
5-
"env": {
6-
"CLAUDE_PROJECT_DIR": "${CLAUDE_PROJECT_DIR}"
7-
}
4+
"command": "${CLAUDE_PLUGIN_ROOT}/dist/index.js"
85
}
96
}
107
}

.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "codex-subagents",
33
"version": "0.1.0",
4-
"description": "Launch OpenAI Codex agents from Claude Code through a daemonless MCP server.",
4+
"description": "Launch OpenAI Codex agents, Spark agents, and parallel Codex subagents from Claude Code through a daemonless read-only MCP server.",
55
"author": {
66
"name": "xuio"
77
},

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ npm run test:claude-desktop
6363

6464
`test:claude-real-codex` is the full opt-in live path: Claude Code loads the plugin and calls real Codex through the desktop app binary, including one single agent, one parallel run, and one nested Spark subagent run. It spends both Claude and Codex tokens, so it is intentionally not part of the default suite.
6565

66+
`test:claude-autodiscovery` is an opt-in live Claude Code test for automatic tool selection. It gives Claude a natural "ask Codex" request, uses the installed plugin and fake Codex binary, and verifies that Claude chooses the Codex MCP tool without being told the exact tool name.
67+
6668
Run Claude Code with the local plugin:
6769

6870
```sh
@@ -77,6 +79,8 @@ After startup, ask Claude to use Codex subagents, or invoke the plugin skill:
7779

7880
## MCP Tools
7981

82+
`codex_usage_guide` returns the operating guide and example calls Claude can use when deciding how to delegate to Codex.
83+
8084
`run_agent` launches one Codex `exec` process.
8185

8286
`run_agents` launches multiple Codex `exec` processes concurrently with a bounded `max_parallel` setting.

dist/index.js

Lines changed: 97 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21703,13 +21703,36 @@ async function probeCodexVersion(codexBin, env = process.env) {
2170321703
}
2170421704

2170521705
// src/index.ts
21706+
var usageGuide = [
21707+
"Claude Code integration guide for codex-subagents:",
21708+
"",
21709+
"Use this MCP server whenever the user asks Claude to use Codex, OpenAI Codex, Codex subagents, Codex Spark, a Codex second opinion, parallel Codex review, or independent Codex codebase analysis. You do not need the user to name an MCP tool.",
21710+
"",
21711+
"Tool choice:",
21712+
"- Use run_agent for one delegated Codex task.",
21713+
"- Use run_agents when the work can be split into independent concurrent tasks, for example separate reviewers for API flow, tests, security, performance, UI, docs, or migration risk.",
21714+
"- Use codex_status only for diagnostics or when you need to confirm the Codex binary/version.",
21715+
"- Use codex_usage_guide if you are unsure how to structure a Codex delegation.",
21716+
"",
21717+
"Default operating rules:",
21718+
"- Keep sandbox read-only unless the user explicitly asks for a different sandbox.",
21719+
"- Approvals are non-interactive; do not expect Codex to ask permission.",
21720+
'- Prefer model_preset "spark" for fast focused checks, small reviews, UI iteration, and responsive sidecar analysis.',
21721+
'- Use reasoning_effort "medium" by default, "low" for simple checks, and "high" or "xhigh" only for difficult analysis.',
21722+
"- Pass project_dir whenever Claude knows the active project directory so Codex works in the same tree as Claude Code.",
21723+
"- Ask Codex for concise results with file paths, line references, and actionable findings when reviewing code.",
21724+
"",
21725+
"Nested Codex subagents:",
21726+
"- When the user wants Codex to use its own subagents, pass complete custom definitions in codex_subagents and explicit work items in subagent_tasks.",
21727+
"- Keep subagent_runtime.max_depth at 1 unless recursive delegation is intentionally requested."
21728+
].join("\n");
2170621729
var server = new McpServer(
2170721730
{
2170821731
name: "codex-subagents",
2170921732
version: "0.1.0"
2171021733
},
2171121734
{
21712-
instructions: "Launch OpenAI Codex agents from Claude Code. Use run_agent for one read-only Codex delegation and run_agents for parallel delegations. Defaults are daemonless stdio, Codex desktop app binary when installed, read-only sandbox, approval_policy=never, and fast service tier."
21735+
instructions: usageGuide
2171321736
}
2171421737
);
2171521738
var reasoningEffortSchema = external_exports.enum(reasoningEfforts);
@@ -21743,10 +21766,16 @@ var subagentRuntimeSchema = external_exports.object({
2174321766
job_max_runtime_seconds: external_exports.number().int().positive().max(86400).optional()
2174421767
});
2174521768
var commonInputSchema = {
21746-
model: external_exports.string().trim().min(1).optional().describe("Codex model, for example gpt-5.3-codex. Omit to use the plugin or Codex default."),
21747-
model_preset: modelPresetSchema.optional().describe("Convenience model preset. `spark` maps to gpt-5.3-codex-spark."),
21748-
reasoning_effort: reasoningEffortSchema.optional().describe("Codex model reasoning effort. Defaults to plugin config or medium."),
21749-
sandbox: sandboxModeSchema.default("read-only").describe("Codex sandbox mode. Defaults to read-only."),
21769+
model: external_exports.string().trim().min(1).optional().describe(
21770+
"Exact Codex model, for example gpt-5.3-codex. Omit to use model_preset, the plugin default, or Codex default."
21771+
),
21772+
model_preset: modelPresetSchema.optional().describe(
21773+
"Convenience model preset. Use `spark` for fast Codex Spark work; it maps to gpt-5.3-codex-spark."
21774+
),
21775+
reasoning_effort: reasoningEffortSchema.optional().describe(
21776+
"Codex model reasoning effort. Prefer medium by default, low for simple checks, high/xhigh only for difficult analysis."
21777+
),
21778+
sandbox: sandboxModeSchema.default("read-only").describe("Codex sandbox mode. Keep read-only unless the user explicitly asks otherwise."),
2175021779
service_tier: serviceTierSchema.default("fast").describe("Codex service tier. Defaults to fast for responsiveness."),
2175121780
model_verbosity: modelVerbositySchema.optional().describe("Optional GPT-5 model verbosity override."),
2175221781
reasoning_summary: reasoningSummarySchema.optional().describe("Optional Codex reasoning summary setting."),
@@ -21757,14 +21786,18 @@ var commonInputSchema = {
2175721786
codex_bin: external_exports.string().trim().min(1).optional().describe("Explicit Codex CLI path. Overrides default binary resolution for this call."),
2175821787
profile: external_exports.string().trim().min(1).optional().describe("Optional Codex config profile."),
2175921788
timeout_ms: external_exports.number().int().positive().max(864e5).default(6e5).describe("Maximum runtime per Codex process in milliseconds."),
21760-
max_output_chars: external_exports.number().int().positive().max(5e5).default(6e4).describe("Maximum final message/stdout characters retained per agent."),
21789+
max_output_chars: external_exports.number().int().positive().max(5e5).default(6e4).describe("Maximum final message/stdout characters retained per agent. Lower this for concise parallel reviews."),
2176121790
include_events: external_exports.boolean().default(false).describe("Include parsed Codex JSONL events in the result. Usually leave false."),
2176221791
ephemeral: external_exports.boolean().default(true).describe("Run Codex without persisting session rollout files."),
2176321792
skip_git_repo_check: external_exports.boolean().default(false).describe("Allow Codex to run outside a Git repository."),
2176421793
ignore_rules: external_exports.boolean().default(false).describe("Skip Codex execpolicy .rules files."),
21765-
codex_subagents: external_exports.array(codexSubagentSchema).max(24).optional().describe("Custom Codex subagents available inside this Codex run."),
21766-
subagent_tasks: external_exports.array(subagentTaskSchema).max(24).optional().describe("Specific built-in or custom Codex subagents the parent Codex agent should spawn."),
21767-
subagent_runtime: subagentRuntimeSchema.optional().describe("Runtime limits for nested Codex subagent orchestration.")
21794+
codex_subagents: external_exports.array(codexSubagentSchema).max(24).optional().describe(
21795+
"Complete custom Codex subagent definitions available inside this Codex run for nested delegation."
21796+
),
21797+
subagent_tasks: external_exports.array(subagentTaskSchema).max(24).optional().describe(
21798+
"Specific built-in or custom Codex subagents the parent Codex agent should spawn and wait for."
21799+
),
21800+
subagent_runtime: subagentRuntimeSchema.optional().describe("Runtime limits for nested Codex subagent orchestration. Keep max_depth at 1 by default.")
2176821801
};
2176921802
function toCodexSubagents(agents) {
2177021803
return agents?.map((agent) => ({
@@ -21823,13 +21856,57 @@ function toRunOptions(args) {
2182321856
} : void 0
2182421857
};
2182521858
}
21859+
server.registerTool(
21860+
"codex_usage_guide",
21861+
{
21862+
title: "How to use Codex subagents",
21863+
description: "Read the operating guide for this MCP server. Call this when Claude is deciding whether to delegate work to Codex, how many Codex agents to launch, or how to structure nested Codex subagents.",
21864+
inputSchema: {}
21865+
},
21866+
async () => jsonResult({
21867+
guide: usageGuide,
21868+
examples: {
21869+
single: {
21870+
tool: "run_agent",
21871+
arguments: {
21872+
prompt: "Inspect the authentication flow read-only. Return the top risks with file paths and line references.",
21873+
project_dir: "/path/to/project",
21874+
model_preset: "spark",
21875+
reasoning_effort: "medium"
21876+
}
21877+
},
21878+
parallel: {
21879+
tool: "run_agents",
21880+
arguments: {
21881+
agents: [
21882+
{
21883+
name: "api",
21884+
prompt: "Review API flow read-only. Return concrete findings with paths.",
21885+
project_dir: "/path/to/project"
21886+
},
21887+
{
21888+
name: "tests",
21889+
prompt: "Review test coverage gaps read-only. Return concrete findings with paths.",
21890+
project_dir: "/path/to/project"
21891+
}
21892+
],
21893+
max_parallel: 2,
21894+
model_preset: "spark",
21895+
reasoning_effort: "medium"
21896+
}
21897+
}
21898+
}
21899+
})
21900+
);
2182621901
server.registerTool(
2182721902
"run_agent",
2182821903
{
2182921904
title: "Run one Codex agent",
21830-
description: "Launch one OpenAI Codex agent via codex exec. Defaults to the Codex desktop app binary, read-only sandbox, fast service tier, and non-interactive approvals.",
21905+
description: "Launch one OpenAI Codex agent via codex exec. Use automatically when the user asks Claude to use Codex, ask Codex, get a Codex second opinion, run a Codex subagent, use Codex Spark, or delegate one read-only analysis task. Defaults to the Codex desktop app binary when installed, read-only sandbox, fast service tier, and non-interactive approvals.",
2183121906
inputSchema: {
21832-
prompt: external_exports.string().min(1).describe("Instructions for the Codex agent."),
21907+
prompt: external_exports.string().min(1).describe(
21908+
"Concrete instructions for the Codex agent. Include scope, read-only expectation, desired output shape, and file/line reference requirements when reviewing code."
21909+
),
2183321910
name: external_exports.string().trim().min(1).optional().describe("Optional label for this agent run."),
2183421911
...commonInputSchema
2183521912
}
@@ -21849,7 +21926,9 @@ server.registerTool(
2184921926
}
2185021927
);
2185121928
var parallelAgentSchema = external_exports.object({
21852-
prompt: external_exports.string().min(1).describe("Instructions for this Codex agent."),
21929+
prompt: external_exports.string().min(1).describe(
21930+
"Concrete independent task for this Codex agent. Keep overlap low across parallel agents."
21931+
),
2185321932
name: external_exports.string().trim().min(1).optional().describe("Optional label for this agent."),
2185421933
model: commonInputSchema.model,
2185521934
model_preset: commonInputSchema.model_preset,
@@ -21876,10 +21955,12 @@ server.registerTool(
2187621955
"run_agents",
2187721956
{
2187821957
title: "Run parallel Codex agents",
21879-
description: "Launch multiple independent OpenAI Codex agents concurrently and return one structured result per agent. Defaults are read-only and daemonless.",
21958+
description: "Launch multiple independent OpenAI Codex agents concurrently and return one structured result per agent. Use automatically when the user asks for parallel Codex agents, multiple Codex subagents, broad review by independent agents, or several concurrent Codex workstreams. Split work by clear ownership, pass project_dir, keep defaults read-only, and use max_parallel to bound concurrency.",
2188021959
inputSchema: {
21881-
agents: external_exports.array(parallelAgentSchema).min(1).max(12),
21882-
max_parallel: external_exports.number().int().min(1).max(8).default(4),
21960+
agents: external_exports.array(parallelAgentSchema).min(1).max(12).describe(
21961+
"Independent Codex agent tasks. Use names like api, tests, security, docs, performance, or ui when helpful."
21962+
),
21963+
max_parallel: external_exports.number().int().min(1).max(8).default(4).describe("Maximum concurrent Codex processes. Use 2-4 for most responsive parallel reviews."),
2188321964
...commonInputSchema
2188421965
}
2188521966
},
@@ -21948,7 +22029,7 @@ server.registerTool(
2194822029
"codex_status",
2194922030
{
2195022031
title: "Codex status",
21951-
description: "Report Codex binary resolution, version, server working directory, and default execution settings.",
22032+
description: "Report Codex binary resolution, version, server working directory, and default execution settings. Use for diagnostics before delegation only when Codex availability is uncertain or a prior tool call failed.",
2195222033
inputSchema: {
2195322034
codex_bin: commonInputSchema.codex_bin
2195422035
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"test:reliability": "node test/reliability-matrix.mjs",
2626
"test:codex-runtime": "node test/codex-runtime-probe.mjs",
2727
"test:claude-orchestration": "node test/claude-orchestration.mjs",
28+
"test:claude-autodiscovery": "node test/claude-autodiscovery.mjs",
2829
"test:claude-real-codex": "node test/claude-real-codex.mjs",
2930
"test:ci": "npm run build && npm test && npm run smoke:mcp && npm run test:reliability",
3031
"test:comprehensive": "npm run build && npm test && npm run smoke:mcp && npm run test:reliability && npm run test:codex-runtime && npm run validate:plugin && npm run test:claude-desktop",

skills/codex-subagents/SKILL.md

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
---
2-
description: Launch one or more OpenAI Codex agents from Claude Code for read-only exploration, review, planning, or parallel codebase analysis. Use when the user asks for Codex subagents, parallel Codex agents, or wants Claude Code to delegate work to Codex.
2+
description: Launch one or more OpenAI Codex agents from Claude Code for read-only exploration, review, planning, second opinions, Spark checks, or parallel codebase analysis. Use automatically when the user asks for Codex, OpenAI Codex, Codex Spark, Codex subagents, parallel Codex agents, a Codex second opinion, or for Claude Code to delegate work to Codex.
33
---
44

55
# Codex Subagents
66

7-
Use the `codex-subagents` MCP server when the task benefits from delegating read-only work to OpenAI Codex from inside Claude Code.
7+
Use the `codex-subagents` MCP server when the task benefits from delegating read-only work to OpenAI Codex from inside Claude Code. If the user asks to "use Codex", "ask Codex", "launch Codex subagents", "use Spark", "get a Codex second opinion", or "run parallel Codex agents", call the MCP tools directly. Do not wait for the user to name the MCP tool.
88

99
Default behavior:
1010

@@ -16,16 +16,51 @@ Default behavior:
1616
- Supports `model_preset: "spark"` for Codex Spark (`gpt-5.3-codex-spark`) without requiring Claude to remember the exact model string.
1717
- Supports nested Codex subagents by passing `codex_subagents`, `subagent_tasks`, and `subagent_runtime`; custom agents are sent as Codex `agents.<name>...` config overrides for the child run.
1818

19-
For one delegated task, call `run_agent`.
19+
For one delegated task, call `run_agent`. Make the prompt self-contained: include the scope, the expected read-only behavior, and the output shape Claude needs. For code review and exploration, ask for concise findings with file paths and line references.
2020

21-
For independent tasks that can run concurrently, call `run_agents` with one agent object per task. Keep each prompt concrete and bounded, and ask Codex to return concise findings with file paths and line references when relevant.
21+
For independent tasks that can run concurrently, call `run_agents` with one agent object per task. Split by ownership such as API flow, tests, security, performance, UI, docs, or migration risk. Keep prompts concrete and bounded, and set `max_parallel` to the smaller of the useful agent count and `4` unless the user asks for more.
2222

2323
When Claude wants Codex to work in the same repository or folder as the active Claude Code session, pass that folder as `project_dir`. Use `cwd` only as a compatibility alias.
2424

2525
Prefer `reasoning_effort: "medium"` for exploration and `high` or `xhigh` only when the task is complex enough to justify the extra latency and token usage.
2626

2727
Use `model_preset: "spark"` for fast, focused work such as UI iteration, narrow exploration, small reviews, and quick sidecar checks.
2828

29+
Use `codex_status` only when diagnosing installation or binary resolution, or after a failed Codex tool call. Normal delegation should start with `run_agent` or `run_agents`.
30+
31+
Example single-agent call:
32+
33+
```json
34+
{
35+
"prompt": "Review the MCP server implementation read-only. Return the top risks with file paths and line references, then a brief summary.",
36+
"project_dir": "/path/to/project",
37+
"model_preset": "spark",
38+
"reasoning_effort": "medium"
39+
}
40+
```
41+
42+
Example parallel call:
43+
44+
```json
45+
{
46+
"agents": [
47+
{
48+
"name": "api",
49+
"prompt": "Review the MCP tool schemas and runtime options read-only. Return concrete risks with paths.",
50+
"project_dir": "/path/to/project"
51+
},
52+
{
53+
"name": "tests",
54+
"prompt": "Review the test coverage read-only. Identify missing scenarios with paths.",
55+
"project_dir": "/path/to/project"
56+
}
57+
],
58+
"max_parallel": 2,
59+
"model_preset": "spark",
60+
"reasoning_effort": "medium"
61+
}
62+
```
63+
2964
When nested Codex delegation is needed:
3065

3166
- Put complete custom subagent definitions in `codex_subagents`.

0 commit comments

Comments
 (0)