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