@heretyc/subagent-mcp 2.12.5-beta.2 → 2.12.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -33
- package/dist/concurrency.js +1 -1
- package/dist/index.js +2 -3
- package/dist/orchestration/marker.js +12 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -5,39 +5,56 @@
|
|
|
5
5
|
[](https://www.npmjs.com/package/@heretyc/subagent-mcp)
|
|
6
6
|
[](https://github.com/Heretyc/subagent-mcp/actions/workflows/claude-routine.yml)
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- **
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- **
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
8
|
+
## Core premise
|
|
9
|
+
|
|
10
|
+
subagent-mcp is an MCP (stdio) server that turns any AI coding assistant
|
|
11
|
+
(Claude Code, Codex, Gemini CLI) into a **manager/orchestrator of a team of
|
|
12
|
+
AI sub-agents** running on macOS, Linux, and Windows. It drives the locally
|
|
13
|
+
authenticated `claude` and `codex` CLIs you already signed into — **no direct
|
|
14
|
+
HTTP API calls and no API keys, ever** (an explicit, permanent non-goal). It
|
|
15
|
+
serves developers running big, long-horizon coding jobs who want to escape a
|
|
16
|
+
single conversation's context limits and vendor lock-in.
|
|
17
|
+
|
|
18
|
+
Its central promise: the orchestrator **monitors but never reads or writes
|
|
19
|
+
files itself** — every step is delegated to a fresh sub-agent, so the
|
|
20
|
+
orchestrator's context fills only with ≤100-line summaries. This extends
|
|
21
|
+
effective context "geometrically" instead of linearly, enabling marathon tasks
|
|
22
|
+
with little or no compaction. Guarantees/invariants it promises: a single
|
|
23
|
+
machine-global, provider-agnostic concurrency cap (default 20, min 10; rejects
|
|
24
|
+
at cap, never queues); fail-safe **ON** on hosts lacking hooks (unknown
|
|
25
|
+
orchestration state defaults to ON); orchestration state is authoritative only
|
|
26
|
+
via harness-verified `<subagent-mcp state="...">` hook tags, never inferred from
|
|
27
|
+
prose (guards against directive drift/hallucination); sub-agents run **gated by
|
|
28
|
+
default** (permission ceiling `auto`); and automatic model/provider/effort
|
|
29
|
+
routing per task category so the user never picks a model.
|
|
30
|
+
|
|
31
|
+
## Key problems it solves
|
|
32
|
+
|
|
33
|
+
- **Context exhaustion / compaction on long tasks** — delegate-only
|
|
34
|
+
orchestration keeps the manager's context holding summaries, not raw files,
|
|
35
|
+
so long jobs run with minimal compaction.
|
|
36
|
+
- **Single-vendor blind spots and lock-in** — mixed Claude + Codex (provider-
|
|
37
|
+
agnostic) operation means one vendor's weakness or outage doesn't blind or
|
|
38
|
+
block the whole job.
|
|
39
|
+
- **No API keys / no direct API calls** — drives locally signed-in vendor CLIs
|
|
40
|
+
instead of the Anthropic/OpenAI HTTP APIs, avoiding key management and cost of
|
|
41
|
+
a gateway.
|
|
42
|
+
- **Directive drift & hallucination over long runs** — operating rules are
|
|
43
|
+
re-injected redundantly (MCP `instructions`, INIT_BLOCK, per-turn hooks,
|
|
44
|
+
managed AGENTS.md/CLAUDE.md/GEMINI.md blocks) and made authoritative via
|
|
45
|
+
harness-verified state tags.
|
|
46
|
+
- **Model-selection burden** — a benchmark-derived routing table auto-picks
|
|
47
|
+
provider/model/effort from a plain-English prompt + task category.
|
|
48
|
+
- **Uncontrolled/unsafe sub-agent actions** — a shared permission engine gates
|
|
49
|
+
sub-agent operations (SAFE→allow, DANGER→deny, NEUTRAL→park for a decision)
|
|
50
|
+
with `auto`/`manual`/`yolo` ceilings and one-time `respond_permission`.
|
|
51
|
+
- **Runaway fan-out / resource contention** — one machine-wide concurrency cap
|
|
52
|
+
and worktree isolation (branch-per-task) with a first-line sub-agent
|
|
53
|
+
carve-out to prevent fork-bomb recursion.
|
|
54
|
+
- **Orchestrator observability** — a fixed set of tools (launch/poll/kill/
|
|
55
|
+
send_message/list/wait/respond_permission + orchestration & model modes) plus
|
|
56
|
+
a status lifecycle (processing/stalled/finished/errored/stopped/
|
|
57
|
+
zombie_killed/permission_requested) so a quiet agent isn't mistaken for dead.
|
|
41
58
|
|
|
42
59
|
## Install
|
|
43
60
|
|
package/dist/concurrency.js
CHANGED
|
@@ -25,7 +25,7 @@ export function clampCap(raw) {
|
|
|
25
25
|
return v;
|
|
26
26
|
}
|
|
27
27
|
export function stripJsoncComments(text) {
|
|
28
|
-
return text.replace(/^\s*\/\/.*$/gm, "");
|
|
28
|
+
return text.replace(/^\uFEFF/, "").replace(/^\s*\/\/.*$/gm, "");
|
|
29
29
|
}
|
|
30
30
|
function parseJsonObject(text) {
|
|
31
31
|
const parsed = JSON.parse(stripJsoncComments(text));
|
package/dist/index.js
CHANGED
|
@@ -441,8 +441,7 @@ function handleCompletedStdoutLines(agent, lines, at) {
|
|
|
441
441
|
agent.status = "finished";
|
|
442
442
|
if (agent.exitedAt === null)
|
|
443
443
|
agent.exitedAt = at;
|
|
444
|
-
|
|
445
|
-
agent.slotPath = null;
|
|
444
|
+
updateSlotMetadata(agent, at);
|
|
446
445
|
}
|
|
447
446
|
}
|
|
448
447
|
}
|
|
@@ -516,7 +515,7 @@ const ORCHESTRATION_INSTRUCTIONS = "subagent-mcp - CANONICAL OPERATING MODEL (fu
|
|
|
516
515
|
const SUBAGENT_INSTRUCTIONS = "SUB-AGENT SESSION: you are a child process launched by subagent-mcp. Follow the parent prompt. Do not treat yourself as the orchestrator, do not re-trigger orchestration carryover, and do not launch further sub-agents unless the parent prompt explicitly assigns that.\n\nMODEL SELECTION MODE (parallel to orchestration-mode, set via the model-selection-mode tool). DEFAULT is \"smart\" and is used whenever unset: in smart, launch_agent REJECTS any call supplying provider/model/effort selectors and the server auto-picks the best model. \"user-approved-overrides\" opens a 30-MINUTE window where selectors are HONORED, enforced LAZILY (the mode reverts to smart on the next launch_agent call after 30 minutes) and re-enabling does NOT extend an active window. HONOR-BASED: you MUST NOT set \"user-approved-overrides\" without explicit interactive USER authorization via the structured-question tool (AskUserQuestion on Claude / request-user-input on Codex); never enable it on your own initiative.";
|
|
517
516
|
const server = new McpServer({
|
|
518
517
|
name: "subagent-mcp",
|
|
519
|
-
version: "2.12.
|
|
518
|
+
version: "2.12.7",
|
|
520
519
|
description: "Launches always-interactive local Claude and Codex sub-agent sessions and is the orchestrator's sole launch channel. Claude runs via the Claude Agent SDK over the local Claude Code executable; Codex via `codex app-server` over stdio. The server never calls Anthropic or OpenAI HTTP APIs directly.",
|
|
521
520
|
}, {
|
|
522
521
|
instructions: process.env.SUBAGENT_MCP_SUBAGENT === "1"
|
|
@@ -55,6 +55,9 @@ function cwdDisablePath(cwd) {
|
|
|
55
55
|
export function sessionPointerPath(cwd) {
|
|
56
56
|
return join(stateDir, `orch-session-${cwdHash(cwd)}.json`);
|
|
57
57
|
}
|
|
58
|
+
export function serverSessionPointerPath(cwd, serverKey = process.ppid) {
|
|
59
|
+
return join(stateDir, `orch-session-${cwdHash(cwd)}-${hashKey(String(serverKey))}.json`);
|
|
60
|
+
}
|
|
58
61
|
/**
|
|
59
62
|
* Enable orchestration for cwd. ALWAYS overwrites — re-enabling re-baselines by
|
|
60
63
|
* clearing owner_session/baseline_turn back to null so the next hook turn
|
|
@@ -128,9 +131,15 @@ export function writeDisableCwd(cwd) {
|
|
|
128
131
|
// Fail-safe: never throw to the caller.
|
|
129
132
|
}
|
|
130
133
|
}
|
|
131
|
-
export function writeCurrentSession(cwd, sessionKey) {
|
|
134
|
+
export function writeCurrentSession(cwd, sessionKey, serverKey = process.ppid) {
|
|
132
135
|
try {
|
|
133
136
|
mkdirSync(stateDir, { recursive: true, mode: 0o700 });
|
|
137
|
+
writeFileSync(serverSessionPointerPath(cwd, serverKey), JSON.stringify({ session_key: sessionKey }), {
|
|
138
|
+
encoding: "utf8",
|
|
139
|
+
mode: 0o600,
|
|
140
|
+
});
|
|
141
|
+
// Back-compat only: older consumers may still read the cwd-keyed pointer.
|
|
142
|
+
// New disable/query paths must read the server-scoped pointer instead.
|
|
134
143
|
writeFileSync(sessionPointerPath(cwd), JSON.stringify({ session_key: sessionKey }), {
|
|
135
144
|
encoding: "utf8",
|
|
136
145
|
mode: 0o600,
|
|
@@ -140,9 +149,9 @@ export function writeCurrentSession(cwd, sessionKey) {
|
|
|
140
149
|
// Fail-safe: never throw to the caller.
|
|
141
150
|
}
|
|
142
151
|
}
|
|
143
|
-
export function readCurrentSession(cwd) {
|
|
152
|
+
export function readCurrentSession(cwd, serverKey = process.ppid) {
|
|
144
153
|
try {
|
|
145
|
-
const raw = readFileSync(
|
|
154
|
+
const raw = readFileSync(serverSessionPointerPath(cwd, serverKey), "utf8");
|
|
146
155
|
const parsed = JSON.parse(raw);
|
|
147
156
|
return typeof parsed.session_key === "string" ? parsed.session_key : undefined;
|
|
148
157
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heretyc/subagent-mcp",
|
|
3
|
-
"version": "2.12.
|
|
3
|
+
"version": "2.12.7",
|
|
4
4
|
"description": "MCP server that launches and manages always-interactive Claude Code and Codex sub-agent sessions (no direct Anthropic/OpenAI API).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"postinstall": "node scripts/postinstall.mjs",
|
|
39
39
|
"prepare": "npm run build",
|
|
40
40
|
"prepublishOnly": "npm test",
|
|
41
|
-
"test": "npm run check:versions && node test/effort.test.mjs && node test/drivers.test.mjs && node test/platform.test.mjs && node test/wait.test.mjs && node test/status.test.mjs && node test/output.test.mjs && node test/stream.test.mjs && node test/routing.test.mjs && node test/deadlock.test.mjs && node test/handler-validation.test.mjs && node test/index-handler.test.mjs && node test/ruleset.test.mjs && node test/ruleset-exec.test.mjs && node test/ruleset-handler.test.mjs && node test/failover.test.mjs && node test/global-concurrency-cap.test.mjs && node test/update-check.test.mjs && node test/zombie.test.mjs && node test/zombie-reap-idle.test.mjs && node test/orchestration-marker.test.mjs && node test/orchestration-hook-core.test.mjs && node test/orchestration-adapters.test.mjs && node test/orchestration-pretool.test.mjs && node test/orchestration-directives.test.mjs && node test/no-five-call.test.mjs && node test/no-per-provider-cap.test.mjs && node test/rag-pointers.test.mjs && node test/check-worktree-subagent.test.mjs && node test/launch-agent-upsert.test.mjs && node test/claude-session-limit.test.mjs && node test/init-migration.test.mjs && node test/init-global.test.mjs && node test/mirror-fragments.test.mjs && node test/performance-tier-effort.test.mjs && node test/setup-repair.test.mjs && node test/setup-quoting.test.mjs && node test/setup-wire.test.mjs && node test/setup-cli-integration.test.mjs && node test/init.test.mjs && node test/model-selection-mode.test.mjs && node test/cli-args.test.mjs && node test/index-guard.test.mjs && node test/drivers-guard.test.mjs && node test/audit-next13-lb3.test.mjs && node test/zombie-guard.test.mjs && node test/concurrency-guard.test.mjs && node test/hook-core-guard.test.mjs && node scripts/validate_provider.mjs && node scripts/validate_seed_sites.mjs && node scripts/validate_routing_audit.mjs && node test/seed-sites.test.mjs && node test/mcp-compliance.test.mjs"
|
|
41
|
+
"test": "npm run check:versions && node test/effort.test.mjs && node test/drivers.test.mjs && node test/platform.test.mjs && node test/wait.test.mjs && node test/status.test.mjs && node test/output.test.mjs && node test/stream.test.mjs && node test/routing.test.mjs && node test/deadlock.test.mjs && node test/handler-validation.test.mjs && node test/index-handler.test.mjs && node test/ruleset.test.mjs && node test/ruleset-exec.test.mjs && node test/ruleset-handler.test.mjs && node test/failover.test.mjs && node test/global-concurrency-cap.test.mjs && node test/update-check.test.mjs && node test/zombie.test.mjs && node test/zombie-reap-idle.test.mjs && node test/orchestration-marker.test.mjs && node test/orchestration-hook-core.test.mjs && node test/orchestration-adapters.test.mjs && node test/orchestration-pretool.test.mjs && node test/orchestration-directives.test.mjs && node test/no-five-call.test.mjs && node test/no-per-provider-cap.test.mjs && node test/rag-pointers.test.mjs && node test/check-worktree-subagent.test.mjs && node test/launch-agent-upsert.test.mjs && node test/claude-session-limit.test.mjs && node test/init-migration.test.mjs && node test/init-global.test.mjs && node test/mirror-fragments.test.mjs && node test/performance-tier-effort.test.mjs && node test/setup-repair.test.mjs && node test/setup-quoting.test.mjs && node test/setup-wire.test.mjs && node test/setup-cli-integration.test.mjs && node test/init.test.mjs && node test/model-selection-mode.test.mjs && node test/cli-args.test.mjs && node test/index-guard.test.mjs && node test/drivers-guard.test.mjs && node test/audit-next13-lb3.test.mjs && node test/zombie-guard.test.mjs && node test/concurrency-guard.test.mjs && node test/hook-core-guard.test.mjs && node scripts/validate_provider.mjs && node scripts/validate_seed_sites.mjs && node scripts/validate_routing_audit.mjs && node test/seed-sites.test.mjs && node test/config-bom.test.mjs && node test/permission-system.test.mjs && node test/lifecycle-matrix.test.mjs && node test/output-hook-registration.test.mjs && node test/mcp-compliance.test.mjs"
|
|
42
42
|
},
|
|
43
43
|
"author": "Lexi Blackburn",
|
|
44
44
|
"license": "Apache-2.0",
|