MCP 标准能力

发布于:2025-07-05 ⋅ 阅读:(27) ⋅ 点赞:(0)

MCP 概念基础
MCP 传输机制
MCP 传输机制(Streamable HTTP)


参考
https://zhuanlan.zhihu.com/p/32593727614
https://blog.csdn.net/lys_828/article/details/148438996
https://blog.51cto.com/qiangmzsx/13635845
https://www.zhihu.com/question/5290049088/answer/1898149469289157356

1. MCP 能力概述

1.1. Resources

Resources 是 Model Context Protocol (MCP) 中的一个核心原语,它允许 servers 暴露可以被 clients 读取并用作与 LLM 交互的上下文数据和内容。

用途:
提供数据和上下文信息

特点:
只读操作
类似 REST API 的 GET 请求
使用 URI 风格的路径
适合缓存

典型场景:
读取文件内容
获取配置信息
查询数据库数据
获取系统状态

每个 resource 都由一个唯一的 URI 标识,并且可以包含文本或二进制数据。

1.2. Prompts

Prompts 允许 servers 定义可复用的提示模板和工作流,clients 可以轻松地将它们呈现给用户和 LLMs。Prompts 提供了一种强大的方式来标准化和共享常见的 LLM 交互。

用途:
定义与 LLM 交互的模板

特点:
提供结构化的提示模板
可以包含参数
指导 LLM 的输出
可重用的交互模式

典型场景:
生成文本模板
定义对话流程
标准化 LLM 输出
创建特定任务的指令

1.3. Tools

Tools 使 servers 能够向 clients 暴露可执行功能。通过 tools,LLMs 可以与外部系统交互、执行计算并在现实世界中采取行动。
Tools 的关键特性有:
Discovery (发现):Clients 可以通过 tools/list endpoint 列出可用的 tools
Invocation (调用):Tools 使用 tools/call endpoint 调用,其中 servers 执行请求的操作并返回结果
Flexibility (灵活性):Tools 的范围可以从简单的计算到复杂的 API 交互

用途:
执行操作和计算

特点:
可以影响或修改外部系统的状态
类似 REST API 的 POST/PUT/DELETE
执行具体的功能

典型场景:
数学计算
数据处理
API 调用
文件操作

与 resources 一样,tools 通过唯一的名称进行标识,并且可以包含描述以指导其使用。但是,与 resources 不同的是,tools 代表可以修改状态或与外部系统交互的动态操作。

2. 服务器编码

2.1. 服务器实例

2.1.1. 创建服务器实例

FastMCP 为 MCP 服务端的主要实现类。创建服务端名称为 “MCP Test Server” 的实例
启用了调试模式,产生更详细的日志输出,方便调试。
服务器配置为监听 0.0.0.0(所有网络接口),接受来自本地和远程的连接
端口设置为 8002,这是客户端连接服务器的端口
注意:host=“0.0.0.0” 设置使服务器可以接受来自任何 IP 地址的连接,这在开发环境中很方便,但在生产环境中可能需要更严格的访问控制。

# 导入必要的模块
from mcp.server.fastmcp import FastMCP  # 导入 MCP 服务器的主类
# import psycopg2  # PostgreSQL 数据库连接库
import json  # JSON 处理库
# from psycopg2.extras import RealDictCursor  # 使查询结果以字典形式返回的游标
from mcp.server.fastmcp.prompts import base  # MCP 提示模板的基础类

# 创建 MCP 服务器
mcp = FastMCP("MCP Test Server",    # 服务器名称
              debug=True,           # 启用调试模式,会输出详细日志
              host="0.0.0.0",       # 监听所有网络接口,允许远程连接
              port=8002)            # 服务器监听的端口号

2.1.2. Resources 实现

mcp 服务端可以为 mcp 客户端定义访问数据库数据的资源端点,允许客户端查询数据库的元数据、数据表数据。下面以访问 pg 数据库数据为例。
简单的测试资源,用于验证服务器是否正常工作。当客户端请求 test://hello 资源时,将返回 “Hello, World!” 字符串。

