Follow Discord
Sweep 22 Oct 2026 · 04:32Z Build v2.1.308 527 read Stable v2.1.308 Latest v2.1.308 Next v2.1.308 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · mcp

Architecture overview changeddocs/2026-07-28/learn/architecture

Nearest release: v2.1.305, published under an hour before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Upstream edited this page at 20 Oct 2026 20:02 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 20 Oct 2026 20:07 UTC.

Upstream edited
Recorded here
Lines+399added
Lines−407removed
From line 15 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits2to this page, all time

#### Understanding the Discovery Exchange #### How This Works in AI Applications #### Understanding the Tool Discovery Request #### Understanding the Tool Discovery Response #### How This Works in AI Applications #### Understanding the Tool Execution Request #### Key Elements of Tool Execution #### Understanding the Tool Execution Response #### How This Works in AI Applications #### Subscribing to Changes #### Understanding Tool List Change Notifications #### Key Features of MCP Notifications #### Client Response to Notifications #### Why Notifications Matter #### How This Works in AI Applications

The whole hunk

from line 15, old and new numbered
/
lines

The two sides of this change are more than 400 edits apart, too far apart to line up, so this is the differ's own diff of it and the words inside a line are not marked.

from line 15
1515* **MCP Development Tools**: Tools for developing MCP servers and clients, including the [MCP Inspector](https://github.com/modelcontextprotocol/inspector)
1616* [MCP Reference Server Implementations](https://github.com/modelcontextprotocol/servers): Reference implementations of MCP servers.
1717 
18<Note>
19 MCP focuses solely on the protocol for context exchange—it does not dictate
20 how AI applications use LLMs or manage the provided context.
21</Note>
18> [!NOTE]
19>
20> MCP focuses solely on the protocol for context exchange—it does not dictate
21> how AI applications use LLMs or manage the provided context.
2222 
2323## Concepts of MCP
2424 
from line 104
104104 
105105#### Statelessness and discovery
106106 
107MCP is a <Tooltip tip="Every request contains all the information needed to process it, so servers infer nothing from previous requests">stateless protocol</Tooltip>. Every request carries the protocol version and the <Tooltip tip="Features and operations that a client or server supports, such as tools, resources, or prompts">capabilities</Tooltip> relevant to that request in its `_meta` field, so the server can process each request on its own. Clients should also identify themselves in the same field unless configured not to. Servers advertise their supported versions and capabilities through the mandatory [`server/discover`](/specification/2026-07-28/server/discover) request, which clients may send before any other request. Detailed information can be found in the [specification](/specification/2026-07-28/basic/index#statelessness), and the [example](#example) showcases the per-request metadata and the discovery sequence.
107MCP is a stateless protocol (Every request contains all the information needed to process it, so servers infer nothing from previous requests). Every request carries the protocol version and the capabilities (Features and operations that a client or server supports, such as tools, resources, or prompts) relevant to that request in its `_meta` field, so the server can process each request on its own. Clients should also identify themselves in the same field unless configured not to. Servers advertise their supported versions and capabilities through the mandatory [`server/discover`](/specification/2026-07-28/server/discover) request, which clients may send before any other request. Detailed information can be found in the [specification](/specification/2026-07-28/basic/index#statelessness), and the [example](#example) showcases the per-request metadata and the discovery sequence.
108108 
109109#### Primitives
110110 
from line 148
148148 
149149This section provides a step-by-step walkthrough of an MCP client-server interaction, focusing on the data layer protocol. We'll demonstrate discovery, tool operations, and notifications using JSON-RPC 2.0 messages.
150150 
151<Steps>
152 <Step title="Discovery">
153 As described in the [statelessness and discovery](#statelessness-and-discovery) section, every MCP request carries the protocol version and client capabilities in its `_meta` field, and clients should also include their identity there. A client that wants to learn what a server supports before issuing other requests sends a `server/discover` request, which every server must implement. The discovery response is typically cacheable, meaning it can be re-used so the discovery flow does not need to be performed for every request.
154 
155 <CodeGroup>
156 ```json Discover Request theme={null}
151**1. Discovery**
152 
153As described in the [statelessness and discovery](#statelessness-and-discovery) section, every MCP request carries the protocol version and client capabilities in its `_meta` field, and clients should also include their identity there. A client that wants to learn what a server supports before issuing other requests sends a `server/discover` request, which every server must implement. The discovery response is typically cacheable, meaning it can be re-used so the discovery flow does not need to be performed for every request.
154 
155```json Discover Request theme={null}
156{
157 "jsonrpc": "2.0",
158 "id": 1,
159 "method": "server/discover",
160 "params": {
161 "_meta": {
162 "io.modelcontextprotocol/protocolVersion": "2026-07-28",
163 "io.modelcontextprotocol/clientInfo": {
164 "name": "example-client",
165 "version": "1.0.0"
166 },
167 "io.modelcontextprotocol/clientCapabilities": {
168 "elicitation": {}
169 }
170 }
171 }
172}
173```
174 
175```json Discover Response theme={null}
176{
177 "jsonrpc": "2.0",
178 "id": 1,
179 "result": {
180 "resultType": "complete",
181 "supportedVersions": ["2026-07-28"],
182 "capabilities": {
183 "tools": {
184 "listChanged": true
185 },
186 "resources": {}
187 },
188 "_meta": {
189 "io.modelcontextprotocol/serverInfo": {
190 "name": "example-server",
191 "version": "1.0.0"
192 }
193 },
194 "ttlMs": 3600000,
195 "cacheScope": "public"
196 }
197}
198```
199 
200#### Understanding the Discovery Exchange
201 
202The `_meta` fields and the discovery response together serve several purposes:
203 
2041. **Protocol Version Selection**: The `io.modelcontextprotocol/protocolVersion` field declares the version the client is speaking on this request, and `supportedVersions` in the response lists the versions the server accepts. If a server does not support the requested version, it rejects the request with an `UnsupportedProtocolVersionError` listing the versions it does support, and the client retries with a mutually supported version.
205 
2062. **Capability Discovery**: The client declares its capabilities in `io.modelcontextprotocol/clientCapabilities` on every request, and the server returns its own `capabilities` object from `server/discover`. This tells each party which [primitives](#primitives) the other can handle (tools, resources, prompts) and whether change [notifications](#notifications) are available, so unsupported operations are never attempted.
207 
2083. **Identity Exchange**: The `io.modelcontextprotocol/clientInfo` field in the request's `_meta` and the `io.modelcontextprotocol/serverInfo` field in the result's `_meta` provide identification and versioning information for debugging and compatibility purposes.
209 
210In this example, the exchange demonstrates how MCP capabilities are declared:
211 
212**Client Capabilities**:
213 
214* `"elicitation": {}` - The client declares it can gather additional input from the user when the server requests it
215 
216**Server Capabilities**:
217 
218* `"tools": {"listChanged": true}` - The server supports the tools primitive and can honor a `toolsListChanged` filter in [`subscriptions/listen`](/specification/2026-07-28/basic/patterns/subscriptions). Clients that request this filter receive `notifications/tools/list_changed` when the tool list changes.
219* `"resources": {}` - The server also supports the resources primitive (can handle `resources/list` and `resources/read` methods)
220 
221Calling `server/discover` is optional. Because every request carries the same `_meta` fields, a client is free to send any request directly and handle a version error if one comes back. Discovery is a convenient way to fetch the server's identity, capabilities, and supported versions in a single request.
222 
223#### How This Works in AI Applications
224 
225The AI application's MCP client manager connects to configured servers and stores their discovered capabilities for later use. The application uses this information to determine which servers can provide specific types of functionality (tools, resources, prompts) and whether they support real-time updates. In the Python SDK, discovery happens while the client connects. The results are then available on the client object.
226 
227```python Pseudo-code for AI application discovery theme={null}
228# Pseudo Code
229async with Client(stdio_client(server_config)) as client:
230 if client.server_capabilities.tools:
231 app.register_mcp_server(client, supports_tools=True)
232 app.set_server_ready(client)
233```
234 
235**2. Tool Discovery (Primitives)**
236 
237The client can discover available tools by sending a `tools/list` request. This request is fundamental to MCP's tool discovery mechanism: it allows clients to understand what tools are available on the server before attempting to use them.
238 
239```json Tools List Request theme={null}
240{
241 "jsonrpc": "2.0",
242 "id": 2,
243 "method": "tools/list",
244 "params": {
245 "_meta": {
246 "io.modelcontextprotocol/protocolVersion": "2026-07-28",
247 "io.modelcontextprotocol/clientInfo": {
248 "name": "example-client",
249 "version": "1.0.0"
250 },
251 "io.modelcontextprotocol/clientCapabilities": {
252 "elicitation": {}
253 }
254 }
255 }
256}
257```
258 
259```json Tools List Response theme={null}
260{
261 "jsonrpc": "2.0",
262 "id": 2,
263 "result": {
264 "resultType": "complete",
265 "tools": [
157266 {
158 "jsonrpc": "2.0",
159 "id": 1,
160 "method": "server/discover",
161 "params": {
162 "_meta": {
163 "io.modelcontextprotocol/protocolVersion": "2026-07-28",
164 "io.modelcontextprotocol/clientInfo": {
165 "name": "example-client",
166 "version": "1.0.0"
167 },
168 "io.modelcontextprotocol/clientCapabilities": {
169 "elicitation": {}
170 }
171 }
172 }
173 }
174 ```
175 
176 ```json Discover Response theme={null}
177 {
178 "jsonrpc": "2.0",
179 "id": 1,
180 "result": {
181 "resultType": "complete",
182 "supportedVersions": ["2026-07-28"],
183 "capabilities": {
184 "tools": {
185 "listChanged": true
186 },
187 "resources": {}
188 },
189 "_meta": {
190 "io.modelcontextprotocol/serverInfo": {
191 "name": "example-server",
192 "version": "1.0.0"
267 "name": "calculator_arithmetic",
268 "title": "Calculator",
269 "description": "Perform mathematical calculations including basic arithmetic, trigonometric functions, and algebraic operations",
270 "inputSchema": {
271 "type": "object",
272 "properties": {
273 "expression": {
274 "type": "string",
275 "description": "Mathematical expression to evaluate (e.g., '2 + 3 * 4', 'sin(30)', 'sqrt(16)')"
193276 }
194277 },
195 "ttlMs": 3600000,
196 "cacheScope": "public"
278 "required": ["expression"]
197279 }
198 }
199 ```
200 </CodeGroup>
201 
202 #### Understanding the Discovery Exchange
203 
204 The `_meta` fields and the discovery response together serve several purposes:
205 
206 1. **Protocol Version Selection**: The `io.modelcontextprotocol/protocolVersion` field declares the version the client is speaking on this request, and `supportedVersions` in the response lists the versions the server accepts. If a server does not support the requested version, it rejects the request with an `UnsupportedProtocolVersionError` listing the versions it does support, and the client retries with a mutually supported version.
207 
208 2. **Capability Discovery**: The client declares its capabilities in `io.modelcontextprotocol/clientCapabilities` on every request, and the server returns its own `capabilities` object from `server/discover`. This tells each party which [primitives](#primitives) the other can handle (tools, resources, prompts) and whether change [notifications](#notifications) are available, so unsupported operations are never attempted.
209 
210 3. **Identity Exchange**: The `io.modelcontextprotocol/clientInfo` field in the request's `_meta` and the `io.modelcontextprotocol/serverInfo` field in the result's `_meta` provide identification and versioning information for debugging and compatibility purposes.
211 
212 In this example, the exchange demonstrates how MCP capabilities are declared:
213 
214 **Client Capabilities**:
215 
216 * `"elicitation": {}` - The client declares it can gather additional input from the user when the server requests it
217 
218 **Server Capabilities**:
219 
220 * `"tools": {"listChanged": true}` - The server supports the tools primitive and can honor a `toolsListChanged` filter in [`subscriptions/listen`](/specification/2026-07-28/basic/patterns/subscriptions). Clients that request this filter receive `notifications/tools/list_changed` when the tool list changes.
221 * `"resources": {}` - The server also supports the resources primitive (can handle `resources/list` and `resources/read` methods)
222 
223 Calling `server/discover` is optional. Because every request carries the same `_meta` fields, a client is free to send any request directly and handle a version error if one comes back. Discovery is a convenient way to fetch the server's identity, capabilities, and supported versions in a single request.
224 
225 #### How This Works in AI Applications
226 
227 The AI application's MCP client manager connects to configured servers and stores their discovered capabilities for later use. The application uses this information to determine which servers can provide specific types of functionality (tools, resources, prompts) and whether they support real-time updates. In the Python SDK, discovery happens while the client connects. The results are then available on the client object.
228 
229 ```python Pseudo-code for AI application discovery theme={null}
230 # Pseudo Code
231 async with Client(stdio_client(server_config)) as client:
232 if client.server_capabilities.tools:
233 app.register_mcp_server(client, supports_tools=True)
234 app.set_server_ready(client)
235 ```
236 </Step>
237 
238 <Step title="Tool Discovery (Primitives)">
239 The client can discover available tools by sending a `tools/list` request. This request is fundamental to MCP's tool discovery mechanism: it allows clients to understand what tools are available on the server before attempting to use them.
240 
241 <CodeGroup>
242 ```json Tools List Request theme={null}
280 },
243281 {
244 "jsonrpc": "2.0",
245 "id": 2,
246 "method": "tools/list",
247 "params": {
248 "_meta": {
249 "io.modelcontextprotocol/protocolVersion": "2026-07-28",
250 "io.modelcontextprotocol/clientInfo": {
251 "name": "example-client",
252 "version": "1.0.0"
282 "name": "weather_current",
283 "title": "Weather Information",
284 "description": "Get current weather information for any location worldwide",
285 "inputSchema": {
286 "type": "object",
287 "properties": {
288 "location": {
289 "type": "string",
290 "description": "City name, address, or coordinates (latitude,longitude)"
253291 },
254 "io.modelcontextprotocol/clientCapabilities": {
255 "elicitation": {}
292 "units": {
293 "type": "string",
294 "enum": ["metric", "imperial", "kelvin"],
295 "description": "Temperature units to use in response",
296 "default": "metric"
256297 }
257 }
298 },
299 "required": ["location"]
258300 }
259301 }
260 ```
261 
262 ```json Tools List Response theme={null}
302 ],
303 "ttlMs": 300000,
304 "cacheScope": "public"
305 }
306}
307```
308 
309#### Understanding the Tool Discovery Request
310 
311The `tools/list` request requires no parameters beyond the standard `_meta` fields that accompany every MCP request. It also accepts an optional `cursor` parameter for [pagination](/specification/2026-07-28/server/utilities/pagination), which the example above omits.
312 
313#### Understanding the Tool Discovery Response
314 
315The response contains a `tools` array that provides comprehensive metadata about each available tool. This array-based structure allows servers to expose multiple tools simultaneously while maintaining clear boundaries between different functionalities.
316 
317Each tool object in the response includes several key fields:
318 
319* **`name`**: A unique identifier for the tool within the server's namespace. This serves as the primary key for tool execution and should follow a clear naming pattern (e.g., `calculator_arithmetic` rather than just `calculate`)
320* **`title`**: A human-readable display name for the tool that clients can show to users
321* **`description`**: Detailed explanation of what the tool does and when to use it
322* **`inputSchema`**: A JSON Schema that defines the expected input parameters, enabling type validation and providing clear documentation about required and optional parameters
323 
324The result is marked `"resultType": "complete"` and carries two caching fields. `ttlMs` is a freshness hint in milliseconds, so this tool list can be cached for five minutes. `cacheScope` indicates who may reuse the response. The specification's [caching utility](/specification/2026-07-28/server/utilities/caching) defines the full rules.
325 
326#### How This Works in AI Applications
327 
328The AI application fetches available tools from all connected MCP servers and combines them into a unified tool registry that the language model can access. This allows the LLM to understand what actions it can perform and automatically generates the appropriate tool calls during conversations.
329 
330```python Pseudo-code for AI application tool discovery theme={null}
331# Pseudo-code using MCP Python SDK patterns
332available_tools = []
333for client in app.mcp_clients():
334 tools_response = await client.list_tools()
335 available_tools.extend(tools_response.tools)
336conversation.register_available_tools(available_tools)
337```
338 
339Clients that federate many servers can use [progressive tool discovery](/docs/2026-07-28/develop/clients/client-best-practices#progressive-tool-discovery) rather than loading every tool upfront.
340 
341**3. Tool Execution (Primitives)**
342 
343The client can now execute a tool using the `tools/call` method. This demonstrates how MCP primitives are used in practice: after discovering available tools, the client can invoke them with appropriate arguments.
344 
345#### Understanding the Tool Execution Request
346 
347The `tools/call` request follows a structured format that ensures type safety and clear communication between client and server. Note that we're using the proper tool name from the discovery response (`weather_current`) rather than a simplified name:
348 
349```json Tool Call Request theme={null}
350{
351 "jsonrpc": "2.0",
352 "id": 3,
353 "method": "tools/call",
354 "params": {
355 "name": "weather_current",
356 "arguments": {
357 "location": "San Francisco",
358 "units": "imperial"
359 },
360 "_meta": {
361 "io.modelcontextprotocol/protocolVersion": "2026-07-28",
362 "io.modelcontextprotocol/clientInfo": {
363 "name": "example-client",
364 "version": "1.0.0"
365 },
366 "io.modelcontextprotocol/clientCapabilities": {
367 "elicitation": {}
368 }
369 }
370 }
371}
372```
373 
374```json Tool Call Response theme={null}
375{
376 "jsonrpc": "2.0",
377 "id": 3,
378 "result": {
379 "resultType": "complete",
380 "content": [
263381 {
264 "jsonrpc": "2.0",
265 "id": 2,
266 "result": {
267 "resultType": "complete",
268 "tools": [
269 {
270 "name": "calculator_arithmetic",
271 "title": "Calculator",
272 "description": "Perform mathematical calculations including basic arithmetic, trigonometric functions, and algebraic operations",
273 "inputSchema": {
274 "type": "object",
275 "properties": {
276 "expression": {
277 "type": "string",
278 "description": "Mathematical expression to evaluate (e.g., '2 + 3 * 4', 'sin(30)', 'sqrt(16)')"
279 }
280 },
281 "required": ["expression"]
282 }
283 },
284 {
285 "name": "weather_current",
286 "title": "Weather Information",
287 "description": "Get current weather information for any location worldwide",
288 "inputSchema": {
289 "type": "object",
290 "properties": {
291 "location": {
292 "type": "string",
293 "description": "City name, address, or coordinates (latitude,longitude)"
294 },
295 "units": {
296 "type": "string",
297 "enum": ["metric", "imperial", "kelvin"],
298 "description": "Temperature units to use in response",
299 "default": "metric"
300 }
301 },
302 "required": ["location"]
303 }
304 }
305 ],
306 "ttlMs": 300000,
307 "cacheScope": "public"
308 }
309 }
310 ```
311 </CodeGroup>
312 
313 #### Understanding the Tool Discovery Request
314 
315 The `tools/list` request requires no parameters beyond the standard `_meta` fields that accompany every MCP request. It also accepts an optional `cursor` parameter for [pagination](/specification/2026-07-28/server/utilities/pagination), which the example above omits.
316 
317 #### Understanding the Tool Discovery Response
318 
319 The response contains a `tools` array that provides comprehensive metadata about each available tool. This array-based structure allows servers to expose multiple tools simultaneously while maintaining clear boundaries between different functionalities.
320 
321 Each tool object in the response includes several key fields:
322 
323 * **`name`**: A unique identifier for the tool within the server's namespace. This serves as the primary key for tool execution and should follow a clear naming pattern (e.g., `calculator_arithmetic` rather than just `calculate`)
324 * **`title`**: A human-readable display name for the tool that clients can show to users
325 * **`description`**: Detailed explanation of what the tool does and when to use it
326 * **`inputSchema`**: A JSON Schema that defines the expected input parameters, enabling type validation and providing clear documentation about required and optional parameters
327 
328 The result is marked `"resultType": "complete"` and carries two caching fields. `ttlMs` is a freshness hint in milliseconds, so this tool list can be cached for five minutes. `cacheScope` indicates who may reuse the response. The specification's [caching utility](/specification/2026-07-28/server/utilities/caching) defines the full rules.
329 
330 #### How This Works in AI Applications
331 
332 The AI application fetches available tools from all connected MCP servers and combines them into a unified tool registry that the language model can access. This allows the LLM to understand what actions it can perform and automatically generates the appropriate tool calls during conversations.
333 
334 ```python Pseudo-code for AI application tool discovery theme={null}
335 # Pseudo-code using MCP Python SDK patterns
336 available_tools = []
337 for client in app.mcp_clients():
338 tools_response = await client.list_tools()
339 available_tools.extend(tools_response.tools)
340 conversation.register_available_tools(available_tools)
341 ```
342 
343 Clients that federate many servers can use [progressive tool discovery](/docs/2026-07-28/develop/clients/client-best-practices#progressive-tool-discovery) rather than loading every tool upfront.
344 </Step>
345 
346 <Step title="Tool Execution (Primitives)">
347 The client can now execute a tool using the `tools/call` method. This demonstrates how MCP primitives are used in practice: after discovering available tools, the client can invoke them with appropriate arguments.
348 
349 #### Understanding the Tool Execution Request
350 
351 The `tools/call` request follows a structured format that ensures type safety and clear communication between client and server. Note that we're using the proper tool name from the discovery response (`weather_current`) rather than a simplified name:
352 
353 <CodeGroup>
354 ```json Tool Call Request theme={null}
355 {
356 "jsonrpc": "2.0",
357 "id": 3,
358 "method": "tools/call",
359 "params": {
360 "name": "weather_current",
361 "arguments": {
362 "location": "San Francisco",
363 "units": "imperial"
364 },
365 "_meta": {
366 "io.modelcontextprotocol/protocolVersion": "2026-07-28",
367 "io.modelcontextprotocol/clientInfo": {
368 "name": "example-client",
369 "version": "1.0.0"
370 },
371 "io.modelcontextprotocol/clientCapabilities": {
372 "elicitation": {}
373 }
374 }
375 }
376 }
377 ```
378 
379 ```json Tool Call Response theme={null}
380 {
381 "jsonrpc": "2.0",
382 "id": 3,
383 "result": {
384 "resultType": "complete",
385 "content": [
386 {
387 "type": "text",
388 "text": "Current weather in San Francisco: 68°F, partly cloudy with light winds from the west at 8 mph. Humidity: 65%"
389 }
390 ]
391 }
392 }
393 ```
394 </CodeGroup>
395 
396 #### Key Elements of Tool Execution
397 
398 The request structure includes several important components:
399 
400 1. **`name`**: Must match exactly the tool name from the discovery response (`weather_current`). This ensures the server can correctly identify which tool to execute.
401 
402 2. **`arguments`**: Contains the input parameters as defined by the tool's `inputSchema`. In this example:
403 * `location`: "San Francisco" (required parameter)
404 * `units`: "imperial" (optional parameter, defaults to "metric" if not specified)
405 
406 3. **`_meta`**: Carries the standard per-request fields: the protocol version and client capabilities that every MCP request must include, plus the client's identity, which clients should include unless configured not to.
407 
408 4. **JSON-RPC Structure**: Uses standard JSON-RPC 2.0 format with unique `id` for request-response correlation.
409 
410 #### Understanding the Tool Execution Response
411 
412 The response demonstrates MCP's flexible content system:
413 
414 1. **`content` Array**: Tool responses return an array of content objects, allowing for rich, multi-format responses (text, images, resources, etc.)
415 
416 2. **Content Types**: Each content object has a `type` field. In this example, `"type": "text"` indicates plain text content, but MCP supports various content types for different use cases.
417 
418 3. **Structured Output**: The response provides actionable information that the AI application can use as context for language model interactions.
419 
420 This execution pattern allows AI applications to dynamically invoke server functionality and receive structured responses that can be integrated into conversations with language models.
421 
422 #### How This Works in AI Applications
423 
424 When the language model decides to use a tool during a conversation, the AI application intercepts the tool call, routes it to the appropriate MCP server, executes it, and returns the results back to the LLM as part of the conversation flow. This enables the LLM to access real-time data and perform actions in the external world.
425 
426 ```python theme={null}
427 # Pseudo-code for AI application tool execution
428 async def handle_tool_call(conversation, tool_name, arguments):
429 client = app.find_mcp_client_for_tool(tool_name)
430 result = await client.call_tool(tool_name, arguments)
431 conversation.add_tool_result(result.content)
432 ```
433 </Step>
434 
435 <Step title="Real-time Updates (Notifications)">
436 MCP supports real-time notifications that enable servers to inform clients about changes without being polled for them. This demonstrates the notification system, a key feature that keeps clients synchronized and responsive.
437 
438 #### Subscribing to Changes
439 
440 Change notifications are opt-in. To receive them, the client opens a long-lived notification stream by sending a [`subscriptions/listen`](/specification/2026-07-28/basic/patterns/subscriptions) request with a `notifications` filter naming the event types it wants. Here the client asks for tool list changes:
441 
442 ```json Listen Request theme={null}
443 {
444 "jsonrpc": "2.0",
445 "id": 4,
446 "method": "subscriptions/listen",
447 "params": {
448 "_meta": {
449 "io.modelcontextprotocol/protocolVersion": "2026-07-28",
450 "io.modelcontextprotocol/clientInfo": {
451 "name": "example-client",
452 "version": "1.0.0"
453 },
454 "io.modelcontextprotocol/clientCapabilities": {
455 "elicitation": {}
456 }
457 },
458 "notifications": {
459 "toolsListChanged": true
460 }
461 }
462 }
463 ```
464 
465 Every client request carries the `io.modelcontextprotocol/protocolVersion` and `io.modelcontextprotocol/clientCapabilities` fields in `_meta`, and normally `io.modelcontextprotocol/clientInfo` as well, so the server can identify the client without relying on connection state.
466 
467 The server acknowledges the subscription with `notifications/subscriptions/acknowledged`, which is the first message carrying that subscription's ID in `_meta` (the server sends no other notification for that subscription before it). Its `notifications` field reflects the subset of the requested filter the server agreed to honor, with unsupported notification types omitted:
468 
469 ```json Acknowledgment theme={null}
470 {
471 "jsonrpc": "2.0",
472 "method": "notifications/subscriptions/acknowledged",
473 "params": {
474 "_meta": {
475 "io.modelcontextprotocol/subscriptionId": 4
476 },
477 "notifications": {
478 "toolsListChanged": true
479 }
480 }
481 }
482 ```
483 
484 #### Understanding Tool List Change Notifications
485 
486 After the acknowledgment, when the server's available tools change (for example, when new functionality becomes available, existing tools are modified, or tools become temporarily unavailable), the server delivers a notification on that stream:
487 
488 ```json Notification theme={null}
489 {
490 "jsonrpc": "2.0",
491 "method": "notifications/tools/list_changed",
492 "params": {
493 "_meta": {
494 "io.modelcontextprotocol/subscriptionId": 4
495 }
496 }
497 }
498 ```
499 
500 #### Key Features of MCP Notifications
501 
502 1. **No Response Required**: Notice there's no `id` field in the notification. This follows JSON-RPC 2.0 notification semantics where no response is expected or sent.
503 
504 2. **Opt-In Based**: This notification is only sent to clients that requested `"toolsListChanged": true` in their `subscriptions/listen` filter, and it is only available from servers that declared `"listChanged": true` in their tools capability (as shown in Step 1).
505 
506 3. **Subscription-ID Tagging**: Every notification on the stream carries `io.modelcontextprotocol/subscriptionId` in `_meta`. The value is the JSON-RPC ID of the `subscriptions/listen` request that opened the stream (`4` in this example), so clients can correlate each notification with the subscription that produced it.
507 
508 4. **Event-Driven**: The server decides when to send notifications based on internal state changes, making MCP connections dynamic and responsive.
509 
510 5. **Best Effort**: There are no guarantees that every notification will be sent or received, particularly across transport reconnects. Clients should also rely on polling to preserve freshness of results.
511 
512 #### Client Response to Notifications
513 
514 Upon receiving this notification, the client typically reacts by requesting the updated tool list. This creates a refresh cycle that keeps the client's understanding of available tools current:
515 
516 ```json Request theme={null}
517 {
518 "jsonrpc": "2.0",
519 "id": 5,
520 "method": "tools/list",
521 "params": {
522 "_meta": {
523 "io.modelcontextprotocol/protocolVersion": "2026-07-28",
524 "io.modelcontextprotocol/clientInfo": {
525 "name": "example-client",
526 "version": "1.0.0"
527 },
528 "io.modelcontextprotocol/clientCapabilities": {
529 "elicitation": {}
530 }
531 }
532 }
533 }
534 ```
535 
536 #### Why Notifications Matter
537 
538 This notification system is crucial for several reasons:
539 
540 1. **Dynamic Environments**: Tools may come and go based on server state, external dependencies, or user permissions
541 2. **Efficiency**: Clients don't need to poll for changes; they're notified when updates occur
542 3. **Consistency**: Ensures clients always have accurate information about available server capabilities
543 4. **Real-time Collaboration**: Enables responsive AI applications that can adapt to changing contexts
544 
545 This notification pattern extends beyond tools to other MCP primitives, enabling comprehensive real-time synchronization between clients and servers.
546 
547 #### How This Works in AI Applications
548 
549 The AI application keeps a notification stream open for the changes it cares about. When one arrives, it immediately refreshes its tool registry and updates the LLM's available capabilities. This ensures that ongoing conversations always have access to the most current set of tools, and the LLM can dynamically adapt to new functionality as it becomes available.
550 
551 ```python theme={null}
552 # Pseudo-code for AI application notification handling
553 async def follow_tool_changes(client):
554 async with client.listen(tools_list_changed=True) as sub:
555 async for _event in sub:
556 tools_response = await client.list_tools()
557 app.update_available_tools(client, tools_response.tools)
558 if app.conversation.is_active():
559 app.conversation.notify_llm_of_new_capabilities()
560 ```
561 </Step>
562</Steps>
382 "type": "text",
383 "text": "Current weather in San Francisco: 68°F, partly cloudy with light winds from the west at 8 mph. Humidity: 65%"
384 }
385 ]
386 }
387}
388```
389 
390#### Key Elements of Tool Execution
391 
392The request structure includes several important components:
393 
3941. **`name`**: Must match exactly the tool name from the discovery response (`weather_current`). This ensures the server can correctly identify which tool to execute.
395 
3962. **`arguments`**: Contains the input parameters as defined by the tool's `inputSchema`. In this example:
397 * `location`: "San Francisco" (required parameter)
398 * `units`: "imperial" (optional parameter, defaults to "metric" if not specified)
399 
4003. **`_meta`**: Carries the standard per-request fields: the protocol version and client capabilities that every MCP request must include, plus the client's identity, which clients should include unless configured not to.
401 
4024. **JSON-RPC Structure**: Uses standard JSON-RPC 2.0 format with unique `id` for request-response correlation.
403 
404#### Understanding the Tool Execution Response
405 
406The response demonstrates MCP's flexible content system:
407 
4081. **`content` Array**: Tool responses return an array of content objects, allowing for rich, multi-format responses (text, images, resources, etc.)
409 
4102. **Content Types**: Each content object has a `type` field. In this example, `"type": "text"` indicates plain text content, but MCP supports various content types for different use cases.
411 
4123. **Structured Output**: The response provides actionable information that the AI application can use as context for language model interactions.
413 
414This execution pattern allows AI applications to dynamically invoke server functionality and receive structured responses that can be integrated into conversations with language models.
415 
416#### How This Works in AI Applications
417 
418When the language model decides to use a tool during a conversation, the AI application intercepts the tool call, routes it to the appropriate MCP server, executes it, and returns the results back to the LLM as part of the conversation flow. This enables the LLM to access real-time data and perform actions in the external world.
419 
420```python theme={null}
421# Pseudo-code for AI application tool execution
422async def handle_tool_call(conversation, tool_name, arguments):
423 client = app.find_mcp_client_for_tool(tool_name)
424 result = await client.call_tool(tool_name, arguments)
425 conversation.add_tool_result(result.content)
426```
427 
428**4. Real-time Updates (Notifications)**
429 
430MCP supports real-time notifications that enable servers to inform clients about changes without being polled for them. This demonstrates the notification system, a key feature that keeps clients synchronized and responsive.
431 
432#### Subscribing to Changes
433 
434Change notifications are opt-in. To receive them, the client opens a long-lived notification stream by sending a [`subscriptions/listen`](/specification/2026-07-28/basic/patterns/subscriptions) request with a `notifications` filter naming the event types it wants. Here the client asks for tool list changes:
435 
436```json Listen Request theme={null}
437{
438 "jsonrpc": "2.0",
439 "id": 4,
440 "method": "subscriptions/listen",
441 "params": {
442 "_meta": {
443 "io.modelcontextprotocol/protocolVersion": "2026-07-28",
444 "io.modelcontextprotocol/clientInfo": {
445 "name": "example-client",
446 "version": "1.0.0"
447 },
448 "io.modelcontextprotocol/clientCapabilities": {
449 "elicitation": {}
450 }
451 },
452 "notifications": {
453 "toolsListChanged": true
454 }
455 }
456}
457```
458 
459Every client request carries the `io.modelcontextprotocol/protocolVersion` and `io.modelcontextprotocol/clientCapabilities` fields in `_meta`, and normally `io.modelcontextprotocol/clientInfo` as well, so the server can identify the client without relying on connection state.
460 
461The server acknowledges the subscription with `notifications/subscriptions/acknowledged`, which is the first message carrying that subscription's ID in `_meta` (the server sends no other notification for that subscription before it). Its `notifications` field reflects the subset of the requested filter the server agreed to honor, with unsupported notification types omitted:
462 
463```json Acknowledgment theme={null}
464{
465 "jsonrpc": "2.0",
466 "method": "notifications/subscriptions/acknowledged",
467 "params": {
468 "_meta": {
469 "io.modelcontextprotocol/subscriptionId": 4
470 },
471 "notifications": {
472 "toolsListChanged": true
473 }
474 }
475}
476```
477 
478#### Understanding Tool List Change Notifications
479 
480After the acknowledgment, when the server's available tools change (for example, when new functionality becomes available, existing tools are modified, or tools become temporarily unavailable), the server delivers a notification on that stream:
481 
482```json Notification theme={null}
483{
484 "jsonrpc": "2.0",
485 "method": "notifications/tools/list_changed",
486 "params": {
487 "_meta": {
488 "io.modelcontextprotocol/subscriptionId": 4
489 }
490 }
491}
492```
493 
494#### Key Features of MCP Notifications
495 
4961. **No Response Required**: Notice there's no `id` field in the notification. This follows JSON-RPC 2.0 notification semantics where no response is expected or sent.
497 
4982. **Opt-In Based**: This notification is only sent to clients that requested `"toolsListChanged": true` in their `subscriptions/listen` filter, and it is only available from servers that declared `"listChanged": true` in their tools capability (as shown in Step 1).
499 
5003. **Subscription-ID Tagging**: Every notification on the stream carries `io.modelcontextprotocol/subscriptionId` in `_meta`. The value is the JSON-RPC ID of the `subscriptions/listen` request that opened the stream (`4` in this example), so clients can correlate each notification with the subscription that produced it.
501 
5024. **Event-Driven**: The server decides when to send notifications based on internal state changes, making MCP connections dynamic and responsive.
503 
5045. **Best Effort**: There are no guarantees that every notification will be sent or received, particularly across transport reconnects. Clients should also rely on polling to preserve freshness of results.
505 
506#### Client Response to Notifications
507 
508Upon receiving this notification, the client typically reacts by requesting the updated tool list. This creates a refresh cycle that keeps the client's understanding of available tools current:
509 
510```json Request theme={null}
511{
512 "jsonrpc": "2.0",
513 "id": 5,
514 "method": "tools/list",
515 "params": {
516 "_meta": {
517 "io.modelcontextprotocol/protocolVersion": "2026-07-28",
518 "io.modelcontextprotocol/clientInfo": {
519 "name": "example-client",
520 "version": "1.0.0"
521 },
522 "io.modelcontextprotocol/clientCapabilities": {
523 "elicitation": {}
524 }
525 }
526 }
527}
528```
529 
530#### Why Notifications Matter
531 
532This notification system is crucial for several reasons:
533 
5341. **Dynamic Environments**: Tools may come and go based on server state, external dependencies, or user permissions
5352. **Efficiency**: Clients don't need to poll for changes; they're notified when updates occur
5363. **Consistency**: Ensures clients always have accurate information about available server capabilities
5374. **Real-time Collaboration**: Enables responsive AI applications that can adapt to changing contexts
538 
539This notification pattern extends beyond tools to other MCP primitives, enabling comprehensive real-time synchronization between clients and servers.
540 
541#### How This Works in AI Applications
542 
543The AI application keeps a notification stream open for the changes it cares about. When one arrives, it immediately refreshes its tool registry and updates the LLM's available capabilities. This ensures that ongoing conversations always have access to the most current set of tools, and the LLM can dynamically adapt to new functionality as it becomes available.
544 
545```python theme={null}
546# Pseudo-code for AI application notification handling
547async def follow_tool_changes(client):
548 async with client.listen(tools_list_changed=True) as sub:
549 async for _event in sub:
550 tools_response = await client.list_tools()
551 app.update_available_tools(client, tools_response.tools)
552 if app.conversation.is_active():
553 app.conversation.notify_llm_of_new_capabilities()
554```
563555 
Feedback