A single-machine, non-git-tracked, persistent, multi-agent-aware CLI task tracker and fact store exposed via MCP protocol
Corvee demonstrates solid tool design with consistent naming (verb_noun pattern), comprehensive parameter descriptions, and well-structured schemas. All 17 tools follow a clear naming convention (fact_*, task_*) and include detailed descriptions (avg ~180 chars, within baseline 194). Parameters are well-annotated with types and descriptions. However, output schemas are not explicitly documented in the visible code, and error handling guidance is minimal. The server shows good composition (single responsibility per tool) and proper parameter constraints (enums for scope/priority). Missing are tool annotations (readOnlyHint, destructiveHint, idempotentHint) and explicit output schema documentation.
Session-start snapshot in one call: tasks claimed by (or assigned and unclaimed to) this actor, up to 5 ready-to-start tasks, tasks whose claim has gone stale, and the project's label vocabulary. Read-only.
Record a new fact, unverified by default. `proof`, if given, verifies it immediately. `is_global` files it into the shared global database instead of the local project (default `false`, same as the CLI's own `--global` default) -- the one creating tool on this surface, so the one tool that needs an explicit scope choice rather than inheriting one from an existing id. `session_id` defaults to this server's own session id if omitted.
Facts whose claim contains <text>, case-insensitive. `limit` (default 20) applies to the merged, sorted result across every scope searched, never per database. `omitted` reports how many further matches `limit` cut off, so a capped `result` is never mistaken for "no more matches exist". Read-only.
Read one fact by id (FACT-<n>, FACT-GLOBAL-<n>, or a bare integer): claim, status, current proof, and its revision timeline. Read-only.
Mark a fact verified, with proof. Re-verifying an already-verified fact succeeds and refreshes both. `session_id` defaults to this server's own session id if omitted.
Output schemas not explicitly documented in visible code. LLMs cannot plan downstream tool calls or extract required fields without knowing return structure.
Tool annotations (readOnlyHint, destructiveHint, idempotentHint) are absent. LLMs cannot distinguish safe read-only tools from destructive ones without explicit hints.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 61 | 2026-07-28+ | v2 |
File a new task. `title` and `description` are both required and must not be empty or whitespace-only. `priority` and `type` default to the project's own defaults (or the global defaults if no project resolves). `is_global` files it into the shared global database instead of the local project (default `false`, same as the CLI's own `--global` default) -- the one creating tool on this surface, so the one tool that needs an explicit scope choice rather than inheriting one from an existing id. `session_id` defaults to this server's own session id if omitted.
Move a task to blocked. Requires a non-empty `comment` explaining why, enforced only on this MCP surface (not the CLI): `blocked` is not self-explanatory the way `done`/`cancelled` are, and a subagent cannot be relied on to leave one unless it is required. The comment is written as an event.
Move a task to cancelled, clearing its claim. Use this for a task that turned out obsolete, not for one that was actually finished -- `task_done` is `done`, this is `cancelled`. `session_id` defaults to this server's own session id if omitted.
Claim a task (TASK-<n>, TASK-GLOBAL-<n>, or a bare integer). `force` steals a claim held by another actor. `session_id` defaults to this server's own session id if omitted.
Leave a note on a task. Not claim-gated (§4.4): any actor can comment at any time. `session_id` defaults to this server's own session id if omitted.
Move a task to done, clearing its claim. `session_id` defaults to this server's own session id if omitted.
Move a task back to open. Use this to undo a mis-cancel or a premature done: `task_start`/`task_review`/`task_block` refuse an already-`cancelled`/`done` task with `invalid_transition`, and `task_claim` refuses one with `task_terminal`, so before this tool there was no way back from either state on this surface. Fails with `invalid_transition` itself when called from `review`, the one state `open` is not reachable from directly (§4.5). `session_id` defaults to this server's own session id if omitted.
Move a task to review: the work is done but needs someone else to check it before it counts as `done`. Keeps the current claim (§4.4: `review` is not a terminal state). `session_id` defaults to this server's own session id if omitted.
Tasks whose title or description contains <text>, case-insensitive. `include_all` also matches done/cancelled tasks (excluded by default). `include_comments` also matches comment bodies, not just title/description. `limit` (default 20) applies to the merged, sorted result across every scope searched, never per database. `omitted` reports how many further matches `limit` cut off, so a capped `result` is never mistaken for "no task like this exists yet" when checking for a duplicate before filing one. Read-only.
Read one task by id (TASK-<n>, TASK-GLOBAL-<n>, or a bare integer): description, labels, links, subtasks, and its event timeline. Read-only.
Claim (if unclaimed) and move to in_progress in one call. To take over a stale claim first, call `task_claim(force=true)`. `session_id` defaults to this server's own session id if omitted.
Release a claim. Only the current claimant may do this without `force`; `force` releases someone else's (typically stale) claim. `session_id` defaults to this server's own session id if omitted.
Error handling lacks recovery guidance. Tools return errors but do not suggest next steps (e.g., 'Try task_search() first' or 'Invalid ref format: use TASK-<n> or bare integer').
STDIO transport only. Server is not remotely accessible and cannot be used by hosted MCP clients. Limits deployment to local/subprocess scenarios.
Pagination for search results relies on 'limit' and 'omitted' but lacks explicit 'next_cursor' or 'offset' for resuming large result sets. LLMs cannot reliably iterate through all results.