@mcp.resource("test://hello")
def hello() -> str:
    """简单的测试资源"""
    return "Hello, World!"

查询数据库中 public 模式下的全部表名,返回一个表名列表的 JSON 字符串。

# 定义资源:获取所有表名
@mcp.resource("db://tables")
def list_tables() -> str:
    """获取所有表名列表"""
    with get_db_connection() as conn:
        with conn.cursor() as cur:
            cur.execute("""
                SELECT table_name
                FROM information_schema.tables
                WHERE table_schema = 'public'
            """)
            tables = [row[0] for row in cur.fetchall()]
            return json.dumps(tables)

2.1.3. Prompts 实现

定义了 MCP prompt(提示模板),用于指导 LLM 如何回答特定类型的查询。
1 中国省份介绍使用
@mcp.prompt() 装饰器注册为 MCP 服务器的提示模板
接受一个参数 province,表示要介绍的中国省份名称
返回一个字符串提示模板,引导 LLM 按照特定结构介绍指定省份
提示模板要求 LLM 从四个方面介绍省份:历史沿革、人文地理和风俗习惯、经济发展状况、旅游建议

# 中国省份介绍
@mcp.prompt()
def introduce_china_province(province: str) -> str:
    """介绍中国省份

    参数:
    province: 省份名称
    """
    return f"""
    请介绍这个省份:{province}

    要求介绍以下内容:
    1. 历史沿革
    2. 人文地理、风俗习惯
    3. 经济发展状况
    4. 旅游建议
    """

2 代码调试提示模板
提示模板的功能:
使用 @mcp.prompt() 装饰器注册
接受两个参数:code(需要调试的代码)和 error_message(错误信息)
与第一个模板不同,这个模板返回的是 list[base.Message] 类型,表示一个多轮对话的消息列表
对话包含五条消息:
系统消息:定义助手的角色和任务
用户消息:请求帮助修复代码
用户消息:包含代码内容(使用代码块格式)
用户消息:包含错误信息
助手消息:初始回应,表明将分析问题

使用场景:当用户遇到代码错误需要帮助调试时,通过预设对话历史,引导 LLM 进入特定的思考模式,提供结构化的上下文,使 LLM 能够更有效地分析和解决代码问题。

# 调试代码提示
@mcp.prompt()
def debug_code(code: str, error_message: str) -> list[base.Message]:
    """调试代码的对话式提示模板

    参数:
    code: 需要调试的代码
    error_message: 错误信息
    """
    return [
        base.SystemMessage("你是一位专业的代码调试助手。请仔细分析用户提供的代码和错误信息,找出问题所在并提供修复方案。"),
        base.UserMessage("我的代码有问题,请帮我修复:"),
        base.UserMessage(f"```\n{code}\n```"),
        base.UserMessage(f"错误信息:\n{error_message}"),
        base.AssistantMessage("我会帮你分析这段代码和错误信息。首先让我理解问题所在..."),
    ]

2.1.4. Tools 实现

定义了四个基本的数学运算工具,通过 @mcp.tool() 装饰器,将这些函数注册为 MCP 服务端的工具(可以被客户端直接调用)

@mcp.tool()
def add(a: float, b: float) -> float:
    """加法运算

    参数:
    a: 第一个数字
    b: 第二个数字

    返回:
    两数之和
    """
    return a + b

@mcp.tool()
def subtract(a: float, b: float) -> float:
    """减法运算

    参数:
    a: 第一个数字
    b: 第二个数字

    返回:
    两数之差 (a - b)
    """
    return a - b

@mcp.tool()
def multiply(a: float, b: float) -> float:
    """乘法运算

    参数:
    a: 第一个数字
    b: 第二个数字

    返回:
    两数之积
    """
    return a * b

@mcp.tool()
def divide(a: float, b: float) -> float:
    """除法运算

    参数:
    a: 被除数
    b: 除数

    返回:
    两数之商 (a / b)

    异常:
    ValueError: 当除数为零时
    """
    if b == 0:
        raise ValueError("除数不能为零")
    return a / b

2.1.5. main 函数

