@didwork/mcp
Your agent said it's done. Did it work?
DidWork as an MCP server: gives any MCP-capable agent — Claude Code, Claude Desktop, Cursor, or your own — a did_verify tool, so the agent gates its next action on independently gathered evidence instead of grading its own work.
Agent acts → did_verify(claim) → VERIFIED / FAILED / UNKNOWN → agent proceeds or escalates
Setup
Before authorizing verification, understand the data flow: claim fields, including
private repository identifiers, branch names and commit SHAs, plus optional subject,
account labels and tool profiles, are sent to the configured DidWork API (default
https://api.didwork.sh). DidWork reads connected provider state without modifying
it. Authenticated verification creates a DidWork record containing the claim,
verdict, timestamps and evidence; evidence can include provider response data.
Verification evidence follows plan retention: Free 7 days, Pro 365 days. Contract
verification also sends and stores the contract and its caller-supplied provenance.
Watches store the schedule and webhook URL and send notifications to that URL.
A public-URL check proves connectivity only. For private-repository onboarding,
connect the intended GitHub account, authorize the disclosed transfer, and verify a
known commit with github.commit_in_branch using repository, branch, and
commit. Repeat in a new Codex task. Follow the
Codex release acceptance procedure before
claiming compatibility. A host approval rejection is a blocked tool invocation,
not a DidWork failed or unknown verdict. Report the exact rejection separately;
do not loop on permission requests or bypass it with another transport.
No key is required to try it: keyless, http.ok claims verify against any public URL (rate limited, not stored), so the server delivers a first verdict straight from /plugin install. A free API key from didwork.sh/console unlocks every claim type, the verification log, and watches.
Claude Code — install the plugin (this server plus a session rule, skill, /didwork:verify command, and verifier subagent):
/plugin marketplace add didworksh/claude-plugin
/plugin install didwork@didwork
Or wire up just the MCP server:
claude mcp add didwork -e DIDWORK_API_KEY=dk_your_key -- npx -y @didwork/mcp
Cursor — install the plugin, or add the server to ~/.cursor/mcp.json. Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"didwork": {
"command": "npx",
"args": ["-y", "@didwork/mcp"],
"env": { "DIDWORK_API_KEY": "dk_your_key" }
}
}
}
Tools
did_verify | Verify a claim now — returns the verdict with evidence attached |
did_get | Fetch a verification by id (poll async verifications) |
did_list | Recent verifications for this key, evidence included |
did_watch | Re-verify a claim on an interval; webhook on verdict transitions |
did_watches | List active watches and their last verdicts |
did_unwatch | Stop a watch |
did_usage | Verifications performed, by month |
did_inspect_tool | Capability Trust: what the agent tools in a project can actually affect, with file:line evidence, risk, confidence, and declaration mismatches. Local, keyless. |
Claim types
- stripe —
refund, payment_succeeded, subscription_active, subscription_cancelled, invoice_paid, checkout_completed, payout_paid, payment_method_attached
- github —
pr_merged, workflow_passed, issue_closed, release_published, commit_in_branch, file_exists, deployment_succeeded, pr_review_approved, branch_exists
- gitlab —
mr_merged, pipeline_passed, issue_closed, commit_in_branch, file_exists, release_published
- linear —
issue_completed, issue_in_state, issue_assigned
- jira —
issue_done, issue_in_status, issue_assigned
- sentry —
issue_resolved, no_new_events_since, issue_ignored
- slack —
message_posted, reaction_added, channel_exists
- email (Resend) —
delivered, bounced
- http —
ok (any public URL, no provider connection needed)
Reach for the most specific type the outcome has. http.ok is unauthenticated: against a private repo, dashboard, or anything behind a login it sees a 404 and reports failed, which tells you about visibility, not about the work.
Field reference: didwork.sh/docs#claims. Providers connect once, read-only, at didwork.sh/console.
Capability Trust
did_inspect_tool answers a different question from did_verify: not "did it work?" but "what can this tool do, and why does DidWork think so?" It statically analyses the MCP tool handlers and did.tool() declarations in a TypeScript/JavaScript project and returns, per tool, the evidenced capabilities (financial.refund, communication.external, data.delete, …), each backed by file:line evidence, a risk level and a separate confidence level, and a status: verified, failed (DECLARATION_MISMATCH — the implementation exceeds what the tool declares), or unknown (insufficient evidence; never read as safe).
Analysis is local and reads source only; nothing is uploaded and no API key is needed. It is provided by @didwork/inspect, an optional peer dependency — it carries the TypeScript compiler, so it is not pulled in by npx -y @didwork/mcp. To enable the tool, install it where the server runs:
npm install @didwork/inspect
Needs @didwork/mcp 0.0.11 or later. Earlier versions declare the peer as ^0.0.1, which npm reads as >=0.0.1 <0.0.2, so installing them alongside a current @didwork/inspect fails outright with ERESOLVE rather than degrading — upgrade the server if you see that.
Until then did_inspect_tool answers in-band with that instruction and infers nothing. The same analysis is available on the command line as npx @didwork/inspect inspect.
Prompting the agent
A line like this in your agent's instructions makes the tool bite:
After any consequential action (refund, deploy, ticket close, message send), call did_verify with the matching claim before reporting success. Proceed only on verified. Treat failed and unknown as stop-and-escalate.
Environment
DIDWORK_API_KEY | From the console. Unset = keyless mode: http.ok only, other tools answer with how to unlock |
DIDWORK_BASE_URL | Optional — defaults to https://api.didwork.sh |