API reference
Base URL: http://<registry-host>:5001. All bodies are JSON. Errors use
{"detail": "<message>"} with a conventional status code.
Authentication
Section titled “Authentication”Authorization: Bearer <jwt> — HS256 against the platform JWT_SECRET.
Identity comes from sub (or user_id); tokens without exp are accepted,
expired ones are treated as anonymous. With no JWT_SECRET configured
(dev mode) any non-empty bearer authenticates as demo_user.
Read endpoints are public. Mutations require auth; tokens carrying a
scope/scopes claim additionally need mcp-registry:write (or
mcp-registry:admin) — see publishing.
/v0.1 — official spec surface (2025-12-11)
Section titled “/v0.1 — official spec surface (2025-12-11)”| Method | Path | Notes |
|---|---|---|
| GET | /v0.1/servers |
limit (≤100), cursor (opaque), search, updated_since (RFC 3339; implies update-time ordering + tombstones), include_deleted |
| GET | /v0.1/servers/{name}/versions |
All versions, each a full server document |
| GET | /v0.1/servers/{name}/versions/{version} |
latest resolves to the current version |
| PUT | /v0.1/servers/{name}/versions/{version} |
Publish; 409 if the version exists (immutability) |
| PATCH | /v0.1/servers/{name}/status |
{"status", "statusMessage"?} — deprecate/delete/reactivate |
| PATCH | /v0.1/servers/{name}/versions/{version}/status |
Per-version lifecycle |
| GET | /v0.1/health · /v0.1/ping · /v0.1/version |
version reports "specVersion": "2025-12-11" |
{name} is the URL-encoded full name (io.github.acme%2Fwidget).
Listing shape:
{ "servers": [ { "$schema": "...", "name": "...", "version": "...", "_meta": { } } ], "metadata": { "nextCursor": "b2Zmc2V0OjUw", "count": 50 }}The _meta blocks
Section titled “The _meta blocks”Every served document carries:
io.modelcontextprotocol.registry/official—status,publishedAt,updatedAt,isLatest, and when set,statusMessage+statusChangedAt.ai.brutor.registry(extension) —downloadCount,stars,verified,namespaceVerified,securityScan,sourceConnection(provenance), andgovernanceStatus:governed|ungoverned|unknown.
Extensions
Section titled “Extensions”GET /v0.1/x/ai.brutor/governance/{name} — just the governance block for one
server, for tooling that only wants posture:
{ "extension": "ai.brutor.registry/governance", "server": "io.github.acme/widget", "governance": { "governanceStatus": "governed", "verified": true }}Unprefixed extension routes: POST /namespace/verify,
POST /namespace/verify/check, GET /auth/github/callback — see
namespace verification.
/v0 — legacy surface
Section titled “/v0 — legacy surface”Server listings and details on this surface carry a
source_registry: {"id", "name"} field on aggregator-imported records —
the connection the server was federated from; locally published servers
omit it.
Kept for the Console and older tooling: GET /v0/servers (offset cursors,
namespace/keyword/verified_only filters), GET /v0/servers/{id} (also
accepts row UUIDs; increments the download counter), POST /v0/publish,
POST /v0/validate (no-auth dry run), icon endpoints
(GET/PUT/DELETE /v0/servers/{id}/icon — PNG/JPEG/SVG/WebP, ≤ 512 KiB,
GET is public), version listing/status routes, and the
connections API under /v0/connections.
System endpoints
Section titled “System endpoints”| Path | Auth | Notes |
|---|---|---|
/health |
public | 200 healthy / 503 with a JSON body when the DB is unreachable |
/status |
public | Uptime, totals, aggregator state |
/config |
public | Effective non-secret configuration |
/logs |
required | Last ≤ 500 in-process log entries, ?level= filter |
/metrics |
required | Request/publish/download/search counters, response-time stats |

