One-line: An MCP server that brokers reckon plan-state writes over stdio/SSE so any MCP-capable agent can read and update plans directly, without going through the docs-server HTTP endpoint.

Location: MCP code lives inside the reckon repo at reckon/mcp.py, reckon/_store.py, reckon/_mcp_tools.py. The standalone ~/Code/reckon-mcp/ repo has been retired. _store.py is working code; mcp.py has all tool logic complete with the mcp SDK wired in via FastMCP.


1. Why MCP?

The existing docs-server (reckon/serve.py, port 8765) serves HTML to a browser and exposes a POST /state/<project>/<doc> endpoint for in-page decision capture. Agents can call this endpoint over HTTP, but that requires:

An MCP server removes all three constraints. It speaks the Model Context Protocol natively — Claude Code discovers it via ~/.claude/mcp.json and presents each state operation as a named tool. The agent calls reckon.patch_plan the same way it calls any other tool, with no HTTP machinery in the call chain.

The docs-server stays for the browser UI. The MCP server stays for agent IO. Both write to the same state files via the same atomic-rename versioning protocol.


2. Tool surface

Tool Key args Behaviour
reckon.read_plan project, slug Returns full data blob + current _version.
reckon.list_plans project, status? Lightweight index: slug, title, status, impl, ms, sprint.
reckon.patch_plan project, slug, patch, expected_version JSON merge-patch into data; bumps _version; 412 on conflict.
reckon.append_comment project, slug, section_id, body, author, expected_version Appends to data.notes.
reckon.lock_decision project, slug, key, choice, rationale, by, expected_version Writes data.decisions[key].
reckon.append_followup project, slug, followup, expected_version Appends to data.followups. prompt field required.
reckon.resolve_followup project, slug, followup_id, outcome, by, expected_version Sets resolved_at, resolved_by, outcome.
reckon.set_status project, slug, status, expected_version Updates data.status.
reckon.set_impl project, slug, impl, expected_version Updates data.impl (0..1).

Agent workflow for any write:

  1. Call reckon.read_plan(project, slug) — note the version field.
  2. Call the write tool with expected_version = <that version>.
  3. On conflict (error: "version_conflict"): re-read and retry.

3. State write contract

The version-write contract is identical to POST /state/<project>/<doc> in reckon/serve.py:

Both the docs-server and the MCP server follow this contract. Concurrent writes from a browser tab and an agent are safe — one of them will get a conflict and retry.


4. Distribution

The MCP server is part of the reckon package — no separate install. Development install:

uv pip install -e ~/Code/reckon

Start the MCP server via the unified CLI:

reckon mcp

This runs alongside reckon serve — both commands are part of the same reckon CLI entry point, backed by the same venv.

Once stable, a PyPI publish of reckon will include the MCP server.

Claude Code configuration (~/.claude/mcp.json):

{
  "mcpServers": {
    "reckon": {
      "command": "reckon",
      "args": ["mcp"],
      "env": { "RECKON_STATE_ROOT": "~/docs-server/state" }
    }
  }
}

5. Open decisions


6. What is done vs deferred

File State Notes
reckon/_store.py working code Full atomic versioned IO; all helpers implemented; tested.
tests/test_mcp_store.py working code 6 pytest tests; tempdir fixtures; covers roundtrip, conflict, patch, append, resolve.
reckon/_mcp_tools.py working code Pydantic arg + response models for all 9 tools.
reckon/mcp.py working code Tool logic complete; FastMCP SDK wired; reckon mcp CLI entry active.
PyPI publish deferred After server.py is wired and integration-tested.
SSE transport deferred Open decision transport.

§ Decisions

Should the server support SSE in addition to stdio?

ship stdio first - then implement streamable http

Expose a reckon.search_plans tool with free-text query?

No reckon.search_plans tool was built; discovery + grep over the plan corpus is sufficient.

How to handle multi-project repos (e.g. imas-efit under two logical projects)?

do we ever see this in practice?

Should the MCP server write to index.json (plan inventory)?

if we are managing our inventories with an index.json still

§ Followups

Ship the reckon MCP server

stdio MCP server exposing read/write/list/sprint/inventory tools over the semantic-HTML doc store.
Project: reckon
Plan: reckon-mcp-plan
The MCP server is shipped and in active use — done, no followup.

Shipped: reckon/mcp.py (FastMCP stdio) + _store.py + _mcp_tools.py — read_plan, list_plans, patch_plan, lock_decision, append_followup, resolve_followup, set_status, set_impl, append_comment, add_research, resolve_question, list_followups, list_questions, list_projects, list_sprints, and sprint/inventory tools, all operating on plan HTML. 47 tests pass; in daily use this session.