{
  "type": "guide",
  "id": "publish-agent-discovery-files",
  "title": "Make your site and API discoverable by agents",
  "summary": "Publish the files agents look for: an RFC 9727 API catalog, an AI Catalog, an MCP Server Card, an Agent Skills index and llms.txt. Minimal valid examples, the headers each spec asks for, each spec's real status, and how to check the result with our discovery probe.",
  "author": "Agentica Author",
  "tags": [
    "discovery",
    "well-known",
    "api-catalog",
    "ai-catalog",
    "mcp",
    "server-card",
    "agent-skills",
    "llms-txt",
    "publishing"
  ],
  "published": "2026-11-03",
  "last_verified": "2026-11-03",
  "difficulty": "intermediate",
  "time_estimate": "45 min",
  "entries": [
    "rfc-9727",
    "ai-catalog",
    "mcp-server-cards",
    "agent-skills-discovery-rfc",
    "llms-txt",
    "agent-skills-spec",
    "a2a-protocol",
    "rfc-9728"
  ],
  "links": {
    "html": "https://indexagentica.com/guides/publish-agent-discovery-files/",
    "markdown": "https://indexagentica.com/guides/publish-agent-discovery-files.md",
    "json": "https://indexagentica.com/api/longform/guides/publish-agent-discovery-files.json",
    "source": "https://github.com/Drudley/indexagentica/blob/main/content-long/guides/publish-agent-discovery-files.md"
  },
  "status": "published",
  "prerequisites": [
    "Control over your site's web server or CDN headers (media types, Link and CORS headers)",
    "Python 3 for the probe, and Node.js if you want to validate the Server Card with the official schema"
  ],
  "entries_detail": [
    {
      "id": "rfc-9727",
      "name": "RFC 9727: api-catalog",
      "summary": "IETF Proposed Standard (June 2025) defining the /.well-known/api-catalog URI and api-catalog link relation so agents can find a publisher's APIs.",
      "url": "https://indexagentica.com/entries/rfc-9727/",
      "json": "https://indexagentica.com/api/entries/rfc-9727.json"
    },
    {
      "id": "ai-catalog",
      "name": "AI Catalog",
      "summary": "Draft JSON format, served at /.well-known/ai-catalog.json, that lists a host's MCP servers, A2A agents, plugins, datasets and other AI artifacts.",
      "url": "https://indexagentica.com/entries/ai-catalog/",
      "json": "https://indexagentica.com/api/entries/ai-catalog.json"
    },
    {
      "id": "mcp-server-cards",
      "name": "MCP Server Cards",
      "summary": "Experimental MCP extension defining a static JSON card that describes a remote MCP server's identity and transport endpoints so clients can find and connect to it.",
      "url": "https://indexagentica.com/entries/mcp-server-cards/",
      "json": "https://indexagentica.com/api/entries/mcp-server-cards.json"
    },
    {
      "id": "agent-skills-discovery-rfc",
      "name": "Agent Skills Discovery RFC",
      "summary": "Cloudflare's draft for publishing Agent Skills at /.well-known/agent-skills/, with an index.json listing each skill and a SHA-256 digest.",
      "url": "https://indexagentica.com/entries/agent-skills-discovery-rfc/",
      "json": "https://indexagentica.com/api/entries/agent-skills-discovery-rfc.json"
    },
    {
      "id": "llms-txt",
      "name": "llms.txt",
      "summary": "Proposal to standardize a /llms.txt Markdown file that gives LLMs and agents a concise guide to a website's content.",
      "url": "https://indexagentica.com/entries/llms-txt/",
      "json": "https://indexagentica.com/api/entries/llms-txt.json"
    },
    {
      "id": "agent-skills-spec",
      "name": "Agent Skills Specification",
      "summary": "Open format for packaging agent capabilities as folders with a SKILL.md (YAML frontmatter + instructions) plus optional scripts and resources.",
      "url": "https://indexagentica.com/entries/agent-skills-spec/",
      "json": "https://indexagentica.com/api/entries/agent-skills-spec.json"
    },
    {
      "id": "a2a-protocol",
      "name": "Agent2Agent Protocol (A2A)",
      "summary": "Open standard, hosted by the Linux Foundation, that lets independent AI agents discover each other, delegate work and exchange results across vendors.",
      "url": "https://indexagentica.com/entries/a2a-protocol/",
      "json": "https://indexagentica.com/api/entries/a2a-protocol.json"
    },
    {
      "id": "rfc-9728",
      "name": "RFC 9728: OAuth 2.0 Protected Resource Metadata",
      "summary": "IETF Proposed Standard defining a metadata document a protected resource publishes (at /.well-known/oauth-protected-resource) naming its authorization servers and capabilities.",
      "url": "https://indexagentica.com/entries/rfc-9728/",
      "json": "https://indexagentica.com/api/entries/rfc-9728.json"
    }
  ],
  "related": [
    {
      "type": "skill",
      "id": "discover-agent-interfaces",
      "title": "Discover a site's agent interfaces",
      "url": "https://indexagentica.com/skills/discover-agent-interfaces/",
      "json": "https://indexagentica.com/api/longform/skills/discover-agent-interfaces.json"
    },
    {
      "type": "guide",
      "id": "publish-an-mcp-server",
      "title": "Publish an MCP server so agents can find it",
      "url": "https://indexagentica.com/guides/publish-an-mcp-server/",
      "json": "https://indexagentica.com/api/longform/guides/publish-an-mcp-server.json"
    },
    {
      "type": "guide",
      "id": "add-oauth-to-your-mcp-server",
      "title": "Add OAuth authorization to your own MCP server",
      "url": "https://indexagentica.com/guides/add-oauth-to-your-mcp-server/",
      "json": "https://indexagentica.com/api/longform/guides/add-oauth-to-your-mcp-server.json"
    },
    {
      "type": "guide",
      "id": "connect-an-agent-to-a-remote-mcp-server",
      "title": "Connect an agent to a remote MCP server",
      "url": "https://indexagentica.com/guides/connect-an-agent-to-a-remote-mcp-server/",
      "json": "https://indexagentica.com/api/longform/guides/connect-an-agent-to-a-remote-mcp-server.json"
    },
    {
      "type": "guide",
      "id": "give-your-coding-agent-up-to-date-docs",
      "title": "Give your coding agent up-to-date library docs over MCP (Context7, GitMCP, DeepWiki, Microsoft Learn)",
      "url": "https://indexagentica.com/guides/give-your-coding-agent-up-to-date-docs/",
      "json": "https://indexagentica.com/api/longform/guides/give-your-coding-agent-up-to-date-docs.json"
    }
  ],
  "sources": [
    {
      "title": "RFC 9727: api-catalog, a well-known URI and link relation to help discovery of APIs",
      "url": "https://www.rfc-editor.org/rfc/rfc9727.html",
      "accessed": "2026-11-03"
    },
    {
      "title": "RFC 9727 on the IETF Datatracker (status)",
      "url": "https://datatracker.ietf.org/doc/rfc9727/",
      "accessed": "2026-11-03"
    },
    {
      "title": "RFC 9264: Linkset media types",
      "url": "https://www.rfc-editor.org/rfc/rfc9264.html",
      "accessed": "2026-11-03"
    },
    {
      "title": "AI Catalog specification (Agent-Card/ai-catalog)",
      "url": "https://github.com/Agent-Card/ai-catalog/blob/main/specification/ai-catalog.md",
      "accessed": "2026-11-03"
    },
    {
      "title": "AI Catalog published draft",
      "url": "https://ai-catalog.io/",
      "accessed": "2026-11-03"
    },
    {
      "title": "SEP-2127: MCP Server Cards",
      "url": "https://modelcontextprotocol.io/seps/2127-mcp-server-cards",
      "accessed": "2026-11-03"
    },
    {
      "title": "MCP Server Cards extension repository (README, schema, examples)",
      "url": "https://github.com/modelcontextprotocol/ext-server-card",
      "accessed": "2026-11-03"
    },
    {
      "title": "MCP Server Cards: discovery and HTTP requirements",
      "url": "https://github.com/modelcontextprotocol/ext-server-card/blob/main/docs/discovery.md",
      "accessed": "2026-11-03"
    },
    {
      "title": "MCP Server Card JSON Schema",
      "url": "https://github.com/modelcontextprotocol/ext-server-card/blob/main/schema.json",
      "accessed": "2026-11-03"
    },
    {
      "title": "Agent Skills Discovery via Well-Known URIs (v0.2.0 draft)",
      "url": "https://github.com/cloudflare/agent-skills-discovery-rfc",
      "accessed": "2026-11-03"
    },
    {
      "title": "Agent Skills specification",
      "url": "https://agentskills.io/specification",
      "accessed": "2026-11-03"
    },
    {
      "title": "The /llms.txt file, v2",
      "url": "https://llmstxt.org/",
      "accessed": "2026-11-03"
    }
  ],
  "front_matter": {
    "id": "publish-agent-discovery-files",
    "type": "guide",
    "title": "Make your site and API discoverable by agents",
    "summary": "Publish the files agents look for: an RFC 9727 API catalog, an AI Catalog, an MCP Server Card, an Agent Skills index and llms.txt. Minimal valid examples, the headers each spec asks for, each spec's real status, and how to check the result with our discovery probe.",
    "description": "A publisher-side guide to agent discovery files. It gives a minimal, validated example of each file and where it goes: /.well-known/api-catalog (RFC 9727, a Linkset served as application/linkset+json), /.well-known/ai-catalog.json (AI Catalog, application/ai-catalog+json), an MCP Server Card at <mcp-url>/server-card with the required CORS headers, /.well-known/agent-skills/index.json with SHA-256 digests, and llms.txt. It states each spec's status as of 2026-11-03, from IETF Proposed Standard to draft and proposal, and lists the HTTP headers to set. It shows how to check the result: JSON parsing, media types, the Server Card JSON Schema, and the discover-agent-interfaces probe. All examples were served from a local fixture and checked on 2026-11-03.",
    "author": "Agentica Author",
    "difficulty": "intermediate",
    "time_estimate": "45 min",
    "prerequisites": [
      "Control over your site's web server or CDN headers (media types, Link and CORS headers)",
      "Python 3 for the probe, and Node.js if you want to validate the Server Card with the official schema"
    ],
    "tags": [
      "discovery",
      "well-known",
      "api-catalog",
      "ai-catalog",
      "mcp",
      "server-card",
      "agent-skills",
      "llms-txt",
      "publishing"
    ],
    "entries": [
      "rfc-9727",
      "ai-catalog",
      "mcp-server-cards",
      "agent-skills-discovery-rfc",
      "llms-txt",
      "agent-skills-spec",
      "a2a-protocol",
      "rfc-9728"
    ],
    "related": [
      "discover-agent-interfaces",
      "publish-an-mcp-server",
      "add-oauth-to-your-mcp-server",
      "connect-an-agent-to-a-remote-mcp-server",
      "give-your-coding-agent-up-to-date-docs"
    ],
    "sources": [
      {
        "title": "RFC 9727: api-catalog, a well-known URI and link relation to help discovery of APIs",
        "url": "https://www.rfc-editor.org/rfc/rfc9727.html",
        "accessed": "2026-11-03"
      },
      {
        "title": "RFC 9727 on the IETF Datatracker (status)",
        "url": "https://datatracker.ietf.org/doc/rfc9727/",
        "accessed": "2026-11-03"
      },
      {
        "title": "RFC 9264: Linkset media types",
        "url": "https://www.rfc-editor.org/rfc/rfc9264.html",
        "accessed": "2026-11-03"
      },
      {
        "title": "AI Catalog specification (Agent-Card/ai-catalog)",
        "url": "https://github.com/Agent-Card/ai-catalog/blob/main/specification/ai-catalog.md",
        "accessed": "2026-11-03"
      },
      {
        "title": "AI Catalog published draft",
        "url": "https://ai-catalog.io/",
        "accessed": "2026-11-03"
      },
      {
        "title": "SEP-2127: MCP Server Cards",
        "url": "https://modelcontextprotocol.io/seps/2127-mcp-server-cards",
        "accessed": "2026-11-03"
      },
      {
        "title": "MCP Server Cards extension repository (README, schema, examples)",
        "url": "https://github.com/modelcontextprotocol/ext-server-card",
        "accessed": "2026-11-03"
      },
      {
        "title": "MCP Server Cards: discovery and HTTP requirements",
        "url": "https://github.com/modelcontextprotocol/ext-server-card/blob/main/docs/discovery.md",
        "accessed": "2026-11-03"
      },
      {
        "title": "MCP Server Card JSON Schema",
        "url": "https://github.com/modelcontextprotocol/ext-server-card/blob/main/schema.json",
        "accessed": "2026-11-03"
      },
      {
        "title": "Agent Skills Discovery via Well-Known URIs (v0.2.0 draft)",
        "url": "https://github.com/cloudflare/agent-skills-discovery-rfc",
        "accessed": "2026-11-03"
      },
      {
        "title": "Agent Skills specification",
        "url": "https://agentskills.io/specification",
        "accessed": "2026-11-03"
      },
      {
        "title": "The /llms.txt file, v2",
        "url": "https://llmstxt.org/",
        "accessed": "2026-11-03"
      }
    ],
    "last_verified": "2026-11-03",
    "published": "2026-11-03"
  },
  "markdown": "\n## What agents look for\n\nAn agent that arrives at your domain has a few well-known places to check. Each file answers a different question:\n\n| File | Answers | Where | Status on 2026-11-03 |\n|---|---|---|---|\n| [API catalog](https://indexagentica.com/entries/rfc-9727/) | Which HTTP APIs do you publish, and where are their descriptions? | `/.well-known/api-catalog` | IETF RFC 9727, Proposed Standard (June 2025) |\n| [AI Catalog](https://indexagentica.com/entries/ai-catalog/) | Which agent artifacts (MCP servers, A2A agents, skills, plugins) do you offer? | `/.well-known/ai-catalog.json` (optional), or any URL you link to | `specVersion` 1.0, Agent Card Working Group. Not a standards-body spec; the copy at ai-catalog.io is an editor's draft |\n| [MCP Server Card](https://indexagentica.com/entries/mcp-server-cards/) | How do I connect to your remote MCP server? | `<your MCP URL>/server-card` | SEP-2127 is **Final** (merged 6 Oct 2026). The extension repository's README still says \"Experimental\", and the `$schema` URL returned 404 when we checked |\n| [Agent Skills index](https://indexagentica.com/entries/agent-skills-discovery-rfc/) | Which [Agent Skills](https://indexagentica.com/entries/agent-skills-spec/) can I download? | `/.well-known/agent-skills/index.json` | Draft v0.2.0 (updated 2026-03-12) |\n| [llms.txt](https://indexagentica.com/entries/llms-txt/) | Where is the LLM-readable documentation? | `/llms.txt` or a subpath such as `/docs/llms.txt` | A proposal (v2), not a standard |\n\nYou don't need all five. If you run a public API, start with the API catalog. If you run a remote MCP server, add a Server Card and an AI Catalog that points to it. Publish a skills index only if you have skills you want agents to install. llms.txt is cheap and helps any documentation site.\n\nThe examples below are for a made-up company, `example.com`, with one REST API, one remote MCP server and one skill. They were served together from a local test server and checked as described under \"Check your files\" below.\n\n## The API catalog (RFC 9727)\n\nA publisher that supports the URI \"SHALL resolve an HTTPS GET request to /.well-known/api-catalog and return an API catalog document\". It also SHALL answer a HEAD request with a `Link` header using the `api-catalog` relation. The catalog \"MUST include hyperlinks to API endpoints\" and MUST be a Linkset, `application/linkset+json` (RFC 9264). It SHOULD carry the profile `https://www.rfc-editor.org/info/rfc9727`.\n\nThis example combines the RFC's two appendix patterns. The first context lists the APIs as `item` links (Appendix A.2). The second describes one API with the RFC 8631 relations `service-desc`, `service-doc` and `status` (Appendix A.1).\n\n```json\n{\n  \"linkset\": [\n    {\n      \"anchor\": \"https://example.com/.well-known/api-catalog\",\n      \"item\": [\n        {\"href\": \"https://api.example.com/v1/\"}\n      ]\n    },\n    {\n      \"anchor\": \"https://api.example.com/v1/\",\n      \"service-desc\": [\n        {\"href\": \"https://api.example.com/v1/openapi.json\", \"type\": \"application/json\"}\n      ],\n      \"service-doc\": [\n        {\"href\": \"https://example.com/docs/api/\", \"type\": \"text/html\"}\n      ],\n      \"status\": [\n        {\"href\": \"https://api.example.com/v1/health\", \"type\": \"application/json\"}\n      ]\n    }\n  ]\n}\n```\n\nServe it with:\n\n```http\nContent-Type: application/linkset+json; profile=\"https://www.rfc-editor.org/info/rfc9727\"\nLink: </.well-known/api-catalog>; rel=\"api-catalog\"\n```\n\nThe RFC also lets you point to the catalog from any page with a `Link: </.well-known/api-catalog>; rel=\"api-catalog\"` header or an `<a rel=\"api-catalog\">` link. Keep it to public APIs. The RFC's security section asks publishers to audit a public catalog so that no internal-only APIs or internal domains are included.\n\n## The AI Catalog\n\nAn AI Catalog is a JSON document with `specVersion` and `entries`. Each entry has an `identifier`, a `type` (the media type of the artifact) and exactly one of `url` or `data`. That is the spec's Level 1, \"Minimal\". Adding a `host` object gives Level 2, \"Discoverable\". Level 3 adds signed trust manifests, which this guide doesn't cover.\n\n```json\n{\n  \"specVersion\": \"1.0\",\n  \"host\": {\n    \"displayName\": \"Example Corp\"\n  },\n  \"entries\": [\n    {\n      \"identifier\": \"urn:air:example.com:mcp:invoices\",\n      \"type\": \"application/mcp-server-card+json\",\n      \"url\": \"https://example.com/mcp/server-card\"\n    },\n    {\n      \"identifier\": \"urn:air:example.com:skill:invoice-lookup\",\n      \"type\": \"application/agent-skills+md\",\n      \"url\": \"https://example.com/.well-known/agent-skills/invoice-lookup/SKILL.md\"\n    }\n  ]\n}\n```\n\nMedia types in use here: `application/mcp-server-card+json` for a Server Card, and `application/agent-skills+md` for a single `SKILL.md`. The spec notes the `+md` suffix is still \"to be registered\". It also lists `application/a2a-agent-card+json` for [A2A](https://indexagentica.com/entries/a2a-protocol/) agents and `+zip` or `+gzip` types for skill bundles. Serve the file as `application/ai-catalog+json`.\n\nHosts \"MAY\" use `/.well-known/ai-catalog.json`, and that location is optional. The spec's discovery order for agents is a `Link` header with `rel=\"ai-catalog\"`, then an HTML `<link rel=\"ai-catalog\">`, then the well-known URI. The Server Card extension's discovery flow starts by fetching `/.well-known/ai-catalog.json`. If you publish a Server Card, put the catalog there as well, and add a pointer from your pages:\n\n```html\n<!doctype html>\n<html><head><title>Example Corp</title>\n<link rel=\"ai-catalog\" href=\"/.well-known/ai-catalog.json\" type=\"application/ai-catalog+json\">\n<link rel=\"describedby\" href=\"/llms.txt\">\n</head><body>\n<p><a href=\"/.well-known/api-catalog\" rel=\"api-catalog\">Example Corp APIs</a></p>\n</body></html>\n```\n\n## The MCP Server Card\n\nA Server Card describes a remote MCP server: its name, version and endpoints. It does not list tools; those come from the server itself. The extension's discovery document reserves `GET <streamable-http-url>/server-card` as the recommended location. Cards are found through AI Catalog entries of type `application/mcp-server-card+json`. The extension considered `/.well-known/mcp/server-card` and did not recommend it, because a single server's card isn't site-wide metadata. Clients SHOULD request the card with `Accept: application/mcp-server-card+json`.\n\n```json\n{\n  \"$schema\": \"https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json\",\n  \"name\": \"com.example/invoices\",\n  \"version\": \"1.4.0\",\n  \"title\": \"Example Corp Invoices\",\n  \"description\": \"Read-only MCP server for looking up Example Corp invoices.\",\n  \"websiteUrl\": \"https://example.com/docs/mcp/\",\n  \"remotes\": [\n    {\n      \"type\": \"streamable-http\",\n      \"url\": \"https://example.com/mcp\",\n      \"headers\": [\n        {\n          \"name\": \"Authorization\",\n          \"description\": \"Bearer token from your Example Corp dashboard.\",\n          \"isRequired\": true,\n          \"isSecret\": true\n        }\n      ],\n      \"supportedProtocolVersions\": [\"2025-11-25\"]\n    }\n  ]\n}\n```\n\n`$schema`, `name`, `version` and `description` are required. `headers` lists the headers a client must send. Mark secrets with `isSecret` and never put a real value there. The discovery document says cards MUST NOT include credentials, internal topology or private endpoints, and clients must not treat a card as authoritative for security decisions.\n\nThe card endpoint MUST send these CORS headers, and SHOULD send `Cache-Control` and an `ETag` and answer `If-None-Match` with 304:\n\n```http\nContent-Type: application/mcp-server-card+json\nAccess-Control-Allow-Origin: *\nAccess-Control-Allow-Methods: GET\nAccess-Control-Allow-Headers: Content-Type, If-None-Match\nAccess-Control-Expose-Headers: ETag\nCache-Control: public, max-age=3600\n```\n\nHosted cards MUST be served over HTTPS (TLS 1.2 or later) in production. If you're also listing the server in the MCP Registry, see [publishing an MCP server](https://indexagentica.com/guides/publish-an-mcp-server/). The Registry's `server.json` and the Server Card are separate documents.\n\n## The Agent Skills index\n\nPublishers MUST serve the index at `/.well-known/agent-skills/index.json` as `application/json`. It needs a top-level `$schema` and a `skills` array. Each skill has `name`, `type` (`skill-md` or `archive`), `description`, `url` and `digest`. The digest is `sha256:` followed by the SHA-256 of the artifact's raw bytes, in lowercase hex. Clients MUST verify the digest before using the file. Names follow the Agent Skills rules: 1 to 64 lowercase letters, digits and hyphens, with no leading, trailing or double hyphens.\n\n```json\n{\n  \"$schema\": \"https://schemas.agentskills.io/discovery/0.2.0/schema.json\",\n  \"skills\": [\n    {\n      \"name\": \"invoice-lookup\",\n      \"type\": \"skill-md\",\n      \"description\": \"Look up an Example Corp invoice by number with the read-only Invoices API. Use when a user asks about the status or total of an Example Corp invoice.\",\n      \"url\": \"/.well-known/agent-skills/invoice-lookup/SKILL.md\",\n      \"digest\": \"sha256:7aa74d22d8c80b32667021087950b36e5e273eaee0ca5d5f8f351b10c1210279\"\n    }\n  ]\n}\n```\n\nThe skill it points to, served as `text/markdown`:\n\n```markdown\n---\nname: invoice-lookup\ndescription: Look up an Example Corp invoice by number with the read-only Invoices API. Use when a user asks about the status or total of an Example Corp invoice.\n---\n\n# Invoice lookup\n\n1. Call `GET https://api.example.com/v1/invoices/{number}` with the user's API key.\n2. Report `status`, `total` and `due_date`. Never create or change invoices.\n```\n\nCompute the digest from the exact bytes you serve, and recompute it whenever the file changes:\n\n```bash\necho \"sha256:$(sha256sum .well-known/agent-skills/invoice-lookup/SKILL.md | cut -d' ' -f1)\"\n```\n\nThe `$schema` URI is an opaque identifier, and the draft says it \"does not need to be resolvable\". Skills with scripts or other files go in a `.tar.gz` or `.zip` with `type: \"archive\"`, served as `application/gzip` or `application/zip`. The draft says clients SHALL NOT run bundled scripts by default. Agents load skill text straight into their context, so put nothing in a skill you wouldn't want an agent to act on.\n\n## llms.txt\n\nllms.txt is Markdown. The only required part is an H1 with the site or project name. Then come an optional blockquote summary, optional prose, and H2 sections of `[name](url): notes` links. A section named \"Optional\" holds links an agent can skip. Version 2 of the proposal allows the file at a subpath, where it covers the pages under that path. It suggests markdown copies of pages at `page.html.md` or `page.md`, announced with `rel=\"alternate\" type=\"text/markdown\"`. The covering llms.txt is announced with `rel=\"describedby\"`.\n\n```markdown\n# Example Corp\n\n> Example Corp sells invoicing software. This file points agents at the API reference, the MCP server and the agent skill.\n\n## Docs\n\n- [Invoices API reference](https://example.com/docs/api/invoices.md): read-only endpoints, auth and errors\n- [MCP server](https://example.com/docs/mcp.md): remote endpoint, tools and scopes\n\n## Optional\n\n- [Changelog](https://example.com/changelog.md)\n```\n\nThe proposal doesn't set a media type; we served it as `text/markdown`.\n\n## Check your files\n\n1. **Parse every JSON file.** `python3 -m json.tool < .well-known/ai-catalog.json > /dev/null` fails loudly on a stray comma.\n2. **Check the headers.** `curl -sI https://example.com/.well-known/api-catalog` should show the Linkset media type with the RFC 9727 profile, and the `Link` header. Run the same check for the card's CORS headers and the AI Catalog's media type.\n3. **Validate the Server Card against the official schema.** Clone `modelcontextprotocol/ext-server-card` and run `npm install`. `npm run validate` checks the repository's own examples (7 passed for us). To check your card, compile `#/$defs/ServerCard` from `schema.json` with Ajv 2020, as the repository's `scripts/validate-examples.ts` does. Our card passed. A card without `description` was rejected with \"must have required property 'description'\".\n4. **Recompute skill digests** and compare them with the index.\n5. **Run the probe.** The [discover-agent-interfaces](https://indexagentica.com/skills/discover-agent-interfaces/) skill's `probe_site.py` fetches what an agent would fetch. It treats every result as untrusted.\n\n```bash\npython3 scripts/probe_site.py https://example.com --no-mcp-guess\n```\n\nAgainst our local copy of these files, version 1.1.1 of the probe reported:\n\n```text\nAI Catalog: http://127.0.0.1:8787/.well-known/ai-catalog.json (specVersion 1.0), 2 entries\n  - application/mcp-server-card+json  urn:air:example.com:mcp:invoices  http://127.0.0.1:8787/mcp/server-card\n      MCP remote: http://127.0.0.1:8787/mcp (streamable-http)\n  - application/agent-skills+md  urn:air:example.com:skill:invoice-lookup  http://127.0.0.1:8787/.well-known/agent-skills/invoice-lookup/SKILL.md\nAPI catalog (RFC 9727): http://127.0.0.1:8787/.well-known/api-catalog  APIs=['https://api.example.com/v1/']  descriptions=['https://api.example.com/v1/openapi.json', 'http://127.0.0.1:8787/docs/api/']\nAgent Skills index: http://127.0.0.1:8787/.well-known/agent-skills/index.json  1 skills\n  - invoice-lookup (skill-md)  http://127.0.0.1:8787/.well-known/agent-skills/invoice-lookup/SKILL.md\nllms.txt: http://127.0.0.1:8787/llms.txt  \"Example Corp\"  2 sections, 3 links, 407 bytes\n```\n\nFor the local run, our test server rewrote `https://example.com` to the local address. There was no MCP server behind the card, so the probe also reported \"no MCP endpoint found here\". The probe counts APIs from `item` links. A catalog that uses only the Appendix A.1 pattern showed `APIs=[]` and listed the descriptions only, which is one more reason to include an `item` list.\n\n## Before you publish\n\n- Everything in these files is public and will be read by machines that act on it. Leave out internal hosts, private endpoints, tokens and anything you wouldn't put on your homepage.\n- Each file can go stale: the version in the card, digests in the index, links in llms.txt. Generate them in your build rather than by hand.\n- If your API or MCP server uses OAuth, publish protected resource metadata ([RFC 9728](https://indexagentica.com/entries/rfc-9728/)) as well. See [adding OAuth to an MCP server](https://indexagentica.com/guides/add-oauth-to-your-mcp-server/).\n- Several of these specs are drafts. Check each one again when you update the files.\n",
  "raw": "---\nid: publish-agent-discovery-files\ntype: guide\ntitle: Make your site and API discoverable by agents\nsummary: \"Publish the files agents look for: an RFC 9727 API catalog, an AI Catalog, an MCP Server Card, an Agent Skills index and llms.txt. Minimal valid examples, the headers each spec asks for, each spec's real status, and how to check the result with our discovery probe.\"\ndescription: \"A publisher-side guide to agent discovery files. It gives a minimal, validated example of each file and where it goes: /.well-known/api-catalog (RFC 9727, a Linkset served as application/linkset+json), /.well-known/ai-catalog.json (AI Catalog, application/ai-catalog+json), an MCP Server Card at <mcp-url>/server-card with the required CORS headers, /.well-known/agent-skills/index.json with SHA-256 digests, and llms.txt. It states each spec's status as of 2026-11-03, from IETF Proposed Standard to draft and proposal, and lists the HTTP headers to set. It shows how to check the result: JSON parsing, media types, the Server Card JSON Schema, and the discover-agent-interfaces probe. All examples were served from a local fixture and checked on 2026-11-03.\"\nauthor: Agentica Author\ndifficulty: intermediate\ntime_estimate: 45 min\nprerequisites:\n  - \"Control over your site's web server or CDN headers (media types, Link and CORS headers)\"\n  - \"Python 3 for the probe, and Node.js if you want to validate the Server Card with the official schema\"\ntags: [discovery, well-known, api-catalog, ai-catalog, mcp, server-card, agent-skills, llms-txt, publishing]\nentries: [rfc-9727, ai-catalog, mcp-server-cards, agent-skills-discovery-rfc, llms-txt, agent-skills-spec, a2a-protocol, rfc-9728]\nrelated: [discover-agent-interfaces, publish-an-mcp-server, add-oauth-to-your-mcp-server, connect-an-agent-to-a-remote-mcp-server, give-your-coding-agent-up-to-date-docs]\nsources:\n  - title: \"RFC 9727: api-catalog, a well-known URI and link relation to help discovery of APIs\"\n    url: https://www.rfc-editor.org/rfc/rfc9727.html\n    accessed: 2026-11-03\n  - title: RFC 9727 on the IETF Datatracker (status)\n    url: https://datatracker.ietf.org/doc/rfc9727/\n    accessed: 2026-11-03\n  - title: \"RFC 9264: Linkset media types\"\n    url: https://www.rfc-editor.org/rfc/rfc9264.html\n    accessed: 2026-11-03\n  - title: AI Catalog specification (Agent-Card/ai-catalog)\n    url: https://github.com/Agent-Card/ai-catalog/blob/main/specification/ai-catalog.md\n    accessed: 2026-11-03\n  - title: AI Catalog published draft\n    url: https://ai-catalog.io/\n    accessed: 2026-11-03\n  - title: \"SEP-2127: MCP Server Cards\"\n    url: https://modelcontextprotocol.io/seps/2127-mcp-server-cards\n    accessed: 2026-11-03\n  - title: \"MCP Server Cards extension repository (README, schema, examples)\"\n    url: https://github.com/modelcontextprotocol/ext-server-card\n    accessed: 2026-11-03\n  - title: \"MCP Server Cards: discovery and HTTP requirements\"\n    url: https://github.com/modelcontextprotocol/ext-server-card/blob/main/docs/discovery.md\n    accessed: 2026-11-03\n  - title: MCP Server Card JSON Schema\n    url: https://github.com/modelcontextprotocol/ext-server-card/blob/main/schema.json\n    accessed: 2026-11-03\n  - title: Agent Skills Discovery via Well-Known URIs (v0.2.0 draft)\n    url: https://github.com/cloudflare/agent-skills-discovery-rfc\n    accessed: 2026-11-03\n  - title: Agent Skills specification\n    url: https://agentskills.io/specification\n    accessed: 2026-11-03\n  - title: The /llms.txt file, v2\n    url: https://llmstxt.org/\n    accessed: 2026-11-03\nlast_verified: 2026-11-03\npublished: 2026-11-03\n---\n\n## What agents look for\n\nAn agent that arrives at your domain has a few well-known places to check. Each file answers a different question:\n\n| File | Answers | Where | Status on 2026-11-03 |\n|---|---|---|---|\n| [API catalog](https://indexagentica.com/entries/rfc-9727/) | Which HTTP APIs do you publish, and where are their descriptions? | `/.well-known/api-catalog` | IETF RFC 9727, Proposed Standard (June 2025) |\n| [AI Catalog](https://indexagentica.com/entries/ai-catalog/) | Which agent artifacts (MCP servers, A2A agents, skills, plugins) do you offer? | `/.well-known/ai-catalog.json` (optional), or any URL you link to | `specVersion` 1.0, Agent Card Working Group. Not a standards-body spec; the copy at ai-catalog.io is an editor's draft |\n| [MCP Server Card](https://indexagentica.com/entries/mcp-server-cards/) | How do I connect to your remote MCP server? | `<your MCP URL>/server-card` | SEP-2127 is **Final** (merged 6 Oct 2026). The extension repository's README still says \"Experimental\", and the `$schema` URL returned 404 when we checked |\n| [Agent Skills index](https://indexagentica.com/entries/agent-skills-discovery-rfc/) | Which [Agent Skills](https://indexagentica.com/entries/agent-skills-spec/) can I download? | `/.well-known/agent-skills/index.json` | Draft v0.2.0 (updated 2026-03-12) |\n| [llms.txt](https://indexagentica.com/entries/llms-txt/) | Where is the LLM-readable documentation? | `/llms.txt` or a subpath such as `/docs/llms.txt` | A proposal (v2), not a standard |\n\nYou don't need all five. If you run a public API, start with the API catalog. If you run a remote MCP server, add a Server Card and an AI Catalog that points to it. Publish a skills index only if you have skills you want agents to install. llms.txt is cheap and helps any documentation site.\n\nThe examples below are for a made-up company, `example.com`, with one REST API, one remote MCP server and one skill. They were served together from a local test server and checked as described under \"Check your files\" below.\n\n## The API catalog (RFC 9727)\n\nA publisher that supports the URI \"SHALL resolve an HTTPS GET request to /.well-known/api-catalog and return an API catalog document\". It also SHALL answer a HEAD request with a `Link` header using the `api-catalog` relation. The catalog \"MUST include hyperlinks to API endpoints\" and MUST be a Linkset, `application/linkset+json` (RFC 9264). It SHOULD carry the profile `https://www.rfc-editor.org/info/rfc9727`.\n\nThis example combines the RFC's two appendix patterns. The first context lists the APIs as `item` links (Appendix A.2). The second describes one API with the RFC 8631 relations `service-desc`, `service-doc` and `status` (Appendix A.1).\n\n```json\n{\n  \"linkset\": [\n    {\n      \"anchor\": \"https://example.com/.well-known/api-catalog\",\n      \"item\": [\n        {\"href\": \"https://api.example.com/v1/\"}\n      ]\n    },\n    {\n      \"anchor\": \"https://api.example.com/v1/\",\n      \"service-desc\": [\n        {\"href\": \"https://api.example.com/v1/openapi.json\", \"type\": \"application/json\"}\n      ],\n      \"service-doc\": [\n        {\"href\": \"https://example.com/docs/api/\", \"type\": \"text/html\"}\n      ],\n      \"status\": [\n        {\"href\": \"https://api.example.com/v1/health\", \"type\": \"application/json\"}\n      ]\n    }\n  ]\n}\n```\n\nServe it with:\n\n```http\nContent-Type: application/linkset+json; profile=\"https://www.rfc-editor.org/info/rfc9727\"\nLink: </.well-known/api-catalog>; rel=\"api-catalog\"\n```\n\nThe RFC also lets you point to the catalog from any page with a `Link: </.well-known/api-catalog>; rel=\"api-catalog\"` header or an `<a rel=\"api-catalog\">` link. Keep it to public APIs. The RFC's security section asks publishers to audit a public catalog so that no internal-only APIs or internal domains are included.\n\n## The AI Catalog\n\nAn AI Catalog is a JSON document with `specVersion` and `entries`. Each entry has an `identifier`, a `type` (the media type of the artifact) and exactly one of `url` or `data`. That is the spec's Level 1, \"Minimal\". Adding a `host` object gives Level 2, \"Discoverable\". Level 3 adds signed trust manifests, which this guide doesn't cover.\n\n```json\n{\n  \"specVersion\": \"1.0\",\n  \"host\": {\n    \"displayName\": \"Example Corp\"\n  },\n  \"entries\": [\n    {\n      \"identifier\": \"urn:air:example.com:mcp:invoices\",\n      \"type\": \"application/mcp-server-card+json\",\n      \"url\": \"https://example.com/mcp/server-card\"\n    },\n    {\n      \"identifier\": \"urn:air:example.com:skill:invoice-lookup\",\n      \"type\": \"application/agent-skills+md\",\n      \"url\": \"https://example.com/.well-known/agent-skills/invoice-lookup/SKILL.md\"\n    }\n  ]\n}\n```\n\nMedia types in use here: `application/mcp-server-card+json` for a Server Card, and `application/agent-skills+md` for a single `SKILL.md`. The spec notes the `+md` suffix is still \"to be registered\". It also lists `application/a2a-agent-card+json` for [A2A](https://indexagentica.com/entries/a2a-protocol/) agents and `+zip` or `+gzip` types for skill bundles. Serve the file as `application/ai-catalog+json`.\n\nHosts \"MAY\" use `/.well-known/ai-catalog.json`, and that location is optional. The spec's discovery order for agents is a `Link` header with `rel=\"ai-catalog\"`, then an HTML `<link rel=\"ai-catalog\">`, then the well-known URI. The Server Card extension's discovery flow starts by fetching `/.well-known/ai-catalog.json`. If you publish a Server Card, put the catalog there as well, and add a pointer from your pages:\n\n```html\n<!doctype html>\n<html><head><title>Example Corp</title>\n<link rel=\"ai-catalog\" href=\"/.well-known/ai-catalog.json\" type=\"application/ai-catalog+json\">\n<link rel=\"describedby\" href=\"/llms.txt\">\n</head><body>\n<p><a href=\"/.well-known/api-catalog\" rel=\"api-catalog\">Example Corp APIs</a></p>\n</body></html>\n```\n\n## The MCP Server Card\n\nA Server Card describes a remote MCP server: its name, version and endpoints. It does not list tools; those come from the server itself. The extension's discovery document reserves `GET <streamable-http-url>/server-card` as the recommended location. Cards are found through AI Catalog entries of type `application/mcp-server-card+json`. The extension considered `/.well-known/mcp/server-card` and did not recommend it, because a single server's card isn't site-wide metadata. Clients SHOULD request the card with `Accept: application/mcp-server-card+json`.\n\n```json\n{\n  \"$schema\": \"https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json\",\n  \"name\": \"com.example/invoices\",\n  \"version\": \"1.4.0\",\n  \"title\": \"Example Corp Invoices\",\n  \"description\": \"Read-only MCP server for looking up Example Corp invoices.\",\n  \"websiteUrl\": \"https://example.com/docs/mcp/\",\n  \"remotes\": [\n    {\n      \"type\": \"streamable-http\",\n      \"url\": \"https://example.com/mcp\",\n      \"headers\": [\n        {\n          \"name\": \"Authorization\",\n          \"description\": \"Bearer token from your Example Corp dashboard.\",\n          \"isRequired\": true,\n          \"isSecret\": true\n        }\n      ],\n      \"supportedProtocolVersions\": [\"2025-11-25\"]\n    }\n  ]\n}\n```\n\n`$schema`, `name`, `version` and `description` are required. `headers` lists the headers a client must send. Mark secrets with `isSecret` and never put a real value there. The discovery document says cards MUST NOT include credentials, internal topology or private endpoints, and clients must not treat a card as authoritative for security decisions.\n\nThe card endpoint MUST send these CORS headers, and SHOULD send `Cache-Control` and an `ETag` and answer `If-None-Match` with 304:\n\n```http\nContent-Type: application/mcp-server-card+json\nAccess-Control-Allow-Origin: *\nAccess-Control-Allow-Methods: GET\nAccess-Control-Allow-Headers: Content-Type, If-None-Match\nAccess-Control-Expose-Headers: ETag\nCache-Control: public, max-age=3600\n```\n\nHosted cards MUST be served over HTTPS (TLS 1.2 or later) in production. If you're also listing the server in the MCP Registry, see [publishing an MCP server](https://indexagentica.com/guides/publish-an-mcp-server/). The Registry's `server.json` and the Server Card are separate documents.\n\n## The Agent Skills index\n\nPublishers MUST serve the index at `/.well-known/agent-skills/index.json` as `application/json`. It needs a top-level `$schema` and a `skills` array. Each skill has `name`, `type` (`skill-md` or `archive`), `description`, `url` and `digest`. The digest is `sha256:` followed by the SHA-256 of the artifact's raw bytes, in lowercase hex. Clients MUST verify the digest before using the file. Names follow the Agent Skills rules: 1 to 64 lowercase letters, digits and hyphens, with no leading, trailing or double hyphens.\n\n```json\n{\n  \"$schema\": \"https://schemas.agentskills.io/discovery/0.2.0/schema.json\",\n  \"skills\": [\n    {\n      \"name\": \"invoice-lookup\",\n      \"type\": \"skill-md\",\n      \"description\": \"Look up an Example Corp invoice by number with the read-only Invoices API. Use when a user asks about the status or total of an Example Corp invoice.\",\n      \"url\": \"/.well-known/agent-skills/invoice-lookup/SKILL.md\",\n      \"digest\": \"sha256:7aa74d22d8c80b32667021087950b36e5e273eaee0ca5d5f8f351b10c1210279\"\n    }\n  ]\n}\n```\n\nThe skill it points to, served as `text/markdown`:\n\n```markdown\n---\nname: invoice-lookup\ndescription: Look up an Example Corp invoice by number with the read-only Invoices API. Use when a user asks about the status or total of an Example Corp invoice.\n---\n\n# Invoice lookup\n\n1. Call `GET https://api.example.com/v1/invoices/{number}` with the user's API key.\n2. Report `status`, `total` and `due_date`. Never create or change invoices.\n```\n\nCompute the digest from the exact bytes you serve, and recompute it whenever the file changes:\n\n```bash\necho \"sha256:$(sha256sum .well-known/agent-skills/invoice-lookup/SKILL.md | cut -d' ' -f1)\"\n```\n\nThe `$schema` URI is an opaque identifier, and the draft says it \"does not need to be resolvable\". Skills with scripts or other files go in a `.tar.gz` or `.zip` with `type: \"archive\"`, served as `application/gzip` or `application/zip`. The draft says clients SHALL NOT run bundled scripts by default. Agents load skill text straight into their context, so put nothing in a skill you wouldn't want an agent to act on.\n\n## llms.txt\n\nllms.txt is Markdown. The only required part is an H1 with the site or project name. Then come an optional blockquote summary, optional prose, and H2 sections of `[name](url): notes` links. A section named \"Optional\" holds links an agent can skip. Version 2 of the proposal allows the file at a subpath, where it covers the pages under that path. It suggests markdown copies of pages at `page.html.md` or `page.md`, announced with `rel=\"alternate\" type=\"text/markdown\"`. The covering llms.txt is announced with `rel=\"describedby\"`.\n\n```markdown\n# Example Corp\n\n> Example Corp sells invoicing software. This file points agents at the API reference, the MCP server and the agent skill.\n\n## Docs\n\n- [Invoices API reference](https://example.com/docs/api/invoices.md): read-only endpoints, auth and errors\n- [MCP server](https://example.com/docs/mcp.md): remote endpoint, tools and scopes\n\n## Optional\n\n- [Changelog](https://example.com/changelog.md)\n```\n\nThe proposal doesn't set a media type; we served it as `text/markdown`.\n\n## Check your files\n\n1. **Parse every JSON file.** `python3 -m json.tool < .well-known/ai-catalog.json > /dev/null` fails loudly on a stray comma.\n2. **Check the headers.** `curl -sI https://example.com/.well-known/api-catalog` should show the Linkset media type with the RFC 9727 profile, and the `Link` header. Run the same check for the card's CORS headers and the AI Catalog's media type.\n3. **Validate the Server Card against the official schema.** Clone `modelcontextprotocol/ext-server-card` and run `npm install`. `npm run validate` checks the repository's own examples (7 passed for us). To check your card, compile `#/$defs/ServerCard` from `schema.json` with Ajv 2020, as the repository's `scripts/validate-examples.ts` does. Our card passed. A card without `description` was rejected with \"must have required property 'description'\".\n4. **Recompute skill digests** and compare them with the index.\n5. **Run the probe.** The [discover-agent-interfaces](https://indexagentica.com/skills/discover-agent-interfaces/) skill's `probe_site.py` fetches what an agent would fetch. It treats every result as untrusted.\n\n```bash\npython3 scripts/probe_site.py https://example.com --no-mcp-guess\n```\n\nAgainst our local copy of these files, version 1.1.1 of the probe reported:\n\n```text\nAI Catalog: http://127.0.0.1:8787/.well-known/ai-catalog.json (specVersion 1.0), 2 entries\n  - application/mcp-server-card+json  urn:air:example.com:mcp:invoices  http://127.0.0.1:8787/mcp/server-card\n      MCP remote: http://127.0.0.1:8787/mcp (streamable-http)\n  - application/agent-skills+md  urn:air:example.com:skill:invoice-lookup  http://127.0.0.1:8787/.well-known/agent-skills/invoice-lookup/SKILL.md\nAPI catalog (RFC 9727): http://127.0.0.1:8787/.well-known/api-catalog  APIs=['https://api.example.com/v1/']  descriptions=['https://api.example.com/v1/openapi.json', 'http://127.0.0.1:8787/docs/api/']\nAgent Skills index: http://127.0.0.1:8787/.well-known/agent-skills/index.json  1 skills\n  - invoice-lookup (skill-md)  http://127.0.0.1:8787/.well-known/agent-skills/invoice-lookup/SKILL.md\nllms.txt: http://127.0.0.1:8787/llms.txt  \"Example Corp\"  2 sections, 3 links, 407 bytes\n```\n\nFor the local run, our test server rewrote `https://example.com` to the local address. There was no MCP server behind the card, so the probe also reported \"no MCP endpoint found here\". The probe counts APIs from `item` links. A catalog that uses only the Appendix A.1 pattern showed `APIs=[]` and listed the descriptions only, which is one more reason to include an `item` list.\n\n## Before you publish\n\n- Everything in these files is public and will be read by machines that act on it. Leave out internal hosts, private endpoints, tokens and anything you wouldn't put on your homepage.\n- Each file can go stale: the version in the card, digests in the index, links in llms.txt. Generate them in your build rather than by hand.\n- If your API or MCP server uses OAuth, publish protected resource metadata ([RFC 9728](https://indexagentica.com/entries/rfc-9728/)) as well. See [adding OAuth to an MCP server](https://indexagentica.com/guides/add-oauth-to-your-mcp-server/).\n- Several of these specs are drafts. Check each one again when you update the files.\n",
  "html": "<h2>What agents look for</h2>\n<p>An agent that arrives at your domain has a few well-known places to check. Each file answers a different question:</p>\n<table><thead><tr><th scope=\"col\">File</th><th scope=\"col\">Answers</th><th scope=\"col\">Where</th><th scope=\"col\">Status on 2026-11-03</th></tr></thead><tbody><tr><td><a href=\"/entries/rfc-9727/\">API catalog</a></td><td>Which HTTP APIs do you publish, and where are their descriptions?</td><td><code>/.well-known/api-catalog</code></td><td>IETF RFC 9727, Proposed Standard (June 2025)</td></tr><tr><td><a href=\"/entries/ai-catalog/\">AI Catalog</a></td><td>Which agent artifacts (MCP servers, A2A agents, skills, plugins) do you offer?</td><td><code>/.well-known/ai-catalog.json</code> (optional), or any URL you link to</td><td><code>specVersion</code> 1.0, Agent Card Working Group. Not a standards-body spec; the copy at ai-catalog.io is an editor&#39;s draft</td></tr><tr><td><a href=\"/entries/mcp-server-cards/\">MCP Server Card</a></td><td>How do I connect to your remote MCP server?</td><td><code>&lt;your MCP URL&gt;/server-card</code></td><td>SEP-2127 is <strong>Final</strong> (merged 6 Oct 2026). The extension repository&#39;s README still says &quot;Experimental&quot;, and the <code>$schema</code> URL returned 404 when we checked</td></tr><tr><td><a href=\"/entries/agent-skills-discovery-rfc/\">Agent Skills index</a></td><td>Which <a href=\"/entries/agent-skills-spec/\">Agent Skills</a> can I download?</td><td><code>/.well-known/agent-skills/index.json</code></td><td>Draft v0.2.0 (updated 2026-03-12)</td></tr><tr><td><a href=\"/entries/llms-txt/\">llms.txt</a></td><td>Where is the LLM-readable documentation?</td><td><code>/llms.txt</code> or a subpath such as <code>/docs/llms.txt</code></td><td>A proposal (v2), not a standard</td></tr></tbody></table>\n<p>You don&#39;t need all five. If you run a public API, start with the API catalog. If you run a remote MCP server, add a Server Card and an AI Catalog that points to it. Publish a skills index only if you have skills you want agents to install. llms.txt is cheap and helps any documentation site.</p>\n<p>The examples below are for a made-up company, <code>example.com</code>, with one REST API, one remote MCP server and one skill. They were served together from a local test server and checked as described under &quot;Check your files&quot; below.</p>\n<h2>The API catalog (RFC 9727)</h2>\n<p>A publisher that supports the URI &quot;SHALL resolve an HTTPS GET request to /.well-known/api-catalog and return an API catalog document&quot;. It also SHALL answer a HEAD request with a <code>Link</code> header using the <code>api-catalog</code> relation. The catalog &quot;MUST include hyperlinks to API endpoints&quot; and MUST be a Linkset, <code>application/linkset+json</code> (RFC 9264). It SHOULD carry the profile <code>https://www.rfc-editor.org/info/rfc9727</code>.</p>\n<p>This example combines the RFC&#39;s two appendix patterns. The first context lists the APIs as <code>item</code> links (Appendix A.2). The second describes one API with the RFC 8631 relations <code>service-desc</code>, <code>service-doc</code> and <code>status</code> (Appendix A.1).</p>\n<pre><code class=\"language-json\">{\n  &quot;linkset&quot;: [\n    {\n      &quot;anchor&quot;: &quot;https://example.com/.well-known/api-catalog&quot;,\n      &quot;item&quot;: [\n        {&quot;href&quot;: &quot;https://api.example.com/v1/&quot;}\n      ]\n    },\n    {\n      &quot;anchor&quot;: &quot;https://api.example.com/v1/&quot;,\n      &quot;service-desc&quot;: [\n        {&quot;href&quot;: &quot;https://api.example.com/v1/openapi.json&quot;, &quot;type&quot;: &quot;application/json&quot;}\n      ],\n      &quot;service-doc&quot;: [\n        {&quot;href&quot;: &quot;https://example.com/docs/api/&quot;, &quot;type&quot;: &quot;text/html&quot;}\n      ],\n      &quot;status&quot;: [\n        {&quot;href&quot;: &quot;https://api.example.com/v1/health&quot;, &quot;type&quot;: &quot;application/json&quot;}\n      ]\n    }\n  ]\n}</code></pre>\n<p>Serve it with:</p>\n<pre><code class=\"language-http\">Content-Type: application/linkset+json; profile=&quot;https://www.rfc-editor.org/info/rfc9727&quot;\nLink: &lt;/.well-known/api-catalog&gt;; rel=&quot;api-catalog&quot;</code></pre>\n<p>The RFC also lets you point to the catalog from any page with a <code>Link: &lt;/.well-known/api-catalog&gt;; rel=&quot;api-catalog&quot;</code> header or an <code>&lt;a rel=&quot;api-catalog&quot;&gt;</code> link. Keep it to public APIs. The RFC&#39;s security section asks publishers to audit a public catalog so that no internal-only APIs or internal domains are included.</p>\n<h2>The AI Catalog</h2>\n<p>An AI Catalog is a JSON document with <code>specVersion</code> and <code>entries</code>. Each entry has an <code>identifier</code>, a <code>type</code> (the media type of the artifact) and exactly one of <code>url</code> or <code>data</code>. That is the spec&#39;s Level 1, &quot;Minimal&quot;. Adding a <code>host</code> object gives Level 2, &quot;Discoverable&quot;. Level 3 adds signed trust manifests, which this guide doesn&#39;t cover.</p>\n<pre><code class=\"language-json\">{\n  &quot;specVersion&quot;: &quot;1.0&quot;,\n  &quot;host&quot;: {\n    &quot;displayName&quot;: &quot;Example Corp&quot;\n  },\n  &quot;entries&quot;: [\n    {\n      &quot;identifier&quot;: &quot;urn:air:example.com:mcp:invoices&quot;,\n      &quot;type&quot;: &quot;application/mcp-server-card+json&quot;,\n      &quot;url&quot;: &quot;https://example.com/mcp/server-card&quot;\n    },\n    {\n      &quot;identifier&quot;: &quot;urn:air:example.com:skill:invoice-lookup&quot;,\n      &quot;type&quot;: &quot;application/agent-skills+md&quot;,\n      &quot;url&quot;: &quot;https://example.com/.well-known/agent-skills/invoice-lookup/SKILL.md&quot;\n    }\n  ]\n}</code></pre>\n<p>Media types in use here: <code>application/mcp-server-card+json</code> for a Server Card, and <code>application/agent-skills+md</code> for a single <code>SKILL.md</code>. The spec notes the <code>+md</code> suffix is still &quot;to be registered&quot;. It also lists <code>application/a2a-agent-card+json</code> for <a href=\"/entries/a2a-protocol/\">A2A</a> agents and <code>+zip</code> or <code>+gzip</code> types for skill bundles. Serve the file as <code>application/ai-catalog+json</code>.</p>\n<p>Hosts &quot;MAY&quot; use <code>/.well-known/ai-catalog.json</code>, and that location is optional. The spec&#39;s discovery order for agents is a <code>Link</code> header with <code>rel=&quot;ai-catalog&quot;</code>, then an HTML <code>&lt;link rel=&quot;ai-catalog&quot;&gt;</code>, then the well-known URI. The Server Card extension&#39;s discovery flow starts by fetching <code>/.well-known/ai-catalog.json</code>. If you publish a Server Card, put the catalog there as well, and add a pointer from your pages:</p>\n<pre><code class=\"language-html\">&lt;!doctype html&gt;\n&lt;html&gt;&lt;head&gt;&lt;title&gt;Example Corp&lt;/title&gt;\n&lt;link rel=&quot;ai-catalog&quot; href=&quot;/.well-known/ai-catalog.json&quot; type=&quot;application/ai-catalog+json&quot;&gt;\n&lt;link rel=&quot;describedby&quot; href=&quot;/llms.txt&quot;&gt;\n&lt;/head&gt;&lt;body&gt;\n&lt;p&gt;&lt;a href=&quot;/.well-known/api-catalog&quot; rel=&quot;api-catalog&quot;&gt;Example Corp APIs&lt;/a&gt;&lt;/p&gt;\n&lt;/body&gt;&lt;/html&gt;</code></pre>\n<h2>The MCP Server Card</h2>\n<p>A Server Card describes a remote MCP server: its name, version and endpoints. It does not list tools; those come from the server itself. The extension&#39;s discovery document reserves <code>GET &lt;streamable-http-url&gt;/server-card</code> as the recommended location. Cards are found through AI Catalog entries of type <code>application/mcp-server-card+json</code>. The extension considered <code>/.well-known/mcp/server-card</code> and did not recommend it, because a single server&#39;s card isn&#39;t site-wide metadata. Clients SHOULD request the card with <code>Accept: application/mcp-server-card+json</code>.</p>\n<pre><code class=\"language-json\">{\n  &quot;$schema&quot;: &quot;https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json&quot;,\n  &quot;name&quot;: &quot;com.example/invoices&quot;,\n  &quot;version&quot;: &quot;1.4.0&quot;,\n  &quot;title&quot;: &quot;Example Corp Invoices&quot;,\n  &quot;description&quot;: &quot;Read-only MCP server for looking up Example Corp invoices.&quot;,\n  &quot;websiteUrl&quot;: &quot;https://example.com/docs/mcp/&quot;,\n  &quot;remotes&quot;: [\n    {\n      &quot;type&quot;: &quot;streamable-http&quot;,\n      &quot;url&quot;: &quot;https://example.com/mcp&quot;,\n      &quot;headers&quot;: [\n        {\n          &quot;name&quot;: &quot;Authorization&quot;,\n          &quot;description&quot;: &quot;Bearer token from your Example Corp dashboard.&quot;,\n          &quot;isRequired&quot;: true,\n          &quot;isSecret&quot;: true\n        }\n      ],\n      &quot;supportedProtocolVersions&quot;: [&quot;2025-11-25&quot;]\n    }\n  ]\n}</code></pre>\n<p><code>$schema</code>, <code>name</code>, <code>version</code> and <code>description</code> are required. <code>headers</code> lists the headers a client must send. Mark secrets with <code>isSecret</code> and never put a real value there. The discovery document says cards MUST NOT include credentials, internal topology or private endpoints, and clients must not treat a card as authoritative for security decisions.</p>\n<p>The card endpoint MUST send these CORS headers, and SHOULD send <code>Cache-Control</code> and an <code>ETag</code> and answer <code>If-None-Match</code> with 304:</p>\n<pre><code class=\"language-http\">Content-Type: application/mcp-server-card+json\nAccess-Control-Allow-Origin: *\nAccess-Control-Allow-Methods: GET\nAccess-Control-Allow-Headers: Content-Type, If-None-Match\nAccess-Control-Expose-Headers: ETag\nCache-Control: public, max-age=3600</code></pre>\n<p>Hosted cards MUST be served over HTTPS (TLS 1.2 or later) in production. If you&#39;re also listing the server in the MCP Registry, see <a href=\"/guides/publish-an-mcp-server/\">publishing an MCP server</a>. The Registry&#39;s <code>server.json</code> and the Server Card are separate documents.</p>\n<h2>The Agent Skills index</h2>\n<p>Publishers MUST serve the index at <code>/.well-known/agent-skills/index.json</code> as <code>application/json</code>. It needs a top-level <code>$schema</code> and a <code>skills</code> array. Each skill has <code>name</code>, <code>type</code> (<code>skill-md</code> or <code>archive</code>), <code>description</code>, <code>url</code> and <code>digest</code>. The digest is <code>sha256:</code> followed by the SHA-256 of the artifact&#39;s raw bytes, in lowercase hex. Clients MUST verify the digest before using the file. Names follow the Agent Skills rules: 1 to 64 lowercase letters, digits and hyphens, with no leading, trailing or double hyphens.</p>\n<pre><code class=\"language-json\">{\n  &quot;$schema&quot;: &quot;https://schemas.agentskills.io/discovery/0.2.0/schema.json&quot;,\n  &quot;skills&quot;: [\n    {\n      &quot;name&quot;: &quot;invoice-lookup&quot;,\n      &quot;type&quot;: &quot;skill-md&quot;,\n      &quot;description&quot;: &quot;Look up an Example Corp invoice by number with the read-only Invoices API. Use when a user asks about the status or total of an Example Corp invoice.&quot;,\n      &quot;url&quot;: &quot;/.well-known/agent-skills/invoice-lookup/SKILL.md&quot;,\n      &quot;digest&quot;: &quot;sha256:7aa74d22d8c80b32667021087950b36e5e273eaee0ca5d5f8f351b10c1210279&quot;\n    }\n  ]\n}</code></pre>\n<p>The skill it points to, served as <code>text/markdown</code>:</p>\n<pre><code class=\"language-markdown\">---\nname: invoice-lookup\ndescription: Look up an Example Corp invoice by number with the read-only Invoices API. Use when a user asks about the status or total of an Example Corp invoice.\n---\n\n# Invoice lookup\n\n1. Call `GET https://api.example.com/v1/invoices/{number}` with the user&#39;s API key.\n2. Report `status`, `total` and `due_date`. Never create or change invoices.</code></pre>\n<p>Compute the digest from the exact bytes you serve, and recompute it whenever the file changes:</p>\n<pre><code class=\"language-bash\">echo &quot;sha256:$(sha256sum .well-known/agent-skills/invoice-lookup/SKILL.md | cut -d&#39; &#39; -f1)&quot;</code></pre>\n<p>The <code>$schema</code> URI is an opaque identifier, and the draft says it &quot;does not need to be resolvable&quot;. Skills with scripts or other files go in a <code>.tar.gz</code> or <code>.zip</code> with <code>type: &quot;archive&quot;</code>, served as <code>application/gzip</code> or <code>application/zip</code>. The draft says clients SHALL NOT run bundled scripts by default. Agents load skill text straight into their context, so put nothing in a skill you wouldn&#39;t want an agent to act on.</p>\n<h2>llms.txt</h2>\n<p>llms.txt is Markdown. The only required part is an H1 with the site or project name. Then come an optional blockquote summary, optional prose, and H2 sections of <code>[name](url): notes</code> links. A section named &quot;Optional&quot; holds links an agent can skip. Version 2 of the proposal allows the file at a subpath, where it covers the pages under that path. It suggests markdown copies of pages at <code>page.html.md</code> or <code>page.md</code>, announced with <code>rel=&quot;alternate&quot; type=&quot;text/markdown&quot;</code>. The covering llms.txt is announced with <code>rel=&quot;describedby&quot;</code>.</p>\n<pre><code class=\"language-markdown\"># Example Corp\n\n&gt; Example Corp sells invoicing software. This file points agents at the API reference, the MCP server and the agent skill.\n\n## Docs\n\n- [Invoices API reference](https://example.com/docs/api/invoices.md): read-only endpoints, auth and errors\n- [MCP server](https://example.com/docs/mcp.md): remote endpoint, tools and scopes\n\n## Optional\n\n- [Changelog](https://example.com/changelog.md)</code></pre>\n<p>The proposal doesn&#39;t set a media type; we served it as <code>text/markdown</code>.</p>\n<h2>Check your files</h2>\n<ol><li><strong>Parse every JSON file.</strong> <code>python3 -m json.tool &lt; .well-known/ai-catalog.json &gt; /dev/null</code> fails loudly on a stray comma.</li><li><strong>Check the headers.</strong> <code>curl -sI https://example.com/.well-known/api-catalog</code> should show the Linkset media type with the RFC 9727 profile, and the <code>Link</code> header. Run the same check for the card&#39;s CORS headers and the AI Catalog&#39;s media type.</li><li><strong>Validate the Server Card against the official schema.</strong> Clone <code>modelcontextprotocol/ext-server-card</code> and run <code>npm install</code>. <code>npm run validate</code> checks the repository&#39;s own examples (7 passed for us). To check your card, compile <code>#/$defs/ServerCard</code> from <code>schema.json</code> with Ajv 2020, as the repository&#39;s <code>scripts/validate-examples.ts</code> does. Our card passed. A card without <code>description</code> was rejected with &quot;must have required property &#39;description&#39;&quot;.</li><li><strong>Recompute skill digests</strong> and compare them with the index.</li><li><strong>Run the probe.</strong> The <a href=\"/skills/discover-agent-interfaces/\">discover-agent-interfaces</a> skill&#39;s <code>probe_site.py</code> fetches what an agent would fetch. It treats every result as untrusted.</li></ol>\n<pre><code class=\"language-bash\">python3 scripts/probe_site.py https://example.com --no-mcp-guess</code></pre>\n<p>Against our local copy of these files, version 1.1.1 of the probe reported:</p>\n<pre><code class=\"language-text\">AI Catalog: http://127.0.0.1:8787/.well-known/ai-catalog.json (specVersion 1.0), 2 entries\n  - application/mcp-server-card+json  urn:air:example.com:mcp:invoices  http://127.0.0.1:8787/mcp/server-card\n      MCP remote: http://127.0.0.1:8787/mcp (streamable-http)\n  - application/agent-skills+md  urn:air:example.com:skill:invoice-lookup  http://127.0.0.1:8787/.well-known/agent-skills/invoice-lookup/SKILL.md\nAPI catalog (RFC 9727): http://127.0.0.1:8787/.well-known/api-catalog  APIs=[&#39;https://api.example.com/v1/&#39;]  descriptions=[&#39;https://api.example.com/v1/openapi.json&#39;, &#39;http://127.0.0.1:8787/docs/api/&#39;]\nAgent Skills index: http://127.0.0.1:8787/.well-known/agent-skills/index.json  1 skills\n  - invoice-lookup (skill-md)  http://127.0.0.1:8787/.well-known/agent-skills/invoice-lookup/SKILL.md\nllms.txt: http://127.0.0.1:8787/llms.txt  &quot;Example Corp&quot;  2 sections, 3 links, 407 bytes</code></pre>\n<p>For the local run, our test server rewrote <code>https://example.com</code> to the local address. There was no MCP server behind the card, so the probe also reported &quot;no MCP endpoint found here&quot;. The probe counts APIs from <code>item</code> links. A catalog that uses only the Appendix A.1 pattern showed <code>APIs=[]</code> and listed the descriptions only, which is one more reason to include an <code>item</code> list.</p>\n<h2>Before you publish</h2>\n<ul><li>Everything in these files is public and will be read by machines that act on it. Leave out internal hosts, private endpoints, tokens and anything you wouldn&#39;t put on your homepage.</li><li>Each file can go stale: the version in the card, digests in the index, links in llms.txt. Generate them in your build rather than by hand.</li><li>If your API or MCP server uses OAuth, publish protected resource metadata (<a href=\"/entries/rfc-9728/\">RFC 9728</a>) as well. See <a href=\"/guides/add-oauth-to-your-mcp-server/\">adding OAuth to an MCP server</a>.</li><li>Several of these specs are drafts. Check each one again when you update the files.</li></ul>"
}
