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#### Lifecycle management
106106
107MCP is a <Tooltip tip="A subset of MCP can be made stateless using the Streamable HTTP transport">stateful protocol</Tooltip> that requires lifecycle management. The purpose of lifecycle management is to negotiate the <Tooltip tip="Features and operations that a client or server supports, such as tools, resources, or prompts">capabilities</Tooltip> that both client and server support. Detailed information can be found in the [specification](/specification/2025-11-25/basic/lifecycle), and the [example](#example) showcases the initialization sequence.
107MCP is a stateful protocol (A subset of MCP can be made stateless using the Streamable HTTP transport) that requires lifecycle management. The purpose of lifecycle management is to negotiate the capabilities (Features and operations that a client or server supports, such as tools, resources, or prompts) that both client and server support. Detailed information can be found in the [specification](/specification/2025-11-25/basic/lifecycle), and the [example](#example) showcases the initialization sequence.
108108
109109#### Primitives
110110
from line 145
145145
146146This section provides a step-by-step walkthrough of an MCP client-server interaction, focusing on the data layer protocol. We'll demonstrate the lifecycle sequence, tool operations, and notifications using JSON-RPC 2.0 messages.
147147
148<Steps>
149 <Step title="Initialization (Lifecycle Management)">
150 MCP begins with lifecycle management through a capability negotiation handshake. As described in the [lifecycle management](#lifecycle-management) section, the client sends an `initialize` request to establish the connection and negotiate supported features.
151
152 <CodeGroup>
153 ```json Initialize Request theme={null}
148**1. Initialization (Lifecycle Management)**
149
150MCP begins with lifecycle management through a capability negotiation handshake. As described in the [lifecycle management](#lifecycle-management) section, the client sends an `initialize` request to establish the connection and negotiate supported features.
151
152```json Initialize Request theme={null}
153{
154 "jsonrpc": "2.0",
155 "id": 1,
156 "method": "initialize",
157 "params": {
158 "protocolVersion": "2025-11-25",
159 "capabilities": {
160 "elicitation": {}
161 },
162 "clientInfo": {
163 "name": "example-client",
164 "version": "1.0.0"
165 }
166 }
167}
168```
169
170```json Initialize Response theme={null}
171{
172 "jsonrpc": "2.0",
173 "id": 1,
174 "result": {
175 "protocolVersion": "2025-11-25",
176 "capabilities": {
177 "tools": {
178 "listChanged": true
179 },
180 "resources": {}
181 },
182 "serverInfo": {
183 "name": "example-server",
184 "version": "1.0.0"
185 }
186 }
187}
188```
189
190#### Understanding the Initialization Exchange
191
192The initialization process is a key part of MCP's lifecycle management and serves several critical purposes:
193
1941. **Protocol Version Negotiation**: The `protocolVersion` field (e.g., "2025-11-25") ensures both client and server are using compatible protocol versions. This prevents communication errors that could occur when different versions attempt to interact. If a mutually compatible version is not negotiated, the connection should be terminated.
195
1962. **Capability Discovery**: The `capabilities` object allows each party to declare what features they support, including which [primitives](#primitives) they can handle (tools, resources, prompts) and whether they support features like [notifications](#notifications). This enables efficient communication by avoiding unsupported operations.
197
1983. **Identity Exchange**: The `clientInfo` and `serverInfo` objects provide identification and versioning information for debugging and compatibility purposes.
199
200In this example, the capability negotiation demonstrates how MCP primitives are declared:
201
202**Client Capabilities**:
203
204* `"elicitation": {}` - The client declares it can work with user interaction requests (can receive `elicitation/create` method calls)
205
206**Server Capabilities**:
207
208* `"tools": {"listChanged": true}` - The server supports the tools primitive AND can send `tools/list_changed` notifications when its tool list changes
209* `"resources": {}` - The server also supports the resources primitive (can handle `resources/list` and `resources/read` methods)
210
211After successful initialization, the client sends a notification to indicate it's ready:
212
213```json Notification theme={null}
214{
215 "jsonrpc": "2.0",
216 "method": "notifications/initialized"
217}
218```
219
220#### How This Works in AI Applications
221
222During initialization, the AI application's MCP client manager establishes connections to configured servers and stores their 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.
223
224```python Pseudo-code for AI application initialization theme={null}
225# Pseudo Code
226async with stdio_client(server_config) as (read, write):
227 async with ClientSession(read, write) as session:
228 init_response = await session.initialize()
229 if init_response.capabilities.tools:
230 app.register_mcp_server(session, supports_tools=True)
231 app.set_server_ready(session)
232```
233
234**2. Tool Discovery (Primitives)**
235
236Now that the connection is established, 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.
237
238```json Tools List Request theme={null}
239{
240 "jsonrpc": "2.0",
241 "id": 2,
242 "method": "tools/list"
243}
244```
245
246```json Tools List Response theme={null}
247{
248 "jsonrpc": "2.0",
249 "id": 2,
250 "result": {
251 "tools": [
154252 {
155 "jsonrpc": "2.0",
156 "id": 1,
157 "method": "initialize",
158 "params": {
159 "protocolVersion": "2025-11-25",
160 "capabilities": {
161 "elicitation": {}
253 "name": "calculator_arithmetic",
254 "title": "Calculator",
255 "description": "Perform mathematical calculations including basic arithmetic, trigonometric functions, and algebraic operations",
256 "inputSchema": {
257 "type": "object",
258 "properties": {
259 "expression": {
260 "type": "string",
261 "description": "Mathematical expression to evaluate (e.g., '2 + 3 * 4', 'sin(30)', 'sqrt(16)')"
262 }
162263 },
163 "clientInfo": {
164 "name": "example-client",
165 "version": "1.0.0"
166 }
264 "required": ["expression"]
265 }
266 },
267 {
268 "name": "weather_current",
269 "title": "Weather Information",
270 "description": "Get current weather information for any location worldwide",
271 "inputSchema": {
272 "type": "object",
273 "properties": {
274 "location": {
275 "type": "string",
276 "description": "City name, address, or coordinates (latitude,longitude)"
277 },
278 "units": {
279 "type": "string",
280 "enum": ["metric", "imperial", "kelvin"],
281 "description": "Temperature units to use in response",
282 "default": "metric"
283 }
284 },
285 "required": ["location"]
167286 }
168287 }
169 ```
170
171 ```json Initialize Response theme={null}
288 ]
289 }
290}
291```
292
293#### Understanding the Tool Discovery Request
294
295The `tools/list` request is simple, containing no parameters.
296
297#### Understanding the Tool Discovery Response
298
299The 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.
300
301Each tool object in the response includes several key fields:
302
303* **`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`)
304* **`title`**: A human-readable display name for the tool that clients can show to users
305* **`description`**: Detailed explanation of what the tool does and when to use it
306* **`inputSchema`**: A JSON Schema that defines the expected input parameters, enabling type validation and providing clear documentation about required and optional parameters
307
308#### How This Works in AI Applications
309
310The 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.
311
312```python Pseudo-code for AI application tool discovery theme={null}
313# Pseudo-code using MCP Python SDK patterns
314available_tools = []
315for session in app.mcp_server_sessions():
316 tools_response = await session.list_tools()
317 available_tools.extend(tools_response.tools)
318conversation.register_available_tools(available_tools)
319```
320
321**3. Tool Execution (Primitives)**
322
323The 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.
324
325#### Understanding the Tool Execution Request
326
327The `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:
328
329```json Tool Call Request theme={null}
330{
331 "jsonrpc": "2.0",
332 "id": 3,
333 "method": "tools/call",
334 "params": {
335 "name": "weather_current",
336 "arguments": {
337 "location": "San Francisco",
338 "units": "imperial"
339 }
340 }
341}
342```
343
344```json Tool Call Response theme={null}
345{
346 "jsonrpc": "2.0",
347 "id": 3,
348 "result": {
349 "content": [
172350 {
173 "jsonrpc": "2.0",
174 "id": 1,
175 "result": {
176 "protocolVersion": "2025-11-25",
177 "capabilities": {
178 "tools": {
179 "listChanged": true
180 },
181 "resources": {}
182 },
183 "serverInfo": {
184 "name": "example-server",
185 "version": "1.0.0"
186 }
187 }
351 "type": "text",
352 "text": "Current weather in San Francisco: 68°F, partly cloudy with light winds from the west at 8 mph. Humidity: 65%"
188353 }
189 ```
190 </CodeGroup>
191
192 #### Understanding the Initialization Exchange
193
194 The initialization process is a key part of MCP's lifecycle management and serves several critical purposes:
195
196 1. **Protocol Version Negotiation**: The `protocolVersion` field (e.g., "2025-11-25") ensures both client and server are using compatible protocol versions. This prevents communication errors that could occur when different versions attempt to interact. If a mutually compatible version is not negotiated, the connection should be terminated.
197
198 2. **Capability Discovery**: The `capabilities` object allows each party to declare what features they support, including which [primitives](#primitives) they can handle (tools, resources, prompts) and whether they support features like [notifications](#notifications). This enables efficient communication by avoiding unsupported operations.
199
200 3. **Identity Exchange**: The `clientInfo` and `serverInfo` objects provide identification and versioning information for debugging and compatibility purposes.
201
202 In this example, the capability negotiation demonstrates how MCP primitives are declared:
203
204 **Client Capabilities**:
205
206 * `"elicitation": {}` - The client declares it can work with user interaction requests (can receive `elicitation/create` method calls)
207
208 **Server Capabilities**:
209
210 * `"tools": {"listChanged": true}` - The server supports the tools primitive AND can send `tools/list_changed` notifications when its tool list changes
211 * `"resources": {}` - The server also supports the resources primitive (can handle `resources/list` and `resources/read` methods)
212
213 After successful initialization, the client sends a notification to indicate it's ready:
214
215 ```json Notification theme={null}
216 {
217 "jsonrpc": "2.0",
218 "method": "notifications/initialized"
219 }
220 ```
221
222 #### How This Works in AI Applications
223
224 During initialization, the AI application's MCP client manager establishes connections to configured servers and stores their 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.
225
226 ```python Pseudo-code for AI application initialization theme={null}
227 # Pseudo Code
228 async with stdio_client(server_config) as (read, write):
229 async with ClientSession(read, write) as session:
230 init_response = await session.initialize()
231 if init_response.capabilities.tools:
232 app.register_mcp_server(session, supports_tools=True)
233 app.set_server_ready(session)
234 ```
235 </Step>
236
237 <Step title="Tool Discovery (Primitives)">
238 Now that the connection is established, 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.
239
240 <CodeGroup>
241 ```json Tools List Request theme={null}
242 {
243 "jsonrpc": "2.0",
244 "id": 2,
245 "method": "tools/list"
246 }
247 ```
248
249 ```json Tools List Response theme={null}
250 {
251 "jsonrpc": "2.0",
252 "id": 2,
253 "result": {
254 "tools": [
255 {
256 "name": "calculator_arithmetic",
257 "title": "Calculator",
258 "description": "Perform mathematical calculations including basic arithmetic, trigonometric functions, and algebraic operations",
259 "inputSchema": {
260 "type": "object",
261 "properties": {
262 "expression": {
263 "type": "string",
264 "description": "Mathematical expression to evaluate (e.g., '2 + 3 * 4', 'sin(30)', 'sqrt(16)')"
265 }
266 },
267 "required": ["expression"]
268 }
269 },
270 {
271 "name": "weather_current",
272 "title": "Weather Information",
273 "description": "Get current weather information for any location worldwide",
274 "inputSchema": {
275 "type": "object",
276 "properties": {
277 "location": {
278 "type": "string",
279 "description": "City name, address, or coordinates (latitude,longitude)"
280 },
281 "units": {
282 "type": "string",
283 "enum": ["metric", "imperial", "kelvin"],
284 "description": "Temperature units to use in response",
285 "default": "metric"
286 }
287 },
288 "required": ["location"]
289 }
290 }
291 ]
292 }
293 }
294 ```
295 </CodeGroup>
296
297 #### Understanding the Tool Discovery Request
298
299 The `tools/list` request is simple, containing no parameters.
300
301 #### Understanding the Tool Discovery Response
302
303 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.
304
305 Each tool object in the response includes several key fields:
306
307 * **`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`)
308 * **`title`**: A human-readable display name for the tool that clients can show to users
309 * **`description`**: Detailed explanation of what the tool does and when to use it
310 * **`inputSchema`**: A JSON Schema that defines the expected input parameters, enabling type validation and providing clear documentation about required and optional parameters
311
312 #### How This Works in AI Applications
313
314 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.
315
316 ```python Pseudo-code for AI application tool discovery theme={null}
317 # Pseudo-code using MCP Python SDK patterns
318 available_tools = []
319 for session in app.mcp_server_sessions():
320 tools_response = await session.list_tools()
321 available_tools.extend(tools_response.tools)
322 conversation.register_available_tools(available_tools)
323 ```
324 </Step>
325
326 <Step title="Tool Execution (Primitives)">
327 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.
328
329 #### Understanding the Tool Execution Request
330
331 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:
332
333 <CodeGroup>
334 ```json Tool Call Request theme={null}
335 {
336 "jsonrpc": "2.0",
337 "id": 3,
338 "method": "tools/call",
339 "params": {
340 "name": "weather_current",
341 "arguments": {
342 "location": "San Francisco",
343 "units": "imperial"
344 }
345 }
346 }
347 ```
348
349 ```json Tool Call Response theme={null}
350 {
351 "jsonrpc": "2.0",
352 "id": 3,
353 "result": {
354 "content": [
355 {
356 "type": "text",
357 "text": "Current weather in San Francisco: 68°F, partly cloudy with light winds from the west at 8 mph. Humidity: 65%"
358 }
359 ]
360 }
361 }
362 ```
363 </CodeGroup>
364
365 #### Key Elements of Tool Execution
366
367 The request structure includes several important components:
368
369 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.
370
371 2. **`arguments`**: Contains the input parameters as defined by the tool's `inputSchema`. In this example:
372 * `location`: "San Francisco" (required parameter)
373 * `units`: "imperial" (optional parameter, defaults to "metric" if not specified)
374
375 3. **JSON-RPC Structure**: Uses standard JSON-RPC 2.0 format with unique `id` for request-response correlation.
376
377 #### Understanding the Tool Execution Response
378
379 The response demonstrates MCP's flexible content system:
380
381 1. **`content` Array**: Tool responses return an array of content objects, allowing for rich, multi-format responses (text, images, resources, etc.)
382
383 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.
384
385 3. **Structured Output**: The response provides actionable information that the AI application can use as context for language model interactions.
386
387 This execution pattern allows AI applications to dynamically invoke server functionality and receive structured responses that can be integrated into conversations with language models.
388
389 #### How This Works in AI Applications
390
391 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.
392
393 ```python theme={null}
394 # Pseudo-code for AI application tool execution
395 async def handle_tool_call(conversation, tool_name, arguments):
396 session = app.find_mcp_session_for_tool(tool_name)
397 result = await session.call_tool(tool_name, arguments)
398 conversation.add_tool_result(result.content)
399 ```
400 </Step>
401
402 <Step title="Real-time Updates (Notifications)">
403 MCP supports real-time notifications that enable servers to inform clients about changes without being explicitly requested. This demonstrates the notification system, a key feature that keeps MCP connections synchronized and responsive.
404
405 #### Understanding Tool List Change Notifications
406
407 When the server's available tools change—such as when new functionality becomes available, existing tools are modified, or tools become temporarily unavailable—the server can proactively notify connected clients:
408
409 ```json Request theme={null}
410 {
411 "jsonrpc": "2.0",
412 "method": "notifications/tools/list_changed"
413 }
414 ```
415
416 #### Key Features of MCP Notifications
417
418 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.
419
420 2. **Capability-Based**: This notification is only sent by servers that declared `"listChanged": true` in their tools capability during initialization (as shown in Step 1).
421
422 3. **Event-Driven**: The server decides when to send notifications based on internal state changes, making MCP connections dynamic and responsive.
423
424 #### Client Response to Notifications
425
426 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:
427
428 ```json Request theme={null}
429 {
430 "jsonrpc": "2.0",
431 "id": 4,
432 "method": "tools/list"
433 }
434 ```
435
436 #### Why Notifications Matter
437
438 This notification system is crucial for several reasons:
439
440 1. **Dynamic Environments**: Tools may come and go based on server state, external dependencies, or user permissions
441 2. **Efficiency**: Clients don't need to poll for changes; they're notified when updates occur
442 3. **Consistency**: Ensures clients always have accurate information about available server capabilities
443 4. **Real-time Collaboration**: Enables responsive AI applications that can adapt to changing contexts
444
445 This notification pattern extends beyond tools to other MCP primitives, enabling comprehensive real-time synchronization between clients and servers.
446
447 #### How This Works in AI Applications
448
449 When the AI application receives a notification about changed tools, 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.
450
451 ```python theme={null}
452 # Pseudo-code for AI application notification handling
453 async def handle_tools_changed_notification(session):
454 tools_response = await session.list_tools()
455 app.update_available_tools(session, tools_response.tools)
456 if app.conversation.is_active():
457 app.conversation.notify_llm_of_new_capabilities()
458 ```
459 </Step>
460</Steps>
354 ]
355 }
356}
357```
358
359#### Key Elements of Tool Execution
360
361The request structure includes several important components:
362
3631. **`name`**: Must match exactly the tool name from the discovery response (`weather_current`). This ensures the server can correctly identify which tool to execute.
364
3652. **`arguments`**: Contains the input parameters as defined by the tool's `inputSchema`. In this example:
366 * `location`: "San Francisco" (required parameter)
367 * `units`: "imperial" (optional parameter, defaults to "metric" if not specified)
368
3693. **JSON-RPC Structure**: Uses standard JSON-RPC 2.0 format with unique `id` for request-response correlation.
370
371#### Understanding the Tool Execution Response
372
373The response demonstrates MCP's flexible content system:
374
3751. **`content` Array**: Tool responses return an array of content objects, allowing for rich, multi-format responses (text, images, resources, etc.)
376
3772. **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.
378
3793. **Structured Output**: The response provides actionable information that the AI application can use as context for language model interactions.
380
381This execution pattern allows AI applications to dynamically invoke server functionality and receive structured responses that can be integrated into conversations with language models.
382
383#### How This Works in AI Applications
384
385When 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.
386
387```python theme={null}
388# Pseudo-code for AI application tool execution
389async def handle_tool_call(conversation, tool_name, arguments):
390 session = app.find_mcp_session_for_tool(tool_name)
391 result = await session.call_tool(tool_name, arguments)
392 conversation.add_tool_result(result.content)
393```
394
395**4. Real-time Updates (Notifications)**
396
397MCP supports real-time notifications that enable servers to inform clients about changes without being explicitly requested. This demonstrates the notification system, a key feature that keeps MCP connections synchronized and responsive.
398
399#### Understanding Tool List Change Notifications
400
401When the server's available tools change—such as when new functionality becomes available, existing tools are modified, or tools become temporarily unavailable—the server can proactively notify connected clients:
402
403```json Request theme={null}
404{
405 "jsonrpc": "2.0",
406 "method": "notifications/tools/list_changed"
407}
408```
409
410#### Key Features of MCP Notifications
411
4121. **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.
413
4142. **Capability-Based**: This notification is only sent by servers that declared `"listChanged": true` in their tools capability during initialization (as shown in Step 1).
415
4163. **Event-Driven**: The server decides when to send notifications based on internal state changes, making MCP connections dynamic and responsive.
417
418#### Client Response to Notifications
419
420Upon 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:
421
422```json Request theme={null}
423{
424 "jsonrpc": "2.0",
425 "id": 4,
426 "method": "tools/list"
427}
428```
429
430#### Why Notifications Matter
431
432This notification system is crucial for several reasons:
433
4341. **Dynamic Environments**: Tools may come and go based on server state, external dependencies, or user permissions
4352. **Efficiency**: Clients don't need to poll for changes; they're notified when updates occur
4363. **Consistency**: Ensures clients always have accurate information about available server capabilities
4374. **Real-time Collaboration**: Enables responsive AI applications that can adapt to changing contexts
438
439This notification pattern extends beyond tools to other MCP primitives, enabling comprehensive real-time synchronization between clients and servers.
440
441#### How This Works in AI Applications
442
443When the AI application receives a notification about changed tools, 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.
444
445```python theme={null}
446# Pseudo-code for AI application notification handling
447async def handle_tools_changed_notification(session):
448 tools_response = await session.list_tools()
449 app.update_available_tools(session, tools_response.tools)
450 if app.conversation.is_active():
451 app.conversation.notify_llm_of_new_capabilities()
452```
461453
No line in this hunk matches that.