stepwell
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
stepwell
CLI + MCP server for reading, checking and managing the project docs
(BACKLOG.md, PROGRESS.md, docs/archive/*) in repos following the
STEPWELL method — steps, archive pattern, test-first.
Status: fifteen phases complete. Phase 1 — core library (fault-tolerant parsers,
status/validation reports) · Phase 2 — MCP server + CLI (read tools, resources) ·
Phase 3 — mutations (archive_item, progress_update, each dry-run + apply) ·
Phase 4 — locale profiles (de/en, test-first) · Phase 5 — server name stepwell ·
Phase 6 — review fixes (stale span, synonym regexes, CRLF roundtrip, stale check,
STEP_DUPLICATE) + tool CRUD (backlog_add/update/remove, progress_plan_phase,
CLI ASCII aliases, title parameter). Phases 7–15: CI + field test + packaging,
archive/index hardening, coverage gate, annotations, init/templates, JSON schema
versioning, token economy, STEPWELL naming, language switch to English primary.
Current state and step history: PROGRESS.md.
Principles
Markdown stays the source of truth. The tool reads, validates and assists — it does not replace the docs. If the docs are lost, no data is lost.
Fault tolerance instead of abort. Projects follow the method, not byte-exact: structure drift is reported as a structured warning (
ParseResult<T>withwarnings[]), never as a crash. Every partial result stays queryable.Dry-run first. The two write tools (
archive_item,progress_update) return a plan with a diff preview by default; writing happens only withdryRun: false/--apply— afterwards the result is freshly parsed and verified.Narrow write surface. The error-prone structural operations are automated by the tool (verbatim move, Done Index, status cells, item CRUD, phase planning). Everything else (prose, goal/acceptance texts) is edited directly in the Markdown files by humans/agents.
Multi-project. The project root is passed per tool call / CLI invocation — one server instance serves any number of STEPWELL projects.
File requirement: all four files are mandatory —
BACKLOG.md, PROGRESS.md, docs/archive/BACKLOG_ARCHIVE.md,
docs/archive/PROGRESS_ARCHIVE.md. If one is missing, the project does not
load (hard error with a clear message).
Format legend (canonical: PLAYBOOK §3 + §7):
Symbol | Meaning | ID series |
🔴 critical · 🟠 high · 🟡 medium · 🟢 low | backlog priority = section |
|
🔵 test gap | backlog priority = section | no series — explicit ID required |
⬜ open · 🔄 in progress · ✅ done · ⛔ blocked | step status in | steps |
other series letters ( | thematic series, not priority-bound | consecutive, never reused |
Related MCP server: markdown-mcp
Requirements & setup
Node.js ≥ 22.18 — the repo ships TypeScript source and uses Node's native type stripping (no build step).
npm install
npm run typecheck # strict, covers src AND tests
npm run test # Vitest, protocol-faithful against the fixtures
npm run test:watchMCP server
Server name stepwell (transport stdio, entry packages/mcp/src/serve.ts).
This repo already wires the server into opencode.json (restart opencode after
config changes). Other MCP clients (Claude Desktop, Cursor, …) follow the same
pattern:
{
"mcp": {
"stepwell": {
"type": "local",
"command": ["node", "/path/to/stepwell-tool/packages/mcp/src/serve.ts"],
"enabled": true
}
}
}Manual verification with the inspector:
npx @modelcontextprotocol/inspector node packages/mcp/src/serve.tsThe test suite covers the same protocol path automatically
(InMemoryTransport + client, plus a real stdio handshake test).
Distribution (two channels)
MCP server:
npx stepwell(orserve.ts) — operational, tools as below. The published package ships compileddist(since 10.4/H1) and therefore runs directly fromnode_modules—prepublishOnlybuilds before publishing.SKILL.md:
packages/mcp/skills/stepwell/SKILL.md(included in the npm pack) — portable signpost for skill ecosystems (Claude Skills, Gemini CLI, …): which tool when, gates (release/content), test-first, status maintenance only via tools. It replaces neither the MCP server nor PLAYBOOK.md — both remain binding.
Tools
All tools take root (absolute path to the project root) per call. All JSON text
payloads are compact (no indentation — token economy, E1). docs_validate,
progress_update and archive_item also deliver their data as
structuredContent only on opt-in with structured: true (M3/9.7, dedupe since
E1 — default is text only); error responses (isError: true, including
PROJECT_NOT_INITIALIZED) carry no structuredContent.
Errors (missing mandatory file, unknown ID/phase) return isError: true
with a clear message — the server does not crash.
Read
Tool | Parameters | Result |
|
| Aggregate: open items per priority, 🔄 steps + assigned phases, ✅ quote of the table, all findings + warnings, |
|
| Items of BACKLOG.md without |
|
| Merge view for one item ID across open BACKLOG ↔ Done Index ↔ BACKLOG_ARCHIVE, including |
|
| Rows of the progress table |
|
| Detail block including |
|
| Validate findings (consistency rules) + collected parse warnings, |
Write (dry-run + apply)
Tool | Parameters | Behaviour |
|
| Plans the verbatim move of an item: remove the block (span-based) from BACKLOG.md, in the archive copy flip the checkbox → |
|
| Sets the status cell(s) of the steps (missing rows are added, name derived from the scope bullet); on 🔄 creates a detail-block skeleton under "Active Phases" ( |
|
| Creates an open item at the end of the target section: ID with convention check ( |
|
| Changes title/priority/text/section in the block format (span recomputation, checkbox and |
|
| No hard delete: block moves verbatim into BACKLOG_ARCHIVE (checkbox stays |
|
| Plans a phase ahead: table rows for all steps ( |
Response formats: dry-run returns the plan {dryRun, changes:[{file, description, before, after, diff}]}; apply returns {written, verification:{ok, messages}}.
With detail: "summary" (E1) dry-run changes are projected onto {file, description, beforeLines, afterLines} + top-level marker detail: "summary" —
the default stays "diff" with the full preview (safety note unchanged).
Locale profiles
The doc files may be formatted in German or English — mixed within the same repo is forbidden; one language per project. The tool separates:
Reading: always language-tolerant (zero-config). Parser and validator recognise the role markers of both languages via union matching —
Erledigt-Index|Done Index,Ort|Location,erledigt|done,Ziel|Goal,Abnahme|Acceptance,Verifikation|Verification,Umfang|Scope,Fortschritt|Progress,Laufende Phasen|Active Phases,abgeschlossen|completed,Stand:|As of:.Writing: the
localeoption onarchive_itemandprogress_update/backlog_remove("de" | "en"; default = auto-detection from the file context, tie →ensince 14.3). Generated texts (index line, done/verification/removed markers, skeletons) follow the target language; CLI equivalent:--locale de|en.More languages:
packages/core/src/profile.tsholds the role synonyms — a new language is a new key per role, no parser rebuild.
Resources (resource templates)
The root is percent-encoded into the URI segment (Windows paths
contain : and \); the read callback decodes it. Content verbatim,
text/markdown:
stepwell://{root}/backlog → BACKLOG.md
stepwell://{root}/progress → PROGRESS.md
stepwell://{root}/archive/{kind} → kind = "backlog" | "progress"
stepwell://{root}/phase/{phase} → phase context: phase verbatim + table rows
+ merged backlog item bodies in step order (G5/12.6)
stepwell://{root}/hashes → SHA256 per doc file (application/json;
hash short-circuit, E2/12.5 — fast-path foundation E3)
stepwell://templates/{kind} → skeletons of the four mandatory files
(kind = "backlog" | "progress" |
"backlog-archive" | "progress-archive")M4 alternative check (G5): resource instead of tool — the phase context is a pure read path, and the composition happens at read time instead of as a duplicate in the files (anti-drift): a subagent gets phase + item bodies in one read, without a new tool growing the surface.
Example: stepwell://D%3A%5Cproj%5Cdemo/backlog
Project init (M8, variant A): for newly created projects the agent reads the four
skeletons from stepwell://templates/{kind} and creates the files itself —
deliberately no init_project write tool (M4 guardrail: keep the write surface
small); the skeletons live canonically in stepwell-core (projectTemplates) and are
finding-free under docs_validate. The init-fallback guidance (PROJECT_NOT_INITIALIZED)
points to this path.
CLI
packages/mcp/src/cli.ts — runnable directly in the workspace repo
(node packages/mcp/src/cli.ts …); from the installed package
(npm i -g stepwell or npx stepwell) under the bin name
stepwell.
Human output on stdout; --json returns the core payloads with a leading
schema version field (currently 2, bumped with N1/13.2 — a resource-URI change is a MAJOR contract). Field contract per command:
Command | Fields (besides |
|
|
|
|
|
|
|
|
|
|
|
|
| like |
Contract rule (M6/Decision 16): a breaking change to this field set ⇒
bump schema (in lockstep with the npm MAJOR).
Releases (version policy, L6)
Format:
CHANGELOG.mdper Keep a Changelog 1.1.0,[Unreleased]on top, curated user-relevant aggregates. Redundancy rule: no git-log dump, no duplication of Done Index/BACKLOG_ARCHIVE — item/commit history stays in the STEPWELL files. Date formatYYMMDD/HHMM(Decision 11) instead of ISO — documented deviation.Lockstep SemVer (Decision 16): root,
stepwellandstepwell-corealways carry the same version. MAJOR = breaking in the tool/JSON/resource contract (always together with theschemafield), MINOR = new tools/features, PATCH = fixes. 0.x until the passed field test;1.0.0= release moment.Publish checklist: (1) curate
Unreleasedin the CHANGELOG, (2) bump the version in all threepackage.json(lockstep), (3) CHANGELOG section[<version>] - <YYMMDD/HHMM>, (4) git tagv<version>, (5) publish onlystepwell(npm publish --otp, dist-taglatest; core is distributed as a dependency), (6) CI jobpack-smokemust be green — dynamic since 10.5/H1, proves the handshake against the installed artefact (server stepwell).
# Status aggregate
node packages/mcp/src/cli.ts status --root <project> [--json]
# List/filter backlog — icons or ASCII aliases (red/kritisch/p1, hoch/p2, mittel/p3, niedrig/p4, blue/test/p5)
node packages/mcp/src/cli.ts backlog --root <project> [--priority red,yellow] [--open false] [--section HIGH] [--json]
# Progress table — status as icon or alias (open, running/wip, done, blocked)
node packages/mcp/src/cli.ts progress --root <project> [--status done] [--json]
# Consistency check (exit 1 on findings — CI-suitable)
node packages/mcp/src/cli.ts validate --root <project> [--json]
# Archive a completed item (dry-run preview, then --apply)
node packages/mcp/src/cli.ts archive --root <project> --id H1 [--note "Commit abc1234"] [--locale en] [--apply]
# Maintain step status (dry-run preview, then --apply) — --title renames the block heading
node packages/mcp/src/cli.ts progress-update --root <project> --phase "Phase 2" --step 2.2 --status running [--title "New title"] [--note "…"] [--checkpoint <sha>] [--locale en] [--apply]Invalid values exit with code 2 and the list of allowed aliases (e.g.
🔴=red/kritisch/p1, …, ⬜=open, 🔄=running/wip, ✅=done, ⛔=blocked).
Exit codes: 0 success (or no validate findings) · 1 error or
validate findings · 2 usage error (unknown command, missing required option).
CI (optional)
This repo uses GitHub Actions (.github/workflows/ci.yml): install → typecheck
→ test (JUnit + coverage report as artefact) → validate --root . (exit 1 on
doc findings flips the job).
For smaller projects the local run suffices — the pipeline is overkill when nobody looks at it:
npm install && npm run typecheck && npm run test && node packages/mcp/src/cli.ts validate --root .STEPWELL projects may copy ci.yml as a template; the method (PLAYBOOK) does not
require CI.
Warning codes
Parse warnings arise when parsing individual files (drift tolerance),
validate findings check cross-file consistency (docs_validate
collects both). Convention warnings affect only open files — archives
are append-only and never flagged. A UTF-8 BOM (U+FEFF) at the start of a file
is silently tolerated (stripped deterministically, T5/9.13) — no warning.
Code | Level | Meaning |
| parse | no priority suffix in the title — priority taken from the section emoji |
| parse | several priority markers in the title — one is captured |
| parse | unknown priority emoji (e.g. 🟣) — |
| parse | item without |
| parse | item ID without a title after the separator |
| parse | unknown status icon in the table — |
| parse | table row without a status column |
| validate |
|
| validate | item ID appears twice |
| validate | ID violates |
| validate | Done Index entry without an archive block |
| validate | completed archive block ( |
| validate | 🔄 row without a matching detail block |
| validate | detail block without a 🔄 step (orphaned or planned ahead via |
| validate | step number appears twice in the progress table — |
| validate | legacy |
| validate | root without a STEPWELL project (all four files missing) — exactly one finding with guidance instead of an error desert; |
Typical workflow (agent + stepwell)
1. docs_status → where do we stand? Which priorities are open?
2. backlog_list --open → what is next? (BINDING: sequential by priority)
3. (work on the code, test-first — the agent edits prose directly)
4. progress_plan_phase → plan a new phase ahead (rows + scope skeleton)
5. progress_update (🔄) → step started: keep table + detail block clean
6. progress_update (✅) → step done; if the phase is complete, the block moves into the archive
7. backlog_add/update → create/change items format-safe (instead of hand-editing)
8. archive_item → archive the completed item verbatim + Done Index
9. backlog_remove → move an obsolete item into the archive (without a done marker)
10. docs_validate → must be clean before committingThe PLAYBOOK rules (sequence, test-first, commit discipline, archive pattern) live in
docs/PLAYBOOK.md; the review checklist in
docs/LESSONS.md.
Architecture
Design rule (M4/Decision 17): the tool surface stays small — tools only for concrete structure/read operations, no guide/meta tools; method knowledge lives in PLAYBOOK.md, SKILL.md and the resources. Every new tool (or new parameter surface) justifies the surface growth via the alternative check (parameter on an existing tool/resource instead of a new tool) — documented like the docs_review decision (L5).
packages/
├── core/ stepwell-core — zero dependencies, no MCP dependency
│ ├── src/backlog.ts BACKLOG parser (sections, item blocks, Done Index)
│ ├── src/progress.ts PROGRESS parser (table, detail blocks) + scopeSteps
│ ├── src/archive.ts archive parser (ArchiveItem = BacklogItem + doneLine)
│ ├── src/project.ts loadProject (4-file requirement, lazy + memoized), backlogShow
│ ├── src/status.ts docsStatus (aggregate)
│ ├── src/validate.ts docsValidate (consistency rules + parse warnings)
│ ├── src/mutations.ts plan/apply: archive_item, progress_update, backlog CRUD, planPhase
│ ├── src/aliases.ts ASCII aliases for priority emojis and status icons (CLI)
│ ├── src/diff.ts line-based mini diff for the plan preview
│ ├── src/profile.ts locale profiles: role synonyms de/en (read union, write canonical)
│ └── tests/fixtures/ project-a (clean) + project-b-drift (cases D1–D15)
│ + project-d-tablefirst (table before detail blocks),
│ README there = working specification
└── mcp/ stepwell — thin transport layer over core
├── src/server.ts createDocsServer (all tools + resources)
├── src/tools.ts tool registration (JSON payloads, isError wrapping)
├── src/resources.ts resource templates (percent-encoded root)
├── src/serve.ts stdio entry
└── src/cli.ts stepwell command lineStack: TypeScript (strict,
NodeNext,noUncheckedIndexedAccess,exactOptionalPropertyTypes), npm workspaces, Vitest, MCP SDK v1.x stable (^1.30.0) + zod v3. Deliberately decided against build/bundle steps: Node ≥ 22.18 executes the TS source directly (type stripping), import specifiers therefore end on.ts.Data model:
ParseResult<T> = { value, warnings[] },Warning = { code, file, line?, message }— item blocks carryspan(lines) andraw(verbatim) as the basis of the verbatim move.Tests: 318 tests, developed test-first (RED → GREEN). Mutations in tests run exclusively against temp copies of the fixtures — the originals are read-only and protected by a test.
Development
npm install && npm run typecheck && npm run test # acceptance before every completion
npx vitest run packages/core # core only
npx vitest run packages/mcp # MCP/CLI onlyNew features follow the STEPWELL method: plan → package in PROGRESS.md →
implement test-first → verification → commit → maintain status. Details:
AGENTS.md.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
Related MCP Connectors
Build and publish pages, manage collections, records and files in a Markerloop workspace.
Generate and review codebase docs. 77 tools; scoped, credit-approved repository reviews.
Stateless advisor + validator for Conducted Development: kickoff, artifact validation, rule checks.
Publish Markdown incident reports, ADRs, RFCs and runbooks as web pages, with team spaces.
Related MCP Servers
- AlicenseBqualityDmaintenanceManages backlog items and todos with status tracking, priorities, and dependencies. Stores work items as human-readable markdown files with automatic versioning.7MIT
- AlicenseBqualityCmaintenanceEnables reading and optionally editing existing Markdown files under a configured root folder, including section-level queries, overwrites, appends, deletions, and front matter management, over stdio with no network dependencies.2MIT
- AlicenseAqualityCmaintenanceEnables AI coding agents to consult a project's Git-versioned Markdown knowledge base over local stdio — checking knowledge health, listing the catalog, searching topics, and reading guides before acting. Access stays read-only, so project guidance, decisions, and lessons learned remain shared with human teammates and traceable beside the code.41MIT
- FlicenseNot gradedqualityAmaintenanceEnables Codex projects to read Git-backed context, acceptance criteria, progress, and handoff packages, and to append validated, audited progress events with matching project-record commits.-