
This page is part of our MCP specification reference, a plain-English guide to the Model Context Protocol spec (version 2026-07-28), within The MCP Guide. Building a server? See MCP development.
Status in the 2026-07-28 spec: core (servers MUST implement it; clients MAY call it)
server/discover is the MCP request a client sends to ask a server three things at once: which protocol versions it supports, which capabilities it offers and who it is. Every server must implement it. Clients may call it first, but they do not have to.
It arrived in the 2026-07-28 spec, when MCP dropped the initialize handshake. Discovery is the stateless replacement for the "getting to know you" part of that handshake.
This page explains the request in plain English, using the official discovery page, current as of October 2026.
Key Takeaways
server/discoverreturns a server's supported versions, capabilities, identity and optional instructions in one reply.- Servers MUST implement it; clients MAY call it before any other request, or skip it.
- A client that skips it can call any method directly and handle an "unsupported version" error if one comes back.
- The response supports caching through
ttlMsandcacheScopehints. - On stdio, clients that also support older servers SHOULD send it first as a compatibility probe.
- It is not the same as finding servers in the MCP Registry; it describes one server you already know about.
What server/discover does
The spec puts it simply: "server/discover lets a client query a server's supported protocol versions, capabilities, and identity before sending any other requests. Servers MUST implement it."
The request has no parameters beyond the standard _meta block that every 2026-07-28 request carries. Here is the spec's own example:
{
"jsonrpc": "2.0",
"id": "discover-1",
"method": "server/discover",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": { "name": "ExampleClient", "version": "1.0.0" },
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}
And the server's reply:
{
"jsonrpc": "2.0",
"id": "discover-1",
"result": {
"resultType": "complete",
"supportedVersions": ["2026-07-28"],
"capabilities": { "tools": {}, "resources": {} },
"_meta": {
"io.modelcontextprotocol/serverInfo": { "name": "ExampleServer", "version": "1.0.0" }
},
"instructions": "This server provides weather and resource utilities.",
"ttlMs": 3600000,
"cacheScope": "public"
}
}
The result fields are:
| Field | What it tells the client |
|---|---|
supportedVersions | Protocol versions the server accepts; the client picks one |
capabilities | Features offered, such as tools, resources, prompts and extensions |
_meta serverInfo | Server name and version (SHOULD be included) |
instructions | Optional plain-language hints for the AI model on using the server |
ttlMs, cacheScope | How long the answer can be cached, and by whom |
Why it exists
Before 2026-07-28, every connection began with an initialize request. The 2025-11-25 lifecycle page said it "MUST be the first interaction," and the server's reply carried its version, capabilities, serverInfo and instructions. That made each server remember a session.
The 2026-07-28 release removed the handshake so any request can land on any server instance. The changelog then added server/discover so clients still have one place to learn about a server up front. Read why MCP became stateless for the bigger story.
How clients use it
The versioning page says a client "is free to invoke any RPC inline and handle UnsupportedProtocolVersionError if its preferred version is not supported." So discovery is useful, not mandatory. The discovery page names two good reasons to call it:
- Showing server information. One
server/discovercall returns identity, capabilities and versions. That avoids separate probes withtools/list,prompts/listandresources/listjust to see what exists. - The stdio compatibility probe. On stdio there is no HTTP status code to signal "wrong version." A client that supports both new and old servers SHOULD send
server/discoverfirst.
The stdio transport page lists the probe's three outcomes. A DiscoverResult means a modern server. An UnsupportedProtocolVersionError means a modern server that wants another version, so the client must not fall back to initialize. Any other error, or silence, means a legacy server, so the client falls back to the old handshake.
Discovery tells you that tools exist, not what they are. To get the actual tool list, the client still calls tools/list. See MCP capabilities explained for what each capability unlocks.
Caching the answer
The discovery response "supports caching." The ttlMs value is a freshness hint in milliseconds; the example's 3,600,000 means one hour. cacheScope is "public" when the response holds no user-specific data and shared intermediaries may cache it, or "private" when it may be reused only within the same authorization context, per the schema.
This matters for gateways. A gateway can serve a cached public discovery result to many users instead of asking the server every time. Our guide to MCP gateways covers where that fits.
What changed across spec versions
| Version | How a client learned what a server offered |
|---|---|
| 2025-11-25 and earlier | initialize request and response, then notifications/initialized |
| 2026-07-28 | Optional server/discover; version and client capabilities sent on every request |
A server that wants to serve both eras MAY implement both behaviors. The versioning page calls these "dual-era" servers.
Common mistakes
- Not implementing it on the server. It is a MUST, even though clients may never call it.
- Calling it before every request. It is meant to be called up front or cached, not repeated per call.
- Falling back on one specific error code. The stdio rules say fallback "MUST NOT be keyed to one specific error code," because legacy servers answer unknown requests in different ways.
- Trusting
serverInfofor security. The spec says it "is self-reported by the server and is not verified." Use it for display and logs only. - Caching user-specific results as public. If capabilities differ per user, set
cacheScopeto"private". - Confusing it with the MCP Registry. The registry helps you find servers;
server/discoverdescribes a server you already connect to. See what the MCP Registry is.
Next step
Discovery returns a capabilities object. Learn what each entry means and who must declare what in MCP capabilities explained. For every spec topic, see the MCP specification hub.
Frequently asked questions
Is server/discover required in MCP?
For servers, yes: the 2026-07-28 spec says servers MUST implement it. For clients, no. A client may call any method directly and retry if it gets an unsupported-version error.
What replaced the MCP initialize request?
Two things. Every request now carries its protocol version and client capabilities in _meta. And server/discover gives clients an optional way to learn a server's versions, capabilities and identity up front.
Does server/discover list the server's tools?
No. It returns the server's capabilities, such as whether it offers tools at all. The client calls tools/list to get the actual tools and their schemas.
Can I cache the server/discover response?
Yes. The response includes ttlMs, a freshness hint in milliseconds, and cacheScope, which says whether shared caches may reuse it. Respect private results by keeping them within one authorization context.
How does a client tell an old MCP server from a new one?
On stdio, it sends server/discover first. A discovery result or a recognized modern error means a new server; any other error or no reply means a legacy server that expects initialize. On HTTP, the client checks the body of a 400 Bad Request.











