MCP server for AI coding agents
An agent does not get to mark its own work done.
LetsTask is the coordination substrate for agent-driven development. Work decomposes into a five-level hierarchy, every status change runs through a state machine, and the transitions that matter are refused until the proof exists.
86 MCP tools5 hierarchy levels4 enforced gates1 source of truth
The problem
Task trackers were built for humans who could be trusted to be honest about "done".
Autonomous agents are fast, confident, and structurally incapable of knowing when they are wrong. Given a GUI-shaped tracker with a free-form status field, they will close everything.
Self-reported completion
An agent that writes the code also writes the status update. LetsTask separates the two: completion runs through a review session, and a session that made edits cannot approve its own work.
Execution before planning
Agents start typing before the plan is read. Analysis and Implementation are distinct entities — features and tasks do not exist as real records until the analysis is approved and materialized.
Guessed ordering
Sequence gets inferred from list order. Here it is declared: task-to-task dependencies, cycle detection at both task and feature level, and get_ready_tasks to answer what is actually startable.
The model
Five levels, and a hard seam between planning and execution.
The seam is the Analysis/Implementation split — the one design decision the rest of the system hangs on.
planned_structure — a JSON proposal of features and tasks. Nothing is executable yet.Plan → approve → materialize
An agent proposes structure as JSON on the analysis. A human (or a supervising agent) reviews that proposal in one place, as one artifact, before a single task record exists. On approval the implementation is created, the proposed features and tasks are written for real, and declared dependencies are wired.
The effect: reviewing a plan is cheap, and an agent cannot quietly widen scope by inventing tasks mid-run — in a supervised feature, agent-created tasks arrive unapproved and cannot start.
Two supervision modes
| Mode | Behaviour |
|---|---|
| autonomous | Tasks are approved on creation. The agent picks up the next ready task and keeps moving. Gates still apply at REVIEW and DONE. |
| supervised | Agent-created tasks need explicit human approval before TODO → DOING, and only one task may sit in DOING or REVIEW at a time. Serialized, inspectable work. |
Set per project as the default (feature_schema), overridable per feature (supervision_mode).
The enforcement
Four gates, in the order an agent hits them.
These are not lint warnings or prompt instructions. They are server-side refusals: the transition throws, the tool call returns an error, and the agent has to deal with it.
Nothing starts out of order.
A task with unfinished dependencies cannot start, and a feature cannot start unless its parent implementation is active. Cycles are rejected at creation — both direct task cycles and the implicit feature cycles that cross-feature task dependencies would create.
// update_task_status(412, 'DOING') Error: Cannot start task: blocked by unfinished dependencies: "Migrate orders table" (DOING)
An agent cannot approve its own scope.
In a supervised feature, tasks an agent created start unapproved. Until a human approves them they are invisible to get_next_task and refused on transition. Concurrency is capped at one in-flight task per feature, so the audit trail stays linear.
// get_next_task(featureId: 27) Error: No approved tasks available. This is a supervised feature with 3 unapproved task(s).
Submitting for review means handing over the evidence packet.
Every required deliverable on the task must carry at least one piece of evidence — a test run id, a commit SHA, a screenshot URL, a log. No evidence, no review. The escape hatch is explicit: waive it, with a reason that is recorded.
// update_task_status(412, 'REVIEW') Error: Cannot move task to REVIEW: 1 required deliverable(s) have no evidence: #88 "browser test: guest checkout". Submit evidence with submit_evidence(deliverableId, ...), or waive with waive_deliverable(deliverableId, reason).
Done is a review session outcome, not a status write.
Analyses and features reach DONE only through end_review_session with result APPROVED. If the reviewer changed anything during the session, approval is refused — end as EDITED and verify in a fresh session. Approving a feature also requires every required deliverable across the feature and its tasks to be satisfied or waived.
// end_review_session(token, 'APPROVED') Error: Cannot approve: changes were made during this review session. Either end with EDITED to keep in REVIEW, or start a new session to verify the changes.
Deliverables & evidence
A definition of done that something else can check.
Acceptance criteria describe what should be true. Deliverables name the artifact that proves it, and evidence is the proof — with the strength of that proof recorded, not assumed.
Deliverable kinds
Status
pending → satisfied · pending → failed · pending → waived (reason recorded)
Evidence types
Only required deliverables gate transitions. Optional ones document intent without blocking.
The trust spectrum
| Level | Means | Strength |
|---|---|---|
| L0 asserted | An agent or reviewer typed the result. No independent check. | weak |
| L1 referenced | Points at a real artifact — a run id, a SHA, a URL — that a reviewer can open. | checkable |
| L2 verified | LetsTask resolved the reference through a federated call and confirmed it. verified: true. | independent |
Straight answer on L2: the verifier path ships wired but inert until a federated test service is configured for the project. Until then the gate enforces presence and asserted pass — stronger than an advisory checklist, weaker than independent verification. The level is stamped on every evidence row, so you always know which one you are looking at.
Surface area
86 MCP tools, and the domain is the API.
No generic update_entity catch-all. Each tool maps to one legal domain operation, which is what makes the gates enforceable and the audit trail readable. List tools accept brief: true to strip descriptions, summaries, and criteria when an agent only needs the shape.
Analyses
8Implementations
12Features
8Tasks
10Deliverables & evidence
6Dependencies & scheduling
8Reviews & sessions
8Blocking
6Estimation & risk
3Comments & summaries
4Tags
5Checkpoints
4Attachments
3Project
1Checkpoints
Polymorphic context snapshots on any entity. A crashed or compacted agent reloads get_latest_checkpoint and resumes where it left off instead of re-deriving state.
Real-time events
Every mutation broadcasts over WebSocket. Orchestrators, dashboards, and supervising agents react to state changes without polling.
REST for everything else
Project-scoped REST endpoints under /:project/… behind JWT, plus S3-backed attachments with presigned URLs. Same services, same gates.
Getting started
One HTTP MCP endpoint and a project key.
{
"mcpServers": {
"letstask": {
"type": "http",
"url": "https://hey.letstask.ai/api/mcp",
"headers": {
"X-API-Key": "proj_<project>_<key>"
}
}
}
}
The key scopes every call to one project — there is no cross-project read. Humans sign in to the dashboard at hey.letstask.ai with a JWT or federated BitBot SSO.
Slash commands shipped for Claude Code
Twelve commands ship in total, including /letstask-close-implementation, /letstask-resume-analysis, /letstask-sync-git, /letstask-pr, /letstask-do-next-feature and /letstask-cleanup.
Under the hood
Boring where it should be.
| Layer | Built on |
|---|---|
| Runtime | Node.js · Express 5 |
| Database | PostgreSQL |
| Agent protocol | MCP SDK · streamable HTTP |
| Real-time | WebSocket (ws) |
| Auth | JWT (jose) · JWKS · project API keys |
| Attachments | S3-compatible object storage |
| Dashboard | React 19 · Vite · Tailwind · Zustand |
Federated, not isolated
LetsTask authenticates against BitBot via JWKS, accepts provisioned projects, and publishes project stats and an activity feed over the shared tool contract — so a portal, an orchestrator, or a neighbouring service sees the same work state your agent does.
The same federation path is what carries evidence verification: a deliverable pointing at a test run in a connected testing service is what turns an asserted pass into an independently verified one.
Runs standalone just as well. The federation is opt-in configuration, not a dependency.
Give your agents a project manager that says no.
Point a Claude Code session at the MCP endpoint, run one analysis, and watch it get refused the first time it tries to close a task it cannot prove.