DidWork for Claude Code
Claude Code can run the command, read the output, and report the task
complete — all without the outcome being true. The deploy script
exits 0 against a service that never came
up. The refund call returns 200 on a refund
that never settles. The agent is not lying; it is reporting on itself,
from the only evidence it has.
DidWork gives it a second source. The agent forms a claim, DidWork gathers evidence from the system that can actually prove it, and returns a verdict the agent gates on instead of its own output.
Install
Two commands in Claude Code:
/plugin marketplace add didworksh/claude-plugin /plugin install didwork@didwork
Restart Claude Code so the MCP server loads. That is the whole install — there is no "now remember to use it" step, because the plugin ships the rule that makes verification the default.
A free API key at didwork.sh/console unlocks the
provider-backed claims and keeps every verdict as a shareable receipt.
Without one the server still runs: http.ok
verifies keylessly, and nothing is stored.
See it catch a miss
Before pointing it at anything real, watch it fail honestly:
/didwork:demo
It narrates a deploy that printed ✓ Deployed
successfully and exited 0, then checks
the health endpoint that deploy supposedly brought up. The verdict comes
back FAILED with the
503 as evidence, then
VERIFIED against a healthy one. About thirty
seconds, no key, and nothing in your project is touched.
What the plugin adds
| Piece | What it does |
|---|---|
| MCP server | did_verify, did_get, did_list, did_watch, did_watches, did_unwatch, did_usage, did_inspect_tool |
| Session rule | Injected at session start: verify external outcomes, gate on the verdict, never treat UNKNOWN as success |
| Stop gate | Blocks ending a turn when a side-effectful command ran with no verification after it |
| Skill | The claim types and the verify → gate workflow |
| Commands | /didwork:demo, /didwork:setup, /didwork:verify |
| Subagent | outcome-verifier — verifies one claim and reports the verdict with evidence |
The Stop gate
A rule asks the agent to verify. The Stop gate checks that it did. When
the agent tries to end its turn after running commands whose outcomes
live somewhere else — git push,
gh pr merge,
npm publish, a deploy
(wrangler, vercel,
fly,
terraform apply), a Stripe CLI mutation, a
mutating curl — with no DidWork
verification afterward, the stop is blocked once and the agent is told
exactly what to verify and with which claim type.
This is the part that changes behaviour. A rule is advice; the gate is the thing that notices when the advice was skipped.
Point it at your project
/didwork:setup
Proves the connection end to end, reads the repo for systems DidWork can
verify (Stripe SDK, STRIPE_ variables,
GitHub workflows, Sentry config, Linear or Jira references, a deployed
URL), recommends the providers actually worth connecting, and backfills
verdicts over your recent merged PRs and CI runs — so the log
starts populated with your own work instead of empty.
What it can verify
Nearly forty claim types across Stripe, GitHub, GitLab, Linear, Jira, Sentry, Slack, email, and any public URL. The full table with each type's exact semantics is in the docs. The distinctions are the point:
| Claim | What it refuses to call success |
|---|---|
github.pr_merged | closed but not merged |
stripe.subscription_cancelled | scheduled to cancel at period end |
github.workflow_passed | still running — that is UNKNOWN |
email.delivered | accepted by the provider but not delivered |
sentry.issue_resolved | ignored rather than resolved |
Without the plugin
One command writes the server config and the rule into this project, without the plugin's hooks:
npx @didwork/inspect init
It merges into an existing .mcp.json rather
than replacing it, adds a DidWork block to
CLAUDE.md leaving the rest alone, and never
writes your key into either — those are files you commit.
Or add just the server, and the rule yourself:
claude mcp add didwork -e DIDWORK_API_KEY=dk_your_key -- npx -y @didwork/mcp
Then a line in CLAUDE.md, or the agent will
go on grading its own work:
Before reporting a task complete, verify each outcome you claim with did_verify. Report done only on VERIFIED. Surface FAILED and UNKNOWN instead of retrying silently.
Troubleshooting
The did_verify tool is not
there. The MCP server loads at startup — restart Claude
Code after installing, then run
/didwork:demo.
Everything comes back UNKNOWN.
Usually a missing provider connection: the claim named a system DidWork
has no read credential for. Connect it at
didwork.sh/console/providers —
read-only credentials, which is all verification ever needs.
A GitHub claim says the repository is not visible. A fine-grained token whose resource owner is your user rather than the repository's owner cannot read it. Reconnect with the repository's owner as resource owner and Contents: Read.
Nothing is stored. That is a keyless run. Add
DIDWORK_API_KEY and the claim, evidence and
verdict are kept as a receipt you can share.
Next
The same verdicts can gate a merge: DidWork for GitHub Actions fails the build when a required outcome is not true. Using a different editor? Cursor. Wiring another host yourself? The MCP server.