Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

Did It Work?

REMOTE · API.DIDITWORK.ORG

Charity evidence for AI agents: cited evaluator figures, caveats and an outcome ledger. Read-only.

+3 this week 71 Trust /100

Last scanned (3 hours ago)

Scores higher than 57% of remote servers

Reachable. Last reached 5 Nov 2026.

Category Finance and Payments

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →

Endpoint Security74
Transport & Reachability100
Schema Quality & AI Usability55
  • AI-judged instruction clarity (good).Pass
  • Context-footprint check failed: tool/resource definitions use about 6556 tokens (~298/item across 22 items; 22 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management37
  • Stability observed for 11 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage82
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 47% of tool parameters carry a description.Partial
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • We read all 22 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
  • An AI judge read all 23 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a current MCP spec version (2026-07-28).Pass
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 4 Nov 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 30 to 33. That category is still filling its 30-day observation window: 9 days of observed history at the previous scan, 10 at this one. The score rises as the window fills, whether or not the server changes.

  • 2 Nov 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

  • 31 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 17 to 20. That category is still filling its 30-day observation window: 5 days of observed history at the previous scan, 6 at this one. The score rises as the window fills, whether or not the server changes.

  • 30 Oct 26 0
    • Tool “decision_brief” rewrote its description, which is the text the model reads security
    • Tool “search_orgs” rewrote its description, which is the text the model reads security
  • 29 Oct 26 +1
    • “search_orgs” added an optional parameter “q” cosmetic

    1 cosmetic change on this day. Switch on “Show cosmetic changes” to see it.

  • 28 Oct 26 0
    • Tool “decision_brief” rewrote its description, which is the text the model reads security
    • Tool “search_orgs” rewrote its description, which is the text the model reads security
    • Schema quality: 246 → 291 ▼ functional
    • New tool “verdict_chain” functional
  • 27 Oct 26 −1
    • Tool “decision_brief” rewrote its description, which is the text the model reads security
    • Tool “search_orgs” rewrote its description, which is the text the model reads security
    • Schema quality: 164 → 246 ▼ functional
  • 26 Oct 26 0
    • The server rewrote its instructions, which are the text every model session reads security
    • Tool “compare_charities” rewrote its description, which is the text the model reads security
    • Tool “create_giving_intent” rewrote its description, which is the text the model reads security
    • Tool “estimate_impact” rewrote its description, which is the text the model reads security
    • Tool “get_org” rewrote its description, which is the text the model reads security
    • Tool “list_charities” rewrote its description, which is the text the model reads security
    • Tool “list_claims” rewrote its description, which is the text the model reads security
    • Tool “recommend_charity” rewrote its description, which is the text the model reads security
    • Tool “search_orgs” rewrote its description, which is the text the model reads security
    • Schema quality: 114 → 164 ▼ functional
    • Stability: unverified → 0.03 ▲ functional
    • New tool “decision_brief” functional
    • New tool “report_decision_effect” functional
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 5 Nov 2026 · Probed https://api.diditwork.org/mcp

TLS valid

Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .

Subject Issuer Valid from Valid until Key Signature Serial
CN=diditwork.org CN=WE1,O=Google Trust Services,C=US 21 Oct 2026 19 Jan 2027 ECDSA 256 ECDSA-SHA256 f7656a3076a669d713b4747b9a88b4c2
SANs: diditwork.org, api.diditwork.org, *.api.diditwork.org
CN=WE1,O=Google Trust Services,C=US (CA) CN=GTS Root R4,O=Google Trust Services LLC,C=US 13 Dec 2023 20 Feb 2029 ECDSA 256 ECDSA-SHA384 7ff31977972c224a76155d13b6d685e3
CN=GTS Root R4,O=Google Trust Services LLC,C=US (CA) CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE 15 Nov 2023 28 Jan 2028 ECDSA 384 SHA256-RSA 7fe530bf331343bedd821610493d8a1b

Background: What to check on a remote MCP endpoint →

DNSSEC insecure

Validation of api.diditwork.org. — Not signed

Zone DS Keys Algorithms Outcome
. trust_anchor 20326, 38696 8, 8 Verified
org. present 725, 26974 8, 8 Verified
diditwork.org. absent Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation
Authentication No authorisation required

The endpoint answered without asking for a token. Anyone who knows the URL can reach it.

Result No authorisation required
HTTP status 200
Header Value
x-content-type-options nosniff
x-frame-options DENY
referrer-policy no-referrer

Background: How OAuth 2.1 works in the 2026 MCP spec →

Transports 2 probes
Transport URL Outcome Status Location
streamable-http https://api.diditwork.org/mcp Verified 200
http (plaintext) http://api.diditwork.org/mcp HTTPS enforced 301 https://api.diditwork.org/mcp
MCP tools · 22 exposed · ~6,387 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
allocate_portfolio ~158

Suggest a donor portfolio: split budget_usd across top-ranked orgs (conviction_weighted / equal_split / top_only). Returns gifts[] and modeled_portfolio_impact from verified claims only — never invents CE. Always modeled≠guaranteed.

NameTypeReqDescription
budget_usdnumberyes–
geographystring––
include_fundsboolean––
methodstring–Allocation method (alias: allocation_method on POST)
outcomestringyeslives_saved | wellbeing_wellbys | income
red_linesstring–Comma-separated cause ids or tags to exclude
riskstring––
taxstring––
top_ninteger––

No output schema declared.

No examples provided.

compare_charities ~152

Side-by-side claims, recommendation tiers, and trust for two or more org_* ids. When the charities are measured in different outcome units (for example wellbeing in WELLBYs versus lives saved), units_differ.sentence says so in plain words; the units can't be converted without a moral judgment, which is the donor's. Answers carry decision_brief: the charity's own donate_url (next_action), the evaluator's fund as a let-the-evaluator-choose alternative, the like-for-like comparison page when one exists, and modeled: true / guaranteed: false when figures are present. No figure, rating or order is added.

NameTypeReqDescription
idsstringyesComma-separated org ids (minimum two)

No output schema declared.

No examples provided.

create_giving_intent ~140

NO-CHARGE deep-link giving handoff (Phase 3 MVP). Returns mode=deep_link, org donate_url, donation_proof=null, charge=false. Did It Work? never processes payment, stores cards, or calls Stripe. Optional modeled_impact is modeled≠guaranteed. Prefer GET; POST accepts the same fields as JSON body.

NameTypeReqDescription
amount_usdnumberyes–
include_impactboolean–When true, attach modeled_impact (MODELED, NOT GUARANTEED)
org_idstringyes–
values_profile_idstring––
vehiclestring––

No output schema declared.

No examples provided.

decision_brief ~1,556

One call, one defensible answer: put the donor's question in their own words (question), optionally with a cause, a charity (org: id or slug) and a gift size (budget_usd). Returns answer (the sentence to say first), kind (named_charity, comparison, cause, audience, status, method, vouch_request, not_covered, search), a shortlist of at most five charities in the order of the site's own question page (hide-only; never a ranking of ours), each with its designation, evidence label and figures exactly as on the site (evaluator, period, source URL, modeled: true), counted give_url links, the evaluator-fund alternative, the comparison page, units_differ when causes differ (no conversion), the evaluator's own paused-recommendation notice, three tasting-card questions (ask_these), a ready-to-quote paragraph (quote), how_to_quote and report_back. Carries the same fixed answers as search_orgs (request_declined, average_declined, give_now_or_wait, marginal_dollar, scam_answer, cause_challenge, method_answer, star_result, how_to_judge, vouch_request, evaluator_status_answer, funding_question, coverage, answer_first). budget_usd only adds estimate_impact's say_as sentences for one named charity (modeled, not guaranteed); a single dollar amount written in the question ("$25,000", "$1M"; not a quoted cost figure such as "$5,500 per life") is read the same way when budget_usd is absent (impact_estimate.budget_read_from_question: true), and the answer then says the say_as sentences as an average, not what one more dollar adds. "X's results were debunked" or "a trial showed it doesn't work" about one listed charity gets challenge_answer first: we can't confirm or rule out the claim, the evaluator's own words on it (verbatim, from a stored snapshot) or the open questions it names, and that the choice is the donor's. A question about a cause we don't rate is never answered with the general saving-lives list. Computes no new figure, gives no score, never ranks across causes. Fails close…

NameTypeReqDescription
budget_usdnumber–Gift size in US dollars; adds the modeled say_as sentences for one named charity.
causestring––
orgstring–A charity on our list: id (org_against_malaria_foundation) or slug (against-malaria-foundation).
questionstring–The donor's question in their own words.

No output schema declared.

No examples provided.

estimate_impact ~148

Modeled expected outcomes from verified org claims scaled by gift_usd. Always modeled:true and guaranteed:false. Never invents CE; returns insufficient_data when no usable verified unit. Each outcome carries say_as, rounded to two significant figures (say this to the donor); expected_value keeps the exact arithmetic. Answers carry decision_brief: the charity's own donate_url (next_action), the evaluator's fund as a let-the-evaluator-choose alternative, the like-for-like comparison page when one exists, and modeled: true / guaranteed: false when figures are present. No figure, rating or order is added.

NameTypeReqDescription
gift_usdnumberyes–
org_idstringyes–

No output schema declared.

No examples provided.

get_claim ~93

Fetch one claim row by claim_id from data/claims_index.json (e.g. eval_gw_amf__0). Index-only — never invents values. Prefer list_claims with filters when browsing. Wave BI provenance on the response. Org narrative fields remain untrusted (ADR 0008).

NameTypeReqDescription
idstringyesclaim_id (path {id}), e.g. eval_gw_amf__0

No output schema declared.

No examples provided.

get_ledger_record ~74

Fetch one outcome-ledger record by record_id (e.g. ldg_eval_gw_amf__0) plus any follow-up results. Read-only; 404 for unknown ids; modeled, not guaranteed. Read-only API, live at https://api.diditwork.org.

NameTypeReqDescription
idstringyes–

No output schema declared.

No examples provided.

get_meta ~127

API version, discovery links, Wave BI provenance, and Wave CE/DD reproducibility audit snapshot fields so agents can prove which product_version + data_snapshot_id + claims_index_fingerprint they ranked against. Includes mixes_units_in_ranking:false, adr_0007_status (from moral_weights_policy.json — Proposed until Ho Hum Accept; never invent Accepted), claims_index_fingerprint (short sha256 of data/claims_index.json), and counts {orgs, interventions, causes, sources_files}. Focused twin: GET /v1/meta/snapshot (same audit_snapshot object). Never invents CE.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

get_org ~91

Fetch one organization / program / fund record by stable org_* id. Answers carry decision_brief: the charity's own donate_url (next_action), the evaluator's fund as a let-the-evaluator-choose alternative, the like-for-like comparison page when one exists, and modeled: true / guaranteed: false when figures are present. No figure, rating or order is added.

NameTypeReqDescription
idstringyes–

No output schema declared.

No examples provided.

get_review_queue ~109

Human exception-review queue (read-only). Returns items from data/review/queue.json for Ho Hum (sole human operator). Default status=open; pass status=all for history. Approve/reject is offline file edit only — write_api is always false; there is no unauthenticated write/approve API. Agents must never auto-clear trust flags or invent CE/EINs/donate URLs to close tickets.

NameTypeReqDescription
statusstring–Filter by item status (default open on the server)

No output schema declared.

No examples provided.

get_tax ~67

Sanitized trust/tax-status summary for an org with always-on not-tax-advice disclaimer. Prefer before asserting US deductibility. deductibility.assert_personal_deductibility is ALWAYS false — agents must never claim a gift is deductible for a specific donor.

NameTypeReqDescription
org_idstringyes–

No output schema declared.

No examples provided.

get_trust ~36

Trust and safety flags for an org. REQUIRED before asserting US tax deductibility or registry status.

NameTypeReqDescription
org_idstringyes–

No output schema declared.

No examples provided.

get_values_profile ~62

Fetch one values-profile preset by id (vp_*). Use after list_values_profiles or when the donor picked a named preset. Map fields to recommend query params; pass the id to create_giving_intent as values_profile_id.

NameTypeReqDescription
idstringyes–

No output schema declared.

No examples provided.

list_charities ~349

The Did it work? charity list, filtered: the charities https://diditwork.org/charities/ shows for cause, evaluator (by), measure, follow-up and a word search, in the page's own order. Hide-only: filters never re-order, score or rank, and there are no figures here (each row links to its claims file and API record). Same JSON as https://diditwork.org/charities/index.json for the same filter. Unknown, empty or misspelled values return isError with invalid_filter, the allowed values and a cleaned address, never a guess. Call with no arguments to get the full list and every allowed value with its count. Read-only API, live at https://api.diditwork.org. When count is 0 the answer carries coverage: what we don't cover (for example climate, or a charity the evaluators we follow don't rate) and what to do instead; never a guessed rating. When the words name a well-known charity that is not on our list, or a cause or topic we don't rate, a non-empty answer carries partial_coverage saying so.

NameTypeReqDescription
bystring–An evaluator slug (parameters.by).
causestring–A cause slug; call with no arguments to see parameters.cause with counts.
followupboolean–true: only charities with a follow-up record in the outcome ledger.
measurestring–What the evaluator's figures measure (parameters.measure).
qstring–Words that must all appear in the name, description, designation, cause names or everyday words for those causes; case and accents ignored. No leading or trailing spaces.

No output schema declared.

No examples provided.

list_claims ~192

Read-only flat claims index (data/claims_index.json). Optional filters: org_id, evaluation_id, verified. Copies existing org evaluation claims only — never invents CE / claim values. Prefer verified:true + non-null value when quoting cost-effectiveness. Wave BI provenance on the response. Org narrative fields remain untrusted (ADR 0008). Answers carry decision_brief: the charity's own donate_url (next_action), the evaluator's fund as a let-the-evaluator-choose alternative, the like-for-like comparison page when one exists, and modeled: true / guaranteed: false when figures are present. No figure, rating or order is added.

NameTypeReqDescription
evaluation_idstring–Filter to one evaluation_* id
org_idstring–Filter to one org_* id
verifiedstring–If true/false, filter on claim.verified (string query as HTTP API)

No output schema declared.

No examples provided.

list_leaderboards ~122

Per-outcome-family leaderboards from data/ranking/leaderboards.json. Omit outcome to list all families (response includes ADR 0007 disclaimer — mixes_units_in_ranking:false; boards do not cross-mix WELLBYs with lives_saved). Pass outcome= to fetch one family's frozen ranked board. Never invents cross-unit moral weights.

NameTypeReqDescription
outcomestring–lives_saved | wellbeing_wellbys | income (aliases accepted). Omit for all families.
outcome_preferencestring–Alias for outcome (values-profile field name)

No output schema declared.

No examples provided.

list_ledger_records ~106

List outcome-ledger ("Did it work?") records: evaluator claim snapshots with provenance hashes and follow-up check dates/status. Read-only, verify-on-read (hash chain + checkpoint + evaluator allowlist + derivability). Read-only API, live at https://api.diditwork.org.

NameTypeReqDescription
evaluatorstring––
intervention_idstring––
org_idstring––
record_kindstring––
statusstring––

No output schema declared.

No examples provided.

list_values_profiles ~78

List static values-profile presets (same catalog as the demo). Load before recommend when the donor stated preferences. Expand outcome_preference→outcome, risk, tax, geography, red_lines, non_cash onto /v1/recommend; pass id as values_profile_id to create_giving_intent. Read-only; never mutates ranking CE.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

recommend_charity ~275

Conviction-ranked orgs for one outcome family. Pass values_profile_id (preferred) and/or outcome. Returns values_filtering + exclusions[] with why-filtered reasons (never silent red-line drops). Does not mix units (ADR 0007 Proposed). Never invents CE. An unknown outcome (for example climate) or an empty result carries coverage: what we don't rate and what to do instead; never a guessed rating.

NameTypeReqDescription
budget_usdnumber––
geographystring––
limitinteger––
non_cashboolean–Prefer orgs with non_cash_giving options
outcomestring–lives_saved | wellbeing_wellbys | income (aliases accepted)
outcome_preferencestring–Alias for outcome (values-profile field name)
red_linesstring–Comma-separated cause ids or tags to exclude
require_geographyboolean––
riskstring––
taxstring––
values_profile_idstring–Preset id (vp_*). Preferred binding: loads outcome_preference, red_lines, risk, tax, geography from data/values_profiles/{id}.json. Outcome may be omitted when the profile supplies it. Surfaced back…

No output schema declared.

No examples provided.

report_decision_effect ~238

Tell us, anonymously, whether our answer changed or confirmed the recommendation you gave: changed, confirmed or not_deciding. Call it once, after the person has decided (or said they are not deciding). Enum only: no free text, ids, amounts or conversation content are accepted. Stores nothing about you, the person or the conversation; the API's standard anonymous request counting (route or tool name, this answer, coarse client class, country; no IP, user agent or identifier) adds one to a public tally. Never changes any data, rating, ranking or answer. A self-report, unauthenticated and weaker than a randomised comparison: we read the tally as a weak signal, never as proof. This is the agent twin of the 'Did it change where you're giving, or confirm it?' line on our decision pages (https://diditwork.org/standards#what-we-count).

NameTypeReqDescription
effectstringyeschanged: our answer changed the charity or fund recommended, or where the person decided to give. confirmed: it confirmed a plan already there. not_deciding: the person was not deciding yet.

No output schema declared.

No examples provided.

search_orgs ~1,959

Heuristic search by cause, outcome family, or donor intent phrase. Prefer recommend_charity when the user wants ranked 'best for outcome' results. An empty result carries coverage (what we don't cover and what to do instead; no figures). A non-empty result that answers only part of the question carries partial_coverage: which part is covered, which is not (for example animal welfare, humanitarian relief, scam checks or tax-return data) and who does assess the rest. Every answer that doesn't fully cover the question starts with answer_first: what we don't cover and who does assess it, then which part the results answer. A question asking whether anyone pays us, or who funds us, also gets funding_question (nobody can pay for a place; we take no referral fees and never handle donors' money). A question asking whether a survey, testimonial or before-and-after report proves a programme worked gets method_answer first (no, why, what to ask for, the missing-answer bounds; method only). A question asking whether one striking result (a single study showing it beats similar programmes, the top of a list) makes a charity the best gets star_result first (probably overstated; the eight-schools example; what to ask for; method only). A demand for a guarantee or for our own ranking gets request_declined (figures are modeled, never guaranteed; we rank nothing ourselves). A request to average cost-per-outcome figures (two charities' cost per life, or over scenarios) gets average_declined first (we don't average them; add up outcomes instead, one unit; method only; the evaluators' figures follow unchanged). "Should I give now or wait a year for better evidence?" (or "invest it and give later?") gets give_now_or_wait first (GiveWell's own answer verbatim; decide on today's best estimate and wait only for named evidence, due in time, that could change the choice; for one named listed charity, the evaluator's dated re-check or our evidence-gap ledger's words; method only, we compute no…

NameTypeReqDescription
causestring––
intentstring––
outcomestring–lives_saved | wellbeing_wellbys | health_dalys | income
qstring–The donor's question or a charity name in their own words (same as GET /v1/search?q=). Fixed answers (answer_first, request_declined, scam_answer and the rest) read q and intent alike.

No output schema declared.

No examples provided.

verdict_chain ~255

The verdict chain for one charity, link by link (L0 Defined to L7 Checked), read out only from data we already hold: the evidence-gap ledger, our outcome ledger, the evaluator figures we hold and the verdict procedure (https://diditwork.org/agents/verdict-procedure.json). Returns record in the procedure's output_record shape: links (id, name, question, answer, rung from the procedure's ladder or null for L0/L7, evaluator_label_verbatim, source, open_question), weakest_link (the procedure's rule), open_questions and summary_donor_voice; plus rung_rules (how each rung follows from existing grades), widest_evidence_gap (the ledger's own binding gap), better_source and covered. Computes nothing: every figure and date is copied whole from a stored value, and the response holds no JSON number. No overall verdict, score, grade or count of strong links: live charities get no worked/didn't-work word. Charities without an evidence-gap entry get covered: false and every link 'Not covered' with a pointer to get_org and the evaluator. Same function as GET /v1/verdict-chain/{org_id}.

NameTypeReqDescription
org_idstringyes–

No output schema declared.

No examples provided.

Install

How do I install the Did It Work? MCP server?

Did It Work? is a hosted endpoint at https://api.diditwork.org/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

remote · api.diditwork.org

# add to Claude Code
claude mcp add --transport http org-diditwork-did-it-work 'https://api.diditwork.org/mcp'
Common questions

What is the Did It Work? MCP server?

Did It Work? is an MCP server listed in the public MCP registry as org.diditwork/did-it-work. Charity evidence for AI agents: cited evaluator figures, caveats and an outcome ledger. Read-only. This page covers its hosted endpoint (https://api.diditwork.org/mcp).

Is the Did It Work? MCP server safe to use?

Did It Work? scores 71 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the Did It Work? MCP server expose?

Did It Work? exposes 22 tools: get_meta, recommend_charity, list_leaderboards, get_review_queue, compare_charities, and 17 more. Their descriptions and schemas cost roughly 6,387 tokens of context every time the server is loaded.

Does the Did It Work? MCP server require authentication?

No. We connected to Did It Work? without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

Is the Did It Work? MCP server still maintained?

Did It Work? is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.