MCP高级应用:构建智能函数工具

函数工具是MCP框架的核心组件之一,它允许开发者定义结构化的函数接口供AI模型调用。本文将深入探讨MCP的函数工具系统,介绍如何创建从简单到复杂的各类工具,包括基本函数、参数验证、枚举类型、复杂数据模型等高级特性。通过这些示例,你将掌握如何为AI应用构建强大而灵活的工具集,使AI能够执行各种复杂任务。

函数工具系统概述

MCP的函数工具系统允许开发者将Python函数暴露为可被AI调用的工具。每个工具都有明确定义的输入参数和返回值,并且可以包含详细的描述信息。MCP会自动处理参数验证、类型转换和错误处理,使开发者能够专注于实现工具的核心功能。

工具类型与实现

1. 基本函数工具

最简单的工具是直接使用Python函数并添加@mcp.tool()装饰器:

python 复制代码
@mcp.tool()
def calculate_sum(numbers: List[float]) -> float:
    """计算数字列表的总和
    
    这个函数接收一个数字列表,然后返回它们的总和。
    非常适合进行简单的数学计算。
    
    Args:
        numbers: 要计算总和的数字列表
        
    Returns:
        所有数字的总和
    """
    return sum(numbers)

MCP会自动从函数名称派生工具名称,并从文档字符串生成描述。类型注解用于指定参数和返回值的类型。

2. 自定义名称的工具

你可以通过name参数为工具指定自定义名称:

python 复制代码
@mcp.tool(name="高级计算器")
def advanced_calculator(a: float, b: float, operation: str) -> float:
    """执行高级数学运算"""
    if operation == "+":
        return a + b
    elif operation == "-":
        return a - b
    # 其他操作...

自定义名称对于创建更易于理解和使用的工具接口非常有用,特别是当函数名称不够直观时。

3. 使用枚举进行参数验证

使用Python的Enum类可以限制参数的可能值,提供更严格的参数验证:

python 复制代码
class ColorFormat(str, Enum):
    RGB = "rgb"
    HEX = "hex"
    HSL = "hsl"

@mcp.tool()
def convert_color(color: str, from_format: ColorFormat, to_format: ColorFormat) -> str:
    """在不同的颜色格式之间转换"""
    # 实现颜色转换逻辑...

枚举类型确保参数只能是预定义的值之一,提高了工具的健壮性。

4. 使用Pydantic模型进行复杂参数验证

对于需要复杂验证规则的参数,可以使用Pydantic模型:

python 复制代码
class Person(BaseModel):
    name: str = Field(..., description="姓名")
    age: int = Field(..., description="年龄", ge=0, lt=150)
    email: Optional[str] = Field(None, description="电子邮件地址")
    tags: List[str] = Field(default_factory=list, description="标签列表")
    
    @validator('email')
    def validate_email(cls, v):
        if v is not None and '@' not in v:
            raise ValueError('必须是有效的电子邮件地址')
        return v

class UserProfile(BaseModel):
    id: str = Field(..., description="用户ID")
    person: Person = Field(..., description="个人信息")
    created_at: datetime = Field(default_factory=datetime.now, description="创建时间")

@mcp.tool()
def create_user_profile(user_data: Dict) -> Dict:
    """创建用户档案"""
    # 使用Pydantic模型验证输入数据
    person_data = user_data.get("person", {})
    person = Person(**person_data)
    
    # 创建用户档案
    profile = UserProfile(
        id=user_data.get("id", f"user_{hash(person.name)}"),
        person=person
    )
    
    return profile.model_dump()

Pydantic模型提供了强大的数据验证、类型转换和默认值处理能力,非常适合处理复杂的数据结构。

5. 返回复杂结构

MCP工具可以返回复杂的数据结构,这些结构会自动转换为MCP支持的类型:

python 复制代码
@mcp.tool()
def generate_report(user_id: str, include_details: bool = False) -> Dict:
    """生成用户报告"""
    # 基本报告
    report = {
        "user_id": user_id,
        "generated_at": datetime.now().isoformat(),
        "summary": {
            "login_count": 42,
            "last_login": "2024-03-15T08:30:00"
        }
    }
    
    # 添加详细信息
    if include_details:
        report["details"] = {
            "activities": [
                {"type": "login", "timestamp": "2024-03-15T08:30:00"},
                # 更多活动...
            ],
            "preferences": {
                "theme": "dark",
                "notifications": True,
                "language": "zh-CN"
            }
        }
    
    return report