mcp 服务端提供 stdio 和 sse 两种传输协议运行方式。默认是使用 stdio 协议(适用于本地调试)。sse 协议适用于生产环境。

if __name__ == "__main__":
    mcp.run('sse')

2.1.6. 使用 MCP Inspector 验证

  • 全量代码 mcp_server.py
# 导入必要的模块
from mcp.server.fastmcp import FastMCP  # 导入 MCP 服务器的主类
# import psycopg2  # PostgreSQL 数据库连接库
import json  # JSON 处理库
# from psycopg2.extras import RealDictCursor  # 使查询结果以字典形式返回的游标
from mcp.server.fastmcp.prompts import base  # MCP 提示模板的基础类

# 创建 MCP 服务器
mcp = FastMCP("MCP Test Server",    # 服务器名称
              debug=True,           # 启用调试模式,会输出详细日志
              host="0.0.0.0",       # 监听所有网络接口,允许远程连接
              port=8002)            # 服务器监听的端口号

@mcp.resource("test://hello")
def hello() -> str:
    """简单的测试资源"""
    return "Hello, World!"

# 中国省份介绍
@mcp.prompt()
def introduce_china_province(province: str) -> str:
    """介绍中国省份

    参数:
    province: 省份名称
    """
    return f"""
    请介绍这个省份:{province}

    要求介绍以下内容:
    1. 历史沿革
    2. 人文地理、风俗习惯
    3. 经济发展状况
    4. 旅游建议
    """

# 调试代码提示
@mcp.prompt()
def debug_code(code: str, error_message: str) -> list[base.Message]:
    """调试代码的对话式提示模板

    参数:
    code: 需要调试的代码
    error_message: 错误信息
    """
    return [
        base.SystemMessage("你是一位专业的代码调试助手。请仔细分析用户提供的代码和错误信息,找出问题所在并提供修复方案。"),
        base.UserMessage("我的代码有问题,请帮我修复:"),
        base.UserMessage(f"```\n{code}\n```"),
        base.UserMessage(f"错误信息:\n{error_message}"),
        base.AssistantMessage("我会帮你分析这段代码和错误信息。首先让我理解问题所在..."),
    ]

@mcp.tool()
def add(a: float, b: float) -> float:
    """加法运算

    参数:
    a: 第一个数字
    b: 第二个数字

    返回:
    两数之和
    """
    return a + b


@mcp.tool()
def subtract(a: float, b: float) -> float:
    """减法运算

    参数:
    a: 第一个数字
    b: 第二个数字

    返回:
    两数之差 (a - b)
    """
    return a - b


@mcp.tool()
def multiply(a: float, b: float) -> float:
    """乘法运算

    参数:
    a: 第一个数字
    b: 第二个数字

    返回:
    两数之积
    """
    return a * b


@mcp.tool()
def divide(a: float, b: float) -> float:
    """除法运算

    参数:
    a: 被除数
    b: 除数

    返回:
    两数之商 (a / b)

    异常:
    ValueError: 当除数为零时
    """
    if b == 0:
        raise ValueError("除数不能为零")
    return a / b

if __name__ == "__main__":
    mcp.run('sse')
  • 运行 MCP Inspector
mcp dev .\src\mcp_server.py
  • 浏览器输入 http://127.0.0.1:6274

注意: 虽然启动的是 sse 服务,但是 Transport Type 还是需要选择 STDIO
Command 选择:uv
Arguments 输入:run --with mcp mcp run src/mcp_server.py
连接到 mcp 客户端后,左侧的页面顶部显示 Resources、Prompts、Tools 三个按钮,可以分别对服务端暴露的 Resources、Prompts、Tools 功能进行测试验证。

  • Resources 功能验证

点击 Resources,然后点击下方的 List Resources、List Templates,可以查看资源 list。
在这里插入图片描述

  • Prompts 功能验证

点击 Prompts 下的 List Prompts,列出全部 Prompts:
在这里插入图片描述

  • Tools 功能验证

点击 Tools 下的 List Tools,列出全部工具,选择其中一个,输入参数,点击 Run Tools,即可调用工具,获取返回的运行结果:
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到