feature-tracker-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@feature-tracker-mcp what approvals are waiting for me?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
feature-tracker-mcp — "oz"
A project-agnostic tracker for the case where one person directs several AI coding sessions at once and has become the bottleneck.
The problem is not "track features." It is: several tracks are in flight, each session is blind to the others, decisions surface constantly, and reading everything is the job. Most of those decisions are mundane and delegable. A few are genuinely yours. Nothing separates them, so you read all of it.
Each project gets its own Postgres instance in a .oz folder — the project owns its tracker outright.
Table of Contents
Related MCP server: Waystone
The model
Goals are objectives, not filing labels. Each carries what is being achieved, what done means, what is deliberately excluded, and what constrains it. A worker reads its goal before starting and declines work that falls inside the non-goals — that is the difference between executing a queue and pursuing an objective.
Features belong to exactly one goal. Ids are allocated atomically (DIP-17, GLG-4) and never change, so anything citing one in a commit message keeps resolving. They carry acceptance criteria, dependencies, and a parity record.
Gates are decisions a session must not take alone — architectural, install, spend, irreversible. Raising one banks the question and moves on; the principal answers a round of them in one sitting.
Parity is tracked across eight dimensions, because work is only done when it is done in all of them: code, unit tests, functional tests, documentation, screens, builds, infrastructure, features.
Studies are investigations whose deliverable is a document and a decision. Pre-registered, and allowed to conclude "do not build this".
Conferrals are the record of Claude working a judgement out with a peer model — ChatGPT, a harder-thinking Claude, DeepSeek. Every goal, feature, study, checkpoint and finished diff requires one, enforced by the tools rather than requested by the docs.
Commands
Driven through the /oz skill.
Working
Command | Does |
| What can be worked now — not done, nothing it depends on outstanding |
| What is waiting, and on what |
| Drive a goal's features to done, here |
| Spawn the backlog maintainer and a worker per goal, each in its own worktree |
| Cross-track state, including uncommitted work per worktree |
| Broadcast to every worker, including ones not yet running |
| Wind down leaving it resumable: stash every worktree, record where. |
| Work interrupted by a shutdown, and putting it back |
| Who is alive, how long since each was heard from, what each holds |
Shaping the work
Command | Does |
| Both passes in order — goals, then the features under them. The order matters: criteria written under an unrefined goal are written against nothing |
| Draft and record every unrefined goal in one pass; gate what the docs cannot settle |
| Give every open feature acceptance criteria in one pass |
| Define a new goal — the conversation produces the name |
| Work through a derived checklist a page at a time |
| Project-wide coverage analysis — what nothing tracks, including goals that should exist. The scoped forms bound what is filed, not what is examined |
| What the project is not |
| Invention, ending in one checkpoint |
| Investigate; deliverable is a document and a recommendation |
| Record something that would otherwise be lost |
| Record a dependency |
Decisions and reporting
Command | Does |
| Watches, and prompts you with the pending gates as a pickable checklist. The only path from a raised gate to a decision |
| The gate queue |
| Counts, items, the append-only record |
| Coverage, and the cheap probe that populates it |
| Goals and hygiene |
| Dump, list, and restore the tracker — take one before any bulk pass |
The peer
One reasoner cannot find its own blind spot, and the principal cannot always supply one. When the question is a derivation they would have to take on trust, asking them is not review — it is handing over an unread liability. That is the problem this exists to solve.
A conferral is an exchange, not a verdict. It runs rounds: put the actual draft and reasoning to the peer, settle what it says it lacked, check what it asserts, disagree where you disagree, keep going while it is still converging, stop when circling. How it ends decides who hears about it.
Outcome | Consequence |
| Recorded. The principal is not involved |
| The peer moved Claude and the change was applied. Recorded with what changed |
| Promoted to the principal, carrying both positions |
Soft gates never reach the principal. architectural and install forks are raised into the loop — gate_raise refuses one with no conferral, because escalating instead of thinking is what made the queue unreadable. spend and irreversible are always the principal's: two models agreeing is not authorisation to spend someone's money or to take an action with no undo.
The peer drafts where it should. Study pre-registration is written by the peer and attacked by Claude, because a method is attacked best by whoever did not write it, and the falsifier is the question a single reasoner is least able to ask itself.
A feature cannot reach done until its diff has been through a peer — checked against the database, not asserted in the same call that closes the work.
Enforcement is mechanical because prose failed. The actor field has accepted the value chat since the first commit and across 76 recorded events has never once held it. A mechanism that recommends conferral is a mechanism that gets skipped.
The framing is kept verbatim. Claude chooses what the peer sees, so agreement can be manufactured with a leading question — and from outside, that is indistinguishable from independent agreement. asked and the peer's own account of what it lacked are what make it distinguishable.
Agents
Agent | Does |
| One per goal, own worktree. Claims, builds, evidences, releases. Refines its own items and gates only genuine forks |
| What a worker structurally cannot: dependencies across goals, cross-goal duplication, staleness |
| Per turn, cheap model. Records what a turn implied that would otherwise be lost |
| Dedups; splits what peers can settle from what only the principal can |
| Investigates, writes it up, links what it spawned and killed |
No agent may call gate_decide. An agent approving its own gate makes the mechanism theatre.
Install
git clone https://github.com/spe-investigator/feature-tracker-mcp.git
cd feature-tracker-mcp
.\install.ps1Builds, copies the /oz skill and the agents into ~/.claude, and registers the server. Requires Node 18+ and Docker; the database is created in the project's .oz folder on first use, and Docker is started automatically if it is not running.
Design notes
The database is the state, and the bus. Sessions cannot see each other, so coordination goes through Postgres rather than messages: a message is lost if its recipient is not running, and unauditable afterwards. Messaging is at most a doorbell.
Ids are allocated atomically. Two sessions reading a file, seeing the next free number and both taking it is how duplicate migration numbers happen. A counter incremented inside the inserting transaction makes it impossible.
Claims are leases, not flags. A worker that dies holding a flag blocks its feature forever; a lease expires and the work returns to the pool.
Counts are two numbers, never a ratio. The numerator is what converged; a growing denominator means real work was found. 12/16 → 12/20 reads as 75% → 60% — a drop — when nothing regressed and two genuine issues were named.
Standup reads working trees, not just commits. Measured here: every worktree reported zero commits ahead while two held real uncommitted work — a new crate in one, four untracked files in another. A standup built on git history calls active tracks idle.
Rejection means two things. "Not for this goal" is a routing error and the feature is moved; "not wanted" is a decision about the project. Only the second suppresses re-derivation. Every refusal keeps its rationale, and accumulated they define what the project is not — the difference between "no" and "no, because we decided X".
Drafting is derivable; decisions are not. Refinement is a batch pass over everything, with gates raised only for what the documents cannot settle. A flow that asks a question per item spends attention on the part that needed no input.
Studies are pre-registered. Method, decisive evidence and falsifier are recorded before execution, because a method chosen after seeing the data can be selected for the answer it produces. Revisions are counted rather than silent.
Thresholds are measured, not guessed. Duplicate detection uses trigram similarity at 0.30 — real restatements score 0.45–0.63, unrelated titles under 0.10, and an initial guess of 0.45 let a genuine duplicate through at 0.449.
Backups are verified, not just written. A dump is read back before it is reported as taken — the expected tables must be present and the file non-trivial. pg_dump can exit zero having written almost nothing, and an unverified dump is a file rather than a backup.
The schema has no migrations. All DDL lives in src/db.ts as idempotent statements applied on every connect, so a schema change ships with the code that needs it and lands the moment any session connects. The cost is that nothing records when a change landed, there is no down-migration, and anything destructive — dropping a column, narrowing a type — has no safe expression in this pattern and needs a real migration path first.
An objective is lifted once, not re-derived. Goals carry doc_ref — the file and heading their objective came from — and refined_commit, the tree it was read at. Without the pointer a refine pass has to re-read the whole source document to locate each goal's section, once per goal, and afterwards nothing distinguishes an objective taken from the document from one invented where the document was thin.
Incorporation, not annotation. converged_after_revision requires stating what changed, and the tool refuses the outcome without it. Feedback logged beside an unchanged draft changes nothing and reads as diligence — which is worse than not conferring, because it looks like the mechanism worked.
Derivation is goal-scoped; gap analysis is not. derive_features asks what one objective implies, so it can only find work inside a goal somebody already wrote. Work between two goals, or outside all of them, is invisible to it by construction — and a missed feature inside a goal surfaces the next time anyone reads that goal, while a missing goal never surfaces at all. /oz gaps is the only thing looking from far enough back to find one, and a missing goal is a hard gate because gate_reopen cannot unwind a goal that already has work routed into it.
A gate blocks work, and answering one has to unblock it. gate.blocks was written from the first commit and read by nothing, so a feature whose blocking question was unanswered was still handed out and coded straight past. feature_ready now skips those and reports them rather than hiding them; feature_unblocked is what a resuming worker calls, because answering a gate changes a gate row and nothing else.
What is not built
/oz starthas never been executed. The spawn line is documented but background spawning is untested here. Try/oz taskon one goal first.The interactive flows are unrun.
/oz refine,/oz design,/oz studyand/oz goalare written and their tools are tested individually; the conversations are not.Parity probes exist for
documentationandcodeonly.buildsandinfrastructureneed a real check — a build, an applied migration — and a reference search would only pretend to answer them.screensis switched off.No test suite. The conferral enforcement has 11 passing checks; nothing else does.
The conferral loop has never been run for real. The enforcement is tested against fabricated conferrals, which is exactly what it cannot detect. Whether the exchanges actually happen is a property of the sessions, not of this code.
The markdown renderer that would regenerate a human-readable tracker from the database does not exist, so a migrated markdown tracker cannot be diffed against the database to prove nothing was lost.
Available Tools
64 toolscheckpointA
Record everything agreed in one design session, in a single transaction. A design conversation produces features, risks, data sources and decisions together and they only make sense together; recording them one call at a time leaves a half-captured design if anything fails, and nothing afterwards can tell which rows came from that sitting. Duplicates are reported rather than skipped or forced — being told 'three of your fourteen already exist' is information the design session should see.
Inputs: items (required), cwd, goal, note, +2 more.
confer_digestB
Whether the peer channel is earning its place: where it changed the answer, and where it could not settle something. Both halves are reported, because showing only the first would make the mechanism unfalsifiable.
Inputs: cwd.
confer_historyB
What a subject has been through with a peer, newest first. Omit both filters for the whole project. Read this before re-litigating something — an argument already had and settled is on the record here.
Inputs: cwd, limit, subject_id, subject_kind.
confer_recordA
Record an exchange with a peer model as its own act. Use for a diff review before a feature is marked done — a worker cannot both review its own work and close it in one call, so the review has to exist first — and for any conferral worth keeping that is not attached to another write. The subject must already exist.
Inputs: subject_id (required), subject_kind (required), cwd, conferral.
db_backupA
Dump the project's tracker to .oz/backups and verify it. Take one before any bulk change — a refine pass, a restore, a migration. A dump restores anywhere, unlike a copy of the data directory, and the dump is checked before being reported as a backup: an unverified backup is a file, not a backup.
Inputs: cwd, label.
db_backupsB
Backups on disk, newest first.
Inputs: cwd.
db_restoreA
Restore a backup over the live tracker. DESTRUCTIVE and irreversible: it takes a safety backup first and refuses without confirm: true. Restoring the wrong file over a working tracker is the mistake with no undo.
Inputs: name (required), confirm (required), cwd.
derive_featuresA
Derive a feature checklist for a goal from the documentation and existing features, and put it straight in the backlog at 'proposed' — recorded, not yet agreed. Defining a goal must produce work, not just an objective. Call project_boundaries FIRST: re-proposing something already refused wastes a review round and teaches the principal that the queue does not learn. Candidates matching an existing feature are reported rather than created.
Inputs: goal (required), candidates (required), cwd, note, +2 more.
derive_gapsA
Record what a gap analysis found. Feature gaps land in the backlog at 'proposed' under one proposal, so derive_page/derive_review work on them unchanged. Goal gaps become HARD gates: creating a goal reshapes what every feature hangs off, and gate_reopen cannot unwind it once work routes in, so it stays the principal's however well the pair agrees. Call gap_scan first and check every candidate against the refusals it returns — a settled refusal is a decision, not an oversight. Finding nothing is a real outcome; record it as one rather than manufacturing candidates.
Inputs: cwd, note, actor, scope, +3 more.
derive_listC
Derivations and how far each review has got.
Inputs: cwd, goal.
derive_pageC
A page of a derivation still awaiting review. Deliberately small — a long list gets skimmed, and a skimmed checklist is worse than none because it looks reviewed.
Inputs: id (required), cwd, page, per_page, +1 more.
derive_reviewA
Review backlogged features: promote to 'agreed', reassign, or drop. Rejection means two different things — 'wrong_goal' is a routing error and the feature is still wanted, so it is MOVED not dropped; 'not_wanted' is a decision about the project. A rejection REQUIRES a rationale: accumulated rationales are how the project defines what it is not, and 'no' without a reason cannot be reasoned from.
Inputs: decisions (required), cwd, actor.
directive_ackA
Acknowledge a directive so it stops being returned to this worker.
Inputs: id (required), worker (required), cwd.
directive_issueA
Broadcast stop, pause, resume or rescan to every worker. Broadcast rather than addressed, so a worker that starts after the directive was issued still sees it — the case a point-to-point message silently misses. Scope it to a goal, or omit for all.
Inputs: kind (required), cwd, note, actor, +1 more.
directive_pollA
Directives this worker has not acknowledged. Poll between units of work and obey what comes back: stop means finish the current step and stop, pause means stop and wait for resume.
Inputs: worker (required), cwd, goal.
feature_blockedC
What is waiting, and on what. The mirror of feature_ready.
Inputs: cwd, goal.
feature_claimA
Take a feature to work on, if nobody else holds it. The claim is a LEASE with an expiry, not a flag: a worker that dies holding a flag blocks its feature forever, whereas a lease runs out and the work returns to the pool. Claim before starting, or two workers take the same item and you find out via a merge conflict.
Inputs: id (required), worker (required), cwd, lease_minutes.
feature_historyB
The append-only record: what changed, when, by whom, and against which git commit. This is the audit trail that replaces git history for the tracker itself.
Inputs: id, cwd, limit.
feature_linkA
Record that one feature depends on another. Priority order is meaningless without this: the highest-priority item may be blocked, and handing it to a worker wastes the worker.
Inputs: id (required), depends_on (required), cwd, note.
feature_listB
List tracked items, lowest priority number first. Use before proposing, to avoid duplicates.
Inputs: cwd, goal, kind, limit, +1 more.
feature_proposeA
Record a feature, guardrail, schema change, risk or mitigation so it is not lost. The goal is created if it does not exist, and the id is allocated atomically by the database, so concurrent sessions cannot collide on a number. Only record what would otherwise be lost, is actionable, and is not already tracked -- check feature_list first.
Inputs: goal (required), title (required), cwd, body, +4 more.
feature_readyA
What can be worked right now: not done, nothing it depends on outstanding, and no gate open on it — in goal-priority then feature-priority order. This is what a worker pulls from. Returns skipped_pending_a_gate ALONGSIDE the ready list: a gate clears only when the principal answers it, so the worker skips those and works the rest rather than stalling a whole goal on one question — but it must SAY SO out loud, because silently working around a blocked item looks exactly like having finished the goal.
Inputs: cwd, goal, limit.
feature_reassignA
Move a feature to a different goal. The id never changes, so anything citing it in a commit message or worktree name still resolves; the move is recorded in the history with its reason. Use when a refined objective shows an item does not belong where it was filed.
Inputs: id (required), goal (required), cwd, note, +1 more.
feature_refine_batchA
Set acceptance criteria on many features at once. Most are derivable from the body, the code and the docs, so doing them one at a time spends a round trip per item on work that needed no decision. Anything genuinely undecidable should become a gate rather than a guess.
Inputs: items (required), cwd, actor, conferral.
feature_releaseA
Give up a claim, returning the feature to the pool.
Inputs: id (required), worker (required), cwd.
feature_unblockedA
What a recently answered gate has released. Answering a gate changes a gate row and nothing else, so work it was holding stays invisible unless something looks — this is what a worker calls on resuming. Read each decision_note before starting: it is the answer the work was waiting on.
Inputs: cwd, since_hours.
feature_unlinkB
Remove a dependency between two features.
Inputs: id (required), depends_on (required), cwd.
feature_unrefinedB
Open features with no acceptance criteria — the work list for a refine pass. Until a feature says what done looks like, 'done' is whoever-built-it's opinion.
Inputs: cwd, goal, limit.
feature_updateA
Change a tracked item: status, title, body or priority. Every change is recorded in the append-only history, stamped with the git commit it was made against.
Inputs: id (required), cwd, body, note, +5 more.
gap_scanA
Everything needed to reason about coverage, in one read: every goal's objective, done-means, non-goals and constraints in its own words, what each holds, and every settled refusal. Read-only. This is the input to gap analysis — derive_features asks what ONE goal implies and so can only find work inside a goal somebody already wrote; this asks what the whole set fails to cover, which is the only way a MISSING goal is ever found. Returned unsummarised on purpose: a gap is noticed by reading the actual wording, and does not survive being condensed into counts.
Inputs: cwd.
gate_decideB
Approve or reject a pending gate, unblocking the session that raised it.
Inputs: id (required), decision (required), cwd, note.
gate_decide_batchA
Answer several gates at once, after a question round. Each decision applies independently and is reported separately: answering nine of eleven is a normal outcome, and one bad id must not throw away eight good answers.
Inputs: answers (required), cwd.
gate_listC
Decisions awaiting a human. Read-only; costs no work.
Inputs: cwd, status.
gate_queueA
Every pending decision, oldest first, shaped to be answered in one sitting rather than as interruptions. Carries age, what each gate blocks, the options and the raiser's recommendation — a gate that only asks is a gate that gets deferred. Use this for the periodic question round; it records that each gate was put to the principal.
Inputs: cwd, goal.
gate_raiseA
Raise a decision the working session must not take alone: an architectural choice, an install, a spend, or anything irreversible. The session should stop and wait -- this is how 'this costs $40, are you good with that' becomes a queued question rather than a message someone had to be present to catch.
Inputs: kind (required), question (required), cwd, goal, +7 more.
gate_reconcileA
Re-check a pending gate against the tree as it is now. A gate freezes its question at the moment it was raised and nothing re-reads it, so work that lands afterwards can answer it, invalidate its premise, or build the very thing it asks whether to build -- and it goes on being asked, because the row still says pending. Run this over every pending gate before putting any of them to the principal. 'moot' closes it as settled (never as a decision they did not take, and reversible with gate_reopen); 'repose' rewrites the question and resets asked_count. Both require evidence naming a path or a commit.
Inputs: id (required), verdict (required), evidence (required), cwd, +4 more.
gate_reopenB
Pull back a gate the pair settled. Auto-settling is only safe because it is reversible: two models can be confidently wrong together, and the principal finding that out later needs a lever, not an argument. Reopened gates come back as hard.
Inputs: id (required), cwd, note.
goal_defineA
Create a goal that does not exist yet, at the END of a definition session. The name comes out of the conversation rather than going into it — nobody should have to invent an identifier before working out what the thing is. Follow immediately with goal_refine to record its objective. Check goal_list first: a near-duplicate goal fragments the queue.
Inputs: name (required), cwd.
goal_listA
Categories with their priority, parallelism cap, and item counts. Every feature must belong to one — an uncategorised item is one nobody picks up. Check here before proposing, so a near-duplicate goal is not created alongside an existing one.
Inputs: cwd.
goal_membershipB
Everything filed under a goal, for re-testing membership once its objective is agreed. Imported features inherited their goal from which document heading they sat under — a filing location, not a judgement that the item serves the objective, because at import time there was no objective to test against. Run this after refining a goal that already holds work.
Inputs: name (required), cwd.
goal_pruneA
List categories holding no features, and optionally remove them. Defaults to a dry run: a goal with work is never removed, and Miscellaneous is always kept.
Inputs: cwd, apply.
goal_refineA
Record a goal's objective after a refinement session with the principal. A goal carrying only a name and a priority is a filing label: nothing in it says what is being attempted, so a worker cannot judge whether a feature actually serves it. Do NOT call this mid-discussion — record once, when consensus is reached.
Inputs: name (required), cwd, actor, status, +7 more.
goal_refine_batchA
Refine several goals in one call. Drafting is derivable from each goal's own documentation, so the expensive part is the handful of genuine decisions, not a sitting per goal. Read the source document ONCE and slice it by heading — re-reading it per goal is the same file four times. Draft the lot, record the lot with doc_ref so the next pass has a pointer instead of a search, and raise the questions that remain as gates.
Inputs: goals (required), cwd, actor, conferral.
goal_setB
Set a goal's priority and how many of its features may be worked at once. Parallelism is capped per goal rather than by token budget: the limit that matters is how many things are changing simultaneously.
Inputs: name (required), cwd, priority, max_parallel.
goal_showA
One goal in full — objective, what done means, what is explicitly excluded, constraints — with its item counts. A worker should read this before starting, so it can tell whether what it is about to build actually serves the goal.
Inputs: name (required), cwd.
goal_unrefinedA
Goals with no objective or no definition of done, ordered by how much work they already hold. These cannot be reasoned about: work under them is being ordered without anything saying what it is for. Refine the ones holding the most first. Each row carries its doc_ref where one is known, so the refine pass reads that section rather than searching the tracker markdown for it once per goal.
Inputs: cwd.
oz_shutdownA
Wind the project down and leave it resumable. Broadcasts stop, then stashes every uncommitted change in every worktree — untracked files included — and records where, tying each stash to the feature it belongs to. Does NOT wait for workers: waiting on one that may not poll again turns a wind-down into a vigil, and anything written afterwards is caught by the next run. Use force:true to also release every open claim, which is the 'kill it' form — deliberate, because releasing a live worker's claim invites two workers onto one feature.
Inputs: cwd, note, actor, force.
parity_gapsB
Coverage by dimension: how many features are unknown, missing, partial or satisfied. The cheap probe's target list — it decides where to spend effort, and is not itself the fix.
Inputs: cwd, goal.
parity_scanA
Run the cheap probe for one dimension across every feature and record the result. parity_gaps only reads; this is what makes the states real. A probe decides where to spend effort and is not itself the fix, so it is deliberately narrow: it records what was checked in each row's detail, because 'the id is not mentioned' must never be mistaken for 'the work is not done'. Probes exist for documentation and code; the others need a real check — a build, an applied migration — rather than a reference search.
Inputs: dimension (required), cwd, actor.
parity_setA
Record whether a feature is covered in one dimension — code, unit tests, functional tests, documentation, builds, infrastructure. Work is only done when it is done in every dimension; tracking code alone lets the rest drift silently.
Inputs: id (required), state (required), dimension (required), cwd, +2 more.
project_boundariesA
What this project is NOT: goals' stated non-goals, plus every refusal with its reasoning. The accumulated negative definition — boundaries nobody wrote into a goal statement but which were decided one refusal at a time. Read before deriving or proposing anything.
Inputs: cwd, goal.
standupA
Cross-track state in one call: counts, blocked, pending gates, worker liveness, and every worktree's uncommitted work. Reads working trees, not just commits — measured on this project, every worktree reported zero commits ahead while two held real uncommitted work, so a standup built on git history alone calls active tracks idle.
Inputs: cwd.
stash_listA
Work interrupted by a shutdown and not yet restored, newest first. Each names the worktree it came from — a stash only applies in the tree it was taken in.
Inputs: cwd, include_restored.
stash_restoreA
Put interrupted work back. Applied by sha rather than by position, and the stash entry is applied rather than dropped — so a restore that conflicts can be retried or abandoned without the work having evaporated. Refuses if the target worktree is already dirty: stacking a stash on top mixes two sets of half-finished work with no way to separate them afterwards.
Inputs: id (required), cwd.
study_concludeA
Record a study's recommendation and the document it produced. 'Do not build this' is a successful conclusion, not a failure; so is 'abandoned' when the question stopped mattering. Link the features it spawned or killed with study_outcome before concluding.
Inputs: id (required), recommendation (required), cwd, actor, +2 more.
study_designA
Record the method agreed with the principal, BEFORE execution. This is pre-registration and it is the point of the design phase: a method chosen after seeing the data can be selected — consciously or not — for the answer it produces. Call this once, at consensus, and do not execute a study that has no method recorded. Revising a method later is allowed and is counted, because a silently revised method is indistinguishable from a fitted one.
Inputs: id (required), method (required), cwd, actor, +3 more.
study_listB
Studies with what each spawned, killed or informed. Check before opening one — an already-answered question does not need answering twice.
Inputs: cwd, status.
study_openA
Open an investigation whose deliverable is a document and a decision, not code. Use when a question needs real analysis before anything can sensibly be built — whether an effect is real, which of two designs survives contact with the data, whether something is worth doing at all. A study is NOT a feature: it has no acceptance criteria, and it may correctly conclude 'do not build this'.
Inputs: question (required), cwd, actor, context.
study_outcomeB
Record that a study spawned, killed or informed a feature. 'killed' matters as much as 'spawned': a study that closes work off is doing its job, and without the link the reason a feature was dropped disappears — leaving it to be re-proposed by someone who never saw the study.
Inputs: relation (required), study_id (required), feature_id (required), cwd, +1 more.
study_showC
One study and every feature it touched — the provenance view.
Inputs: id (required), cwd.
study_statusB
Move a study between open, in_progress, concluded and abandoned.
Inputs: id (required), status (required), cwd.
tracker_statusA
Counts by status and goal, pending gates, and which database and tree were read. Progress is two numbers -- done and tracked -- never a ratio: the denominator growing means real work was found, and a percentage would report that as regression.
Inputs: cwd.
worker_heartbeatA
Report that a worker is alive and extend its leases. Silence is what 'stale' means, so a worker that stops heartbeating has its claims expire and its work picked up by someone else. Call this every few minutes while working.
Inputs: worker (required), cwd, goal, worktree, +1 more.
worker_listA
Workers, how long since each was heard from, whether it is stale, and how many features it holds. An idle worker and a working one look identical without this.
Inputs: cwd.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 64 tools
Most tools are carefully scoped and the descriptions do a lot of disambiguation work, but several pairs have blurry boundaries: parity_set vs parity_scan both write coverage, study_conclude vs study_status both touch the concluded state, and feature_ready vs feature_unblocked both answer what can be worked next. Agents would often need to read the full descriptions carefully to avoid misselection.
The dominant pattern is domain-prefixed snake_case (feature_, gate_, goal_, study_, derive_, db_, confer_), which is predictable and consistent. Minor deviations like standup, checkpoint, tracker_status, and oz_shutdown do not fit the prefix pattern, but they are few and still readable.
64 tools is an extreme surface for an agent to hold in context and choose among, especially when many are micro-operations like stash_restore, confer_digest, or goal_membership. Some consolidation into composite tools or subcommands would make the set far more usable without losing capability.
The lifecycle coverage is unusually thorough: features, goals, gates, studies, parity, workers, directives, derivations, backups, conferral, and shutdown workflows all have read/write/action counterparts. The main gap is the absence of a single-feature show/get tool for reading one tracked item's full detail, though feature_list likely covers basic lookup and agents can work around it.
Maintenance
Related MCP Connectors
Shared team record of decisions, changes and handoffs that every coding agent reads and writes.
Shared project memory that keeps teammates and AI agents aligned across sessions.
Shared tables and Markdown docs for teams and AI-built apps, with scoped access and audited changes.
The team layer for AI coding agents: shared contracts, collision alerts, E2EE sessions.
Related MCP Servers
- AlicenseBqualityDmaintenanceGives AI coding assistants persistent memory, safety controls, and project awareness by tracking coding sessions, protecting critical files from modifications, and managing approval workflows with automatic changelog generation.1932 npmMIT
- AlicenseAqualityBmaintenanceEnables AI coding assistants to contribute to and query a team-shared project memory, storing human-confirmed decisions with source and scope so work can continue across machines.122Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables coding agents to persist and resume shared working state—tasks, progress, decisions, commands, tests, checkpoints, and handoffs—backed by SQLite while keeping Git authoritative for files and repository state.MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI coding assistants to persistently save, search, checkpoint, and restore project context across sessions, including decisions, progress, and file state. It supports shared channels, git-aware organization, and batch operations for long-running or parallel development workflows.195 npmMIT