Skip to main content
Glama
README.md
# claim-verifier

An MCP server that verifies outside-world claims — so agents stop asserting
things like "posted", "booked", or "merged" without proof.

The problem: AI agents routinely tell users something happened (a post went
live, a PR merged, a page says X) based on a tool call that *started* the
action, not on evidence it *finished*. claim-verifier is the trust layer:
one assertion in, a boolean verdict plus the raw evidence out, checked live.

## Tools

| Tool | What it does |
|---|---|
| `verify_url` | Fetches a URL (follows redirects), reports `ok`, HTTP `status`, `final_url`, page `title`, a text `snippet`, and whether the page contains an expected phrase (`expect_contains` → `matched`). |
| `verify_github` | Live state of a public GitHub PR/issue via the API: `state`, `merged`, `merged_at`, `title`, `url`. |
| `verify_claim` | Generic entry point. `assertion_type`: `contains` (page text has the phrase), `status_2xx` (URL loads), `github_merged` (PR is merged). Returns `{ verified, evidence, checked_at }`. |

## Install

```bash
npm install -g claim-verifier
# or run without installing:
npx -y claim-verifier
# or from source:
git clone https://github.com/baby-zack-agent/claim-verifier.git
cd claim-verifier && node src/index.js
```

Requires Node.js 18+.

## MCP client config (Claude Desktop style)

```json
{
  "mcpServers": {
    "claim-verifier": {
      "command": "npx",
      "args": ["-y", "claim-verifier"]
    }
  }
}
```

Or point `command` at a local checkout: `"command": "node", "args": ["/path/to/claim-verifier/src/index.js"]`.

The server speaks MCP over stdio (newline-delimited JSON-RPC): `initialize`,
`tools/list`, `tools/call`. Nothing else — no HTTP port, no hosting, no
telemetry, no accounts. It runs inside your own agent.

## Example session

Agent asserts: *"the PR was merged."*

```
→ tools/call verify_claim { "assertion_type": "github_merged", "repo": "octocat/hello-world", "number": 7, "kind": "pr" }
← { "verified": true,
    "evidence": { "state": "closed", "merged": true, "merged_at": "2026-…", "title": "…", "url": "https://github.com/octocat/hello-world/pull/7" },
    "checked_at": "2026-…" }
```

Now the agent can say "merged" — with the evidence attached.

## Tool reference

### verify_url
- `url` (string, required) — http(s) URL to fetch.
- `expect_contains` (string, optional) — phrase that must appear in page text (case-sensitive).
- `timeout_ms` (number, optional) — request timeout, default 15000.
- Returns `{ ok, status, final_url, redirects, title, snippet, matched, checked_at }`.
  `ok` is true for 2xx statuses. `matched` is `null` when `expect_contains` is omitted.

### verify_github
- `repo` (string, required) — `"owner/name"`.
- `number` (integer, required) — PR or issue number.
- `kind` (string, required) — `"pr"` or `"issue"`.
- Returns `{ state, merged, merged_at, title, url, checked_at }`.
  Unauthenticated GitHub API (60 req/hour). `merged`/`merged_at` only apply to PRs.

### verify_claim
- `assertion_type` (string, required) — `"contains"` | `"status_2xx"` | `"github_merged"`.
- `url` + `assertion` — for `contains` / `status_2xx`.
- `repo` + `number` (+ `kind`, default `"pr"`) — for `github_merged`.
- Returns `{ verified, evidence, checked_at }` where `evidence` is the full
  `verify_url` / `verify_github` result.

## Design notes

- **Zero runtime dependencies.** Hand-rolled MCP JSON-RPC over stdio using
  `node:` built-ins only. `npm install` pulls in nothing.
- **Local-first.** stdio transport; it runs inside your agent process. The only
  network calls are the verification targets themselves (the URL you ask about,
  `api.github.com`).
- **No telemetry.** Nothing phones home. Ever.

## Tests

```bash
npm test
```

The suite spins up a local fixture HTTP server (redirects, 404, slow
endpoint) and stubs the GitHub API, so it passes fully offline.

## Liability disclaimer

This software is provided as-is. Verification results are a best-effort
snapshot of a live, changing web — pages change, APIs rate-limit, and a
"verified" result is evidence, not a guarantee. It is not legal, financial,
or compliance advice. You are responsible for decisions you make based on its
output.

## License

MIT — see [LICENSE](LICENSE).

TDQS

A3.7/5.0

Scored across 3 tools

Disambiguation2/5

verify_url and verify_claim both verify URL loading and phrase presence, while verify_github and verify_claim both verify GitHub merged state. The generic verify_claim tool overlaps heavily with both specialized tools, making tool selection ambiguous.

Naming Consistency5/5

All tools follow a strict verify_<target> pattern with clear, predictable nouns. This makes the tool names consistent and easy to guess.

Tool Count4/5

Three tools is a reasonable, focused count for a small claim-verification server. However, verify_claim largely duplicates the other two, so not every tool fully earns its place.

Completeness4/5

Core URL and GitHub PR/issue verification workflows are covered with useful evidence. The surface is narrow and lacks support for other claim types like API responses or commits, but no obvious dead ends exist for the stated purpose.