# MCP Server Cards: The .well-known File Your Server Is Missing

> Server Cards let a client, registry or crawler learn what your MCP server is before opening a single connection. SEP-2127 is still open, the path is still moving, and publishing one now costs about twenty lines. Here is the schema, the gotchas, and how to ship it.

**Source:** https://mcpplaygroundonline.com/blog/mcp-server-cards-well-known-discovery  
**Author:** Nikhil Tiwari  
**Published:** 2026-09-07  
**Updated:** 2026-09-07  
**Category:** Development  
**Reading time:** 11 min read

---

📖 TL;DR

-   An **MCP Server Card** is a small JSON file at a `.well-known` URL that describes your server _before_ anyone connects to it.
-   Think `robots.txt` or `.well-known/openid-configuration` — a static file that unlocks discovery for clients, registries and crawlers.
-   The active proposal is **SEP-2127**, successor to SEP-1649. It is **still open** as of September 2026, and the exact filename has moved more than once.
-   The card carries **identity, docs links, remote endpoints and supported protocol versions**. It deliberately does **not** list your tools.
-   Tools stay dynamic and are discovered at runtime through `tools/list`. Baking them into a static file would go stale instantly.
-   It is **not the same thing** as `server.json` in the official registry, and not the same as an A2A Agent Card.

Table of Contents

