Docs · Anchor Manifest v0.1 · draft
Anchor Manifest specification
There are good formats for describing a server, an API and an agent already. What's missing is one place per publisher that says which of those exist, how to reach each one, what it costs, which variant is safe to hand an agent, and whether anyone still maintains it. The manifest is that place. It's small on purpose and it links out instead of duplicating.
Design goals
- Use existing protocols first. The manifest points at an MCP registry
server.json, an OpenAPI document, an A2A agent card, an llms.txt and x402 discovery data. It doesn't restate any of them. - Add only what agents keep needing and nobody publishes. Read-only variants, per-call payment terms, status and changelog links, and a way to verify who published the file.
- Be readable by a model with no prior knowledge, and small enough to fetch on every crawl.
- Be optional. Tools without a manifest are still listed and scored. A manifest makes their facts more accurate and refreshes them faster.
Location and discovery
Serve the document at https://<publisher-domain>/.well-known/anchor.json with Content-Type: application/json and CORS enabled. Optionally advertise it with Link: </.well-known/anchor.json>; rel="anchor-manifest" on responses from the tool's own endpoints, and list it in llms.txt.
Document
{
"anchor": "0.1",
"publisher": {
"name": "Example Search",
"url": "https://example.com",
"contact": "agents@example.com",
"docs": "https://example.com/docs",
"llmsTxt": "https://example.com/llms.txt"
},
"tools": [
{
"id": "com.example/search",
"kind": "mcp",
"name": "Example Search MCP",
"description": "Web search and page fetch for agents.",
"endpoint": "https://mcp.example.com/mcp",
"transport": "streamable-http",
"auth": ["none", "oauth2", "api-key"],
"readOnlyVariant": "https://mcp.example.com/mcp/readonly",
"scopedVariants": { "search-only": "https://mcp.example.com/mcp/search" },
"payments": [
{ "protocol": "x402", "version": 2, "networks": ["eip155:8453", "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"], "asset": "USDC", "priceUsd": 0.005, "unit": "call", "discovery": "https://api.cdp.coinbase.com/platform/v2/x402/discovery/search?payTo=0x..." }
],
"pricing": "https://example.com/pricing",
"freeTier": { "cardRequired": false, "limit": "1000 calls/month" },
"schemas": {
"mcpServerJson": "https://registry.modelcontextprotocol.io/v0.1/servers/com.example%2Fsearch",
"openapi": "https://api.example.com/openapi.json",
"a2aAgentCard": null
},
"status": "https://status.example.com",
"changelog": "https://example.com/changelog",
"deprecations": [
{ "what": "/sse endpoint", "sunset": "2026-12-31", "replacement": "https://mcp.example.com/mcp" }
],
"telemetry": { "collected": true, "optOut": "EXAMPLE_TELEMETRY=0", "policy": "https://example.com/privacy" },
"security": "https://example.com/.well-known/security.txt",
"source": "https://github.com/example/search-mcp",
"license": "MIT"
}
],
"verify": {
"dnsTxt": "_anchor.example.com",
"http": "https://example.com/.well-known/anchor.json"
},
"updated": "2026-09-25"
}
Fields
Top level
| Field | Required | Type | Notes |
|---|---|---|---|
anchor | yes | string | Specification version, "0.1" |
publisher | yes | object | name, url required. contact, docs, llmsTxt recommended |
tools | yes | array | One entry per tool. May be empty for a publisher that only wants to be verified |
verify | no | object | How the claim is verified, see below |
updated | yes | date | ISO date the document last changed |
Tool entry
| Field | Required | Type | Notes |
|---|---|---|---|
id | yes | string | Reverse-DNS identifier, the same form the MCP registry uses (com.example/search). Use the registry name if the tool is registered. |
kind | yes | mcp · http · openapi · a2a · sdk | What kind of thing the endpoint is |
name, description | yes | string | Short. A model reads them |
endpoint | yes for hosted | URL | The primary hosted endpoint. Local-only tools use packages instead |
packages | no | array of {registry, name} | npm, pypi, oci, nuget |
transport | yes for mcp | streamable-http · stdio · sse | Declare sse only while it still works. List it under deprecations when retiring |
auth | yes | array | Any of none, oauth2, api-key, pat, httpsig, x402. Order by preference. |
readOnlyVariant | no | URL | An endpoint or mode that exposes no write tools. Strongly recommended, and scored. |
scopedVariants | no | map | Named narrower endpoints |
payments[] | no | array | protocol (x402, mpp, l402, card), version, networks (CAIP-2), asset, priceUsd, unit (call, token, page, minute), optional discovery URL |
pricing | no | URL | Human pricing page readable without a login |
freeTier | no | object | cardRequired boolean and a limit string |
schemas | no | object | mcpServerJson, openapi, a2aAgentCard, jsonSchema URLs |
status, changelog | recommended | URL | Scored under transparency |
deprecations[] | no | array | what, sunset (date), replacement |
telemetry | recommended | object | collected boolean, optOut instruction, policy URL |
security | no | URL | Usually the publisher's security.txt |
source, license | no | URL, SPDX id |
Verification
A manifest is trusted for a listing when one of these holds.
- DNS. A TXT record at
_anchor.<publisher-domain>containsanchor-verify=<token>, where the token is issued when claiming the listing. - HTTP. The manifest is served from
/.well-known/anchor.jsonon the same registrable domain as the tool'sendpoint, and the endpoint responds. Same origin is the proof. - Registry. The
idis a verified namespace in the official MCP registry and the registry'sserver.jsonlists the sameendpoint.
A manifest that fails verification is ignored, not penalised. The crawler falls back to what it can observe.
How Anchor Terminal uses it
On every crawl the manifest is fetched, verified and diffed. Changed endpoints, prices, deprecations and variants update the listing's facts the same day. Declared deprecations with sunset dates count as graceful, never as negative events. A declared readOnlyVariant gets probed. If it exposes write tools, the declaration is marked false on the tool's page. Declared payments get probed with the same unpaid-request and canary-settlement method as any other x402 endpoint.
Relationship to other formats
| Format | What it describes | How the manifest relates |
|---|---|---|
MCP registry server.json | Packages and remotes of one server, with a verified namespace | Linked via schemas.mcpServerJson. The manifest reuses its id |
| OpenAPI | Operations of an HTTP API | Linked via schemas.openapi. RFC 9727 /.well-known/api-catalog stays the standard way to list OpenAPI documents |
| A2A agent card | Skills and interfaces of an agent | Linked via schemas.a2aAgentCard. The card stays at /.well-known/agent-card.json |
| llms.txt | Site index for LLMs | Linked from publisher.llmsTxt. The manifest should be listed in it |
x402 Bazaar / /.well-known/x402 | Payable resources and prices | Linked via payments[].discovery. Prices in the live 402 win |
MCP server cards (/.well-known/mcp/server-cards.json, proposed) | Capabilities of MCP servers on a host | If adopted, the manifest will link to it. Until then the manifest carries the minimum needed |
Status
Draft v0.1. Fields get added, not removed, before v1. Anchor Terminal publishes its own manifest at /.well-known/anchor.json.
Nobody outside this site publishes one yet, so the field list is our guess at what agents need rather than something worn in by use. The payments shape is the part I'd expect to change first, because MPP and L402 don't map cleanly onto priceUsd per unit. Feedback to agents@anchorterminal.com.