Multi-Agent AI Orchestration via Model Context Protocol (MCP)
An MCP server that provides Claude Code with access to specialized CLI AI agents including Qwen, Gemini, Aider, Goose, Codex, OpenCode, and Claude itself. Features intelligent fallback, environment isolation, and configurable output filtering.
Before you begin, make sure you have:
- Claude Code installed (installation guide)
-
API Keys ready:
- OpenAI API key (for Aider, Qwen) - Get one here
- Anthropic API key (for Aider with Claude) - Get one here
- Python 3.8+ and Node.js 16+ installed
claude mcp add-json subagents '{"command": "npx", "args": ["mcp-subagents@latest"], "env": {"OPENAI_API_KEY": "your-openai-key", "ANTHROPIC_API_KEY": "your-anthropic-key"}}'
# Python-based agents
pip install aider-chat
# Node.js-based agents
npm install -g @qwen-code/qwen-code
npm install -g @google/gemini-cli
npm install -g @anthropic-ai/claude-code
# Binary-based agents
curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | bash
npm install -g opencode-ai@latest
npm install -g @openai/codex # Requires ChatGPT Plus/Pro
# Optional agents
pip install goose-ai
npm install -g opencode
// Basic usage
await run_agent({
agent: "aider",
task: "Add error handling to my login function"
});
// With specific files
await run_agent({
agent: "qwen",
task: "Refactor this code for better performance",
files: ["src/utils.py", "src/helpers.py"]
});
That's it! You now have access to multiple AI agents through Claude Code.
If you're new to MCP or just want basic functionality, the Quick Start above is all you need. The server uses intelligent defaults:
- Automatic fallback: If one agent fails, others are tried automatically
- 5-minute timeout: Tasks that take too long are cancelled
- Clean output: Verbose logs are filtered for readability
- Environment sharing: API keys are passed to all agents
Want different API keys per agent or custom settings? Add them to your MCP configuration:
{
"mcpServers": {
"subagents": {
"command": "npx",
"args": ["mcp-subagents@latest"],
"env": {
"OPENAI_API_KEY": "sk-your-openai-key",
"ANTHROPIC_API_KEY": "sk-ant-your-anthropic-key",
"OPENAI_BASE_URL": "https://api.openai.com/v1",
"AIDER_MODEL": "gpt-4o",
"AIDER_AUTO_COMMITS": "true"
}
}
}
}
Create ~/.config/mcp-subagents.json
for complete control:
{
"global": {
"enableFallback": true,
"defaultTimeout": 600000,
"maxConcurrentTasks": 10
},
"qwen": {
"enabled": true,
"priority": 10,
"maxConcurrent": 2,
"env": {
"OPENAI_API_KEY": "sk-custom-qwen-key",
"OPENAI_BASE_URL": "https://api.qwen.ai/v1"
}
},
"aider": {
"enabled": true,
"priority": 20,
"flags": ["--model", "gpt-4o", "--yes-always"],
"env": {
"OPENAI_API_KEY": "sk-custom-aider-key",
"AIDER_AUTO_COMMITS": "true"
}
},
"gemini": {
"enabled": true,
"priority": 30,
"model": "gemini-2.5-flash"
}
}
Agent | Best For | Installation | Authentication |
---|---|---|---|
Aider | File editing, bug fixes, features | pip install aider-chat |
OPENAI_API_KEY or ANTHROPIC_API_KEY |
Qwen | Code generation, refactoring | npm install -g @qwen-code/qwen-code |
OPENAI_API_KEY |
Gemini | Analysis, documentation | npm install -g @google/gemini-cli |
Google account login |
Goose | Project exploration, automation | curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | bash |
Provider-specific auth |
Claude | Reasoning, code review | npm install -g @anthropic-ai/claude-code |
Anthropic account |
OpenCode | Terminal AI agent | npm install -g opencode-ai@latest |
Provider auth |
Codex | AI coding assistant | npm install -g @openai/codex |
ChatGPT Plus/Pro account |
{
"global": {
"enableFallback": true, // Auto-retry with other agents
"defaultTimeout": 300000, // 5 minutes in milliseconds
"maxConcurrentTasks": 10 // Max parallel tasks
}
}
{
"agentName": {
"enabled": true, // Enable/disable agent
"priority": 10, // Fallback order (1-100, lower = higher priority)
"maxConcurrent": 2, // Max parallel tasks for this agent
"timeout": 600000, // Agent-specific timeout
"model": "gpt-4o", // Default model to use
"flags": ["--custom", "flags"], // CLI flags to pass
"env": { // Environment variables
"API_KEY": "value"
}
}
}
Environment variables are merged in this order (later overrides earlier):
- System environment (from your shell)
- MCP server environment (from MCP configuration)
- Agent-specific environment (from config file)
- Task-specific environment (from API calls)
Execute a task with a specific agent.
await run_agent({
agent: "aider", // Required: agent name
task: "Add unit tests", // Required: task description
// Optional parameters
model: "gpt-4o", // Override default model
files: ["src/app.py"], // Restrict to specific files
workingDirectory: "/path/to/project", // Set working directory
env: { // Additional environment variables
"CUSTOM_VAR": "value"
},
flags: ["--verbose", "--debug"], // Additional CLI flags
fallbackAgents: ["qwen", "gemini"] // Custom fallback order
});
Important: run_agent
returns only the last 10 lines of output to save context. Use get_task_status
to retrieve full output.
When your task contains special characters, newlines, or is very long, use file-based tasks to avoid terminal display issues:
// 1. Write your complex task to a temp file
await fs.writeFile('/tmp/complex-task-123.txt', `
Analyze the entire codebase and:
- Find all instances of "TODO" comments
- Create a report with line numbers
- Suggest implementation for each TODO
- Use proper error handling patterns
`);
// 2. Pass the file path with file:// prefix
await run_agent({
agent: "claude",
task: "file:///tmp/complex-task-123.txt" // Note: absolute path required
});
Important File-Based Task Rules:
-
Only temp directories allowed:
/tmp/
,/var/tmp/
, orTMPDIR
-
Must use absolute paths (starting with
/
) - File is deleted immediately after reading
- Useful for: Tasks > 200 chars, multi-line instructions, special characters
Get status of all available agents.
const agents = await list_agents();
// Returns: { agents: [{ name, available, status, version, ... }] }
Check task status and retrieve output with fine control.
// Get status with default output (last 20 lines)
const status = await get_task_status({ taskId: "task_123" });
// Get specific output range
const status = await get_task_status({
taskId: "task_123",
outputOptions: {
offset: 50, // Start from line 50
limit: 100, // Get 100 lines
fromEnd: false, // Count from beginning (true = from end)
maxChars: 10000 // Limit total characters
}
});
Some agents support directory restrictions for security:
-
Aider:
--subtree-only
restricts to git subtree -
Goose:
-p, --path
sets working directory -
Others: Use
workingDirectory
parameter for basic isolation
- Child processes receive clean environment
- API keys are isolated per agent when configured
- No access to system credentials unless explicitly provided
- 5-minute timeout prevents runaway processes
- Smart output handling - minimal by default, full access on demand
- Automatic process cleanup on errors
- Fast-fail for common error patterns
// Use Goose to analyze, then Aider to implement
const analysis = await run_agent({
agent: "goose",
task: "Analyze the architecture of this codebase and suggest improvements"
});
const implementation = await run_agent({
agent: "aider",
task: `Based on this analysis: ${analysis.output}, refactor the main module`,
files: ["src/main.py"]
});
// One-off custom configuration
await run_agent({
agent: "qwen",
task: "Generate API documentation",
env: {
"OPENAI_BASE_URL": "https://custom-endpoint.com/v1",
"OPENAI_MODEL": "qwen-coder-plus"
},
flags: ["--verbose", "--output-format", "markdown"]
});
try {
const result = await run_agent({
agent: "gemini",
task: "Complex analysis task",
fallbackAgents: ["qwen", "claude"] // Try these if Gemini fails
});
if (result.fallbackUsed) {
console.log(`Primary agent failed, used ${result.executedBy} instead`);
}
} catch (error) {
console.log("All agents failed:", error);
}
Agent shows "needs_auth"
# Check agent status
await list_agents();
# Set API keys in MCP config or run agent auth
codex login
opencode auth login
claude auth login
Task times out
{
"global": {
"defaultTimeout": 1800000 // 30 minutes
}
}
Output handling
// run_agent returns only last 10 lines by default
const result = await run_agent({ agent: "qwen", task: "Analyze code" });
// Get more output using get_task_status
const fullOutput = await get_task_status({
taskId: result.taskId,
outputOptions: { limit: 100 } // Get 100 lines
});
Agent not found
# Verify installation
which aider
which qwen
which gemini
# Install missing agents
pip install aider-chat
npm install -g @qwen-code/qwen-code
Enable detailed logging by setting environment variables:
{
"env": {
"DEBUG": "1",
"VERBOSE": "true"
}
}
When agents fail with authentication errors:
-
Check agent status first:
const agents = await list_agents(); // Look for "needs_auth" status
-
Verify API keys are set correctly:
- For Aider/Qwen: Check
OPENAI_API_KEY
in MCP config - For Claude models in Aider: Check
ANTHROPIC_API_KEY
- Keys should start with correct prefix (
sk-
for OpenAI)
- For Aider/Qwen: Check
-
Run agent-specific auth commands:
codex login # For Codex opencode auth login # For OpenCode claude auth login # For Claude
-
Test with minimal config:
await run_agent({ agent: "aider", task: "test auth", env: { "OPENAI_API_KEY": "sk-your-key" } });
When an agent hangs or times out:
-
Increase timeout for long tasks:
{ "global": { "defaultTimeout": 1800000 }, // 30 minutes "aider": { "timeout": 3600000 } // 1 hour for Aider }
-
Check task complexity:
- Break large tasks into smaller steps
- Use specific file restrictions with
files: []
- Provide clear, focused prompts
-
Monitor running tasks:
const status = await get_task_status({ taskId: "task_123" }); // Check status, output, and elapsed time
-
Kill stuck processes:
- Restart Claude Code to clean up orphaned processes
- Check system process manager for agent processes
To check if agents are properly installed:
-
Quick verification:
# Check installation paths which aider && echo "✓ Aider installed" which qwen && echo "✓ Qwen installed" which gemini && echo "✓ Gemini installed" # Check versions aider --version qwen --version
-
Use the validate command:
mcp-agent-orchestrator --validate
-
Check Python/Node environments:
# For Python agents (Aider, Goose) pip list | grep -E "aider|goose" # For Node agents (Qwen, Gemini, OpenCode) npm list -g | grep -E "qwen|gemini|opencode"
-
Common installation fixes:
# Python agents python -m pip install --upgrade aider-chat # Node agents npm install -g @qwen-code/qwen-code --force npm install -g @google/gemini-cli --force # Path issues export PATH="$HOME/.local/bin:$PATH" # Python export PATH="/usr/local/bin:$PATH" # Node
git clone <repository>
cd mcp-subagents
npm install
npm run build
# Type check
npm run type-check
# Run Python tests
python -m unittest discover
# Manual testing
npm run dev
# Type check
npm run type-check
# Manual testing
npm run dev
This guide provides comprehensive testing procedures for the MCP Subagents system.
-
Environment Validation
# Check system requirements mcp-subagents --validate # Run full diagnostics mcp-subagents --doctor # View setup guide mcp-subagents --setup
-
Required Test Environment
- OS: macOS or Linux (Windows not supported)
- Node.js: v18.0.0 or newer
- API Keys: OpenAI and Anthropic keys configured
- CLI Agents: At least 2 agents installed for fallback testing
# Test 1: Clean installation
npm install -g mcp-subagents@latest
mcp-subagents --validate
# Test 2: Configuration validation
echo '{"invalid": json}' > ~/.config/mcp-subagents.json
mcp-subagents --validate # Should show config error
# Test 3: Missing dependencies
# Uninstall an agent and verify error handling
npm uninstall -g @qwen-code/qwen-code
mcp-subagents --validate # Should show missing agent
Each agent should be tested for:
- Basic execution: Simple commands work
- Shell execution: Commands that spawn subprocesses
- Error handling: Invalid commands fail gracefully
- Timeout handling: Long-running commands can be terminated
# Test examples for each agent:
# Aider - File editing and shell commands (Python)
echo "check how many .ts files are in src/" | aider --yes-always
# Qwen - Real-time timestamped execution (Node.js)
echo "list files in this directory" | qwen -y -p
# Gemini - Non-interactive execution (Node.js)
echo "what files are here?" | gemini -p "what files are here?"
# Claude - Terminal-based coding (Node.js)
echo "analyze this directory structure" | claude --print
# OpenCode - AI coding agent (Node.js/Binary)
echo "count Python files" | opencode run
# Goose - Task automation (Binary)
echo "find all TODO comments" | goose run -t "find todos"
# Codex - AI coding assistant (Node.js)
echo "create a simple function" | codex exec
Test the MCP server functionality:
// Test 1: Basic agent execution
await run_agent({
agent: "qwen",
task: "echo 'hello world'"
});
// Test 2: Fallback mechanism
await run_agent({
agent: "nonexistent-agent", // Should trigger fallback
task: "simple task",
fallbackAgents: ["qwen", "aider"]
});
// Test 3: Real-time streaming
const taskId = await run_agent({
agent: "qwen",
task: "for i in {1..5}; do echo $i; sleep 1; done",
async: true
});
// Monitor streaming output
await get_task_status({
taskId,
outputOptions: { streaming: { waitForNew: true } }
});
// Test 4: Process termination
await terminate_task({ taskId });
Test error scenarios and recovery:
// Test 1: Invalid API keys
process.env.OPENAI_API_KEY = "invalid-key";
// Should fail gracefully with helpful error
// Test 2: Agent timeouts
await run_agent({
agent: "qwen",
task: "sleep 3600", // Long task
timeout: 5000 // 5 second timeout
});
// Test 3: Resource exhaustion
// Run multiple concurrent tasks to test limits
// Test 4: Malformed configuration
// Test with invalid JSON, missing required fields
# Test 1: Memory usage monitoring
# Run long tasks and monitor memory with `ps` or `htop`
# Test 2: Concurrent execution
# Run multiple agents simultaneously
# Test 3: Large output handling
# Tasks that generate >10MB of output
# Test 4: Process cleanup verification
# Ensure no zombie processes remain after termination
✅ Installation
- [ ] Clean installation works
- [ ] Dependencies are correctly detected
- [ ] Configuration validation catches errors
- [ ] Help commands provide useful information
✅ Agent Execution
- [ ] Each agent executes commands successfully
- [ ] Shell command execution works (not just AI responses)
- [ ] Real-time output streaming functions
- [ ] Error messages are helpful and actionable
✅ MCP Integration
- [ ] All MCP tools respond correctly
- [ ] Streaming API works as documented
- [ ] Task status tracking is accurate
- [ ] Termination works without leaving zombies
✅ Error Handling
- [ ] Invalid inputs fail gracefully
- [ ] API errors provide helpful guidance
- [ ] System errors don't crash the server
- [ ] Recovery mechanisms work correctly
✅ Performance
- [ ] Memory usage stays bounded
- [ ] No resource leaks over time
- [ ] Concurrent operations work smoothly
- [ ] Process cleanup is complete
Issue | Symptoms | Solution |
---|---|---|
No agents ready | All agents show "not available" | Run --setup guide, install agents |
API rate limits | 429 errors from agents | Check API quotas, use fallback |
Zombie processes | Processes remain after termination | Check process group cleanup |
Memory growth | Memory usage increases over time | Monitor output buffer limits |
Streaming delays | Output appears in batches | Verify PTY usage and agent flags |
When reporting bugs, include:
-
System info:
mcp-subagents --doctor
output -
Agent status:
mcp-subagents --validate
output - Reproduction steps: Exact commands used
- Expected vs actual: What should happen vs what happens
- Logs: Full error messages and stack traces
-
src/agents/
: Individual agent implementations -
src/config.ts
: Configuration management -
src/manager.ts
: Task orchestration and fallback logic -
src/utils/process-manager.ts
: Process spawning and cleanup -
src/server.ts
: MCP protocol implementation
MIT License - see LICENSE file for details.