The 30 second answer
MCP is a JSON-RPC protocol that lets an AI host discover tools, resources and prompts at runtime and let a language model choose among them. A host creates one client per server. Current transports are stdio and Streamable HTTP; the older HTTP plus SSE transport is deprecated. The 2026 revision made the protocol stateless: there is no initialize handshake, and every request carries the protocol version and client capabilities.
MCP is an open protocol for connecting LLM applications to external tools and context. It standardises how a host application exposes capabilities from local or remote servers to a language model. This answer follows specification revision 2026-07-28, the current revision. Earlier revisions differ in important ways, and those differences are called out below.
JSON-RPC 2.0 messages. All client and server messages must follow JSON-RPC 2.0. MCP uses requests (an id, a method and optional params), results, errors and notifications (no id, no response). In 2026-07-28 a successful result must include resultType: "complete" or "input_required". Clients must treat a missing resultType from older servers as "complete". The request id must be a string or integer and must not be null, which is stricter than base JSON-RPC.
Host, client and server. The host is the LLM application, for example an IDE or chat app. It creates clients, enforces consent and security policy, and aggregates context for the model. Each client talks to exactly one server and keeps servers isolated from one another. A server exposes resources, tools and prompts; it may be a local subprocess or a remote HTTP service. Servers are not supposed to see the full conversation or other servers. This is closer to the Language Server Protocol's process model than to a typical public REST API: the user-facing product is the host, and servers are plugins that add capabilities.
Transports. Protocol semantics are the same on every transport. The current standard bindings are:
- stdio. The client launches the server as a subprocess. JSON-RPC messages are newline-delimited on standard input and output and must not contain embedded newlines. This is the usual local-tool transport.
- Streamable HTTP. The server exposes a single MCP endpoint that accepts POST. Each JSON-RPC request is its own HTTP POST. The server replies with a JSON object or with a request-scoped Server-Sent Events stream. Streamable HTTP was introduced in protocol version 2025-03-26.
The older HTTP+SSE transport from protocol version 2024-11-05, a separate long-lived GET SSE endpoint plus a POST endpoint, has been deprecated since 2025-03-26. Revision 2026-07-28 reclassifies it as Deprecated. New implementations must not adopt it; existing ones should migrate to Streamable HTTP.
Capability negotiation, with no initialize handshake. This is one of the largest 2026-07-28 changes. Earlier revisions used an initialize handshake and, on HTTP, an optional session id. That handshake is gone. MCP is now a stateless protocol: every request is self-contained. Every client request must carry the protocol version and client capabilities in _meta. Servers must implement server/discover, which advertises supported protocol versions, capabilities and identity. If a server needs state across calls, it mints an explicit handle, returns it in a tool result, and expects the client to pass that handle as an ordinary argument later.
Server primitives. Tools are functions the language model can discover and invoke. They are model-controlled: the host lists them with tools/list, puts the names and JSON Schemas in the model context, and the model chooses what to call; the client then issues tools/call. The specification still says there should be a human in the loop who can deny invocations. Resources are application-driven context identified by URIs, listed and read by the host. Prompts are user-controlled templates, often slash commands in a UI. List endpoints must not vary per connection; they may vary by the authorization presented on the request.
The active client feature is elicitation: the server can ask the user for more information using Multi Round-Trip Requests, returning resultType: "input_required" and expecting a retry with inputResponses. Roots, sampling and logging were deprecated in 2026-07-28 and remain functional only during a deprecation window; new implementations should not add them.
Authorization is optional. When an HTTP transport is used, implementations should follow the MCP authorization specification, which is based on OAuth 2.1: the MCP server is a resource server, the MCP client is an OAuth client, and access tokens are sent as Authorization: Bearer. Stdio transports should not use this HTTP OAuth flow; they should take credentials from the environment.
How MCP differs from REST and gRPC. A REST or gRPC integration is usually a fixed contract written by developers. A human, or a generated client, knows the resources or RPC methods at build time, from OpenAPI or a .proto file. An MCP integration is built so AI agents can discover and call capabilities at runtime. The wire methods (tools/list, tools/call, and so on) are stable; the set of tools can change from server to server and even from request to request, for example by OAuth scope. HTTP, when used, is a transport for those RPC messages, a single POST endpoint, not the public resource vocabulary. An MCP server often wraps an existing REST or gRPC API: the stable backend contract stays as it is, and the MCP layer advertises a smaller, model-friendly tool surface with descriptions the model can read. That wrapping pattern is common practice, not a requirement of the specification.
Example tools/list and tools/call exchange, including the _meta fields that 2026-07-28 requires on every request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {"name": "example-host", "version": "1.0.0"},
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "complete",
"tools": [
{
"name": "search_product_offers",
"title": "Search product offers",
"description": "Search the product catalogue by free-text query and return matching offers.",
"inputSchema": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Free-text product query"},
"limit": {"type": "integer", "minimum": 1, "maximum": 20}
},
"required": ["query"]
}
}
],
"ttlMs": 300000,
"cacheScope": "public"
}
}{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "search_product_offers",
"arguments": {"query": "navy sneakers", "limit": 2},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {"name": "example-host", "version": "1.0.0"},
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}{
"jsonrpc": "2.0",
"id": 2,
"result": {
"resultType": "complete",
"content": [
{"type": "text", "text": "Found 1 offer: p-1001 Navy sneakers, 79.95 EUR."}
],
"structuredContent": {
"items": [
{"id": "p-1001", "title": "Navy sneakers", "price": {"amount": 79.95, "currency": "EUR"}}
]
},
"isError": false
}
}The catalogue data in that result could have come from a REST or gRPC API. The MCP server is a runtime-discoverable façade; it does not have to be the system of record.
Recent revision changes. Protocol versions use a date and only increment when a change is backward-incompatible. The current revision is 2026-07-28. Highlights since 2025-11-25: the protocol became stateless; initialize and protocol sessions were removed; server/discover was added; subscriptions/listen replaced the HTTP GET stream and resources/subscribe; results must include resultType; roots, sampling and logging were deprecated; HTTP+SSE remains deprecated in favour of Streamable HTTP. If a blog post or SDK still shows initialize or HTTP+SSE as current practice, it is describing an older revision.
Alternate interview scenarios
"How would you let an assistant search our catalogue?"
I would not invent a new system of record. I would keep the existing search API, then add an MCP server that exposes a small tool such as search_product_offers, with a clear description and a tight JSON Schema. The host lists the tool, the model chooses to call it, and a human should be able to approve the call. The assistant talks MCP; the catalogue still speaks REST or gRPC.
"I read that MCP starts with an initialize handshake. Is that still true?"
Not in revision 2026-07-28. The handshake and protocol sessions were removed. Every request carries the protocol version and client capabilities, and servers must implement server/discover. I would treat older SDK samples as historical unless they have been updated to this revision.
Sources (13)
- MCP specification, 2026-07-28modelcontextprotocol.io
- MCP versioningmodelcontextprotocol.io
- MCP base protocolmodelcontextprotocol.io
- JSON-RPC 2.0 specificationjsonrpc.org
- MCP architecturemodelcontextprotocol.io
- MCP transportsmodelcontextprotocol.io
- MCP deprecated featuresmodelcontextprotocol.io
- MCP server discoverymodelcontextprotocol.io
- MCP 2026-07-28 changelogmodelcontextprotocol.io
- MCP toolsmodelcontextprotocol.io
- MCP resourcesmodelcontextprotocol.io
- MCP promptsmodelcontextprotocol.io
- MCP authorizationmodelcontextprotocol.io