There is a machine door

Canonical: https://thonly.org/research/mcp · Licence: CC0 1.0

Connect

The corpus is served over MCP at https://corpus.333.eco/mcp. There is no account, no key and no rate limit to negotiate.

{ "mcpServers": { "corpus": { "url": "https://corpus.333.eco/mcp" } } }

Or run it on your own machine, fully offline once downloaded. The package has no dependencies at all — not even an MCP SDK — and needs Node 20 or newer.

{ "mcpServers": { "corpus": { "command": "npx", "args": ["-y", "@333eco/corpus"] } } }

Most clients take one of those blocks; consult your own client's documentation for where it goes. The two surfaces answer identically, and a check in the server's own build fails if they ever advertise different tools.

The six tools

ToolWhat it does
search_corpusFull-text search. Returns matching documents with an excerpt and a provenance envelope — not the full text.
get_documentOne document in full, behind its provenance header.
list_documentsSlugs, titles, genres, licences and provenance summaries. Filter by genre, topic category or licence.
list_predictionsThe pre-registered predictions of the research programme, with each one's registered falsifier and current status.
get_predictionOne prediction by identifier, with the envelope of the paper that registered it.
get_programThe programme's hard core, chapters, stopping rule and its own count reconciliation, verbatim.

The last three appear only where the served index carries a research programme; an index built over a corpus without one advertises three tools, not six.

One move in this API is genuinely not obvious, and it is deliberate: a prediction resolves to its stating paper's envelope, not the register's. A prediction's authority is the document that registered it before the data existed. The register is an index, and an index is not evidence.

Resources, prompts, completions

Every document is also addressable as a resource at corpus://{slug}. A resource read returns the provenance header first and then the document verbatim, so a client that hands the contents straight to a model passes the proof along with the text.

Three prompts ship, and they are worked examples of the API rather than instructions about the subject matter: orient (what is in this corpus), verify_a_quote(slug) (the verification path, end to end), and what_would_falsify(claim) (find a registered falsifier and resolve it to its stating paper). The slug argument is completable, because a prompt argument nobody can autocomplete is only usable by someone who already knows the answer.

The envelope, and how to check it

Every response carries the document's SHA-256, its DOI where one exists, an OpenTimestamps proof anchored in the Bitcoin blockchain, and the exact command that checks them — so a passage can be verified before it is cited, rather than taken on the strength of the channel it arrived over.

"provenance": {
  "sha256": "d6ac93f9…50ecc3c",
  "doi": "10.5281/zenodo.22440983",
  "concept_doi": "10.5281/zenodo.22240458",
  "source_url": "https://raw.githubusercontent.com/thonly/publications/main/…",
  "sha256_covers": "the complete source file at source_url, including its
                    metadata block — NOT the `text` field in this response",
  "opentimestamps": true
}

That sha256_covers line matters more than it looks. The hash covers the whole source file at source_url, not the text you were served — so hashing the response will not reproduce it. Fetch the named source and hash that:

curl -sL <source_url> | shasum -a 256      # compare with provenance.sha256
ots verify <path>.ots                      # in the source repository

A verifiable claim that requires you to already know where the file lives is not one. The envelope names the location so that closing the loop is a single command.

What it deliberately does not do

It never summarises. Text is returned verbatim, always. This is not a preference: a summary cannot be hash-verified, so summarising at the server would destroy the only property the server has. A retrieval service that asserts is an authority, and it propagates its errors; one that exposes is a witness, and it is caught by the first reader who bothers.

It proves bytes, not truth — and not currentness. A timestamp establishes that this exact text existed no later than its date. It says nothing about authorship, originality, or whether any claim in the document is correct. And a genuine, anchored, superseded version verifies perfectly: the anchors order versions by age, not by canonicality. Fetch the named source and compare if what you need is the current text.

The licence gate is in the builder, not the request path. The server has no filesystem access to the corpus at all — it can only serve what the index already contains. A file that declares no licence is excluded and reported, never assumed public domain, and a document under CC-BY carries attribute_to in its licence block. A gate a refactor can route around is a rule; a gate in the artifact is a property.

What it records

The hosted endpoint counts calls by the client software's own name from its handshake — never an IP address, never any identifier derived from one, never a per-caller id of any kind. The only search text ever stored is a search that matched nothing, because the reason to keep a query is to learn what the corpus lacks; a successful search says only what someone was reading.

The npm package records nothing and sends nothing. Its two report commands, --report-gap and --report-bug, send only when you type them, and print the whole payload before the request.

The endpoint discloses all of this itself, under records, at corpus.333.eco — readable before you call anything. A privacy policy is a page someone has to go and find.

The reasoning

The argument, and its limits, are published as Provenance-Carrying Retrieval — including what the mechanism does not establish. The server's source is at github.com/333eco/corpus.333.eco.