Methodology
What we count, how we probe, and what the numbers mean.
Harvest
Every source on the Sources page is pulled in full on a schedule. A listing is one record in one source. A remote endpoint is an HTTP(S) URL a third party could actually call: an MCP Streamable-HTTP URL, an A2A agent card, an ARD ai-catalog.json, an OpenAPI document, an OpenAI-compatible model API. Package-only listings (npm, PyPI, Docker, stdio transport) are counted as listings but are unprobeable by definition. URLs are normalised (scheme and host lower-cased, default ports and fragments dropped) before deduplication, so overlap between sources is exact-URL overlap.
Probe
Each endpoint kind gets the smallest real protocol interaction that proves it is what it claims to be. Every count on this site is per endpoint (one URL of one kind); hosts are counted separately where a page says so. Nothing is executed and nothing is changed on the far side.
| kind | request sequence | score weights |
|---|---|---|
| mcp | POST initialize (Streamable HTTP, JSON or SSE response) → notifications/initialized → tools/list, resources/list, prompts/list → DELETE session. 401/403 + /.well-known/oauth-protected-resource = auth-required. GET returning text/event-stream = legacy HTTP+SSE. | reachable 20 · initialize ok 30 · protocolVersion 10 · serverInfo 10 · tools/list ok 20 · ≥1 tool 10 |
| a2a | GET /.well-known/agent-card.json (fallback agent.json) → validate required fields → JSON-RPC message/send with a labelled ping. | card fetched 20 · JSON 10 · required fields 20 · protocolVersion 10 · endpoint reachable 20 · send accepted or auth-required 20 |
| ard | GET /.well-known/ai-catalog.json, count resources by type. | fetched+JSON 60 · ≥1 resource 20 · version/$schema 20 |
| llm-api | GET /v1/models without credentials. | 200 with data[] 100 · 401/403 (alive, keyed) 70 |
| x402 | GET the resource URL without payment. A live paid resource answers 402 with payment requirements (PAYMENT-REQUIRED header, accepts[] in the body). One row per paid resource (route), not per host: a host selling eight routes is eight x402 endpoints. | 402 with payment header 100 · 402 without 80 · 2xx/3xx (resource open, payment not enforced) 60, protocol-mismatch · 401/403 60, auth-required · 404/405 20 |
| agent-facts | GET the NANDA AgentFacts document, require a JSON object. | JSON object 60 · lists endpoints 20 · signed 20 |
| site | GET the homepage a registry lists instead of an endpoint; reachability only, not counted as an agent. | <400 100 · else 0 |
| openapi | GET the document, check openapi/swagger, count operations. | valid 60 · ≥1 operation 40 |
| llms-txt agents-txt robots sigdir | Per-host conventions fetched once per host: llmstxt.org format check, agents.txt directives, robots.txt AI-bot rules and Content-Usage lines, Web Bot Auth /.well-known/http-message-signatures-directory. | format checks only; not part of the alive/conformant headline |
Outcomes
| outcome | meaning | counts as |
|---|---|---|
| ok | handshake completed and the protocol behaved as declared | alive, conformant |
| auth-required | reachable; the protocol step needs credentials we do not have | alive |
| card-invalid | manifest fetched but fails required-field validation | not alive |
| protocol-mismatch | reachable, but does not speak the declared protocol | not alive |
| http-error timeout tls-fail connect-fail dns-fail | transport-level failure on the primary fetch. A 5xx that carries the platform's own reason keeps it (Hugging Face Spaces answer 503 with space is paused or space is in error; most 503s in the census are those, not outages) | not alive |
| blocked | resolves to a private, loopback, link-local or metadata address — we refuse to connect | excluded |
| unprobeable | no remote endpoint exists for this listing | excluded |
Politeness and safety
User-Agent agentprobe/x.y (+https://agentprobe.org/methodology). One request in flight and ≥2 s between request starts per host; the four large aggregator catalogs get 4 in flight and 0.5 s. A host that answers 429 or 503 (Retry-After honoured), drops connections or returns 5xx is backed off exponentially, 30 s doubling to 1 h, and after five consecutive such answers it is left alone until the next pass. Bodies capped at 2 MiB, 5 redirects, 5 s to connect and 20 s total per fetch. Every endpoint is probed at least once a day, well-known conventions once a week. Probes speak HTTP/1.1; the HTTP version of the last response is recorded with every probe (meta.http_version), so a transport failure is never mistaken for a dead endpoint. DNS is resolved first and private ranges are refused on every hop. The A2A ping message identifies itself and asks to be ignored. To be excluded, block the User-Agent; we re-check robots.txt every run.
Limitations
A single vantage point (us-east-1) — regional outages look like global ones. Auth-required endpoints are alive but we cannot see their capabilities. Registries that only expose HTML are harvested best-effort or not at all, and are marked unverified on the Sources page. The time series is incomplete by construction: endpoints enter when a source first lists them.