Corroborate Mcp

io.github.chefcohenPublished by GitHub account chefcohenv0.1.3Updated Oct 24, 2026

Honest claim corroboration for AI agents: syndication-aware independent-source counting.

Overview

AI-generated overview

Local MCP server that checks how independently a news claim is reported, counting distinct story origins rather than raw citations.

What you can do
  • Return a corroboration verdict for a claim, with confidence, coverage status and the sources behind it
  • List deduplicated sources across several news engines for a query, without a verdict
  • Flag wire-service origins and how many domains echoed the same story
  • Report caveats such as syndication collapse, breaking-news cascades and engine outages
When to use it
Useful when an assistant is about to rely on a current-event or news claim and needs to know whether it is independently reported or one wire story echoed widely. Also handy for ranking or filtering sources by genuine independence before citing them.
Requirements
Runs locally over stdio via npx, requiring Node 18 or newer. No API keys, accounts or configuration; it queries public news sources, so network access is needed.
Before you install
Read-only and keyless, but the verdict measures reporting corroboration, not truth: a distorted version of a widely covered story can still come back CONFIRMED, since there is no stance detection. Coverage is English-language and headline-level, limited to a recency window, and a degraded coverage field means an engine failed rather than that the claim is false.

Installation

In SourceWeft

  1. Open Corroborate Mcp in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

corroborate-mcp

The honest corroboration layer for AI agents. Hand it a claim; it tells you how independently that claim is actually being reported — and shows its work.

[npm] [downloads] [license] [node] [MCP] [API keys]

An AP story echoed by 40 outlets is one origin, not 40 citations. Other verifiers count citations; Corroborate counts independent origins — syndication-aware — then publishes its own error rates and discloses coverage gaps. That's the judgment layer raw search and citation-checkers skip.

text
corroborate_claim("NASA delayed the Artemis III landing")   → CONFIRMED       4 independent origins · conf 0.9corroborate_claim("Zorblatt Corp acquired Portugal")        → UNCORROBORATED  0 origins · conf 0.05

When an agent should call this

  • Before relying on a current-event / news claim — is it independently reported, or one source echoed everywhere?
  • To rank or filter sources by genuine independence, with a confidence score.
  • When you need a verdict you can defend — every answer ships its evidence, its confidence, and its own caveats.

Not a web search engine (use Exa/Tavily/Brave for that) and not a human fact-checking network. It's the narrow, honest primitive in between: how independently is this reported?

Why it's trustworthy — by design

🔑 Zero API keys, zero accountsKeyless engines (Google News RSS · GDELT · Hacker News). Nothing to sign up for.
👁 Read-onlyIt reads public news. It cannot act, write, spend, or touch your data.
🎯 DeterministicNo LLM in the loop — same evidence in, same verdict out. p50 ~0.4s.
📖 Open source (MIT)Read every line of the judgment.
📊 Published error ratesWe measure our own false-CONFIRMED / false-UNCORROBORATED rates on a public benchmark and print them below. Most "fact-check" tools don't.
🚫 Never lies by omissionIf sources are unreachable it returns an error, never a fake "UNCORROBORATED."

What it measures — and what it doesn't

Reporting corroboration, not truth. A claim every outlet syndicated from one wire story comes back SINGLE_SOURCE. A claim nobody covers comes back UNCORROBORATED even if true. The verdict states exactly what was measured, flags its weaknesses in notes, and sets coverage:"degraded" when an engine was down — so absence of evidence is never quietly sold as evidence of absence.

Quickstart

Requires Node ≥ 18. No keys, no config.

Claude Code

bash
claude mcp add corroborate -- npx -y corroborate-mcp

Claude Desktop / Cursor / any MCP client (claude_desktop_config.json, .cursor/mcp.json, …)

json
{ "mcpServers": { "corroborate": { "command": "npx", "args": ["-y", "corroborate-mcp"] } } }

Try it with no MCP client

bash
npx corroborate-mcp   # starts the stdio server (silent = healthy)# or from a checkout:  node cli.js "The Federal Reserve held interest rates steady"

Tools

corroborate_claim — the verdict

{ claim, window_days?=7, max_sources?=8 } →

