MCP开发(一)

MCP Python SDK 中文文档


概述

模型上下文协议(Model Context Protocol,简称 MCP)允许应用程序以标准化的方式为大型语言模型(LLMs)提供上下文,将提供上下文的过程与实际的 LLM 交互分离开来。此 Python SDK 实现了完整的 MCP 规范,使以下任务变得简单:

  • 构建能够连接到任何 MCP 服务器的 MCP 客户端
  • 创建公开资源、提示(prompts)和工具的 MCP 服务器
  • 使用标准传输方式,例如标准输入输出(stdio)和服务器发送事件(SSE)
  • 处理所有 MCP 协议消息和生命周期事件

安装

推荐使用 uv 管理 Python 项目:

uv add "mcp[cli]"

或使用 pip 安装:

pip install mcp

运行独立 MCP 开发工具:

uv run mcp

快速开始

创建一个简单 MCP 服务器示例:

# server.py
from mcp.server.fastmcp import FastMCP

# 创建一个 MCP 服务器
mcp = FastMCP("Demo")


# 添加一个加法工具
@mcp.tool()
def add(a: int, b: int) -> int:
    """两个数字相加"""
    return a + b


# 添加一个动态问候资源
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
    """获取个性化问候语"""
    return f"Hello, {name}!"

快速测试:

mcp dev server.py

什么是 MCP?

模型上下文协议(Model Context Protocol,简称 MCP)允许您构建服务器,以一种安全、标准化的方式向 LLM 应用程序公开数据和功能。可以将其视为一种专为 LLM 交互设计的 Web API。MCP 服务器可以:

  • 通过资源(Resources)公开数据(类似于 GET 端点,用于将信息加载到 LLM 的上下文中)
  • 通过工具(Tools)提供功能(类似于 POST 端点,用于执行代码或产生其他副作用)
  • 通过提示(Prompts)定义交互模式(可重用的 LLM 交互模板)

核心概念

服务器(Server)

核心接口,处理连接、协议合规和消息路由:

# Add lifespan support for startup/shutdown with strong typing
from contextlib import asynccontextmanager
from collections.abc import AsyncIterator
from dataclasses import dataclass

from fake_database import Database  # Replace with your actual DB type

from mcp.server.fastmcp import Context, FastMCP

# 创建服务器
mcp = FastMCP("My App")

# 添加依赖项
mcp = FastMCP("My App", dependencies=["pandas", "numpy"])


@dataclass
class AppContext:
    db: Database


@asynccontextmanager
async def app_lifespan(server: FastMCP) -> AsyncIterator[AppContext]:
    """Manage application lifecycle with type-safe context"""
    # Initialize on startup
    db = await Database.connect()
    try:
        yield AppContext(db=db)
    finally:
        # Cleanup on shutdown
        await db.disconnect()


# 传lifespan给服务器
mcp = FastMCP("My App", lifespan=app_lifespan)


# 在工具中访问类型安全的生命周期上下文
@mcp.tool()
def query_db(ctx: Context) -> str:
    """Tool that uses initialized resources"""
    db = ctx.request_context.lifespan_context["db"]
    return db.query()

资源(Resources)

在 MCP(Model Context Protocol)中,Resources 是一种用来向 LLM(大型语言模型)暴露数据的机制。它们的作用类似于 REST API 中的 GET 端点,主要用于提供数据,而不是执行复杂的计算或产生副作用(如更改状态、写数据库等)。

  • 通过静态或动态路径,Resources 可以灵活地提供各种数据:
    • 静态数据(如配置信息)。
    • 动态数据(如用户信息,根据请求中的参数生成)。
  • MCP 通过 @mcp.resource 装饰器轻松实现资源的注册和管理,使得 LLM 可以通过标准化的方式访问这些数据。
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("My App")

# 定义静态 Resource
@mcp.resource("config://app")
def get_config() -> str:
    """Static configuration data"""
    return "App configuration here"

#  定义动态 Resource
@mcp.resource("users://{user_id}/profile")
def get_user_profile(user_id: str) -> str:
    """Dynamic user data"""
    return f"Profile data for user {user_id}"

