| 
44 | 44 |   - [Advanced Usage](#advanced-usage)  | 
45 | 45 |     - [Low-Level Server](#low-level-server)  | 
46 | 46 |     - [Writing MCP Clients](#writing-mcp-clients)  | 
 | 47 | +    - [Parsing Tool Results](#parsing-tool-results)  | 
47 | 48 |     - [MCP Primitives](#mcp-primitives)  | 
48 | 49 |     - [Server Capabilities](#server-capabilities)  | 
49 | 50 |   - [Documentation](#documentation)  | 
@@ -1418,12 +1419,18 @@ async def run():  | 
1418 | 1419 |                 elif isinstance(item, types.EmbeddedResource):  | 
1419 | 1420 |                     # Check if the embedded resource contains text  | 
1420 | 1421 |                     if isinstance(item.resource, types.TextResourceContents):  | 
1421 |  | -                        print(f"Tool output (EmbeddedResource - Text): {item.resource.text}")  | 
 | 1422 | +                        print(  | 
 | 1423 | +                            f"Tool output (EmbeddedResource - Text): {item.resource.text}"  | 
 | 1424 | +                        )  | 
1422 | 1425 |                     elif isinstance(item.resource, types.BlobResourceContents):  | 
1423 |  | -                        print(f"Tool output (EmbeddedResource - Blob): URI {item.resource.uri}, MIME Type {item.resource.mimeType}")  | 
 | 1426 | +                        print(  | 
 | 1427 | +                            f"Tool output (EmbeddedResource - Blob): URI {item.resource.uri}, MIME Type {item.resource.mimeType}"  | 
 | 1428 | +                        )  | 
1424 | 1429 |                 elif isinstance(item, types.ImageContent):  | 
1425 | 1430 |                     # Showing only a snippet of image data  | 
1426 |  | -                    print(f"Tool output (ImageContent): MIME Type {item.mimeType}, Data (base64): {item.data[:30]}...")  | 
 | 1431 | +                    print(  | 
 | 1432 | +                        f"Tool output (ImageContent): MIME Type {item.mimeType}, Data (base64): {item.data[:30]}..."  | 
 | 1433 | +                    )  | 
1427 | 1434 |                 else:  | 
1428 | 1435 |                     print(f"Tool output (Unknown Content Type): {type(item)}")  | 
1429 | 1436 | 
 
  | 
@@ -1480,12 +1487,18 @@ async def main():  | 
1480 | 1487 |                 elif isinstance(item, types.EmbeddedResource):  | 
1481 | 1488 |                     # Check if the embedded resource contains text  | 
1482 | 1489 |                     if isinstance(item.resource, types.TextResourceContents):  | 
1483 |  | -                        print(f"Tool output (EmbeddedResource - Text): {item.resource.text}")  | 
 | 1490 | +                        print(  | 
 | 1491 | +                            f"Tool output (EmbeddedResource - Text): {item.resource.text}"  | 
 | 1492 | +                        )  | 
1484 | 1493 |                     elif isinstance(item.resource, types.BlobResourceContents):  | 
1485 |  | -                        print(f"Tool output (EmbeddedResource - Blob): URI {item.resource.uri}, MIME Type {item.resource.mimeType}")  | 
 | 1494 | +                        print(  | 
 | 1495 | +                            f"Tool output (EmbeddedResource - Blob): URI {item.resource.uri}, MIME Type {item.resource.mimeType}"  | 
 | 1496 | +                        )  | 
1486 | 1497 |                 elif isinstance(item, types.ImageContent):  | 
1487 | 1498 |                     # Showing only a snippet of image data  | 
1488 |  | -                    print(f"Tool output (ImageContent): MIME Type {item.mimeType}, Data (base64): {item.data[:30]}...")  | 
 | 1499 | +                    print(  | 
 | 1500 | +                        f"Tool output (ImageContent): MIME Type {item.mimeType}, Data (base64): {item.data[:30]}..."  | 
 | 1501 | +                    )  | 
1489 | 1502 |                 else:  | 
1490 | 1503 |                     print(f"Tool output (Unknown Content Type): {type(item)}")  | 
1491 | 1504 | 
 
  | 
@@ -1635,6 +1648,74 @@ async def main():  | 
1635 | 1648 | 
 
  | 
1636 | 1649 | For a complete working example, see [`examples/clients/simple-auth-client/`](examples/clients/simple-auth-client/).  | 
1637 | 1650 | 
 
  | 
 | 1651 | +### Parsing Tool Results  | 
 | 1652 | + | 
 | 1653 | +When calling tools through MCP, the `CallToolResult` object contains the tool's response in a structured format. Understanding how to parse this result is essential for properly handling tool outputs.  | 
 | 1654 | + | 
 | 1655 | +```python  | 
 | 1656 | +"""examples/snippets/clients/parsing_tool_results.py"""  | 
 | 1657 | + | 
 | 1658 | +import asyncio  | 
 | 1659 | + | 
 | 1660 | +from mcp import ClientSession, StdioServerParameters, types  | 
 | 1661 | +from mcp.client.stdio import stdio_client  | 
 | 1662 | + | 
 | 1663 | + | 
 | 1664 | +async def parse_tool_results():  | 
 | 1665 | +    """Demonstrates how to parse different types of content in CallToolResult."""  | 
 | 1666 | +    server_params = StdioServerParameters(  | 
 | 1667 | +        command="python", args=["path/to/mcp_server.py"]  | 
 | 1668 | +    )  | 
 | 1669 | + | 
 | 1670 | +    async with stdio_client(server_params) as (read, write):  | 
 | 1671 | +        async with ClientSession(read, write) as session:  | 
 | 1672 | +            await session.initialize()  | 
 | 1673 | + | 
 | 1674 | +            # Example 1: Parsing text content  | 
 | 1675 | +            result = await session.call_tool("get_data", {"format": "text"})  | 
 | 1676 | +            for content in result.content:  | 
 | 1677 | +                if isinstance(content, types.TextContent):  | 
 | 1678 | +                    print(f"Text: {content.text}")  | 
 | 1679 | + | 
 | 1680 | +            # Example 2: Parsing structured content from JSON tools  | 
 | 1681 | +            result = await session.call_tool("get_user", {"id": "123"})  | 
 | 1682 | +            if hasattr(result, "structuredContent") and result.structuredContent:  | 
 | 1683 | +                # Access structured data directly  | 
 | 1684 | +                user_data = result.structuredContent  | 
 | 1685 | +                print(f"User: {user_data.get('name')}, Age: {user_data.get('age')}")  | 
 | 1686 | + | 
 | 1687 | +            # Example 3: Parsing embedded resources  | 
 | 1688 | +            result = await session.call_tool("read_config", {})  | 
 | 1689 | +            for content in result.content:  | 
 | 1690 | +                if isinstance(content, types.EmbeddedResource):  | 
 | 1691 | +                    resource = content.resource  | 
 | 1692 | +                    if isinstance(resource, types.TextResourceContents):  | 
 | 1693 | +                        print(f"Config from {resource.uri}: {resource.text}")  | 
 | 1694 | +                    elif isinstance(resource, types.BlobResourceContents):  | 
 | 1695 | +                        print(f"Binary data from {resource.uri}")  | 
 | 1696 | + | 
 | 1697 | +            # Example 4: Parsing image content  | 
 | 1698 | +            result = await session.call_tool("generate_chart", {"data": [1, 2, 3]})  | 
 | 1699 | +            for content in result.content:  | 
 | 1700 | +                if isinstance(content, types.ImageContent):  | 
 | 1701 | +                    print(f"Image ({content.mimeType}): {len(content.data)} bytes")  | 
 | 1702 | + | 
 | 1703 | +            # Example 5: Handling errors  | 
 | 1704 | +            result = await session.call_tool("failing_tool", {})  | 
 | 1705 | +            if result.isError:  | 
 | 1706 | +                print("Tool execution failed!")  | 
 | 1707 | +                for content in result.content:  | 
 | 1708 | +                    if isinstance(content, types.TextContent):  | 
 | 1709 | +                        print(f"Error: {content.text}")  | 
 | 1710 | + | 
 | 1711 | + | 
 | 1712 | +async def main():  | 
 | 1713 | +    await parse_tool_results()  | 
 | 1714 | + | 
 | 1715 | + | 
 | 1716 | +if __name__ == "__main__":  | 
 | 1717 | +    asyncio.run(main())  | 
 | 1718 | +```  | 
1638 | 1719 | ### MCP Primitives  | 
1639 | 1720 | 
 
  | 
1640 | 1721 | The MCP protocol defines three core primitives that servers can implement:  | 
 | 
0 commit comments