"""Run from the repository root: uv run examples/snippets/servers/lowlevel/structured_output.py """ import asyncio from typing import Any import mcp.server.stdio import mcp.types as types from mcp.server.lowlevel import NotificationOptions, Server from mcp.server.models import InitializationOptions server = Server("example-server") @server.list_tools() async def list_tools() -> list[types.Tool]: """List available tools with structured output schemas.""" return [ types.Tool( name="get_weather", description="Get current weather for a city", input_schema={ "type": "object", "properties": {"city": {"type": "string", "description": "City name"}}, "required": ["city"], }, output_schema={ "type": "object", "properties": { "temperature": {"type": "number", "description": "Temperature in Celsius"}, "condition": {"type": "string", "description": "Weather condition"}, "humidity": {"type": "number", "description": "Humidity percentage"}, "city": {"type": "string", "description": "City name"}, }, "required": ["temperature", "condition", "humidity", "city"], }, ) ] @server.call_tool() async def call_tool(name: str, arguments: dict[str, Any]) -> dict[str, Any]: """Handle tool calls with structured output.""" if name == "get_weather": city = arguments["city"] # Simulated weather data - in production, call a weather API weather_data = { "temperature": 22.5, "condition": "partly cloudy", "humidity": 65, "city": city, # Include the requested city } # low-level server will validate structured output against the tool's # output schema, and additionally serialize it into a TextContent block # for backwards compatibility with pre-2025-06-18 clients. return weather_data else: raise ValueError(f"Unknown tool: {name}") async def run(): """Run the structured output server.""" async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): await server.run( read_stream, write_stream, InitializationOptions( server_name="structured-output-example", server_version="0.1.0", capabilities=server.get_capabilities( notification_options=NotificationOptions(), experimental_capabilities={}, ), ), ) if __name__ == "__main__": asyncio.run(run())