MCP Registry OAuth Scan

Scans the official MCP registry's remote servers for OAuth support, specifically DCR (dynamic client registration) and CIMD (client_id_metadata_document_supported).

Pipeline

collect.ts ──> registry-state blob ──> collect_http.ts ──> probe/*.json ──> dump.ts ──> merged JSON
 (page registry)                       (probe chunks)        (per-chunk)      (merge + join names)
  1. collect.ts (script, run manually) — pages /v0/servers?limit=100&version=latest with a 6s timeout, 40s budget, and a resumable cursor saved in the registry-state blob. Collects every remote URL with its server name/title/type. Run repeatedly until it logs done: true.
  2. collect_http.ts (HTTP) — probes unique URLs in chunks for OAuth support: MCP initialize POST, 401 + www-authenticate check, protected-resource metadata chain, then authorization-server metadata for registration_endpoint (DCR) and client_id_metadata_document_supported (CIMD).
    • GET ?offset=0&n=300 — probe URLs [offset, offset+n)probe/<offset>.json. Repeat until offset >= totalUrls.
    • GET ?mode=hosts — build recheck-list.json: one representative URL per host that showed dcr|cimd.
    • GET ?mode=recheck&offset=0&n= — re-probe the recheck list → recheck/<offset>.json.
  3. dump.ts (HTTP) — merges all probe chunks and joins back registry names/titles into one JSON array. Reads chunks in parallel (~350ms for 15k results). Query: ?set=probe (default) or ?set=recheck.

Data (blob storage)

KeyContents
registry-stateregistry cursor + all collected entries (name, title, url, type)
probe/<offset>.jsonprobe results per chunk
recheck-list.jsonone representative URL per DCR/CIMD host
recheck/<offset>.jsonrecheck results per chunk

Result record

url, alive, oauth, dcr, cimd, status, www (www-authenticate header), prm (protected-resource metadata found), metaUrl, registration_endpoint, authorization_endpoint, token_endpoint, issuer, pkce, plus joined names[], titles[], type.

Downstream

The ?set=probe dump feeds registry-scan-data.ts in stevekrouse/oauth-demos (one entry per hostname, curated hosts excluded). Keep this val separate from oauth-demos: it's an offline batch scraper with its own blob state, while oauth-demos is a live public app.