Skip to main content

MCP servers

Three stdio servers ship in mcp/, installable into Claude Code, Grok Build (if MCP-capable), or any MCP client:

  • anchor-prompts — makes a lesser model behave (doctrine, templates, preflight)
  • model-fleet — makes a frontier model delegate to OpenAI-compatible endpoints
  • project-orchestrator — binds to one project and exposes a limited .plans/ surface (list/claim/complete, deps suggest, stale warnings)

Until a Preferred orchestrator is set for a project, a frontier session may act as temporary coordinator (see CLI — Preferred orchestrator).

Supported SDK versions

The servers work against both MCP Python SDK majors: mcp[cli]>=1.2.0,<3.

SDK 2.0 removed mcp.server.fastmcp and renamed FastMCP to MCPServer. Because the decorator surface (tool, prompt, resource) and run() are unchanged across the rename, each server resolves the class once at import and works either way — so a fresh install gets 2.x and an operator pinned to 1.x is not broken.

Install with the bound, not bare:

pip install "mcp[cli]>=1.2.0,<3" requests pyyaml

That range is what the servers support, and it is what their pyproject.toml files declare. Anchor's own CI pins a single major (requirements-dev.txt) so a new SDK release cannot turn a blocked push red with no code change — and a separate weekly sdk-unpinned job resolves the real range and imports every server against it, so the detection is kept as a signal rather than traded away.

If mcp seems missing

This repository has its own top-level mcp/ directory. It has no __init__.py, so it is only a PEP 420 namespace portion — an installed mcp package found later on sys.path still wins, and running from the repo root with the SDK installed resolves the real package normally.

It matters only when the SDK is not installed: from the repo root the directory turns the honest No module named 'mcp' into the more confusing No module named 'mcp.server'. If you see that, install the SDK — do not go looking for a path problem.

anchor-prompts

The discipline as callable tools, so weak models fetch structure instead of having to remember it:

  • get_doctrine / get_system_prompt(model) / get_template(name) — the doctrine, mythos-core (or per-model variant), and the four templates
  • tune_prompt(rough_task) — cheap-model spec rewriting via the fleet
  • preflight_check(task_spec)deterministic gate: missing sections or unresolved TODOs → "do not execute." This is the check small models always skip, done in code where it can't be skipped.
  • Prompt scaffolds: plan_task(goal), critique_work(spec, work)

model-fleet

The delegation arm of the orchestrator pattern:

  • delegate(task_spec, role, thinking) — ship a self-contained spec to the right tier; output format-gated on return
  • delegate_parallel_review(task_spec, work) — two independent critics must agree; disagreement → HOLD (the Space-1 verify-twice rule, available everywhere)
  • list_fleet — capped one-line-per-endpoint summary (name, tier, context size, capability phrase) + role routing; no base_url/model/quirk detail
  • lookup_endpoint(name) — full non-secret detail for one endpoint, on demand only
  • fleet_health — reachability sweep

project-orchestrator

Per-project limited plan coordinator (mcp/project-orchestrator/). One server process is bound to one project root (--project or .anchor/mcp.yaml). Tools only touch that tree’s .plans/ — no promote, no plan-file writes, no MCP-initiated git push.

CapTools (v1)Notes
L0project_info, plans_list, plan_read, conventions_get, plans_inventory_for_deps, plans_stale_reportstale/tier-gap warnings are warn-only
L0.5plans_suggest_dependenciesheuristic token overlap; propose only (no LLM)
L1plans_claim, plans_release, plans_completecomplete is move only (client asserts Done when)

Toolsets are role-scoped (scripts/roles.py): start the server with --role planner or --role critic and the L1 lifecycle tools are never registered — the session cannot see them (deny by omission, not refusal). --role executor or no --role keeps the full surface. Role scoping hardens the orchestrated path only; a session without the server is bound by prompt doctrine alone.

Uses the same plan_select / plan_lease rules as /work and work_once — including auto-refusing a claim on a plan with a human Assignee (a person completes it; agents may still edit its body). Use a distinct --agent-id from fleet_watch timers. Full matrix and registration examples: mcp/project-orchestrator/README.md.

claude mcp add anchor-prompts -- python /abs/path/mcp/anchor-prompts/server.py
claude mcp add model-fleet -- python /abs/path/mcp/model-fleet/server.py
claude mcp add myapp-orch -- python /abs/path/mcp/project-orchestrator/server.py \
--project /abs/path/to/myapp --agent-id cursor-mid-1 --tier mid