Crewlead MCP
Allows using Ollama as an OpenAI-compatible worker backend. The setup flow can detect a local Ollama server, read its model and parallel-slot configuration, test tool calling, and use it to run worker models that write and verify code in parallel.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
A crew lead reads the plans and gives the orders, and the crew does the building. Crewlead does the same with LLMs. Your expensive model stays in your coding agent as the lead. Light worker models, local or remote, do the typing and the retries.
Why
The lead model is the expensive part of an agent run. Most of its output tokens go into typing code it has already designed. Crewlead moves that typing to a worker:
The lead writes a contract and a task list, then reads short reports. It never streams file contents.
Each worker runs its own agent loop and only returns a summary, the changed files and a test result.
A failed check is fed back to the worker, which retries on its own. On a local model those retries cost nothing.
Related MCP server: Roundtable AI MCP Server
Example: a pop-up book film
The same prompt (bench/popup-book) built in Claude Code with Fable 5.2 as the lead. Left: Fable writes every file. Right: Fable plans and reviews in boss mode, and three Qwen 3.8 27B workers on a local llama.cpp server write every file.
Fable alone | Fable + 3 local Qwen workers |
With workers the lead wrote no file and produced fewer output tokens, but the whole run took longer. One run each, so data points and not a benchmark. Token counts are as the API reports them; there are no dollar figures because these runs were not billed per run. Rounds, worker results and the bugs these runs found: docs/testing.md.
Quick start with Claude Code
1. Start a worker model. Any OpenAI-compatible server with tool calling works. On a Mac with llama.cpp:
brew install llama.cpp
llama-server -hf unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL --jinja -c 196608 -np 3 --port 8080The first start downloads the model (about 17 GB). Ollama, LM Studio and vLLM work too. For remote workers instead, or as a fallback, export OPENROUTER_API_KEY in the shell that starts Claude Code.
2. Install the plugin. In Claude Code:
/plugin marketplace add antonellof/crewlead
/plugin install crewlead@crewlead3. Ask Claude to set it up. In your project:
> set up crewleadThe setup tool finds the local servers on their default ports (llama.cpp 8080, Ollama 11434, LM Studio 1234, vLLM 8000), reads the model and the number of parallel slots, checks which API key variables are set, writes crewlead.config.json and sends a tool-calling test to every worker. API keys are never written to the file.
Then ask for work as usual. The lead splits it, hands it to the workers with delegate_batch, and reviews what comes back.
Boss mode (optional). Run npx -y github:antonellof/crewlead boss on in the project, or set CREWLEAD_BOSS=1. From then on each prompt reminds the lead to delegate, and Edit and Write are blocked for it, so every change goes through a worker. boss off turns it off.
Long batches. If workers get cut off, start Claude Code with MCP_TOOL_TIMEOUT=1800000.
Example prompts
Type these to the lead (Claude Code, Codex or Pi). The lead plans, the workers write.
Set up or inspect the workers:
set up crewlead
which crewlead workers do I have, and are they working?Build something new in parallel:
Build a todo CLI in Node with no dependencies: storage in src/store.js, argument parsing
in src/args.js, commands in src/cli.js, a node:test file per module. Use crewlead workers,
one per module, and make npm test pass.Add tests to an existing project:
Write node:test tests for every module in src/ that has none. One crewlead worker per
module, each verified by running its own test file.Refactor:
Split src/server.js into src/routes/, src/middleware/ and src/db/. Write the interface
contract first, then delegate one directory per worker with a node --check verify.
Run the full test suite at the end.Fix a failing test:
test/parser.test.js fails. Find the cause, then have a worker fix it, verified with npm test.Something bigger, the prompt used in bench/popup-book:
Build a 30-second film in Three.js: a paper book opens and four pop-up worlds fold out of
it, a castle, a jungle, a port with boats and snowy peaks. Plain ES modules, no build step.Choose where the work runs:
Use the builder-remote worker for this batch, the local server is busy.Tips:
One file per task. Small tasks with a clear file and a verify command pass on the first try far more often than broad ones like "build the book and the paper system".
Name the files and the functions. The worker knows nothing about your conversation. The lead writes this for you, but the more exact your prompt, the better its contract.
Ask for a verify command.
node --test test/x.test.js,node --check src/x.js, a type check or a lint run. A failing check goes back to the worker, which retries for free on a local model.Turn on boss mode when you want to be sure the lead never writes code itself.
Best setup on a Mac
Measured on a Mac Studio M5 Max with 128 GB, Qwen 3.8 27B with thinking off. Speed comes from bench/speed.js (400-token answers, end to end), and the batch is the same three real crewlead tasks (a CSV parser, an LRU cache, a slugify function, each with tests) on three workers. One run per row.
Server | Weights | Memory in use | 1 stream | 3 streams combined | 3-task batch |
llama.cpp 0.9.0 | 41.2 GB, with a 196K-token cache allocated | 26 tok/s | 54 tok/s | 3 of 3, 99.8 s | |
mlx-vlm 0.7.12 | 28.4 GB | 17 tok/s | 50 tok/s | 3 of 3, 94.3 s | |
mlx-vlm 0.7.12 + MTP drafter | same, plus the MTP drafter | not measured | 33 tok/s | 37 tok/s | not run |
All three made 10 of 10 valid tool calls in the speed test.
Which one:
Three parallel workers, the normal crewlead case: llama.cpp Q4 or MLX 8-bit without the drafter. They tied on the real batch. MLX keeps the weights at 8 bits; llama.cpp has the smaller download and the plain Apache 2.0 base model.
One worker at a time, or a local model you also chat with: MLX 8-bit with the MTP drafter, the fastest single stream. In mlx-vlm 0.7.12 the drafter does not combine with parallel requests: three streams shared about the same 37 tok/s as one.
A Mac with 32 to 48 GB: llama.cpp Q4 with
-np 2and a smaller-c.
MLX setup, three workers:
brew install uv
APC_ENABLED=1 uv run --python 3.12 --with mlx-vlm==0.7.12 -- python -m mlx_vlm.server \
--model robgaleano/Swift-1.5-Qwen3.8-27B-MLX-8bit \
--max-num-seqs 3 --prefill-step-size 4096 --max-tokens 32768 --host 127.0.0.1 --port 8080The first start downloads about 28 GB. Then ask the lead to set up crewlead, or copy examples/configs/mac-mlx.json. setup recognises mlx-vlm but cannot read --max-num-seqs, so set maxConcurrency to the same number. For one fast worker instead, add --draft-model robgaleano/Swift-1.5-Qwen3.8-27B-MTP-MLX-8bit --draft-block-size 4 and set maxConcurrency to 1.
The Swift 1.5 fine-tune is under the Swift Open License v1.0, not Apache: free up to US$1M in annual revenue, a separate license above that. Not tested here: contexts above 64K tokens, thinking on, and raising the GPU memory limit (iogpu.wired_limit_mb), which these sizes did not need on 128 GB. Details: docs/testing.md.
Setup recipes
docs/setup.md has full setups for each host (Claude Code, Codex, Pi, command line) and each kind of worker, with ready-to-copy files in examples/configs/:
File | Workers |
llama.cpp on this machine, 3 parallel slots | |
Ollama | |
LM Studio | |
OpenRouter, no GPU: a default and a cheaper | |
Local first, OpenRouter when the server is down or busy | |
Two llama.cpp servers on your LAN | |
MLX on Apple Silicon (mlx-vlm), 3 parallel workers | |
Template for vLLM, hosted APIs or a company gateway |
Other ways to install
Claude Code, MCP server only
The tools without the skill and the boss mode hooks:
claude mcp add crewlead -- npx -y github:antonellof/crewlead mcpAdd --scope user for every project. claude mcp list should show crewlead ... Connected.
From a terminal, the plugin install is claude plugin marketplace add antonellof/crewlead then claude plugin install crewlead@crewlead. From a local clone, pass the path to marketplace add, or try it for one session with claude --plugin-dir /path/to/crewlead.
Codex
In ~/.codex/config.toml:
[mcp_servers.crewlead]
command = "npx"
args = ["-y", "github:antonellof/crewlead", "mcp"]
startup_timeout_sec = 30
tool_timeout_sec = 1800
env_vars = ["OPENROUTER_API_KEY"] # forwards the key from your shell, never stores itPaste codex/AGENTS.snippet.md into your AGENTS.md so the lead knows how to delegate. Not yet tested in a real Codex session.
Pi
pi install git:github.com/antonellof/crewleadThe extension registers the same tools natively, plus a /workers command. No MCP involved. Not yet tested in a real Pi session.
Command line
npx -y github:antonellof/crewlead init # find local servers, write crewlead.config.json
npx -y github:antonellof/crewlead doctor # test every worker
npx -y github:antonellof/crewlead run "Create fizzbuzz.js and a node:test file for it" --verify "node --test"init --user writes ~/.config/crewlead/config.json for every project. init --url http://host:port/v1 probes a server on another port.
Tools the lead gets
delegate runs one task. delegate_batch runs many in parallel and waits for all. A task has these fields:
Field | Meaning |
| Complete instructions. The worker knows nothing about the lead's conversation. |
| The interface contract. Give the same text to every parallel task. |
| Paths the worker may write. Writes elsewhere are rejected. |
| Command that must exit 0. On failure the worker gets the output and retries. |
| Profile name. Omit for the default. |
| Working directory and a label |
A result looks like this:
{
"id": "parser",
"status": "done",
"report": "Built src/parser.js with parse(). 6 tests pass.",
"filesChanged": ["src/parser.js", "test/parser.test.js"],
"verify": { "command": "node --test test/parser.test.js", "passed": true, "attempts": 2 },
"steps": 9,
"worker": "builder",
"provider": "local",
"model": "qwen3.8-27b",
"usage": { "promptTokens": 41250, "completionTokens": 3120, "costUsd": null },
"seconds": 74.2
}status is done, verify_failed, max_steps or error. Only done means the work was accepted.
list_workers shows the configured profiles. It never returns keys.
setup configures crewlead: detect finds servers and suggests a config, write writes it (project or user scope, never overwriting unless asked, never with inline keys), check tests every worker.
Configuration
setup and init write this file for you. Edit it to add workers or change limits.
A worker is a provider (any OpenAI-compatible endpoint) plus a model. Mix local and remote freely:
{
"providers": {
"local": { "baseUrl": "http://127.0.0.1:8080/v1", "maxConcurrency": 3 },
"openrouter": { "baseUrl": "https://openrouter.ai/api/v1", "apiKeyEnv": "OPENROUTER_API_KEY", "maxConcurrency": 8 }
},
"workers": {
"builder": { "provider": "local", "model": "qwen3.8-27b", "fallback": "builder-remote" },
"builder-remote": { "provider": "openrouter", "model": "qwen/qwen3.8-27b" }
},
"defaultWorker": "builder"
}Tasks go to the local server, three at a time. If it is down, each task moves to OpenRouter. The lead can also pick a profile per task with "worker": "builder-remote".
Lookup order: $CREWLEAD_CONFIG, ./crewlead.config.json, ./.crewlead/config.json, ~/.config/crewlead/config.json. With no file, crewlead uses Ollama at 127.0.0.1:11434 with qwen3.8:27b, or one endpoint from CREWLEAD_BASE_URL, CREWLEAD_MODEL, CREWLEAD_API_KEY and CREWLEAD_MAX_CONCURRENCY.
Provider options
Field | Meaning |
| OpenAI-compatible base URL, ending in |
| Name of the environment variable holding the key. Keep keys out of the file. |
| Max parallel workers on this provider. Match it to your server's parallel slots. Default 2. |
| Extra HTTP headers, for example OpenRouter's |
Worker options
Field | Default | Meaning |
| required | Where the worker runs |
| none | Worker profile to use when this provider is unreachable or rejects the key |
| 0.2 | |
| 40 | Max model turns per task |
| 8192 | Max output tokens per turn |
| none | The model's context per request (per slot on llama.cpp). Old tool output is dropped at 70% of it. |
| 3 | Extra attempts after a failed verify command |
| 12 | Shell commands a worker may run without changing a file. Halfway, and after the same command three times in a row, it is told to report if done; past the cap, |
| true | Set false to remove the |
| none | USD per million tokens, for the cost report when the API does not return a cost |
| none | Extra fields merged into the request, for example |
| built in | Replace the worker's system prompt |
Running local workers
Serve one model with several parallel slots. All workers then share one copy of the weights.
llama-server -hf unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL --jinja -c 196608 -np 3 --port 8080-np 3 gives three slots and splits the context between them, so size -c for three workers. Set the provider's maxConcurrency to the same number (setup reads it from llama.cpp). The model must support tool calling through the chat template (--jinja in llama.cpp).
Qwen 3.8 thinks before every answer by default, which makes builders slow. setup turns it off for Qwen 3 models; by hand it is:
"extraBody": { "chat_template_kwargs": { "enable_thinking": false } }Safety
File tools resolve every path inside the task's working directory. Paths that leave it, directly or through a symlink, are rejected.
ownslimits where a worker can write with the file tools.The
runtool is a real shell with your permissions. A worker can do anything you can do from that shell, andownsdoes not restrict it. Use"allowShell": falseon a profile, or run your agent in a container, when you do not trust the model or the task.With a remote provider, the worker sends file contents from your project to that provider.
Two parallel tasks that own the same path will overwrite each other.
delegate_batchwarns about overlaps and still runs.
Status
Version 0.1. The test suite (npm test) runs the worker loop, the pool, the fallback path, setup, the MCP server and the boss hooks against a mock OpenAI-compatible server. Smoke tested with Qwen 3.8 27B on llama.cpp as the worker and Claude Code as the host. Not yet tested in real Codex or Pi sessions, or with a live OpenRouter fallback. What was run and what broke is in docs/testing.md. One benchmark task exists (bench/), with one run per arm so far, so there are no cost or speed claims here.
Planned: git worktree isolation per worker, async dispatch with polling for hosts with short tool timeouts, a run log with per-task cost, headless Pi as an alternative worker runtime.
License
MIT
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
AI work orchestration for plans, tasks, teams, and coding-agent dispatch.
Hand tasks, bugs and finished work to AI coding agents, and get back a write-up with evidence.
Task tracking built for coding agents. Work is leased, so two agents never take the same SubTask.
Coordination hub for AI coding agents: message teammates, ask humans, audit every event.
Related MCP Servers
- FlicenseNot gradedqualityAmaintenanceEnables a primary coding assistant to delegate tasks in parallel to specialized local sub-agents, sharing project context and synthesizing their responses into a single result.-
- FlicenseNot gradedqualityAmaintenanceEnables a primary AI assistant to delegate tasks to specialized local AI sub-agents in parallel, share project context, and synthesize their responses from within an IDE.-
- FlicenseNot gradedqualityAmaintenanceEnables a primary AI assistant to delegate tasks to multiple specialized coding sub-agents, run them in parallel with shared project context, and synthesize their responses from within the IDE.-
- FlicenseNot gradedqualityAmaintenanceEnables a primary AI assistant to delegate tasks in parallel to multiple specialized AI coding assistants, share project context, and synthesize their responses into a single result.-