复杂的返回值允许工具提供丰富的信息,使AI能够处理更复杂的任务。

客户端调用工具

在客户端,我们可以使用session.call_tool()方法来调用工具:

python 复制代码
# 列出所有可用工具
tools = await session.list_tools()

# 调用基本工具
result = await session.call_tool("calculate_sum", {"numbers": [1, 2, 3, 4, 5]})

# 调用自定义名称的工具
result = await session.call_tool("高级计算器", {"a": 10, "b": 3, "operation": "*"})

# 调用使用枚举的工具
result = await session.call_tool("convert_color", {
    "color": "rgb(255,0,0)", 
    "from_format": "rgb", 
    "to_format": "hex"
})

# 调用使用Pydantic模型的工具
result = await session.call_tool("create_user_profile", {"user_data": json.dumps(user_data)})

# 调用返回复杂结构的工具
result = await session.call_tool("generate_report", {"user_id": "user1", "include_details": "true"})

如果你看到如下的输出内容,代表你已经成功的掌握了mcp的functiontool的使用

bash 复制代码
python .\mcp\03_function_tools.py
D:\svn\github.com\ai-learning\mcp\03_function_tools.py:113: PydanticDeprecatedSince20: Pydantic V1 style `@validator` validators are deprecated. You should migrate to Pydantic V2 style `@field_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed 
in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.11/migration/
  @validator('email')

=== 可用工具列表 ===
- ('meta', None)
- ('nextCursor', None)
- ('tools', [Tool(name='calculate_sum', description='计算数字列表的总和\n    \n    这个函数接收一个 
数字列表,然后返回它们的总和。\n    非常适合进行简单的数学计算。\n    \n    Args:\n        numbers: 
要计算总和的数字列表\n        \n    Returns:\n        所有数字的总和\n    ', inputSchema={'properties': {'numbers': {'items': {'type': 'number'}, 'title': 'Numbers', 'type': 'array'}}, 'required': ['numbers'], 'title': 'calculate_sumArguments', 'type': 'object'}, annotations=None), Tool(name='高级计
算器', description='执行高级数学运算\n    \n    根据指定的操作符对两个数字执行数学运算。\n    支持的
操作包括:加法(+)、减法(-)、乘法(*)、除法(/)、幂运算(**)。\n    \n    Args:\n        a: 第一个数字\n        b: 第二个数字\n        operation: 要执行的操作 (+, -, *, /, **)\n        \n    Returns:\n   
     运算结果\n    ', inputSchema={'properties': {'a': {'title': 'A', 'type': 'number'}, 'b': {'title': 'B', 'type': 'number'}, 'operation': {'title': 'Operation', 'type': 'string'}}, 'required': ['a', 'b', 'operation'], 'title': 'advanced_calculatorArguments', 'type': 'object'}, annotations=None), 
Tool(name='convert_color', description='在不同的颜色格式之间转换\n    \n    支持在 RGB、HEX 和 HSL  
格式之间转换颜色值。\n    \n    Args:\n        color: 要转换的颜色值\n        from_format: 源格式 (rgb, hex, hsl)\n        to_format: 目标格式 (rgb, hex, hsl)\n        \n    Returns:\n        转换后的
颜色值\n    ', inputSchema={'$defs': {'ColorFormat': {'enum': ['rgb', 'hex', 'hsl'], 'title': 'ColorFormat', 'type': 'string'}}, 'properties': {'color': {'title': 'Color', 'type': 'string'}, 'from_format': {'$ref': '#/$defs/ColorFormat'}, 'to_format': {'$ref': '#/$defs/ColorFormat'}}, 'required': ['color', 'from_format', 'to_format'], 'title': 'convert_colorArguments', 'type': 'object'}, annotations=None), Tool(name='create_user_profile', description='创建用户档案\n    \n    接收用户数据并创建一
个验证过的用户档案。\n    \n    Args:\n        user_data: 包含用户信息的字典\n        \n    Returns:\n        创建的用户档案\n    ', inputSchema={'properties': {'user_data': {'additionalProperties': True, 'title': 'User Data', 'type': 'object'}}, 'required': ['user_data'], 'title': 'create_user_profileArguments', 'type': 'object'}, annotations=None), Tool(name='generate_report', description='生成 
用户报告\n    \n    根据用户 ID 生成一份报告,可选择是否包含详细信息。\n    \n    Args:\n        user_id: 用户 ID\n        include_details: 是否包含详细信息\n        \n    Returns:\n        用户报告数
据\n    ', inputSchema={'properties': {'user_id': {'title': 'User Id', 'type': 'string'}, 'include_details': {'default': False, 'title': 'Include Details', 'type': 'boolean'}}, 'required': ['user_id'], 'title': 'generate_reportArguments', 'type': 'object'}, annotations=None)])

=== 测试基本工具 ===
计算总和: meta=None content=[TextContent(type='text', text='15.0', annotations=None)] isError=False 

=== 测试自定义名称的工具 ===
高级计算 (10 * 3): meta=None content=[TextContent(type='text', text='30.0', annotations=None)] isError=False

=== 测试枚举验证 ===
颜色转换 (RGB -> HEX): meta=None content=[TextContent(type='text', text="转换错误: invalid literal for int() with base 10: 'rgb(255'", annotations=None)] isError=False

=== 测试 Pydantic 模型验证 ===
创建用户档案: meta=None content=[TextContent(type='text', text='{\n  "id": "user1",\n  "person": {\n    "name": "张三",\n    "age": 28,\n    "email": "[email protected]",\n    "tags": [\n      "开 
发",\n      "Python"\n    ]\n  },\n  "created_at": "2025-06-22T19:12:15.397796"\n}', annotations=None)] isError=False

=== 测试复杂返回值 ===
生成报告: meta=None content=[TextContent(type='text', text='{\n  "user_id": "user1",\n  "generated_at": "2025-06-22T19:12:15.397796",\n  "summary": {\n    "login_count": 42,\n    "last_login": "2024-03-15T08:30:00"\n  },\n  "details": {\n    "activities": [\n      {\n        "type": "login",\n      
  "timestamp": "2024-03-15T08:30:00"\n      },\n      {\n        "type": "page_view",\n        "timestamp": "2024-03-15T08:32:15"\n      },\n      {\n        "type": "download",\n        "timestamp": 
"2024-03-15T08:45:30"\n      }\n    ],\n    "preferences": {\n      "theme": "dark",\n      "notifications": true,\n      "language": "zh-CN"\n    }\n  }\n}', annotations=None)] isError=False

MCP会自动处理参数转换和验证,确保工具接收到正确格式的输入。

工具设计最佳实践

  1. 明确的命名和描述:为工具提供清晰的名称和详细的描述
  2. 完善的参数文档:为每个参数添加描述、类型信息和验证规则
  3. 适当的错误处理:在工具函数中添加适当的错误处理和有意义的错误消息
  4. 合理的默认值:为可选参数提供合理的默认值
  5. 功能单一原则:每个工具应专注于单一功能,避免过于复杂
  6. 参数验证:使用枚举和Pydantic模型进行严格的参数验证
  7. 返回值结构化:返回结构化的数据,便于后续处理
相关推荐
ZackSock4 小时前
FastMCP 快速入门
mcp
bastgia5 小时前
LangGraph + MCP + Ollama 实战教程:打造强大的多智能体聊天机器人
llm·mcp
掘我的金7 小时前
MCP进阶指南:资源管理与动态数据访问
mcp
掘我的金7 小时前
MCP入门指南:打造智能AI工具的第一步
mcp
叶 落11 小时前
三种语言写 MCP
java·python·ai·typescript·mcp
小码农叔叔12 小时前
【AI智能体】Spring AI MCP 服务常用开发模式实战详解
mcp·springboot使用mcp·mcp使用详解·mcp使用·spring ai mcp·mcp 详解·mcp开发模式
qife18 小时前
GitHub MCP Server - 无缝集成GitHub API的自动化工具
go·github·自动化编程·mcp·api集成
赫本的猫1 天前
《像素绘画板》:通过Trae将脑中的创意变为现实
ai编程·mcp·trae
showyoui1 天前
模型上下文协议 (MCP) 全面指南
mcp