加载中

当您使用官方的MCP Python SDK时,构建MCP服务器会变得简单得多。您无需手动编写复杂的JSON模式来定义工具,而是可以使用装饰器来定义它们,并让SDK处理繁重的工作。

我们的MCP服务器的读取和更新工具连接到四个文件:document.pdf、spreadsheet.xlsx、report.txt和spec.md。

在这个示例中,我们正在创建一个管理文档操作的MCP服务器。该服务器将有两个主要工具:一个用于读取文档内容,另一个用于更新文档内容。所有文档都以简单字典的形式存在于内存中,其中键是文档ID,值是内容字符串。

MCP Python SDK的优势

MCP项目为跨多种编程语言构建服务器和客户端提供了官方SDK。使用Python SDK有以下几个优势:

  • 以最少的样板代码创建MCP服务器
  • 从Python函数签名自动生成JSON模式
  • 通过装饰器简化工具定义
  • 处理类型验证和错误处理

我们的MCP服务器的读取和更新工具连接到四个文件:document.pdf、spreadsheet.xlsx、report.txt和spec.md。

以下是使用SDK定义工具的简便方法。@mcp.tool装饰器与类型提示和字段描述相结合,会自动创建Claude能够理解和使用的正确工具模式。

设置服务器

本课程使用MCP Python SDK的第1版。下面的导入在第2版中会失败,因为第2版重命名了FastMCP。如果您自己设置项目,请将SDK版本保持在2以下:

bash
uv add "mcp[cli]<2"

使用pip时,相同的版本锁定方式是pip install "mcp[cli]<2"。

基本的服务器设置只需要几行代码:

python
from mcp.server.fastmcp import FastMCP
from pydantic import Field

mcp = FastMCP("DocumentMCP", log_level="ERROR")

docs = {
    "deposition.md": "This deposition covers the testimony of Angela Smith, P.E.",
    "report.pdf": "The report details the state of a 20m condenser tower.",
    "financials.docx": "These financials outline the project's budget and expenditures",
    "outlook.pdf": "This document presents the projected future performance of the system",
    "plan.md": "The plan outlines the steps for the project's implementation.",
    "spec.txt": "These specifications define the technical requirements for the equipment"
}

实现读取工具

第一个工具允许Claude通过提供文档ID来读取文档内容:

python
@mcp.tool(
    name="read_doc_contents",
    description="Read the contents of a document and return it as a string."
)
def read_document(
    doc_id: str = Field(description="Id of the document to read")
):
    if doc_id not in docs:
        raise ValueError(f"Doc with id {doc_id} not found")
    
    return docs[doc_id]

该工具定义包括:

  • 一个描述该操作的清晰名称
  • 一个解释该工具功能的描述
  • 带有字段描述的类型化参数
  • 针对无效文档ID的错误处理

实现编辑工具

第二个工具对文档内容执行简单的查找和替换操作:

python
@mcp.tool(
    name="edit_document",
    description="Edit a document by replacing a string in the documents content with a new string."
)
def edit_document(
    doc_id: str = Field(description="Id of the document that will be edited"),
    old_str: str = Field(description="The text to replace. Must match exactly, including whitespace."),
    new_str: str = Field(description="The new text to insert in place of the old text.")
):
    if doc_id not in docs:
        raise ValueError(f"Doc with id {doc_id} not found")
    
    docs[doc_id] = docs[doc_id].replace(old_str, new_str)

该工具接受三个参数:文档ID、要查找的文本以及替换文本。该实现为简单起见使用了Python内置的字符串replace()方法。

关键实现细节

在使用MCP SDK定义工具时,请记住以下要点:

  • 从pydantic导入Field以添加参数描述
  • 使用类型提示来指定参数类型
  • 为边缘情况包含错误处理
  • 编写清晰、描述性强的工具名称和描述
  • MCP Python SDK会自动将您的函数签名转换为正确的JSON模式

与手动编写JSON模式相比,MCP Python SDK大大降低了创建工具的复杂性。过去需要数十行模式定义的工作,现在只需几行带装饰器的Python函数即可完成。

@mcp.tool装饰器及其基于签名的模式生成功能来自MCP Python SDK。Claude Agent SDK提供了一个独立的@tool装饰器用于定义自定义工具,它需要一个显式的input_schema参数,而不是函数签名上的pydantic Field注解。在Python中,该模式是一个将参数名称映射到类型的字典,例如{"latitude": float},Agent SDK会为您将其转换为JSON Schema;或者当您需要枚举、范围、可选字段或嵌套对象时,可以使用完整的JSON Schema字典。当您在其他地方阅读工具代码时,请检查它导入的是哪个SDK,因为这两个装饰器很容易混淆。