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

PieceWhat it does
MCP serverdid_verify, did_get, did_list, did_watch, did_watches, did_unwatch, did_usage, did_inspect_tool
Session ruleInjected at session start: verify external outcomes, gate on the verdict, never treat UNKNOWN as success
Stop gateBlocks ending a turn when a side-effectful command ran with no verification after it
SkillThe claim types and the verify → gate workflow
Commands/didwork:demo, /didwork:setup, /didwork:verify
Subagentoutcome-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:

ClaimWhat it refuses to call success
github.pr_mergedclosed but not merged
stripe.subscription_cancelledscheduled to cancel at period end
github.workflow_passedstill running — that is UNKNOWN
email.deliveredaccepted by the provider but not delivered
sentry.issue_resolvedignored 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.

DidWork: verification infrastructure for software outcomes