createmcps.com

Spec explainer

What is server/discover in MCP?

Last verified: 10 August 2026 · spec 2026-07-28 · ruleset 1.4.2

server/discover is how a client learns what a server supports now that initialize is gone. It is a required method that returns the protocol versions, capabilities and identity a server offers — as an ordinary request that establishes nothing and can be called any number of times.

The short answer

Servers MUST implement server/discover.
MCP-DSC-001 MUST · spec 2026-07-28
One request, no preamble
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: server/discover

{ "jsonrpc": "2.0", "id": 0, "method": "server/discover", "params": {} }

It is also the fastest way for a validator — ours included — to classify a server's era in a single round trip, which is why it is the first probe group we built.

How it differs from initialize

initialize compared with server/discover
 initialize (legacy)server/discover
Creates stateYes — a sessionNo
Required firstYes, before any other methodNo — optional, any time
Version outcomeOne negotiated version per connectionA list; the client picks per request
RepeatableNoYes, freely
Our recommendation, not a spec quote: the trap is treating server/discover as a rename of initialize and requiring clients to call it first. Nothing entitles you to that — a conformant client may open with tools/list and never call discovery at all. If your server refuses work until discovery has happened, you have rebuilt the handshake under a new name and will fail MCP-STL-003.

What it returns

`supportedVersions`: Protocol versions the server supports. The client should choose one of these for subsequent requests.
MCP-DSC-002 MUST · spec 2026-07-28
Illustrative shape — see the note below
{
  "jsonrpc": "2.0", "id": 0,
  "result": {
    "resultType": "complete",
    "supportedVersions": ["2026-07-28"],
    "capabilities": { "tools": {} },
    "_meta": {
      "io.modelcontextprotocol/serverInfo": {
        "name": "weather", "version": "1.0.0"
      }
    }
  }
}

The spec requires server/discover and describes what it must convey, but does not publish a worked request/response example the way it does for tools/call. The shape above is a reasonable construction from the described behaviour, not a literal quote — check your SDK's exact response schema before matching on field names.

serverInfo belongs on every result, not just this one

Servers SHOULD include the following io.modelcontextprotocol/* field in every result's _meta, unless specifically configured not to do so, to identify themselves without relying on any prior connection state.
MCP-DSC-005 SHOULD · spec 2026-07-28

Read the clause at the end carefully: without relying on any prior connection state. That is the whole reason this moved from a handshake field to a per-result one. Anything downstream — a gateway logging which server answered, a client showing the user what it is talking to — used to learn identity once at connection time. With no connection to learn it at, it has to ride along.

Every result, not just discovery
function ok(payload) {
  return {
    resultType: "complete",
    ...payload,
    _meta: {
      "io.modelcontextprotocol/serverInfo": SERVER_INFO,
    },
  }
}

Extension identifiers

Extension identifiers MUST follow the _meta key naming rules, with a mandatory prefix.
MCP-DSC-004 MUST · spec 2026-07-28
Reserved vs yours
io.modelcontextprotocol/protocolVersion    ✓ spec-defined
io.modelcontextprotocol/serverInfo        ✓ spec-defined
io.modelcontextprotocol/myOwnThing        ✗ reserved prefix — not yours

com.example/draftId                       ✓ a prefix you control
dev.acme.tools/traceId                    ✓

The reverse-DNS requirement is what keeps two independent extensions from colliding on a short name. Using the io.modelcontextprotocol/ prefix for your own field is the specific failure MCP-DSC-004 catches, and it is an easy one to commit by copying an example.

The 5 discovery rules we check

RuleWhat we checkLevelIf it fails
MCP-DSC-001server/discover is implementedMUSTfail
MCP-DSC-002DiscoverResult advertises supported protocol versionsMUSTfail
MCP-DSC-004Extension identifiers use a valid non-reserved reverse-DNS prefixMUSTfail
MCP-DSC-005Results carry io.modelcontextprotocol/serverInfo in _metaSHOULDwarn
MCP-DSC-003Advertised versions include a currently-supported revisionMAYinfo

Four of the five carry a verbatim spec sentence. MCP-DSC-003 — whether advertised versions include a currently-supported revision — has no single spec sentence behind it and is reported as info rather than a failure.

Check your discovery response

server/discover is the first thing the validator calls, and the only probe group live today — so this is the part of a report that is fully real right now.

Validate a server →

Frequently asked

What is server/discover in MCP?

A required method in the 2026-07-28 revision that advertises which protocol versions a server supports, what capabilities it has, and who it is. It is how a client learns about a server now that the initialize handshake has been removed — one ordinary request, no session, no negotiation state.

Is server/discover required?

Yes. The specification states that servers MUST implement server/discover. It is not an optional convenience: without it a client has no way to learn a server's supported versions except by guessing one, sending a real request, and interpreting the error.

How is server/discover different from initialize?

initialize established a session and negotiated a single agreed version for that connection. server/discover establishes nothing — it is a plain request that returns information, and the client picks a version to use on subsequent requests. Calling it is optional for the client and it can be called any number of times, because nothing about it is stateful.

What does a DiscoverResult contain?

The protocol versions the server supports, so the client can choose one; the server's capabilities; and its identity. Like every result in this revision it also carries resultType, and it should include io.modelcontextprotocol/serverInfo in _meta so the server identifies itself without relying on connection state.

What is io.modelcontextprotocol/serverInfo?

A _meta field servers should include in every result, not just discovery, identifying the server by name and version. It exists because a stateless protocol has no handshake in which identity was established once — so identity has to travel with each response for anything downstream to attribute it.

How do MCP extension identifiers work?

They must follow the _meta key naming rules with a mandatory reverse-DNS prefix, and must not use a reserved prefix. io.modelcontextprotocol/* is reserved for the specification, so your own extensions belong under a prefix you control, such as com.example/my-extension.