diff --git a/docs/concepts.md b/docs/concepts.md index a2d6eb8d3..8495296fe 100644 --- a/docs/concepts.md +++ b/docs/concepts.md @@ -11,3 +11,99 @@ - Context and sessions - Lifecycle and state --> + +## Server Instructions + +When a server initializes, it can send instructions to the client explaining how the tools can be used as a collective group, this can be thought of like an instructions manual for the consumer of a given server. + +### Basic Usage + +Here's how you add instructions to your server: + +```python title="server.py" +from mcp.server.fastmcp import FastMCP + +mcp = FastMCP( + name="Weather & Calendar", + instructions=""" +# How to use this server + +## Weather Tools +- get_weather: Current conditions +- get_forecast: Future predictions + +## Calendar Tools +- list_events: View your calendar +- create_event: Schedule something + +tip: Check the weather forecast before scheduling outdoor events +""" +) + +@mcp.tool() +def get_weather(location: str) -> dict: + """Get current weather""" + return {"temp": 72, "condition": "sunny"} + +@mcp.tool() +def create_event(title: str, date: str) -> dict: + """Schedule an event""" + return {"id": "evt_123", "title": title, "date": date} +``` + +1. Instructions support Markdown formatting for better readability. + +!!! info + The `instructions` field is part of the `InitializeResult` that clients receive during the connection handshake. It's optional, but super helpful when you have multiple related tools. + +### When to Use Instructions + +Instructions are shown to both humans (in client UIs like MCP Inspector) and LLMs (as context for tool selection). They work best when you have multiple related tools and need to explain how they work together. + +Use instructions when: + +- Your server has tools from different domains (like weather + calendar) +- Tools should be used in a specific order or sequence +- You need to share constraints or best practices + +They're **not** for documenting individual tool parameters - use docstrings for that. + +### Writing Good Instructions + +Focus on tool relationships and workflows, not individual tool details: + +```python title="good_instructions.py" +instructions = """ +## File Operations +- read_file: Load file contents +- write_file: Save to disk + +Always use read_file before write_file to avoid overwriting data. + +## Rate Limits +- API calls: 100/hour +- File operations: No limit +""" +``` + +Keep them concise (10-30 lines) and use Markdown headers to group related tools. + +!!! info + Access instructions from tools using `ctx.fastmcp.instructions` to expose them programmatically. + +### Low-Level Server + +If you're using the low-level server API, you set instructions the same way: + +```python +from mcp.server.lowlevel import Server + +server = Server( + name="My Server", + instructions="Your usage guide here..." +) +``` + +### Complete Example + +For a full working example showing instructions with a multi-domain server, check out [examples/snippets/servers/server_instructions.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/server_instructions.py). diff --git a/examples/snippets/servers/server_instructions.py b/examples/snippets/servers/server_instructions.py new file mode 100644 index 000000000..39b82a3e7 --- /dev/null +++ b/examples/snippets/servers/server_instructions.py @@ -0,0 +1,65 @@ +""" +Example showing how to use server instructions to guide tool usage. + +The instructions field helps clients understand how to use your tools +together, effectively providing tool grouping/bundling/namespacing. + +cd to the `examples/snippets` directory and run: + uv run server server_instructions stdio +""" + +from typing import Any + +from mcp.server.fastmcp import FastMCP + +# Create server with instructions +mcp = FastMCP( + name="Multi-Domain Server", + instructions="""This server provides tools across multiple domains: + +## Weather Tools +- get_weather: Get current weather for a location +- get_forecast: Get weather forecast + +These tools work together - use get_weather for current conditions, +then get_forecast for future planning. + +## Calendar Tools +- create_event: Schedule a new calendar event +- list_events: View upcoming events + +Use list_events first to check availability before create_event. + +## Best Practices +- Always check weather before scheduling outdoor events +- Use get_forecast to plan events 2-7 days ahead +""", +) + + +# Define the tools mentioned in instructions +@mcp.tool() +def get_weather(location: str) -> dict[str, Any]: + """Get current weather for a location""" + return {"location": location, "temperature": 72, "condition": "sunny", "humidity": 45} + + +@mcp.tool() +def get_forecast(location: str, days: int = 5) -> list[dict[str, Any]]: + """Get weather forecast for upcoming days""" + return [{"day": i, "high": 70 + i, "low": 50 + i, "condition": "partly cloudy"} for i in range(days)] + + +@mcp.tool() +def create_event(title: str, date: str, time: str) -> dict[str, Any]: + """Schedule a new calendar event""" + return {"id": "evt_123", "title": title, "date": date, "time": time, "status": "created"} + + +@mcp.tool() +def list_events(start_date: str, end_date: str) -> list[dict[str, Any]]: + """View upcoming events in date range""" + return [ + {"title": "Team Meeting", "date": start_date, "time": "10:00"}, + {"title": "Lunch with Client", "date": start_date, "time": "12:00"}, + ]