Package Exports
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@precode/mcp) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@precode/mcp
Open, agent-agnostic MCP server that turns a spec into a self-correcting, verified build. Works with any spec (SPEC.md, .specify, .spec-workflow) and best with a PreCode .precode/ package. Runs locally on your agent and your tokens.
Install: @precode/mcp on npm. Docs: useprecode.vercel.app/mcp.
It fixes the loop/goal failure other spec MCPs ship with:
- Goal re-anchoring — the agent re-reads the goal every phase, so long builds don't drift.
- Hard definition-of-done — when you declare checks in
.precode/checks.json, the MCP runs them itself and the verdict comes from the real exit codes. A fabricated "it passed" cannot move a task to done. - Closed verify → fix → re-verify — gaps come back with fixes and the loop will not advance past them.
- Honest escapes — a check that genuinely can't pass here (needs a secret, a deploy, a paid service) is
precode.defer_task'd with a reason and surfaced inTODO_FOR_YOU.md, never silently skipped.
At the end it writes an IMPLEMENTATION.md (what was built) and a TODO_FOR_YOU.md (what you still need to do — secrets, env, deploy).
Install
Recommended: install globally, then point your MCP host at the precode-mcp binary:
npm i -g @precode/mcp{
"mcpServers": {
"precode": {
"command": "precode-mcp",
"env": { "PRECODE_TELEMETRY_DISABLED": "1" }
}
}
}npx fallback (use quiet flags so install logs do not pollute stdio):
{
"mcpServers": {
"precode": {
"command": "npx",
"args": ["-y", "--silent", "@precode/mcp"],
"env": {
"PRECODE_TELEMETRY_DISABLED": "1",
"NPM_CONFIG_LOGLEVEL": "silent",
"npm_config_update_notifier": "false"
}
}
}
}Full per-host copy-paste configs: useprecode.vercel.app/mcp.
| Host | Config location | How |
|---|---|---|
| Cursor | .cursor/mcp.json |
JSON — precode-mcp (after npm i -g @precode/mcp) |
| Claude Code | .mcp.json (project) |
npm i -g @precode/mcp && claude mcp add ... precode-mcp |
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json |
JSON — same shape as Cursor |
| Codex CLI | ~/.codex/config.toml |
npm i -g @precode/mcp && codex mcp add precode -- precode-mcp |
| VS Code | .vscode/mcp.json |
JSON — uses "servers" not "mcpServers" |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
JSON — same shape as Cursor |
| Antigravity | ~/.gemini/antigravity/mcp_config.json |
Agent panel → Manage MCP Servers → View raw config |
Cursor / Claude Desktop / Windsurf / Antigravity — install globally first (npm i -g @precode/mcp), then:
{
"mcpServers": {
"precode": {
"command": "precode-mcp",
"env": { "PRECODE_TELEMETRY_DISABLED": "1" }
}
}
}Claude Code:
npm i -g @precode/mcp && claude mcp add --env PRECODE_TELEMETRY_DISABLED=1 --transport stdio --scope project precode -- precode-mcpCodex CLI:
npm i -g @precode/mcp && codex mcp add precode -- precode-mcpVS Code — note "servers" wrapper and optional "cwd": "${workspaceFolder}":
{
"servers": {
"precode": {
"type": "stdio",
"command": "precode-mcp",
"cwd": "${workspaceFolder}",
"env": { "PRECODE_TELEMETRY_DISABLED": "1" }
}
}
}Do not use bare npx -y @precode/mcp without --silent and npm log suppression — install logs on stdout corrupt the JSON-RPC channel. Use the npx fallback JSON at the top of this file if global install is impossible.
The server reads .precode/ from the directory the host runs it in (PRECODE_ROOT overrides). Local stdio only — the build loop needs your filesystem.
Telemetry
Telemetry is off unless PRECODE_TELEMETRY_URL is set. When enabled, the server sends privacy-safe beta events such as mcp_next_task, mcp_verify_pass, and mcp_finalize; it hashes the local root path and never sends spec contents, file contents, secrets, or task text. Set PRECODE_TELEMETRY_DISABLED=1 to force-disable it.
Use
- Drop a PreCode export (or run
precode.adopt_specon your ownSPEC.md). - Run the
precode_buildprompt, or just tell your agent: "build this with the precode loop."
Local Verification
npm run test:stdioThe smoke test launches the built MCP server over stdio, verifies the tool list, runs a real executable check, confirms a failing check (and a fabricated passing report) keep the task open, confirms the task closes only once the real check passes, reads precode://docs, and writes the final TODO_FOR_YOU.md. npm test runs the full edge-case suite (test/run.mjs + test/edge.mjs). See EDGE_CASES.md for the verified matrix and known limitations.
Tools
| Tool | Does |
|---|---|
precode.get_goal |
Re-anchor on the goal + progress |
precode.status |
Read-only snapshot of tasks, checks, and deferred work |
precode.next_phase |
Alias for the next phased build step |
precode.next_task |
Pull the next step + acceptance criteria |
precode.verify |
Runs the task's checks.json checks; marks done only on real exit-0. Optional taskIndex targets a specific ready task (parallel agents) |
precode.defer_task |
Honest escape for a check that can't pass here (logged to TODO) |
precode.record_implementation |
Append to the implementation ledger |
precode.finalize |
Write TODO_FOR_YOU.md |
precode.adopt_spec |
Map a non-PreCode spec into .precode/ (+ starter checks.json) |
Checks — the executable done-gate
Declare checks in .precode/checks.json. Each auto check is run by the MCP from the project root on every precode.verify; the task closes only when its real exit code is 0.
{
"checks": [
{ "id": "typecheck", "name": "Type-check", "kind": "auto", "cmd": "npm run typecheck" },
{ "id": "build", "name": "Build", "kind": "auto", "cmd": "npm run build" },
{ "id": "test", "name": "Tests", "kind": "auto", "cmd": "npm test", "expect": "/\\d+ passing/" },
{ "id": "deploy-task-3", "name": "Smoke route /health", "kind": "auto", "cmd": "curl -fsS localhost:3000/health", "taskIndex": 3 },
{ "id": "secrets", "name": "Prod secrets set in real accounts", "kind": "manual" }
]
}kind: "auto"— executed; pass = exit 0 (andexpectsubstring//regex/matches output if set). OptionaltimeoutMs(default 120s).kind: "manual"— never auto-passed; surfaced as a human gate inTODO_FOR_YOU.md(a manual-only task closes with its gate routed to you).taskIndex(aliastask) — bind a check to one task; it then runs only at that task's verify. Setting it impliesscope: "task". Omit to run on every task's verify.- A task never closes on a self-reported pass. Reported
checkResultsare advisory only. A check declared with an emptycmdis treated as unconfigured and HOLDs the task — wire a real command, mark itmanual, orprecode.defer_task. adopt_specinfers real commands from your project (package.jsonscripts,Cargo.toml,go.mod) so a fresh spec is verifiable out of the box. Only when nothing is detected does it write empty placeholders that HOLD until you fill them. Failure advice references the actual command that ran, anddefer_taskis refused if the task's checks actually pass (so it can't be used to dodge verifiable work). Globalmanualgates are listed once inTODO_FOR_YOU.md, not repeated per task.
Security: the runner only executes commands you put in your own repo's checks.json — the same trust level as the agent already running your build. Commands run with a timeout and captured output. Because checks.json lives in your repo, gate tampering shows up in your diff.
Multi-agent / concurrent verify
precode.verify runs the checks lock-free and holds .precode/.lock only for the brief tasks.md mutation. So two agents can verify different ready tasks at the same time — their checks execute in parallel and only the tiny state write serializes.
- Pass
taskIndexto verify a specific dependency-ready task (e.g.precode.verify { "taskIndex": 4 }). Omit it to verify the next ready task. This is how parallel agents target distinct tasks. - If two verifies hit the same task, exactly one closes it; the other gets a graceful "Task #N was already verified by a concurrent run" (no clobber, no double-close).
- Locks are token-owned — only the holder releases; a wrong token cannot drop someone else's lock. The mutation lock briefly blocks-and-retries rather than failing fast.
- Stale locks (e.g. crashed agent) are stolen after 5 minutes via compare-and-unlink. Override with
PRECODE_LOCK_STALE_MS(milliseconds) — e.g.10000for 10s in local dev. - Failed verify records the failure under the lock and releases it so another agent can retry the same open task.
parallelGroup: controls scheduling — any member may be returned by precode.next_task, and parallel agents verify them concurrently by passing each member's taskIndex.
See EDGE_CASES.md for the full stress-test matrix.
Resources
| Resource | Contains |
|---|---|
precode://goal |
Goal and task progress |
precode://docs |
Bundled .precode/docs/*.md specs |
precode://tasks |
Current phased task plan |
precode://acceptance |
Acceptance criteria and self-checks |
precode://progress |
Implementation ledger and human TODOs |
Release
Tagged releases publish to npm via GitHub Actions. See RELEASE.md.