make your ai track the progress of your project without drifting off
概要
A Zig MCP server that lets coding agents persist project goals, progress notes, documentation indexes, and session freshness checks without embedding an LLM. The server is intentionally mechanical. Agents do the analysis, scanning, summarizing, and planning. The MCP validates and stores the structured JSON they provide, writes project_progress.md, and records SQLite metadata so future sessions can detect drift. Markdown and registered-document writes go through unique sibling temp files before rename to reduce partial documentation writes. Leftover *.tmp artifacts are ignored by snapshots and git. SQLite connections use WAL mode, synchronous=NORMAL, and a short busy timeout so concurrent agent sessions can wait through transient database locks. Install Zig and a SQLite development package that provides sqlite3.h and a linkable sqlite3 library. On Windows, make sure sqlite3.lib and sqlite3.dll are available to the compiler/runtime.
README
project-progress-mcp
A Zig MCP server that lets coding agents persist project goals, progress notes, documentation indexes, and session freshness checks without embedding an LLM.
The server is intentionally mechanical. Agents do the analysis, scanning,
summarizing, and planning. The MCP validates and stores the structured JSON they
provide, writes project_progress.md, and records SQLite metadata so future
sessions can detect drift.
Markdown and registered-document writes go through unique sibling temp files
before rename to reduce partial documentation writes. Leftover *.tmp artifacts
are ignored by snapshots and git.
SQLite connections use WAL mode, synchronous=NORMAL, and a short busy timeout
so concurrent agent sessions can wait through transient database locks.
Build
Install Zig and a SQLite development package that provides sqlite3.h and a
linkable sqlite3 library.
zig build
On Windows, make sure sqlite3.lib and sqlite3.dll are available to the
compiler/runtime. If SQLite is not globally discoverable, pass explicit paths:
zig build -Dsqlite_include=C:\sqlite\include -Dsqlite_lib_dir=C:\sqlite\lib
Alternatively, build against the SQLite amalgamation by providing sqlite3.c;
the directory containing that file must also contain sqlite3.h:
zig build -Dsqlite_source=C:\sqlite-amalgamation\sqlite3.c
This repository has been verified on Windows with Zig 0.16.0 using
-Dsqlite_source and the official SQLite amalgamation.
Smoke Test
Run static preflight checks that do not require Zig:
node .\scripts\preflight.mjs
After building, run the stdio MCP smoke test:
node .\scripts\smoke-test.mjs .\zig-out\bin\project-progress-mcp.exe
On non-Windows hosts, omit the .exe or pass the compiled binary path. The
smoke test creates a temporary project, calls the core MCP tools through
Content-Length framed JSON-RPC, checks index validation rejects bad payloads,
initializes a tiny git repository when git is available, and removes the
temporary project afterward.
MCP transport
The server speaks JSON-RPC 2.0 over stdio using Content-Length framed MCP
messages.
On Windows, expose the binary via an NTFS junction so Cursor sees a no-space
path (Cursor shell-splits spaced command paths, and copying under
%USERPROFILE%\.cursor\ triggers ACL/sandbox behavior that blocks stdio):
zig build
node .\scripts\install-cursor-mcp.mjs # creates \pp-mcp junction
# or pick your own no-space path on the same drive:
node .\scripts\install-cursor-mcp.mjs --link=D:\bin\pp-mcp
Then point Cursor at the junctioned executable (use the path the install script prints):
{
"type": "stdio",
"command": "D:/pp-mcp/project-progress-mcp.exe"
}
The junction requires no admin rights; it lives on the same drive as the repo
and stays in sync with every zig build (no copies to keep fresh). See
.mcp.example.json for the full entry and a zig build run dev entry. Tool
argument examples live under examples/.
Agent contract
The MCP does not scan code semantically and does not generate documentation. Agents must:
- Get user permission plus a full goal, MVP, and completion criteria before bootstrapping an empty project.
- Scan non-empty projects themselves and submit structured summaries.
- Keep
project_progress.mdcurrent throughproject_progress.index. - Run
project_progress.session_checkbefore work. - If drift is reported, inspect the changed files and update progress records before continuing.
- Run
project_progress.record_snapshotafter progress documentation is updated.
Tools
tools/list exposes nested input schemas for sections, entries, and documents.
project_progress.instructions
Returns the required JSON shapes and workflow.
project_progress.bootstrap
Creates .project-progress/progress.sqlite, stores the user-approved goal, and
creates project_progress.md if missing. user_authorized must be true and
goal, mvp, and completion_criteria must be supplied and nonblank.
Required arguments:
{
"project_root": "D:/path/to/project",
"user_authorized": true,
"goal": "Full project goal",
"mvp": "MVP description",
"completion_criteria": ["criterion one", "criterion two"]
}
project_progress.session_check
Compares current git state and file modification times against the last stored
snapshot. Returns git_drift plus files the agent must inspect if the project
moved since the last MCP save, including files deleted after the previous
snapshot. It also returns project_empty, file_count, has_snapshot, and
snapshot_file_count so the agent can choose bootstrap or scan flow.
Each file drift item includes legacy size/mtime_ns fields plus structured
current and snapshot file states so agents can distinguish new, modified,
and deleted files without an extra database read.
Git status is captured with branch information plus explicit upstream,
ahead, and behind fields from the local repository. The MCP does not fetch
from remotes; agents should fetch first if they need network-fresh remote state.
session_check is read-only with respect to MCP initialization; if no database
exists, it returns mcp_store_initialized: false.
It also returns a structured action_required value (bootstrap_authorization,
scan_project, inspect_drift, repair_consistency, or ready) and
can_continue, so an agent does not need to infer the session gate from prose.
File drift includes SHA-256 content hashes in addition to size and mtime. This
catches same-size edits and makes comparisons useful across filesystems with
different timestamp precision.
When a database exists, the check is recorded as a check session while git
comparisons still use the latest snapshot session as the saved baseline.
project_progress.index
Stores the agent supplied progress index and optionally replaces the root
project_progress.md. If full_markdown is omitted, the MCP renders
project_progress.md from the supplied sections and entries. The stored
section index is replaced on each call so removed sections do not remain in
future context. Index replacement is transactional.
Entries may include entry_id. Entries with the same entry_id are updated in
place; entries without entry_id are appended as history notes.
The response contains a monotonically increasing revision. Pass the revision
returned by context as expected_revision when updating an existing project;
a stale agent receives Conflict instead of overwriting newer progress.
The MCP stores a hash of the root Markdown alongside the revision. context
and session_check expose markdown_consistency so an interrupted write or
database failure can be detected.
The MCP enforces stable lowercase section IDs, bounded status labels, and
priorities 1 high, 2 normal, 3 later so future agents can sort and update
work deterministically. completion_criteria, section anchors, and document
tags must be arrays of strings.
project_progress.register_docs
Registers documentation files and summaries. When content is supplied, the MCP
writes the documentation file under the project root. Document paths must be
safe relative paths without absolute roots, drive prefixes, empty segments, .,
or .., and tags must be an array of strings. Documentation database
registration is transactional. Before writing content, the MCP resolves the
nearest existing parent and rejects symlink/junction paths that escape the
project root.
project_progress.record_snapshot
Stores current git state and file mtimes after the agent has updated progress documentation. The previous file snapshot is replaced so resolved deletions do not keep reappearing as drift. Snapshot replacement is transactional.
project_progress.context
Returns the saved goal, indexed project_progress.md sections, recent entries,
documentation records, and freshness metadata for the next agent session.
Stored *_json fields, including registered document source_json, are returned
as structured JSON values.
The response also includes work_queue.active, work_queue.blocked, and
work_queue.next, derived from progress entries with active, blocked, and
planned statuses ordered by priority.
Like session_check, this is read-only with respect to MCP initialization; if no
database exists, it returns empty collections with mcp_store_initialized: false.
The response promotes latest_check and latest_snapshot for quick resume
decisions, and also includes recent latest_sessions history. Session history
includes session_kind values such as check and snapshot.
Latest sessions include persisted git upstream/ahead/behind metadata.
The response includes the current progress revision and
markdown_consistency fields.
Session drift_json values use a consistent {git_drift,file_drift} shape for
both checks and snapshots.
Bug reports
Open investigation notes live under docs/bugs/. See in particular
docs/bugs/2026-08-07-large-tree-session-timeout-opaque-errors.md
for timeouts / connection closes on large trees and opaque InvalidRequest tool errors.
インストール
This server does not publish a one-line install command.
Open the repository installation guide