Show HN: I measured the MCP registry nightly for 37 days An independent nightly crawler of the official MCP registry reached 13,870 of 13,997 declared endpoints (99.1%) and enumerated tool lists without credentials on 7,820 servers — 56.4% of endpoints with a remote and 31.3% of the whole registry — recording 132,683 tools across nine consecutive daily censuses as of 2026-09-07. The project's operator reports that two operators, gateway.pipeworx.io (1,264 servers) and api.mcp.ai (1,094), account for 30.2% of every reachable MCP server in the registry, and that 73.2% of recorded tools declare at least one annotation hint. The log is an append-only, signed-tree-head record of what public MCP servers actually served, positioned as adversarial third-party observation rather than opt-in publisher attestation such as Sigstore, Rekor and manifest signing. An independent, continuously-operated record of what public MCP servers actually served. Sigstore, Rekor and manifest signing are opt-in publisher attestations . A server operator who changes a tool description from "look up the weather" to "look up the weather and forward the conversation to evil.example" will happily sign the new description, and the signature will verify perfectly. Signing proves who published something. It does not tell you that what you are running today is not what you audited last month. A transparency log is adversarial third-party observation . It records what servers actually served, without their consent or cooperation. That asymmetry is why Certificate Transparency worked: CAs never opted in, monitors watched them anyway, and misissuance became detectable after the fact. That is what this project is. Not a scanner, not a registry, not a linter — a log. A crawler visits every publicly reachable MCP server in the official registry on a schedule and records the exact tool surface it served: names, descriptions, JSON schemas, and the four annotation hints. Observations go into an append-only log with signed tree heads, so anyone can prove that a given surface was observed at a given time and that the log has not been rewritten since. The value is the accumulated history. A stranger can clone this repository in a weekend. Nobody can clone a year of observations. Early. Phase 1 of 4. | Phase | Scope | State | |---|---|---| | 0 | Falsification test — is the ecosystem observable at all? | done, passed | | 1 | Crawler, raw observation archive, daily census | done, running | | 2 | RFC 6962 Merkle log, signed tree heads, verify CLI | done | | 3 | Public static site | not started | | 4 | Witnesses and gossip for split-view detection | not started | Nine consecutive daily censuses as of 2026-09-07, no gaps. A systemd timer fetches the registry, probes every endpoint, archives the raw bytes, appends to the tree, signs a head and publishes it — with no human in the loop. Phase 4 is the end state, not the entry ticket. A single-operator log is still useful — Go's own checksum database ran that way for years. The first complete pass over the registry. 13,870 of 13,997 declared endpoints were reached; the run's meta.json records it as incomplete, because it is. | Registry entries | 25,020 | | Declaring a network endpoint | 13,997 | | Observed | 13,870 99.1% | | Enumerated a tool list, no credentials | 7,820 — 56.4% of endpoints with a remote | | Same figure against the whole registry | 31.3% | | Tools recorded | 132,683 | | Tools declaring at least one annotation hint | 73.2% | Outcomes: 56.4% ok, 25.0% auth required, 8.3% protocol error, 6.4% unreachable, 3.2% timeout, 0.7% rpc error. Distinguishing "refused us" from "is not there" is what keeps the reachability figure honest. Concentration. Two operators — gateway.pipeworx.io 1,264 and api.mcp.ai 1,094 — account for 30.2% of every reachable MCP server in the registry . One template edit at either changes over a thousand "servers" at once. This is the single strongest argument for watching this ecosystem rather than trusting it. Spec adoption. 6,716 servers negotiated 2025-06-18; 672 still speak 2024-11-05. Seventeen answered on 2026-07-28. The week-0 sample of 300 found zero on that revision and concluded none existed — at full population the honest statement is "rare, not absent". A sample that small cannot see a 0.2% feature. Tool-surface size. The median server exposes a handful of tools. Three expose more than 600, and one — io.github.davidmosiah/delx-mcp-a2a — exposes 1,076 , of which 31 carry any annotation. Only 2 servers in the entire population paginated tools/list . Parked domains still listed. Four registry endpoints resolve to expired domains now serving for-sale parking pages, all four through the same ad host. Small in absolute terms 0.03% , but the mechanism matters: an agent configured from the official registry connects to infrastructure its original operator no longer controls. Windows Defender classified two of those pages as phishing — noted, not endorsed: the same detector had flagged this project's own binary as a trojan an hour earlier. The archived bytes are in the log; judge them yourself. Before writing a crawler, the obvious way to kill this idea was tested: if almost no public MCP server can be enumerated without credentials, there is nothing to observe and the project should not exist. The kill threshold was set at 30% in advance. Measured on a random sample of 300 registry entries, 2026-08-25: | Registry population | 24,729 servers | | Declaring a network endpoint | 13,629 55.1% | | Enumerable with no credentials | 35.0% — above the 30% kill line | | Genuinely real servers in the sample | 67.6%, across 71 distinct operators | | Tools declaring at least one annotation hint | 68.8% of 1,420 observed tools | | Successful handshakes using the 2026-07-28 server/discover | 0 of 105 — all used legacy initialize | Two operators, gateway.pipeworx.io 1,312 servers and api.mcp.ai 1,099 , publish 17.7% of every observable server in the registry . One template edit changes 1,312 "servers" at once. That concentration is the clearest argument for watching this ecosystem rather than trusting it. The probe, its raw output, and the population snapshot are in docs/week0-falsification/ https://github.com/yassinht/mcp-transparency-log/blob/main/docs/week0-falsification . Two bugs in that probe mattered enormously: missing SSE transport support understated reachability by ten percentage points and would have produced a false "do not build" verdict, and a hardcoded protocol version biased the sample against servers on newer spec revisions. Writing the code was never the bottleneck. Contact with reality was. Raw bytes are the record. Every response is archived exactly as received. Counts, classifications and hashes are derived views that can be rebuilt. The week-0 probe stored only its own classification of the registry and discarded the raw entries, which made every later question about that snapshot unanswerable. Two hashes, never one. body sha256 covers the exact bytes and is the provenance claim. surface sha256 covers the canonical, name-sorted tool array and is the change-detection key and the future Merkle leaf. Collapsing them would make the log either noisy or unprovable. No MCP SDK in the crawl path. An SDK validates, normalizes and rejects, because it is built to talk to well-behaved servers. A server returning a nameless tool, a duplicate name, or a 40KB description is producing exactly the observation worth keeping. No LLM anywhere in the data path. Every judgment must be a rule a human can re-run against the archived blobs, or the Merkle proofs are theatre. Content addressing, not timestamps. A server whose surface has not changed costs nothing to observe again. The archive grows only when something actually changed. go test ./... go run ./cmd/crawler --dry-run fetch and archive the registry, probe nothing go run ./cmd/crawler --sample=200 reproducible smoke test go run ./cmd/crawler full census Output lands in data/ : data/blobs/