manifestation-mcp
# manifestation-mcp
An MCP server that makes a coding agent **design-first**. The moment you want to
build something, it doesn't lunge into code — it steps back and interviews you,
teases out a spec and shows it back in **digestible chunks**, turns your sign-off
into a **bite-sized red/green TDD plan**, and then runs a **subagent-driven
development loop** (implementer → reviewer → quality gate) that can grind through
the plan on its own.
It's a portable Python MCP server: the server is the *brain* (a five-phase state
machine + your spec/plan + a skills library) and it runs its *own* subagents
internally via the Claude Agent SDK — so one `run` call can work autonomously for
a long stretch without drifting from the plan.
## The five phases
```
DISCOVERY → interview you; do NOT write code
SPEC → draft a spec; sign off chunk-by-chunk
PLAN → bite-sized red/green TDD task list (YAGNI, DRY)
EXECUTE → per task: implementer subagent → reviewer subagent → gate
DONE → artifacts left under .manifestation/ in your repo
```
State lives as inspectable files in the target repo:
`<repo>/.manifestation/<project-id>/{state.json, spec.md, plan.md}`.
## Requirements
- **Python 3.10+**
- [`uv`](https://docs.astral.sh/uv/) (`brew install uv`)
- For live execution (`run`): the **Claude Code CLI** on your `PATH` and Claude
credentials (`ANTHROPIC_API_KEY` or an existing Claude Code login). The Agent
SDK drives it to run the implementer/reviewer subagents.
- **`git`** in the target repo — the TDD gate uses `git worktree` to verify that a
real failing test preceded the implementation.
## Setup
```bash
cd manifestation-mcp
uv sync
uv run pytest # 96 tests, no network required (1 live smoke skipped)
```
## Run it
Recommended local launcher (robust against uv's editable-install quirk):
```bash
uv run python run_server.py
```
Register it with Claude Code:
```bash
claude mcp add manifestation -- uv run --project /ABS/PATH/TO/manifestation-mcp python /ABS/PATH/TO/manifestation-mcp/run_server.py
```
(For a packaged install via `uvx`/`pipx`, the `manifestation-mcp` console script
works directly.)
### Auto-trigger (optional)
Copy `skill-shim/SKILL.md` into your Claude Code skills (e.g.
`~/.claude/skills/manifestation/SKILL.md`). Its description fires on "build /
implement / add a feature", so the workflow starts itself — you don't have to
invoke anything. Without it, kick off manually with the `/manifestation` prompt or
by calling the `start_project` tool.
## The tools
| Tool | What it does |
|---|---|
| `start_project(brief, repo_path)` | Create a project (validates the repo path); returns interview questions. |
| `submit_answers(project_id, answers)` | Feed answers; asks more or advances to SPEC. |
| `next_spec_chunk(project_id)` | Next digestible spec chunk to review (bounded in size). |
| `review_spec_chunk(project_id, decision, feedback?)` | `approve` / `revise` a chunk. |
| `make_plan(project_id)` | Generate the repo-aware TDD plan; returns full task bodies. Does **not** start execution. |
| `approve_plan(project_id)` | Record the user's sign-off and advance to EXECUTE. |
| `run(project_id, until?, max_agent_calls?, max_budget_usd?)` | Subagent-driven loop with a server-verified TDD gate; checkpoints per step; streams progress; reports `agent_calls`/`cost_usd`. |
| `reset_task(project_id, task_id)` | Unblock a BLOCKED task so `run` can retry it. |
| `status(project_id)` / `list_projects()` | Inspect progress (per-task attempts, findings, approval state). |
Prompt: `/manifestation <brief>`. Resources: `skills://all`, `skill://<name>`.
## Model selection
Nothing is hard-coded to a dated model. By default the server **inherits** the
model the Claude Code CLI is configured with. Override globally with the
`MANIFESTATION_MODEL` env var (e.g. `MANIFESTATION_MODEL=claude-opus-5`), or
per-invocation in code via `AgentSDKClient(model=...)`.
## Safety model (read before using `run`)
`run` executes real subagents in your repo, so understand the trust boundary:
- The **implementer** gets write + `Bash`. That is arbitrary code execution in
the target repo by design — run it only against repos you trust, and prefer a
container/VM for untrusted work. There is no sandbox.
- The **reviewer** and **planner** are read-only two ways: mutating tools are in
the SDK's `disallowed_tools`, **and** a `can_use_tool` permission callback denies
every tool not on their allowlist — covering tools we didn't enumerate (WebFetch,
Task, MCP tools). Safe even in an untrusted repo.
- **TDD is verified server-side, not trusted from prose.** After the implementer
runs, the server runs the task's declared test command itself: it must pass at
`HEAD` (real GREEN), and it must **fail** when re-run against the implementer's
test-only commit (`HEAD~1`) in a throwaway git worktree (real RED). Fabricated
or reordered evidence is caught; fail-closed if git/test can't confirm it.
- A PASS verdict with any trailing findings is treated as a **contradiction** and
fails the task.
- `run` requires an **approved plan**, **checkpoints after every step** (and
resumes a crashed attempt at the review step rather than re-running the
implementer, so edits aren't duplicated), keeps a full **audit trail**, and is
**always bounded** — `max_agent_calls` / `max_budget_usd` (both exposed via MCP),
or a built-in default cap.
- Mutating tool calls are serialized per project by an in-process lock **and** a
cross-process file lock.
- Prompt injection via the brief/answers/spec still flows into subagent prompts —
treat project inputs as untrusted.
## How it stays honest (and testable)
Every LLM interaction goes through one injectable seam (`LLMClient`). Unit tests
inject a `FakeLLMClient`, so the whole state machine — discovery, spec chunking,
plan generation, and the execute loop with its retries and review gates — is
verified with **zero network calls**. The real `AgentSDKClient` sits behind that
seam and is only exercised by the opt-in live smoke test.
## Architecture
```
src/manifestation_mcp/
server.py # MCP tools/prompts/resources (thin wiring)
state.py # Project/Phase/Task model + file persistence + registry
llm.py # LLMClient seam: FakeLLMClient (tests) + AgentSDKClient (real)
agents.py # implementer / reviewer / planner subagent presets
runner.py # CommandRunner seam: SubprocessRunner (real) + FakeCommandRunner
phases/ # discovery, spec, plan, execute, verify (server-side TDD check)
skills/ # bundled Markdown skills, injected into subagent prompts
run_server.py # bulletproof local launcher
skill-shim/ # optional Claude Code auto-trigger skill
```
TDQS
Scored across 11 tools
Each tool maps to a distinct phase or concern: liveness, discovery Q&A, spec chunk retrieval/review, plan generation/approval, execution, task reset, status, and project listing. Pairings like make_plan/approve_plan and next_spec_chunk/review_spec_chunk are sequential rather than overlapping, and the descriptions reinforce their roles.
Most tools follow a verb_noun pattern (start_project, submit_answers, approve_plan, reset_task, list_projects), but health, status, run, and next_spec_chunk deviate by using bare nouns, a bare verb, or a noun-phrase without an action verb. The overall style is still readable and mostly predictable.
11 tools fit the server's staged workflow—discovery, spec, plan, execute, and observe—and each serves a clear purpose. There is no obvious bloat; even the health and list_projects tools are reasonable utility surfaces.
The core lifecycle is well covered: start_project, submit_answers, next_spec_chunk, review_spec_chunk, make_plan, approve_plan, run, reset_task, and status form a coherent path with no dead ends. Minor gaps exist, such as no explicit cancel/stop for a running execution or a revision path for an already-approved plan/spec, but these can likely be worked around.