@loft-902-co/subagents-mcp
v1.4.4
Published
TypeScript MCP server exposing a single delegate tool to run task-specific sub-agents (review, debugger, security) via explicit CLI wrappers.
Maintainers
Readme
subagents-mcp — Model Context Protocol server for task-specific sub‑agents
Minimal TypeScript MCP server that exposes a focused tool surface to run task‑specific sub‑agents (review, debugger, security, etc.) via explicit CLI wrappers (Codex or Cursor). Agent personas are loaded from simple files in an agents/ directory (Markdown or JSON), so you can add or tweak sub‑agents without changing code.
Table of contents
Features
- Minimal, auditable MCP server implemented in TypeScript (stdout is JSON only)
- Single responsibility tool surface:
delegate,delegate_batch,list_agents,validate_agents - Zero-code agent authoring: drop
agents/*.md|jsonto register personas and metadata - Profile-aware execution: calls into Codex or Cursor with the agent’s selected profile
- Optional workspace isolation: mirror repo or use a
git worktreefor larger codebases - Orchestrated execution with token gating and per-request state under
orchestration/<request_id>/ - Works with Node ≥ 18
Quickstart
- Run via npx (no local build required)
npx -y @loft-902-co/subagents-mcp --versionAlternatively: build locally:
npm install
npm run build- Point your client (Codex or Cursor) at the MCP server (explicit wrapper required)
Codex CLI wiring
Add this to your ~/.codex/config.toml and adjust as needed:
[mcp_servers.subagents]
command = "npx"
args = ["-y", "@loft-902-co/subagents-mcp", "--agents-dir", "/ABS/PATH/TO/agents"]
[profiles.review]
model = "gpt-5"
approval_policy = "on-request"
sandbox_mode = "read-only"
[profiles.debugger]
model = "o3"
approval_policy = "on-request"
sandbox_mode = "workspace-write"
[profiles.security]
model = "gpt-5"
approval_policy = "never"
sandbox_mode = "workspace-write"Verify the connection by launching Codex and running /mcp.
Cursor CLI wiring
Register the Cursor wrapper with npx (explicit selection required; optionally point to your agents dir):
[mcp_servers.subagents]
command = "npx"
args = ["-y", "@loft-902-co/subagents-mcp", "--client", "cursor", "--agents-dir", "/ABS/PATH/TO/agents"]Selection is explicit; there is no default client. Use the Codex or Cursor wrapper.
Usage
Built-in tools
These MCP tools are exposed:
delegate(args): run a single sub‑agentdelegate_batch({ items, token? }): run multiple sub‑agents in parallellist_agents(): list built‑in and disk‑loaded agentsvalidate_agents({ dir? }): validate agent registry filesstart_orchestration({ goal?, cwd?, mirror_repo? }): boot the orchestrator and run*helpor*plan {goal}
Minimal examples (from a client that can call MCP tools):
{ "name": "list_agents" }{
"name": "delegate",
"arguments": { "agent": "review", "task": "Review the last commit for readability" }
}To keep the main context clean in your workflow, prefer calling these tools directly instead of lengthy in‑thread analysis when a sub‑agent fits the task. If your project maintains an AGENTS.md, add suggested call patterns there.
Custom agents registry
The server loads agent definitions from disk and merges them with a few built‑ins. You can point to a registry directory via a CLI arg or env var, or rely on auto‑discovery.
- Preferred:
--agents-dir /abs/path/to/agentsor setSUBAGENTS_AGENTS_DIR=/abs/path/to/agents - Auto‑discovery candidates (in order):
./agents,./.<client-id>-subagents/agents(e.g.,./.codex-subagents/agents), and the repo’s bundleddist/../agents
Markdown agent (agents/<name>.md):
---
profile: debugger
approval_policy: on-request # never | on-request | on-failure | untrusted
sandbox_mode: workspace-write # read-only | workspace-write | danger-full-access
---
You are a pragmatic performance analyst. Identify hotspots, propose minimal, measurable fixes,
and outline validation steps with lightweight metrics.JSON agent (agents/<name>.json):
{
"profile": "debugger",
"persona": "You plan and validate safe DB migrations with rollbacks.",
"approval_policy": "on-request",
"sandbox_mode": "workspace-write"
}Validate and list your registry:
{ "name": "validate_agents" }{ "name": "list_agents" }Start orchestration quickly (shows *help by default or plans a goal):
{ "name": "start_orchestration", "arguments": { "goal": "Plan sprint for onboarding flow" } }Tips:
- Keep personas short, specific, and action‑biased (task checklists beat philosophy)
- Align
approval_policyandsandbox_modewith your client profiles in~/.codex/config.toml
Orchestration model
All work is routed through an orchestrator agent. Calls like:
{
"name": "delegate",
"arguments": { "agent": "security", "task": "Scan for secrets and unsafe shell exec" }
}are transparently rewritten to the orchestrator with an envelope. The server injects available_agents into the envelope so the orchestrator knows what it can delegate to. Token gating ensures only the orchestrator can delegate further. Each request creates a state folder:
orchestration/<request_id>/
├─ todo.json # request lifecycle, steps, status
└─ steps/<step-id>/
├─ stdout.txt
└─ stderr.txtParallelism: use delegate_batch for independent items; results preserve input ordering.
Isolation: set mirror_repo=true to copy your workspace into the ephemeral workdir, or prefer a git worktree for large repos.
Environment variables
Client selection and arguments (explicit configuration required):
SUBAGENTS_CLIENT— client identifier (no default)SUBAGENTS_CLIENT_ID— identifier used in paths and defaultsSUBAGENTS_SERVER_NAME— MCP server name in handshakeSUBAGENTS_WORKDIR_PREFIX— prefix for temporary workdirsSUBAGENTS_CLIENT_ARGS_BEFORE_TASK— JSON array or space‑separated templates overriding CLI args; templates support{profile}and{task}SUBAGENTS_CLIENT_ARGS_AFTER_TASK— JSON array or space‑separated templates overriding CLI args; templates support{profile}and{task}SUBAGENTS_CLIENT_CONFIG— JSON object to override multiple fields at once
Registry and behavior:
SUBAGENTS_AGENTS_DIR— absolute path to youragentsregistrySUBAGENTS_MIRROR_ALL=1— include normally skipped paths when mirroring (e.g.,.git,.env,node_modules)DEBUG_MCP=1— timestamped handshake and tool call debug logs to stderr (stdout remains JSON‑only)
Your client (e.g., Codex CLI) may also require additional env like OPENAI_API_KEY to run real model calls.
Expose planning/tasks as @tasks
Some workflows reference a @tasks/ alias for planning artifacts (e.g., planning/tasks/). You can expose this directory to the client process in two ways:
Option A — Mirror the repo when delegating so the tasks are readable at their native path:
- Pass
mirror_repo: truetodelegate(...)when you want agents to readplanning/tasks/directly in the temp workdir.
- Pass
Option B — Mount an alias via client args (recommended if your client supports context/resource flags):
- Use the env passthrough to add client‑specific flags before the task. Example with a hypothetical
--contextflag:
- Use the env passthrough to add client‑specific flags before the task. Example with a hypothetical
POSIX shells:
export SUBAGENTS_CLIENT_ARGS_BEFORE_TASK='exec --profile {profile} --context @tasks=/ABS/PATH/TO/planning/tasks'Windows PowerShell:
$env:SUBAGENTS_CLIENT_ARGS_BEFORE_TASK = 'exec --profile {profile} --context @tasks=C:\ABS\PATH\planning\tasks'Notes:
- The exact flag name depends on your client (e.g.,
--context,--resource, or similar). The server simply forwards these args. - If your client lacks such a flag, use Option A (
mirror_repo=true) and referenceplanning/tasks/paths directly. - Bundling: on build,
agents/andplanning/are copied intodist/(seescripts/copy-static.js) and both are published to npm. Consumers can reference these packaged paths directly.
NPM installs — packaged paths
Local project install (recommended):
# map @tasks to the package-bundled tasks directory
export SUBAGENTS_CLIENT_ARGS_BEFORE_TASK='exec --profile {profile} --context @tasks=./node_modules/@loft-902-co/subagents-mcp/dist/planning/tasks'Global install (POSIX):
export SUBAGENTS_CLIENT_ARGS_BEFORE_TASK="exec --profile {profile} --context @tasks=$(npm root -g)/@loft-902-co/subagents-mcp/dist/planning/tasks"Windows PowerShell (local install):
$env:SUBAGENTS_CLIENT_ARGS_BEFORE_TASK = 'exec --profile {profile} --context @tasks=.\nnode_modules
a loft-902-co
subagents-mcp
dist
planning
tasks' -replace "\n","\\"Agents registry (from npm package):
- You can also point
--agents-dir(orCODEX_SUBAGENTS_DIR) to./node_modules/@loft-902-co/subagents-mcp/dist/agentsif you want to use the packaged example agents.
Operations
Common commands:
- Build:
npm run build - Start (Codex server):
npm run start:codex→node dist/codex/codex-subagents.mcp.js - Start (Cursor server):
npm run start:cursor→node dist/cursor/cursor-subagents.mcp.js - Dev (tsx):
npm run dev:codexornpm run dev:cursor - Lint:
npm run lint - Tests:
npm test - End‑to‑End:
npm run e2e(requirescodexon PATH and configured profiles)
Troubleshooting highlights:
- MCP handshake stalls: ensure stdout emits only newline‑delimited JSON; use
DEBUG_MCP=1 Unknown tool: confirm you are executing the built JS fromdist/- Agents not found: set
--agents-dirorSUBAGENTS_AGENTS_DIR, or create./agents - Timeouts on large repos: prefer
git worktreeover full mirroring
See docs/OPERATIONS.md for details.
Security
This server runs outside the client sandbox and inherits your user permissions. Keep the tool surface minimal and review agent registries regularly.
Trust boundaries and least‑privilege guidance:
- Narrow tool surface:
delegate,delegate_batch,list_agents,validate_agents - Align
approval_policy/sandbox_modewith client profiles to gate write access and approvals - Prefer
read-onlyfor reviewers; use approvals for higher‑risk work - Avoid mirroring secrets; prefer
git worktreefor sensitive/large repos - Keep stdout clean (JSON‑only); debug to stderr with
DEBUG_MCP=1
See docs/SECURITY.md for a fuller risk/mitigation list and auditing pointers.
Development
- Language: TypeScript (compiled to CommonJS)
- Node: ≥ 18
- Dependencies: minimal (runtime:
zod) - MCP protocol:
2024-11-05
Scripts:
{
"build": "tsc -p tsconfig.json",
"dev": "tsx src/codex/codex-subagents.mcp.ts",
"dev:cursor": "tsx src/cursor/cursor-subagents.mcp.ts",
"start": "node dist/codex/codex-subagents.mcp.js",
"start:cursor": "node dist/cursor/cursor-subagents.mcp.js",
"lint": "eslint . --ext .ts",
"test": "vitest run"
}Project layout (high level):
src/
codex/
codex-subagents.mcp.ts # main MCP server (Codex)
cursor/ # Cursor variant wrapper
orchestration.ts # token gating + request lifecycle
docs/ # integration, operations, security, orchestration
agents/ # example agents registry (load from disk)
dist/ # compiled outputs for MCP wiringFAQ
How do I point the server at my agents directory?
- Pass
--agents-dir /abs/path/to/agentsor setSUBAGENTS_AGENTS_DIR=/abs/path/to/agents. If unspecified, the server auto‑detects./agents,./.<client-id>-subagents/agents(e.g.,./.codex-subagents/agents), then a bundled fallback.
Can I run multiple steps in parallel?
- Yes. Use
delegate_batch({ items }). The orchestrator processes independent items concurrently and returns ordered results.
Where can I see logs and lifecycle state?
- For each request, see
orchestration/<request_id>/todo.jsonand per‑stepstdout.txt/stderr.txtundersteps/<step-id>/.
What if I don’t want to copy the whole repo?
- Leave
mirror_repoasfalse(default) and prefergit worktreewhen you need isolation without heavy copies.
Changelog
See CHANGELOG.md for notable changes. Releases follow SemVer.
License
MIT © 2025 Loft 902 Co LLC. See LICENSE.
Related docs
- Project
AGENTS.md— optional repo guide for usage hints (distinct from runtimeSUBAGENTS_PERSONA.md) docs/INTEGRATION.md— client wiring and configurationdocs/OPERATIONS.md— running, logs, environment, troubleshootingdocs/ORCHESTRATION.md— router, token gating, batch, lifecycledocs/SECURITY.md— risks, mitigations, defaults, auditing
Rules file (orchestrator)
You can run Codex directly with the orchestrator persona as a rules file so it greets and prints the command list (*help) on activation.
POSIX:
npx -y codex exec --profile default --rules ./node_modules/@loft-902-co/subagents-mcp/dist/agents/orchestrator.md "Initialize and show available commands"Windows PowerShell:
npx -y codex exec --profile default --rules .\node_modules\@loft-902-co\subagents-mcp\dist\agents\orchestrator.md "Initialize and show available commands"Notes:
- The rules file is packaged at
dist/agents/orchestrator.mdwhen installed from npm. - If you prefer a local build, point
--rulesatdist/agents/orchestrator.mdfrom your repo afternpm run build.
