Courses/Introduction to Model Context Protocol (MCP)/Connection Lifecycle and Capability Negotiation
The MCP Request FlowLesson 5 of 21

Connection Lifecycle and Capability Negotiation

A Connection Has Three Phases

Every MCP connection moves through three phases: initialization, operation, and shutdown. We met initialization briefly in the data-layer lesson; here we look at the full lifecycle and why capabilities — declared once during initialization — govern everything that can happen afterwards.

1. Initializationnegotiate capabilities2. Operationlist / call / read / notify3. Shutdownclean teardown

The three phases of an MCP connection. Capabilities agreed in phase 1 define what's allowed in phase 2.

Capabilities Are a Contract

During initialization both sides send a capabilities object. Think of it as a contract: each party promises what it can do, and agrees not to ask the other for anything it didn't advertise. This is what lets the protocol grow over time — a brand-new client and an old server simply operate on the intersection of what they both support.

jsonA real initialize exchange. The server here supports tools (with change notifications) and resources; the client supports elicitation.
// Client → server
{
  "jsonrpc": "2.0", "id": 1, "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "capabilities": { "elicitation": {} },
    "clientInfo": { "name": "example-client", "version": "1.0.0" }
  }
}

// Server → client
{
  "jsonrpc": "2.0", "id": 1,
  "result": {
    "protocolVersion": "2025-06-18",
    "capabilities": {
      "tools": { "listChanged": true },
      "resources": {}
    },
    "serverInfo": { "name": "example-server", "version": "1.0.0" }
  }
}

Read that exchange carefully. The server declared "tools": {"listChanged": true} — it supports the tools primitive AND can send tools/list_changed notifications. It declared "resources": {} — supports resources, no special sub-features. It did NOT declare prompts, so this client won't try prompts/list against it. The client declared "elicitation": {} — it can handle the server asking the user for input.

Protocol Version Negotiation

The protocolVersion field (a date string like 2025-06-18) ensures both sides speak a compatible version. If they can't agree on a mutually supported version, the connection should be terminated rather than risk mismatched behavior. This date-versioning scheme is how MCP ships breaking changes safely: implementations advertise which dated spec they implement.

ℹ️

Why a date for a version?

MCP spec versions are dates (e.g. 2024-11-05, 2025-03-26, 2025-06-18) rather than semantic numbers. Each represents the state of the spec on that date. Negotiation picks a version both peers understand, so upgrading one side never silently breaks the other.

Operation and Shutdown

After the handshake completes (client sends notifications/initialized), the connection enters the operation phase — this is where all the real work happens: tools/list, tools/call, resources/read, prompts/get, and any notifications. Everything you do in the rest of this course lives here.

  • 1.Initialization: client sends initialize → server responds → client sends notifications/initialized.
  • 2.Operation: requests, responses, and notifications flow per the negotiated capabilities.
  • 3.Shutdown: the connection is closed cleanly (for stdio, by closing the streams / ending the subprocess; for HTTP, by ending the session).

The golden rule of capabilities

Never call a method for a capability the peer didn't advertise. If a server didn't declare 'prompts', calling prompts/list is a protocol error. SDKs help enforce this, but understanding it prevents a whole class of confusing bugs.

Next

Capabilities define what CAN happen. Next we trace what actually DOES happen on a real user question — the full end-to-end request flow from user to server to Claude and back.

Key Takeaways

  • An MCP connection has three phases: initialization (negotiate capabilities), operation (the real work), and shutdown (clean teardown).
  • Capabilities declared during initialization are a contract — neither side asks for anything the other didn't advertise.
  • A server declaring "tools": {"listChanged": true} supports tools and can send change notifications; "resources": {} supports resources with no extra features.
  • Not declaring a primitive (e.g. prompts) means the peer must not call its methods — doing so is a protocol error.
  • protocolVersion is a date string (e.g. 2025-06-18); peers negotiate a mutually supported version or terminate the connection.
  • After the handshake (notifications/initialized), all real operations — list/call/read/get and notifications — happen in the operation phase.

Check Your Understanding

Test what you learned in this lesson.

Q1.What are the three phases of an MCP connection, in order?

Q2.A server's initialize result contains "capabilities": { "tools": {"listChanged": true} } and nothing else. What does this tell the client?

Q3.Why does MCP use date strings like '2025-06-18' for the protocol version?

Q4.What is the 'golden rule' regarding capabilities during the operation phase?

Practice This Lesson