1.  [What Is an MCP Server Card?](#what)
2.  [Why Pre-Connection Discovery Matters](#why)
3.  [The Path (and Why It Keeps Moving)](#path)
4.  [What Goes in the Card](#fields)
5.  [Why Tools Are Not in the Card](#omits)
6.  [Server Card vs server.json vs Agent Card](#vs)
7.  [How to Publish One](#publish)
8.  [Five Mistakes I Keep Seeing](#mistakes)
9.  [How to Verify It](#verify)
10.  [FAQ](#faq)

Right now, the only way to find out what an **MCP server** does is to connect to it. Handshake, auth, `tools/list`, then decide if you even wanted it.

That is fine for one server. It is terrible for a registry indexing twenty thousand of them.

**MCP Server Cards** fix that. One static JSON file at a `.well-known` URL, readable by anything that can make a GET request.

I have been tracking this since SEP-1649 opened, and the proposal has changed shape twice. This post covers what is settled, what is not, and what I would ship today.

Publishing one takes about twenty lines. Skipping it means registries and client UIs have nothing to show about your server.

This assumes you already run a server. If not, my [introduction to the Model Context Protocol](/blog/what-is-model-context-protocol) is the place to start.

## What Is an MCP Server Card?

A _Server Card_ is machine-readable metadata about an MCP server, served over plain HTTP at a well-known path.

It answers the questions a client has **before** it commits to a connection:

-   What is this server called, and who publishes it?
-   Where are its remote endpoints?
-   Which protocol revisions does it speak?
-   Where are the docs and the source?

The mental model that helped me most: **it is `robots.txt` for agents.** A tiny file that makes an entire discovery ecosystem possible.

The Server Card Working Group is developing the convention as part of the MCP roadmap's discovery workstream.

## Why Pre-Connection Discovery Matters

Four groups need this, and none of them can get it today without opening a session.

**Registries.** Indexing servers means connecting to each one, authenticating, and hoping it is up. A card is a cheap crawl.

**Client UIs.** Claude Desktop and Cursor want to show a name, icon and description in an install dialog before you approve anything.

**Agents doing selection.** An agent choosing between three candidate servers should not have to open three connections to compare.

**Security review.** Knowing which protocol revisions and auth methods a server claims, before you connect, is a real triage signal.

**The SEO angle nobody mentions:** a Server Card is also how crawlers find you. If you publish a hosted MCP server and want it listed in directories like the [MCP registry](/mcp-registry), a static card is the lowest-effort way to be indexable.

## The Path (and Why It Keeps Moving)

Here is the honest state of play, because most write-ups on this quote a path that is already out of date.

**SEP-1649** opened the idea: HTTP server discovery via `.well-known`. **SEP-2127** is the active pull request that carries it forward.

SEP-2127 proposes serving the card at:

```
https://example.com/.well-known/mcp/server-cards.json
```

Earlier drafts and several third-party guides use the singular `server-card.json`, and a mid-2026 draft suggested hanging it off the MCP endpoint as `<mcp-endpoint>/server-card` with a site-level catalog.

⚠️ SEP-2127 is still open

As of September 2026 this is a proposal under active review, not a ratified part of the spec. The field names below are stable enough to build against, but do not treat the exact filename as final. Serve both spellings if you want to be safe — it is a static file.

My advice: **publish at the SEP-2127 path and add a redirect from the singular form.** Two lines of config, and you stop caring how the vote goes.

Note the deliberate separation from `.well-known/ai-catalog.json`. That is the protocol-agnostic AI Card standard, a different thing with a different audience.

## What Goes in the Card

The schema is small on purpose. Here is what SEP-2127 carries.

Field

Purpose

`name`

Machine identifier, reverse-DNS style. Stable across releases.

`title`

Human-readable name for install dialogs and directory listings.

`description`

One or two sentences on what the server is for.

`version`

Your server's version, not the protocol version.

`websiteUrl`

Docs or landing page a human should read.

`repository`

Source location. Big trust signal for reviewers.

`remotes`

Array of connectable endpoints with transport type.

`supportedProtocolVersions`

Which revisions you speak. This is the dual-spec field.

`icons`

Icon URLs with sizes, for client UI.

`_meta`

Namespaced escape hatch for vendor-specific extras.

A complete card for a hosted server looks like this. That is the whole file.

/.well-known/mcp/server-cards.json

```
{
  "name": "com.acme/support-tools",
  "title": "Acme Support Tools",
  "description": "Read and triage Acme support tickets, and draft replies.",
  "version": "2.4.0",
  "websiteUrl": "https://acme.com/docs/mcp",
  "repository": {
    "url": "https://github.com/acme/support-mcp",
    "source": "github"
  },
  "remotes": [
    {
      "type": "streamable-http",
      "url": "https://mcp.acme.com/v1"
    }
  ],
  "supportedProtocolVersions": ["2026-07-28", "2025-11-25"],
  "icons": [
    { "src": "https://acme.com/icon-256.png", "sizes": "256x256" }
  ]
}
```

**The `supportedProtocolVersions` array is the field to get right.** It is how a client knows whether to send a 2026 stateless request or the older session handshake.

If you support both revisions, list both. If you have already migrated, list only `2026-07-28` and let old clients fail fast.

## Why Tools Are Not in the Card

This surprises people, and several third-party guides get it wrong by showing a `tools[]` array.

**SEP-2127 deliberately omits tools, resources and prompts.** Community feedback drove that decision, and it is the right call.

Servers are dynamic. Tool lists change with the caller's scopes, feature flags, tenant configuration and deploy cadence.

A static file claiming eleven tools while the live server exposes seven is worse than no file at all. **Stale metadata is a bug that lies confidently.**

So primitives stay where they belong: discovered at runtime through `tools/list`, which since the 2026-07-28 revision returns `ttlMs` and `cacheScope` so clients can cache the answer properly.

That is the actual division of labour. **The card tells you whether to connect. The protocol tells you what you can do once you have.**

## Server Card vs server.json vs A2A Agent Card

Three similar-sounding artifacts, three different jobs. I have watched this confusion cost people an afternoon.

Artifact

Lives where

Answers

**Server Card**

On your own domain, at `.well-known`

What is this server, and should I connect?

**`server.json`**

Submitted to the official MCP registry

How do I install this, including local packages?

**A2A Agent Card**

On an agent's domain, at `.well-known`

What can this _agent_ do, and can I delegate to it?

The registry's `server.json` covers local packages too — npm, PyPI, Docker. The Server Card is **HTTP discovery only**, which is why it was scoped down.

That scoping was deliberate: it avoids breaking changes to `server.json`. Publish both if you distribute a local package and host a remote endpoint.

If registry publishing is the part you need, I wrote a walkthrough on [publishing an MCP server to the registry](/blog/how-to-publish-your-mcp-server-to-registry).

And the A2A comparison is a genuinely different axis, covered in [MCP vs A2A](/blog/mcp-vs-a2a-agent2agent-protocol).

## How to Publish One

It is a static JSON response with CORS enabled. Three flavours below.

### Next.js App Router

app/.well-known/mcp/server-cards.json/route.ts

```
import { NextResponse } from 'next/server';

const card = {
  name: 'com.acme/support-tools',
  title: 'Acme Support Tools',
  description: 'Read and triage Acme support tickets.',
  version: process.env.npm_package_version ?? '1.0.0',
  websiteUrl: 'https://acme.com/docs/mcp',
  remotes: [{ type: 'streamable-http', url: 'https://mcp.acme.com/v1' }],
  supportedProtocolVersions: ['2026-07-28'],
};

export function GET() {
  return NextResponse.json(card, {
    headers: {
      'Cache-Control': 'public, max-age=3600',
      'Access-Control-Allow-Origin': '*',
    },
  });
}
```

### Express

```
app.get('/.well-known/mcp/server-cards.json', (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
  res.set('Cache-Control', 'public, max-age=3600');
  res.json(card);
});
```

### Cloudflare Workers

```
if (url.pathname === '/.well-known/mcp/server-cards.json') {
  return Response.json(card, {
    headers: {
      'Cache-Control': 'public, max-age=3600',
      'Access-Control-Allow-Origin': '*',
    },
  });
}
```

**Serve it from the apex domain of your MCP endpoint's origin.** A card at `docs.acme.com` for a server at `mcp.acme.com` will not be found.

Building on Workers? My [Cloudflare Workers MCP guide](/blog/build-mcp-server-cloudflare-workers-guide) covers the surrounding setup.

Card published — does the server behind it actually work?

Paste the URL from your `remotes` array, connect in the browser, and confirm the protocol revisions you claimed are the ones you speak.

[Test any MCP server free →](https://mcpplaygroundonline.com/mcp-test-server) [Check server compliance](https://mcpplaygroundonline.com/mcp-checker)

## Five Mistakes I Keep Seeing

**1\. Listing tools in the card.** They are not part of SEP-2127. If you copied a schema with a `tools[]` array, you copied an outdated draft.

**2\. Claiming a protocol version you do not implement.** Putting `2026-07-28` in the array while still requiring `Mcp-Session-Id` will break stateless clients.

**3\. Forgetting CORS.** Browser-based clients and web inspectors fetch this file directly. No `Access-Control-Allow-Origin` means invisible to half your audience.

**4\. Putting it behind auth.** The entire point is pre-connection discovery. A card that returns 401 does nothing.

**5\. Letting `version` go stale.** Wire it to your build. A card that says 1.0.0 eighteen months in tells reviewers you are not maintaining the server.

Mistake two is the expensive one. If you are unsure which revision you actually implement, my [breakdown of the stateless changes](/blog/mcp-stateless-2026-release-candidate) has the checklist.

## How to Verify It

Three checks, about ninety seconds total.

**Fetch it cold.** Use curl with no cookies and no auth header:

```
curl -sI https://acme.com/.well-known/mcp/server-cards.json
curl -s https://acme.com/.well-known/mcp/server-cards.json | jq .
```

You want a 200, `content-type: application/json`, and an `access-control-allow-origin` header.

**Cross-check the endpoint.** Take the URL from `remotes` and connect to it. If it does not resolve, your card is pointing users at nothing.

**Cross-check the versions.** Confirm the server really speaks every revision listed in `supportedProtocolVersions`. Claiming both and supporting one is the most common failure.

That last check is what a browser-based tester is for. Connect, list tools, and see which revision the handshake actually negotiates.

New to server testing generally? Start with [how to test MCP servers step by step](/blog/how-to-test-mcp-servers-step-by-step), then come back to the card.

## Ship the Card Now

SEP-2127 is not final, but the cost of being early here is close to zero. It is a static JSON file with two fields you might have to rename.

The cost of being late is that registries, client install dialogs and agent selection logic have nothing to say about your server.

Publish the card, point `remotes` at a URL that works, and be honest in `supportedProtocolVersions`. Then verify all three against a live connection.

One caveat worth holding onto: discovery only helps a server that deserved to be built. I worked through that question in [Is MCP dead? What the CLI backlash gets right](/blog/is-mcp-dead-cli-debate).

## FAQ

**What is an MCP Server Card?+**

A small JSON file served at a .well-known URL that describes an MCP server before any client connects to it. It carries identity, description, documentation and repository links, remote endpoints, supported protocol versions and icons. It exists so registries, client install dialogs, crawlers and agents can evaluate a server without opening a session and authenticating.

**What is the .well-known path for an MCP Server Card?+**

SEP-2127 proposes /.well-known/mcp/server-cards.json, served from the origin of your MCP endpoint. Earlier drafts and several third-party guides use the singular server-card.json, and one mid-2026 draft suggested hanging the card off the MCP endpoint itself. Because the proposal is still open, serving both spellings, or redirecting one to the other, is the safe move.

**Do Server Cards list a server's tools?+**

No. SEP-2127 deliberately omits tools, resources and prompts. Servers are dynamic, so the tool list can vary with the caller's scopes, tenant, feature flags and deploy version. A static file claiming a tool set that does not match the live server is worse than no file. Primitives stay discoverable at runtime through tools/list, which returns ttlMs and cacheScope in the 2026-07-28 revision so clients can cache them correctly.

**Is a Server Card the same as server.json in the MCP registry?+**

No. server.json is what you submit to the official MCP registry, and it covers local package distribution through npm, PyPI or Docker as well as remote endpoints. The Server Card is HTTP discovery only, served from your own domain, and was deliberately scoped down to avoid breaking changes to server.json. If you ship both a local package and a hosted endpoint, publish both artifacts.

**Is SEP-2127 final?+**

Not as of September 2026. SEP-2127 is an open pull request under active review, succeeding SEP-1649, and the Server Card Working Group is still refining conventions as part of the MCP roadmap. Field names such as name, title, description, version, remotes and supportedProtocolVersions are stable enough to build against, but the exact filename has changed more than once, so avoid hard-coding it in client logic.

**Does the Server Card need CORS headers?+**

Yes. Browser-based MCP clients, online inspectors and web install dialogs fetch the card directly from the browser, so without an Access-Control-Allow-Origin header the request fails silently. Serve it with Access-Control-Allow-Origin set to a wildcard, a JSON content type, and a Cache-Control max-age of around an hour. Never place the card behind authentication, since pre-connection discovery is its entire purpose.

## Frequently asked questions

### What is an MCP Server Card?

A small JSON file served at a .well-known URL that describes an MCP server before any client connects to it. It carries identity, description, documentation and repository links, remote endpoints, supported protocol versions and icons. It exists so registries, client install dialogs, crawlers and agents can evaluate a server without opening a session and authenticating.

### What is the .well-known path for an MCP Server Card?

SEP-2127 proposes /.well-known/mcp/server-cards.json, served from the origin of your MCP endpoint. Earlier drafts and several third-party guides use the singular server-card.json, and one mid-2026 draft suggested hanging the card off the MCP endpoint itself. Because the proposal is still open, serving both spellings, or redirecting one to the other, is the safe move.

### Do Server Cards list a server tools?

No. SEP-2127 deliberately omits tools, resources and prompts. Servers are dynamic, so the tool list can vary with the caller scopes, tenant, feature flags and deploy version. A static file claiming a tool set that does not match the live server is worse than no file. Primitives stay discoverable at runtime through tools/list, which returns ttlMs and cacheScope in the 2026-07-28 revision so clients can cache them correctly.

### Is a Server Card the same as server.json in the MCP registry?

No. server.json is what you submit to the official MCP registry, and it covers local package distribution through npm, PyPI or Docker as well as remote endpoints. The Server Card is HTTP discovery only, served from your own domain, and was deliberately scoped down to avoid breaking changes to server.json. If you ship both a local package and a hosted endpoint, publish both artifacts.

### Is SEP-2127 final?

Not as of September 2026. SEP-2127 is an open pull request under active review, succeeding SEP-1649, and the Server Card Working Group is still refining conventions as part of the MCP roadmap. Field names such as name, title, description, version, remotes and supportedProtocolVersions are stable enough to build against, but the exact filename has changed more than once, so avoid hard-coding it in client logic.

### Does the Server Card need CORS headers?

Yes. Browser-based MCP clients, online inspectors and web install dialogs fetch the card directly from the browser, so without an Access-Control-Allow-Origin header the request fails silently. Serve it with Access-Control-Allow-Origin set to a wildcard, a JSON content type, and a Cache-Control max-age of around an hour. Never place the card behind authentication, since pre-connection discovery is its entire purpose.


---

_Canonical page: https://mcpplaygroundonline.com/blog/mcp-server-cards-well-known-discovery — MCP Playground (mcpplaygroundonline.com), the free browser-based tool for testing MCP servers and building AI agents._