json
{  "claim": "Acme Corp acquires Widget Industries for $2 billion",  "corroboration": "CONFIRMED",  "n_independent_sources": 3,  "confidence": 0.9,  "coverage": "full",  "sources": [    { "headline": "Acme Corp to acquire Widget Industries in $2 billion deal",      "outlet": "Financial Times", "domain": "ft.com", "url": "https://…",      "published_at": "2026-07-09T14:02:00Z", "age_days": 0.9,      "wire": false, "echoed_by_n_domains": 1 }  ],  "notes": ["syndication detected: near-identical headlines across multiple domains collapsed into one origin"],  "method": "reporting-corroboration: counts INDEPENDENT story origins (syndication-aware), not raw article count; does not adjudicate truth"}
FieldMeaning
corroborationCONFIRMED (≥2 independent origins) · SINGLE_SOURCE (1) · UNCORROBORATED (0)
n_independent_sourcesDistinct story origins after syndication clustering — not article count
confidence0–1. Rises with origins + cross-engine agreement; penalized for wide single-origin echo
coveragefull, or degraded when an engine failed this call — a weak verdict may then reflect the outage, not the claim
sources[].wireOrigin is a wire service (AP/Reuters/AFP/UPI)
sources[].echoed_by_n_domainsHow many domains carried this same story
notesHonest caveats: syndication collapse, breaking-news cascade (<24h), relevance-gate discards, engine outages

find_sources — the raw evidence

{ query, window_days?=7, max_sources?=10 } → deduped multi-engine list (outlet, domain, url, date), no verdict. The cheaper primitive when you want the coverage and your own judgment.

Measured accuracy — because you should demand it from any fact-check tool

Against a public 40-claim labeled benchmark (benchmark/ — claims, labels, category definitions, and harness are all public; run it yourself with npm run benchmark). The time-sensitive claims are refreshed from current news so the numbers reflect real accuracy, not staleness. Latest run 2026-07-22:

MetricResult
Fabricated claims falsely CONFIRMED0/10
Widely-reported true claims missed0/12 (11 CONFIRMED, 1 single-source)
Niche true claims detected7/8
Stale claims correctly windowed2/5
Distorted claims falsely CONFIRMED6/6 — read the warning ↓
Latencyp50 0.4s · p95 <1s (≤8s worst case when the slow engine is up)

⚠️ Respect the distorted-claim number — it's the honest ceiling of this tool's blind spot. In the latest run all 6 distorted claims came back CONFIRMED (6/6), because each one distorts a currently-reported event, and this tool checks whether independent reporting exists around a claim's topic and entities — it does not do stance detection. So "Samsung cancelled the Galaxy Z Fold8" (they unveiled it) or "OpenAI released GPT-6" confirms off the real coverage of the true story. The rule to live by: if a claim's topic is being reported, a distorted version of it will very likely CONFIRM. Read CONFIRMED as "this topic has independent coverage — now verify the specific facts against the returned sources," never as "this exact claim is true." Stance detection is the v1.1 roadmap item. (Recurring events like championships/elections can likewise match the current cycle's coverage — see the stale-claim leaks.)

How the judgment works

  1. Search Google News RSS, GDELT, Hacker News in parallel (keywords extracted from the claim; quoted phrases preserved).
  2. Relevance gate — an article counts only if its headline genuinely addresses the claim (≥2 core-token hits AND ≥35% of core tokens). Loose topical echoes are discarded; the discard count is reported.
  3. Syndication clustering — near-identical headlines across domains (Jaccard ≥ 0.55) collapse into one origin; wire domains flagged.
  4. Verdict — independent origins = distinct clusters; confidence rises with origins + cross-engine agreement, falls for wide single-origin echoes; every known weakness goes in notes.

Honest limitations

  • No stance detection (the 6/6 above). CONFIRMED = independently covered, not verified in every detail.
  • English-language, headline-level. Paywalled body text isn't fetched.
  • Recency-windowed (default 7 days, max 90). Old claims read UNCORROBORATED — a window statement, not a falsity verdict.
  • Independent rewrites of one wire story can occasionally slip clustering; distinct phrasings of one origin can occasionally count as two.
  • All engines down → error, never a fake UNCORROBORATED.

Development

bash
npm test              # golden-claim suite — deterministic, no networknpm run test:mcp      # MCP stdio handshake + tools/listnpm run test:live     # live invariants against real enginesnpm run benchmark     # 40-claim labeled accuracy benchmark (live, ~2 min)npm run test:release  # all of the above — required green before every release

MIT © Ezra Cohen · github · npm

Source: README.md at commit 1da5f99

Tools

0
SourceWeft has not started this package in its sandbox yet, so its tools are not known.

Version history

1
  1. v0.1.3LatestSep 16, 2026

Score

50% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts

    Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.

  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listed15 pts

    Answer tools/list without a credential, or ship a package that starts in a sandbox without one.

  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts