docs: add snippet verification for docs/ pages (#2115)
This commit is contained in:
parent
cfbbd7d71a
commit
1ef124e4a8
3 changed files with 446 additions and 43 deletions
|
|
@ -225,6 +225,7 @@ For OAuth 2.1 client authentication, see [Authorization](authorization.md#client
|
|||
|
||||
Clients can provide a `list_roots_callback` so that servers can discover the client's workspace roots (directories, project folders, etc.):
|
||||
|
||||
<!-- snippet-source examples/snippets/clients/roots_example.py -->
|
||||
```python
|
||||
from mcp import ClientSession, types
|
||||
from mcp.shared.context import RequestContext
|
||||
|
|
@ -250,6 +251,9 @@ session = ClientSession(
|
|||
)
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/clients/roots_example.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/clients/roots_example.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
When a `list_roots_callback` is provided, the client automatically declares the `roots` capability (with `listChanged=True`) during initialization.
|
||||
|
||||
### Roots Change Notifications
|
||||
|
|
@ -265,6 +269,7 @@ await session.send_roots_list_changed()
|
|||
|
||||
For servers that use the older SSE transport, use `sse_client()` from `mcp.client.sse`:
|
||||
|
||||
<!-- snippet-source examples/snippets/clients/sse_client.py -->
|
||||
```python
|
||||
import asyncio
|
||||
|
||||
|
|
@ -284,6 +289,9 @@ async def main():
|
|||
asyncio.run(main())
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/clients/sse_client.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/clients/sse_client.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
The `sse_client()` function accepts optional `headers`, `timeout`, `sse_read_timeout`, and `auth` parameters. The SSE transport is considered legacy; prefer [Streamable HTTP](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#streamable-http) for new servers.
|
||||
|
||||
## Ping
|
||||
|
|
@ -302,6 +310,7 @@ result = await session.send_ping()
|
|||
|
||||
Pass a `logging_callback` to receive log messages from the server:
|
||||
|
||||
<!-- snippet-source examples/snippets/clients/logging_client.py -->
|
||||
```python
|
||||
from mcp import ClientSession, types
|
||||
|
||||
|
|
@ -318,6 +327,9 @@ session = ClientSession(
|
|||
)
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/clients/logging_client.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/clients/logging_client.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
### Setting the Server Log Level
|
||||
|
||||
Request that the server change its minimum log level:
|
||||
|
|
|
|||
|
|
@ -42,22 +42,29 @@ Both return an `EmptyResult` on success. If the remote side does not respond wit
|
|||
|
||||
Either side can cancel a previously-issued request by sending a `CancelledNotification`:
|
||||
|
||||
<!-- snippet-source examples/snippets/clients/cancellation.py -->
|
||||
```python
|
||||
import mcp.types as types
|
||||
from mcp import ClientSession
|
||||
|
||||
# Send a cancellation notification
|
||||
await session.send_notification(
|
||||
types.ClientNotification(
|
||||
types.CancelledNotification(
|
||||
params=types.CancelledNotificationParams(
|
||||
requestId="request-id-to-cancel",
|
||||
reason="User navigated away",
|
||||
|
||||
async def cancel_request(session: ClientSession) -> None:
|
||||
"""Send a cancellation notification for a previously-issued request."""
|
||||
await session.send_notification(
|
||||
types.ClientNotification(
|
||||
types.CancelledNotification(
|
||||
params=types.CancelledNotificationParams(
|
||||
requestId="request-id-to-cancel",
|
||||
reason="User navigated away",
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/clients/cancellation.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/clients/cancellation.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
The `CancelledNotificationParams` fields:
|
||||
|
||||
- `requestId` (optional): The ID of the request to cancel. Required for non-task cancellations.
|
||||
|
|
@ -106,6 +113,7 @@ During initialization, the client sends `LATEST_PROTOCOL_VERSION`. If the server
|
|||
|
||||
MCP uses [JSON Schema 2020-12](https://json-schema.org/draft/2020-12) for tool input schemas, output schemas, and elicitation schemas. When using Pydantic models, schemas are generated automatically via `model_json_schema()`:
|
||||
|
||||
<!-- snippet-source examples/snippets/servers/json_schema_example.py -->
|
||||
```python
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
|
@ -132,6 +140,9 @@ schema = SearchParams.model_json_schema()
|
|||
# }
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/json_schema_example.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/servers/json_schema_example.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
For FastMCP tools, input schemas are derived automatically from function signatures. For structured output, the output schema is derived from the return type annotation.
|
||||
|
||||
## Pagination
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ _Full example: [examples/snippets/servers/basic_resource.py](https://github.com/
|
|||
|
||||
Resources with URI parameters (e.g., `{name}`) are registered as templates. When a client reads a templated resource, the URI parameters are extracted and passed to the function:
|
||||
|
||||
<!-- snippet-source examples/snippets/servers/resource_templates.py -->
|
||||
```python
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
|
|
@ -117,6 +118,9 @@ def get_user_profile(user_id: str) -> str:
|
|||
return f'{{"user_id": "{user_id}", "name": "User {user_id}"}}'
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/resource_templates.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/servers/resource_templates.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
Clients read a template resource by providing a concrete URI:
|
||||
|
||||
```python
|
||||
|
|
@ -137,6 +141,7 @@ def get_readme(owner: str, repo: str) -> str:
|
|||
|
||||
Resources can return binary data by returning `bytes` instead of `str`. Set the `mime_type` to indicate the content type:
|
||||
|
||||
<!-- snippet-source examples/snippets/servers/binary_resources.py -->
|
||||
```python
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
|
|
@ -150,14 +155,17 @@ def get_logo() -> bytes:
|
|||
return f.read()
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/binary_resources.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/servers/binary_resources.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
Binary content is automatically base64-encoded and returned as `BlobResourceContents` in the MCP response.
|
||||
|
||||
#### Resource Subscriptions
|
||||
|
||||
Clients can subscribe to resource updates. Use the low-level server API to handle subscription and unsubscription requests:
|
||||
|
||||
<!-- snippet-source examples/snippets/servers/resource_subscriptions.py -->
|
||||
```python
|
||||
import mcp.types as types
|
||||
from mcp.server.lowlevel import Server
|
||||
|
||||
server = Server("Subscription Example")
|
||||
|
|
@ -178,6 +186,9 @@ async def handle_unsubscribe(uri) -> None:
|
|||
subscriptions[str(uri)].discard("current_session")
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/resource_subscriptions.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/servers/resource_subscriptions.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
When a subscribed resource changes, notify clients with `send_resource_updated()`:
|
||||
|
||||
```python
|
||||
|
|
@ -468,6 +479,7 @@ _Full example: [examples/snippets/servers/basic_prompt.py](https://github.com/mo
|
|||
|
||||
Prompts can include embedded resources to provide file contents or data alongside the conversation messages:
|
||||
|
||||
<!-- snippet-source examples/snippets/servers/prompt_embedded_resources.py -->
|
||||
```python
|
||||
import mcp.types as types
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
|
@ -497,10 +509,14 @@ def review_file(filename: str) -> list[base.Message]:
|
|||
]
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/prompt_embedded_resources.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/servers/prompt_embedded_resources.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
#### Prompts with Image Content
|
||||
|
||||
Prompts can include images using `ImageContent` or the `Image` helper class:
|
||||
|
||||
<!-- snippet-source examples/snippets/servers/prompt_image_content.py -->
|
||||
```python
|
||||
import mcp.types as types
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
|
@ -524,10 +540,14 @@ def describe_image(image_path: str) -> list[base.Message]:
|
|||
]
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/prompt_image_content.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/servers/prompt_image_content.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
#### Prompt Change Notifications
|
||||
|
||||
When your server dynamically adds or removes prompts, notify connected clients:
|
||||
|
||||
<!-- snippet-source examples/snippets/servers/prompt_change_notifications.py -->
|
||||
```python
|
||||
from mcp.server.fastmcp import Context, FastMCP
|
||||
from mcp.server.session import ServerSession
|
||||
|
|
@ -543,6 +563,9 @@ async def update_prompts(ctx: Context[ServerSession, None]) -> str:
|
|||
return "Prompts updated"
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/prompt_change_notifications.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/servers/prompt_change_notifications.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
### Icons
|
||||
|
||||
MCP servers can provide icons for UI display. Icons can be added to the server implementation, tools, resources, and prompts:
|
||||
|
|
@ -608,6 +631,7 @@ _Full example: [examples/snippets/servers/images.py](https://github.com/modelcon
|
|||
|
||||
FastMCP provides an `Audio` class for returning audio data from tools, similar to `Image`:
|
||||
|
||||
<!-- snippet-source examples/snippets/servers/audio_example.py -->
|
||||
```python
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from mcp.server.fastmcp.utilities.types import Audio
|
||||
|
|
@ -627,12 +651,16 @@ def get_audio_from_bytes(raw_audio: bytes) -> Audio:
|
|||
return Audio(data=raw_audio, format="wav")
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/audio_example.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/servers/audio_example.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
The `Audio` class accepts `path` or `data` (mutually exclusive) and an optional `format` string. Supported formats include `wav`, `mp3`, `ogg`, `flac`, `aac`, and `m4a`. When using a file path, the MIME type is inferred from the file extension.
|
||||
|
||||
### Embedded Resource Results
|
||||
|
||||
Tools can return `EmbeddedResource` to attach file contents or data inline in the result:
|
||||
|
||||
<!-- snippet-source examples/snippets/servers/embedded_resource_results.py -->
|
||||
```python
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from mcp.types import EmbeddedResource, TextResourceContents
|
||||
|
|
@ -655,13 +683,20 @@ def read_config(path: str) -> EmbeddedResource:
|
|||
)
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/embedded_resource_results.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/servers/embedded_resource_results.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
For binary embedded resources, use `BlobResourceContents` with base64-encoded data:
|
||||
|
||||
<!-- snippet-source examples/snippets/servers/embedded_resource_results_binary.py -->
|
||||
```python
|
||||
import base64
|
||||
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from mcp.types import BlobResourceContents, EmbeddedResource
|
||||
|
||||
mcp = FastMCP("Binary Embedded Resource Example")
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def read_binary_file(path: str) -> EmbeddedResource:
|
||||
|
|
@ -678,10 +713,14 @@ def read_binary_file(path: str) -> EmbeddedResource:
|
|||
)
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/embedded_resource_results_binary.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/servers/embedded_resource_results_binary.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
### Tool Change Notifications
|
||||
|
||||
When your server dynamically adds or removes tools at runtime, notify connected clients so they can refresh their tool list:
|
||||
|
||||
<!-- snippet-source examples/snippets/servers/tool_change_notifications.py -->
|
||||
```python
|
||||
from mcp.server.fastmcp import Context, FastMCP
|
||||
from mcp.server.session import ServerSession
|
||||
|
|
@ -700,6 +739,9 @@ async def register_plugin(name: str, ctx: Context[ServerSession, None]) -> str:
|
|||
return f"Plugin '{name}' registered"
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/tool_change_notifications.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/servers/tool_change_notifications.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
### Context
|
||||
|
||||
The Context object is automatically injected into tool and resource functions that request it via type hints. It provides access to MCP capabilities like logging, progress reporting, resource reading, user interaction, and request metadata.
|
||||
|
|
@ -978,6 +1020,7 @@ The `elicit()` method returns an `ElicitationResult` with:
|
|||
|
||||
To present a dropdown or selection list in elicitation forms, use `json_schema_extra` with an `enum` key on a `str` field. Do not use `Literal` -- use a plain `str` field with the enum constraint in the JSON schema:
|
||||
|
||||
<!-- snippet-source examples/snippets/servers/elicitation_enum.py -->
|
||||
```python
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
|
@ -1006,10 +1049,14 @@ async def pick_color(ctx: Context[ServerSession, None]) -> str:
|
|||
return "No color selected"
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/elicitation_enum.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/servers/elicitation_enum.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
#### Elicitation Complete Notification
|
||||
|
||||
For URL mode elicitations, send a completion notification after the out-of-band interaction finishes. This tells the client that the elicitation is done and it may retry any blocked requests:
|
||||
|
||||
<!-- snippet-source examples/snippets/servers/elicitation_complete.py -->
|
||||
```python
|
||||
from mcp.server.fastmcp import Context, FastMCP
|
||||
from mcp.server.session import ServerSession
|
||||
|
|
@ -1018,9 +1065,7 @@ mcp = FastMCP("Elicit Complete Example")
|
|||
|
||||
|
||||
@mcp.tool()
|
||||
async def handle_oauth_callback(
|
||||
elicitation_id: str, ctx: Context[ServerSession, None]
|
||||
) -> str:
|
||||
async def handle_oauth_callback(elicitation_id: str, ctx: Context[ServerSession, None]) -> str:
|
||||
"""Called when OAuth flow completes out-of-band."""
|
||||
# ... process the callback ...
|
||||
|
||||
|
|
@ -1030,6 +1075,9 @@ async def handle_oauth_callback(
|
|||
return "Authorization complete"
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/elicitation_complete.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/servers/elicitation_complete.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
### Sampling
|
||||
|
||||
Tools can interact with LLMs through sampling (generating text):
|
||||
|
|
@ -1101,6 +1149,7 @@ _Full example: [examples/snippets/servers/notifications.py](https://github.com/m
|
|||
|
||||
Clients can request a minimum logging level via `logging/setLevel`. Use the low-level server API to handle this:
|
||||
|
||||
<!-- snippet-source examples/snippets/servers/set_logging_level.py -->
|
||||
```python
|
||||
import mcp.types as types
|
||||
from mcp.server.lowlevel import Server
|
||||
|
|
@ -1117,6 +1166,9 @@ async def handle_set_level(level: types.LoggingLevel) -> None:
|
|||
current_level = level
|
||||
```
|
||||
|
||||
_Full example: [examples/snippets/servers/set_logging_level.py](https://github.com/modelcontextprotocol/python-sdk/blob/v1.x/examples/snippets/servers/set_logging_level.py)_
|
||||
<!-- /snippet-source -->
|
||||
|
||||
When this handler is registered, the server automatically declares the `logging` capability during initialization.
|
||||
|
||||
### Authentication
|
||||
|
|
|
|||
Loading…
Reference in a new issue