工具(Tools)

在 MCP(Model Context Protocol)中,Tools 是一种让 LLM(大型语言模型)通过服务器执行操作的机制。与 Resources 不同,Tools 的设计目标是执行计算任务或产生副作用(如访问外部 API、写入数据库等)。

import httpx
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("My App")


@mcp.tool()
def calculate_bmi(weight_kg: float, height_m: float) -> float:
    """Calculate BMI given weight in kg and height in meters"""
    return weight_kg / (height_m**2)


# 定义一个异步函数 async def
@mcp.tool()
async def fetch_weather(city: str) -> str:
    """Fetch current weather for a city"""
    async with httpx.AsyncClient() as client:
        response = await client.get(f"https://api.weather.com/{city}")
        return response.text

提示模板(Prompts)

Prompts 是一种可重用的模板,用于帮助 LLM(大型语言模型)与服务器进行更高效的交互。Prompts 的主要功能是生成结构化的消息或文本,作为与 LLM 交互的输入内容。

from mcp.server.fastmcp import FastMCP
from mcp.server.fastmcp.prompts import base

mcp = FastMCP("My App")


@mcp.prompt()
def review_code(code: str) -> str:
    return f"Please review this code:\n\n{code}"


@mcp.prompt()
def debug_error(error: str) -> list[base.Message]:
    return [
        base.UserMessage("I'm seeing this error:"),
        base.UserMessage(error),
        base.AssistantMessage("I'll help debug that. What have you tried so far?"),
    ]

图片(Images)

FastMCP 提供的 Image 类来处理图像数据。它通过创建一个 MCP 工具(Tool),实现了从给定的图像路径生成缩略图的功能。

from mcp.server.fastmcp import FastMCP, Image
from PIL import Image as PILImage

mcp = FastMCP("My App")


@mcp.tool()
def create_thumbnail(image_path: str) -> Image:
    """Create a thumbnail from an image"""
    img = PILImage.open(image_path)
    img.thumbnail((100, 100))
    return Image(data=img.tobytes(), format="png")

上下文(Context)

FastMCP 中的 Context 对象,为工具(Tool)和资源提供访问 MCP 功能的能力。Context 对象主要用于管理任务的上下文信息,例如进度跟踪、日志记录以及对资源的读取。

 

from mcp.server.fastmcp import FastMCP, Context

mcp = FastMCP("My App")


@mcp.tool()
async def long_task(files: list[str], ctx: Context) -> str:
    """Process multiple files with progress tracking"""
    for i, file in enumerate(files):
        ctx.info(f"Processing {file}")
        await ctx.report_progress(i, len(files))
        data, mime_type = await ctx.read_resource(f"file://{file}")
    return "Processing complete"

运行服务器

开发模式 MCP Inspector

并通过 开发模式(Development Mode) 快速测试和调试服务器的功能。

mcp dev server.py

Claude桌面集成

mcp install server.py

直接执行

python server.py

挂载到现有ASGI服务器

app = Starlette(routes=[Mount('/', app=mcp.sse_app())])

示例

回声服务器

@mcp.resource("echo://{message}")
def echo_resource(message: str) -> str:
    return f"资源回声: {message}"

SQLite浏览器

@mcp.tool()
def query_data(sql: str) -> str:
    conn = sqlite3.connect("database.db")
    result = conn.execute(sql).fetchall()
    return "\n".join(str(row) for row in result)

高级用法

低级服务器接口

更底层、更灵活的服务器实现,适合高级用户定制。

编写 MCP 客户端

提供客户端接口,连接 MCP 服务器进行交互。

MCP 基本元素

元素

控制方

描述

示例

提示

用户

交互模板

菜单

资源

应用

上下文数据

文件

工具

模型

执行操作

API

服务器能力

服务器启动时声明自身支持的能力,例如 prompts、resources、tools 等。

 

posted @ 2025-03-27 16:14  Arxu  阅读(1437)  评论(1)    收藏  举报