mirror of
https://github.com/aljazceru/mcp-python-sdk.git
synced 2025-12-21 15:54:28 +01:00
docs: Update README with new structure and content
This commit is contained in:
206
README.md
206
README.md
@@ -1,4 +1,9 @@
|
|||||||
# MCP Python SDK
|
# MCP Python SDK
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
<strong>Python implementation of the Model Context Protocol (MCP)</strong>
|
||||||
|
|
||||||
[![PyPI][pypi-badge]][pypi-url]
|
[![PyPI][pypi-badge]][pypi-url]
|
||||||
[![MIT licensed][mit-badge]][mit-url]
|
[![MIT licensed][mit-badge]][mit-url]
|
||||||
[![Python Version][python-badge]][python-url]
|
[![Python Version][python-badge]][python-url]
|
||||||
@@ -6,6 +11,23 @@
|
|||||||
[![Specification][spec-badge]][spec-url]
|
[![Specification][spec-badge]][spec-url]
|
||||||
[![GitHub Discussions][discussions-badge]][discussions-url]
|
[![GitHub Discussions][discussions-badge]][discussions-url]
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- omit in toc -->
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Overview](#overview)
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [Writing MCP Servers](#writing-mcp-servers)
|
||||||
|
- [FastMCP (Recommended)](#fastmcp-recommended)
|
||||||
|
- [Low-Level Server (Advanced)](#low-level-server-advanced)
|
||||||
|
- [Writing MCP Clients](#writing-mcp-clients)
|
||||||
|
- [MCP Primitives](#mcp-primitives)
|
||||||
|
- [Server Capabilities](#server-capabilities)
|
||||||
|
- [Documentation](#documentation)
|
||||||
|
- [Contributing](#contributing)
|
||||||
|
- [License](#license)
|
||||||
|
|
||||||
[pypi-badge]: https://img.shields.io/pypi/v/mcp.svg
|
[pypi-badge]: https://img.shields.io/pypi/v/mcp.svg
|
||||||
[pypi-url]: https://pypi.org/project/mcp/
|
[pypi-url]: https://pypi.org/project/mcp/
|
||||||
[mit-badge]: https://img.shields.io/pypi/l/mcp.svg
|
[mit-badge]: https://img.shields.io/pypi/l/mcp.svg
|
||||||
@@ -19,7 +41,6 @@
|
|||||||
[discussions-badge]: https://img.shields.io/github/discussions/modelcontextprotocol/python-sdk
|
[discussions-badge]: https://img.shields.io/github/discussions/modelcontextprotocol/python-sdk
|
||||||
[discussions-url]: https://github.com/modelcontextprotocol/python-sdk/discussions
|
[discussions-url]: https://github.com/modelcontextprotocol/python-sdk/discussions
|
||||||
|
|
||||||
Python implementation of the [Model Context Protocol](https://modelcontextprotocol.io) (MCP), providing both client and server capabilities for integrating with LLM surfaces.
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
@@ -45,35 +66,13 @@ pip install mcp
|
|||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
## Overview
|
## Writing MCP Servers
|
||||||
MCP servers provide focused functionality like resources, tools, prompts, and other capabilities that can be reused across many client applications. These servers are designed to be easy to build, highly composable, and modular.
|
|
||||||
|
|
||||||
### Key design principles
|
The MCP Python SDK provides two ways to implement servers:
|
||||||
- Servers are extremely easy to build with clear, simple interfaces
|
|
||||||
- Multiple servers can be composed seamlessly through a shared protocol
|
|
||||||
- Each server operates in isolation and cannot access conversation context
|
|
||||||
- Features can be added progressively through capability negotiation
|
|
||||||
|
|
||||||
### Server provided primitives
|
### FastMCP (Recommended)
|
||||||
- [Prompts](https://modelcontextprotocol.io/docs/concepts/prompts): Templatable text
|
|
||||||
- [Resources](https://modelcontextprotocol.io/docs/concepts/resources): File-like attachments
|
|
||||||
- [Tools](https://modelcontextprotocol.io/docs/concepts/tools): Functions that models can call
|
|
||||||
- Utilities:
|
|
||||||
- Completion: Auto-completion provider for prompt arguments or resource URI templates
|
|
||||||
- Logging: Logging to the client
|
|
||||||
- Pagination*: Pagination for long results
|
|
||||||
|
|
||||||
### Client provided primitives
|
FastMCP provides a high-level, Pythonic interface for building MCP servers quickly and easily. It handles all the complex protocol details so you can focus on building great tools:
|
||||||
- [Sampling](https://modelcontextprotocol.io/docs/concepts/sampling): Allow servers to sample using client models
|
|
||||||
- Roots: Information about locations to operate on (e.g., directories)
|
|
||||||
|
|
||||||
Connections between clients and servers are established through transports like **stdio** or **SSE** (Note that most clients support stdio, but not SSE at the moment). The transport layer handles message framing, delivery, and error handling.
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
### FastMCP
|
|
||||||
|
|
||||||
The fastest way to build MCP servers is with FastMCP, which provides a high-level, Pythonic interface:
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
@@ -91,13 +90,17 @@ def get_greeting(name: str) -> str:
|
|||||||
return f"Hello, {name}!"
|
return f"Hello, {name}!"
|
||||||
```
|
```
|
||||||
|
|
||||||
FastMCP handles all the complex protocol details and server management, so you can focus on building great tools. It's designed to be high-level and Pythonic - in most cases, decorating a function is all you need.
|
FastMCP features:
|
||||||
|
- Simple, decorator-based API
|
||||||
|
- Automatic type handling and validation
|
||||||
|
- Built-in support for async functions
|
||||||
|
- Progress reporting and logging
|
||||||
|
- Resource templating
|
||||||
|
- Image handling
|
||||||
|
|
||||||
FastMCP was originally developed by Jeremiah Lowin at [jlowin/fastmcp](https://github.com/jlowin/fastmcp). We are grateful for his contribution in developing this excellent framework that has now been integrated into MCP.
|
### Low-Level Server (Advanced)
|
||||||
|
|
||||||
### Low-Level Implementation
|
For more control, you can use the low-level server implementation directly. This gives you full access to the protocol and allows you to customize every aspect of your server:
|
||||||
|
|
||||||
For more control, you can use the low-level MCP implementation directly. This gives you full access to the protocol and allows you to customize every aspect of your server. We recommend using `mcp.server.lowlevel` for all low-level server implementations, as the direct `mcp.server` imports will be deprecated and removed in SDK 2.0.0.
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from mcp.server.lowlevel import Server, NotificationOptions
|
from mcp.server.lowlevel import Server, NotificationOptions
|
||||||
@@ -108,7 +111,6 @@ import mcp.types as types
|
|||||||
# Create a server instance
|
# Create a server instance
|
||||||
server = Server("example-server")
|
server = Server("example-server")
|
||||||
|
|
||||||
# Add prompt capabilities
|
|
||||||
@server.list_prompts()
|
@server.list_prompts()
|
||||||
async def handle_list_prompts() -> list[types.Prompt]:
|
async def handle_list_prompts() -> list[types.Prompt]:
|
||||||
return [
|
return [
|
||||||
@@ -147,7 +149,6 @@ async def handle_get_prompt(
|
|||||||
)
|
)
|
||||||
|
|
||||||
async def run():
|
async def run():
|
||||||
# Run the server as STDIO
|
|
||||||
async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
|
async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
|
||||||
await server.run(
|
await server.run(
|
||||||
read_stream,
|
read_stream,
|
||||||
@@ -167,9 +168,9 @@ if __name__ == "__main__":
|
|||||||
asyncio.run(run())
|
asyncio.run(run())
|
||||||
```
|
```
|
||||||
|
|
||||||
### Creating a Client
|
## Writing MCP Clients
|
||||||
|
|
||||||
**example_client.py**
|
The SDK provides a high-level client interface for connecting to MCP servers:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from mcp import ClientSession, StdioServerParameters
|
from mcp import ClientSession, StdioServerParameters
|
||||||
@@ -188,17 +189,12 @@ async def run():
|
|||||||
# Initialize the connection
|
# Initialize the connection
|
||||||
await session.initialize()
|
await session.initialize()
|
||||||
|
|
||||||
# The example server only supports prompt primitives:
|
|
||||||
|
|
||||||
# List available prompts
|
# List available prompts
|
||||||
prompts = await session.list_prompts()
|
prompts = await session.list_prompts()
|
||||||
|
|
||||||
# Get a prompt
|
# Get a prompt
|
||||||
prompt = await session.get_prompt("example-prompt", arguments={"arg1": "value"})
|
prompt = await session.get_prompt("example-prompt", arguments={"arg1": "value"})
|
||||||
|
|
||||||
"""
|
|
||||||
Other example calls include:
|
|
||||||
|
|
||||||
# List available resources
|
# List available resources
|
||||||
resources = await session.list_resources()
|
resources = await session.list_resources()
|
||||||
|
|
||||||
@@ -210,16 +206,15 @@ async def run():
|
|||||||
|
|
||||||
# Call a tool
|
# Call a tool
|
||||||
result = await session.call_tool("tool-name", arguments={"arg1": "value"})
|
result = await session.call_tool("tool-name", arguments={"arg1": "value"})
|
||||||
"""
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import asyncio
|
import asyncio
|
||||||
asyncio.run(run())
|
asyncio.run(run())
|
||||||
```
|
```
|
||||||
|
|
||||||
## Primitives
|
## MCP Primitives
|
||||||
|
|
||||||
The MCP Python SDK provides decorators that map to the core protocol primitives. Each primitive follows a different interaction pattern based on how it is controlled and used:
|
The MCP protocol defines three core primitives that servers can implement:
|
||||||
|
|
||||||
| Primitive | Control | Description | Example Use |
|
| Primitive | Control | Description | Example Use |
|
||||||
|-----------|-----------------------|-----------------------------------------------------|------------------------------|
|
|-----------|-----------------------|-----------------------------------------------------|------------------------------|
|
||||||
@@ -227,122 +222,17 @@ The MCP Python SDK provides decorators that map to the core protocol primitives.
|
|||||||
| Resources | Application-controlled| Contextual data managed by the client application | File contents, API responses |
|
| Resources | Application-controlled| Contextual data managed by the client application | File contents, API responses |
|
||||||
| Tools | Model-controlled | Functions exposed to the LLM to take actions | API calls, data updates |
|
| Tools | Model-controlled | Functions exposed to the LLM to take actions | API calls, data updates |
|
||||||
|
|
||||||
### User-Controlled Primitives
|
### Server Capabilities
|
||||||
|
|
||||||
**Prompts** are designed to be explicitly selected by users for their interactions with LLMs.
|
MCP servers declare capabilities during initialization:
|
||||||
|
|
||||||
| Decorator | Description |
|
| Capability | Feature Flag | Description |
|
||||||
|--------------------------|----------------------------------------|
|
|-------------|------------------------------|------------------------------------|
|
||||||
| `@server.list_prompts()` | List available prompt templates |
|
| `prompts` | `listChanged` | Prompt template management |
|
||||||
| `@server.get_prompt()` | Get a specific prompt with arguments |
|
| `resources` | `subscribe`<br/>`listChanged`| Resource exposure and updates |
|
||||||
|
| `tools` | `listChanged` | Tool discovery and execution |
|
||||||
### Application-Controlled Primitives
|
| `logging` | - | Server logging configuration |
|
||||||
|
| `completion`| - | Argument completion suggestions |
|
||||||
**Resources** are controlled by the client application, which decides how and when they should be used based on its own logic.
|
|
||||||
|
|
||||||
| Decorator | Description |
|
|
||||||
|--------------------------------|---------------------------------------|
|
|
||||||
| `@server.list_resources()` | List available resources |
|
|
||||||
| `@server.read_resource()` | Read a specific resource's content |
|
|
||||||
| `@server.subscribe_resource()` | Subscribe to resource updates |
|
|
||||||
|
|
||||||
### Model-Controlled Primitives
|
|
||||||
|
|
||||||
**Tools** are exposed to LLMs to enable automated actions, with user approval.
|
|
||||||
|
|
||||||
| Decorator | Description |
|
|
||||||
|------------------------|------------------------------------|
|
|
||||||
| `@server.list_tools()` | List available tools |
|
|
||||||
| `@server.call_tool()` | Execute a tool with arguments |
|
|
||||||
|
|
||||||
### Server Management
|
|
||||||
|
|
||||||
Additional decorators for server functionality:
|
|
||||||
|
|
||||||
| Decorator | Description |
|
|
||||||
|-------------------------------|--------------------------------|
|
|
||||||
| `@server.set_logging_level()` | Update server logging level |
|
|
||||||
|
|
||||||
### Capabilities
|
|
||||||
|
|
||||||
MCP servers declare capabilities during initialization. These map to specific decorators:
|
|
||||||
|
|
||||||
| Capability | Feature Flag | Decorators | Description |
|
|
||||||
|-------------|------------------------------|-----------------------------------------------------------------|-------------------------------------|
|
|
||||||
| `prompts` | `listChanged` | `@list_prompts`<br/>`@get_prompt` | Prompt template management |
|
|
||||||
| `resources` | `subscribe`<br/>`listChanged`| `@list_resources`<br/>`@read_resource`<br/>`@subscribe_resource`| Resource exposure and updates |
|
|
||||||
| `tools` | `listChanged` | `@list_tools`<br/>`@call_tool` | Tool discovery and execution |
|
|
||||||
| `logging` | - | `@set_logging_level` | Server logging configuration |
|
|
||||||
| `completion`| - | `@complete_argument` | Argument completion suggestions |
|
|
||||||
|
|
||||||
Capabilities are negotiated during connection initialization. Servers only need to implement the decorators for capabilities they support.
|
|
||||||
|
|
||||||
## Client Interaction
|
|
||||||
|
|
||||||
The MCP Python SDK enables servers to interact with clients through request context and session management. This allows servers to perform operations like LLM sampling and progress tracking.
|
|
||||||
|
|
||||||
### Request Context
|
|
||||||
|
|
||||||
The Request Context provides access to the current request and client session. It can be accessed through `server.request_context` and enables:
|
|
||||||
|
|
||||||
- Sampling from the client's LLM
|
|
||||||
- Sending progress updates
|
|
||||||
- Logging messages
|
|
||||||
- Accessing request metadata
|
|
||||||
|
|
||||||
Example using request context for LLM sampling:
|
|
||||||
|
|
||||||
```python
|
|
||||||
@server.call_tool()
|
|
||||||
async def handle_call_tool(name: str, arguments: dict) -> list[types.TextContent]:
|
|
||||||
# Access the current request context
|
|
||||||
context = server.request_context
|
|
||||||
|
|
||||||
# Use the session to sample from the client's LLM
|
|
||||||
result = await context.session.create_message(
|
|
||||||
messages=[
|
|
||||||
types.SamplingMessage(
|
|
||||||
role="user",
|
|
||||||
content=types.TextContent(
|
|
||||||
type="text",
|
|
||||||
text="Analyze this data: " + json.dumps(arguments)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
],
|
|
||||||
max_tokens=100
|
|
||||||
)
|
|
||||||
|
|
||||||
return [types.TextContent(type="text", text=result.content.text)]
|
|
||||||
```
|
|
||||||
|
|
||||||
Using request context for progress updates:
|
|
||||||
|
|
||||||
```python
|
|
||||||
@server.call_tool()
|
|
||||||
async def handle_call_tool(name: str, arguments: dict) -> list[types.TextContent]:
|
|
||||||
context = server.request_context
|
|
||||||
|
|
||||||
if progress_token := context.meta.progressToken:
|
|
||||||
# Send progress notifications
|
|
||||||
await context.session.send_progress_notification(
|
|
||||||
progress_token=progress_token,
|
|
||||||
progress=0.5,
|
|
||||||
total=1.0
|
|
||||||
)
|
|
||||||
|
|
||||||
# Perform operation...
|
|
||||||
|
|
||||||
if progress_token:
|
|
||||||
await context.session.send_progress_notification(
|
|
||||||
progress_token=progress_token,
|
|
||||||
progress=1.0,
|
|
||||||
total=1.0
|
|
||||||
)
|
|
||||||
|
|
||||||
return [types.TextContent(type="text", text="Operation complete")]
|
|
||||||
```
|
|
||||||
|
|
||||||
The request context is automatically set for each request and provides a safe way to access the current client session and request metadata.
|
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|||||||
8
uv.lock
generated
8
uv.lock
generated
@@ -191,7 +191,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mcp"
|
name = "mcp"
|
||||||
version = "1.1.2.dev0"
|
version = "1.2.0.dev0"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "anyio" },
|
{ name = "anyio" },
|
||||||
@@ -565,11 +565,11 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "python-dotenv"
|
name = "python-dotenv"
|
||||||
version = "1.0.1"
|
version = "1.0.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 }
|
sdist = { url = "https://files.pythonhosted.org/packages/31/06/1ef763af20d0572c032fa22882cfbfb005fba6e7300715a37840858c919e/python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba", size = 37399 }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 },
|
{ url = "https://files.pythonhosted.org/packages/44/2f/62ea1c8b593f4e093cc1a7768f0d46112107e790c3e478532329e434f00b/python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a", size = 19482 },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
Reference in New Issue
Block a user