{
  "markdown": "# KeyHalve verify-MCP\n\nFree, public, no-account [MCP](https://modelcontextprotocol.io) server that lets any AI verify\nKeyHalve-sealed documents — from **any** platform on the rail (ValidPay, CheckBooks, …).\n*Seal = the door (a platform's paid MCP). Verify = the room (this one, free forever).*\n\n- **Endpoint:** `https://mcp.keyhalve.com/mcp` (Streamable HTTP, stateless)\n- **Tools:** `keyhalve_verify` · `keyhalve_status` · `keyhalve_explain` — all read-only, no auth\n\n## The blindness rule\n\nThis server **never receives decryption keys.** A verify URL carries the holder's key share in\nthe `#key=` fragment; `parseInput` discards any fragment **before any other logic runs**, and the\nresponse says so. Verification here covers everything provable *without* the key:\n\n| Check | Meaning |\n|---|---|\n| status | active / revoked (with reason) on the issuing platform |\n| ciphertext integrity | SHA-256 of the served ciphertext = commitment recorded at issuance (v2) |\n| rail attestation | Ed25519-verified against the **pinned** rail key; dual-sign content binding when present |\n| time lock | validity window judged client-side (Patent D semantics) |\n| issuer trust | fail-closed: `declared` at best, never proof |\n\nReading the sealed contents still happens **only in the holder's browser** — exactly like the web\nverifier. The overall verdict fails closed: any failed check → `FAILED — DO NOT TRUST`.\n\n## Design notes\n\n- **Zero runtime dependencies.** WebCrypto only; the whole protocol layer is hand-auditable.\n  Same reasoning as the pinned-key rail client in `keyhalve-website`.\n- **Stateless.** No sessions, no SSE, no KV, no cookies; every POST gets `application/json`.\n  Request bodies are never logged.\n- **Tenant-neutral.** Platforms come from the same manifest data as the web verifier\n  (`TENANT_MANIFEST` in `src/verifier.ts`); onboarding a platform = one data entry.\n- **Fail closed.** Unreachable rail, malformed share, partial dual-sign binding, unknown id\n  prefix — all report NOT verified, never a soft pass.\n\n## Develop / deploy\n\n```\nnpm ci\nnpm run typecheck && npm test   # 32 tests\nnpm run dev                      # wrangler dev\n```\n\nDeploys are **manual** (`deploy.yml` via workflow_dispatch, same discipline as rail/console).\nNeeds the `CLOUDFLARE_API_TOKEN` repo secret; the route `mcp.keyhalve.com` is a custom domain\non the business CF account (same account as the watchdog scheduler).\n\n## Directory submissions (Mike-gated)\n\nSubmitting to the Claude Connectors Directory / ChatGPT App Directory is an outward-facing\nstep — prepared separately, goes out only on Mike's go.\n\n## Listings\n\nDirectory-listing assets live in this repo — reuse them, don't invent copy:\n\n- `llms-install.md` — AI-agent install steps (Cline's AI-driven install; also the canonical per-client snippets).\n- `glama.json` — Glama claim file (maintainers; their live schema is maintainers-only).\n- `assets/icon-400.png` — 400×400 icon (white split-circle glyph on Ink #0E1116, from the brand kit).\n- Descriptions must stay byte-consistent with `src/tools.ts` and pass the approved-claims register (no \"split key\", no \"tamper-proof\", no issuer-identity claims).\n",
  "bytes": 3156,
  "sha": "503376a7ccf3eeaffe8304572a1678b92e9dff7b89e581f39eecfe5f4ef38de0",
  "repo_slug": "keyhalve/keyhalve-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_com_keyhalve_verify_cdc83445/readme"
}