首页
Preview

从零开发MCP服务: MCP的简介和入门实践指南

什么是Model Context Protocol (MCP)?

MCP(模型上下文协议)是一种为 AI 助手(如聊天机器人或自动化代理)提供访问外部数据和工具的 通用规则(协议)

传统上,若想让 AI 使用数据库、Web 服务或本地文件,开发者需要为每种连接方式单独编写代码。这意味着每次扩展 AI 功能时,都需为新工具开发专属代码。

MCP 通过 标准化“AI ⇔ 数据或工具”的连接方式,允许 AI 使用统一的机制与各种数据源或外部服务交互。这为 AI 开发者和数据管理者带来了显著的效率提升和更高的代码复用性。

MCP 的通用规则是什么?

MCP 通过初始化时确认双方的“角色与功能”,随后使用统一格式的请求/响应进行自由交互。其核心机制可概括为以下三点:

  1. 通用语言:JSON-RPC 如同国际会议指定英语为通用语言,MCP 使用 JSON-RPC 2.0 作为通信格式。

  2. 首次“名片交换”:initialize

客户端首次向服务器发送 initialize 方法,类似于“自我介绍”:

  • 客户端:我具备这些功能。
  • 服务器:我能提供这些功能。

这建立了双方的信任和功能清单。

  1. 通道建立后的交互

初始化完成后,客户端和服务器可通过统一规则进行以下交互:

  • tools:调用注册的函数。
  • resources:获取文件或数据。
  • prompts:获取对话模板。
  • logging/completion/ping:日志、完成状态或心跳检测。

通信方式自由:JSON-RPC 仅定义格式,实际传输可- 使用标准输入输出(stdio)、Streamable HTTP、WebSocket 等。目前,stdio 和 Streamable HTTP 是标准选项。

MCP 架构

MCP 架构以 主机(Host)客户端(Client)服务器(Server) 三个角色为核心,构建了一个灵活的 AI 功能扩展框架。

  • 一个主机可生成多个客户端。
  • 每个客户端与一个服务器进行一对一通信。
  • 通过这种结构,AI 功能得以动态扩展。

image.png

image.png

三个角色的职责

  1. 主机(Host) 主机是 MCP 系统的核心,负责:
  • 管理客户端:生成并管理多个客户端(会话),控制安全性和权限。
  • 协调 AI:决定 AI(LLM)使用哪些数据或功能,并向服务器发送请求。
  • 整合信息:汇总各客户端从服务器获取的数据,供 AI 优化使用。
  1. 客户端 (Client)

客户端负责与特定服务器进行 一对一通信,其功能包括:

  • 专用通信:一个客户端只与一个服务器交互,例如“数据库客户端”或“翻译客户端”。
  • JSON-RPC 交互:使用 initialize、call_tool、read_resource 等方法与服务器通信。
  • 事件处理:接收服务器的日志通知等,并反馈给主机。
  • 实现要点: (1)客户端实现较简单,主要包括 ClientSession(协议层)和传输模块(如 stdio_client、sse_clientwebsocket_client)。 (2)ClientSession 负责生成和发送 JSON-RPC 消息,处理核心操作(如 initialize、tools/call)。 (3)传输层使用 stdio 或 SSE 交换 JSON 消息。
  1. 服务器 (Server)

服务器为 AI 提供可用的功能或数据,职责包括:

  • 提供工具和资源:公开功能(如翻译、数据库查询、文件读写)供客户端调用。
  • 隔离操作:为安全起见,仅处理自身权限内的资源,不直接访问主机或其他服务器数据。
  • 可选 AI 交互:通过客户端向主机的 LLM 请求额外处理(例如,翻译服务器请求其他语言处理)。
  • 实现要点: (1)提供低级 Server 类和高级 FastMCP 框架。 (2)Server 使用装饰器(如 @server.call_tool@server.list_tools)定义请求处理逻辑,管理“哪个方法调用哪个函数”。 (3)ServerSession 为每个客户端连接生成会话,处理 JSON-RPC 消息并调用注册的处理函数。 (4)FastMCP 自动配置 SSE 路由和工具管理,简化开发。 (5)传输层与客户端类似,使用 stdio 或 SSE。

设计原则

MCP 的设计遵循以下原则:

  • 服务器简洁:服务器专注单一功能,复杂协调由主机负责。
  • 高组合性:通过通用协议,服务器如积木般可自由组合,扩展 AI 功能。
  • 权限隔离:服务器仅操作自身权限内的资源,主机负责全局管理。
  • 渐进扩展:核心功能保持最小化,通过“功能协商”(capability negotiation)逐步添加扩展,兼顾后向兼容性。

客户端与服务器的通信机制

MCP 的通信分为 协议层传输层消息类型 三个层面:

  1. 协议层(会话)
  • 作用:定义消息框架(JSON-RPC 结构),关联请求与响应。
  • 实现: (1)客户端使用 ClientSession 管理“生成请求-发送-接收响应”的流程。 (2)服务器使用 ServerSession 管理“接收请求-调用处理函数-返回结果”的流程。 (3)消息以“请求/结果/错误/通知”形式处理,由会话解析和匹配。
  1. 传输层
  • 作用:负责实际的字节流传输。
  • 标准方式: (1)stdio:通过标准输入输出交换 JSON 消息,适合本地进程间通信。 (2)Streamable HTTP:服务器通过 SSE(Server-Sent Events)发送消息,客户端通过 HTTP POST 发送请求。
  • 机制:会话生成 JSON-RPC 消息,传输层负责实际发送和接收。
  1. 消息类型

MCP 基于 JSON-RPC 定义了四种消息:

  • 请求 (Requests):需要响应的调用,包含 method、params 和 id。
  • 结果 (Results):请求的成功响应,包含 result 字段。
  • 错误 (Errors):请求失败时的信息,包含 code、message 和 data。
  • 通知 (Notifications):无需响应的单向消息,用于日志或进度通知。

连接生命周期

MCP 的客户端与服务器通信遵循明确的生命周期,违反规则将导致错误:

image.png

  1. 初始化 (Initialization)
  • 客户端发送 initialize 请求,包含版本和功能信息。
  • 服务器返回支持的版本和功能。
  • 客户端发送 initialized 通知,确认连接建立。
  • 完成初始化后,进入可交互状态。
  1. 消息交换 (Message Exchange)
  • 请求-响应:双方可互发请求并接收响应。
  • 通知:双方可发送单向通知。
  1. 终止 (Termination)
  • 正常关闭:通过 close() 等方法。
  • 异常终止:网络断开或错误状态。

MCP 的核心组件通过协议层管理交互,传输层处理输入输出,客户端与服务器在统一规则下交换工具、资源等功能。

实现简单的MCP服务器:Python入门实践

准备工作

在开始之前,确保你的系统已安装 Python(推荐 3.8+)和 uv(一个快速的 Python 包管理和虚拟环境工具)。关于 uv 的安装,请参考 uv 官方文档(https://docs.astral.sh/uv/)。

步骤 1:创建虚拟环境

为隔离项目依赖,推荐使用虚拟环境。uv 提供了一种轻量高效的解决方案。以下是创建虚拟环境的命令:

uv init mcp-server-demo
cd mcp-server-demo
uv add "mcp[cli]"

这些命令将初始化一个名为 mcp-server-demo 的项目。然后进入项目目录,安装 MCP Python SDK 及其 CLI 工具。

步骤 2:编写 MCP 服务器代码

在 mcp-server-demo 目录下,创建 server.py文件,并添加以下代码,这个服务器实现了一个简单的加法工具:

//server.py

from mcp.server.fastmcp import FastMCP

# 创建一个启用调试模式的 MCP 服务器
mcp = FastMCP("Demo", debug=True)

# 定义加法工具
@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b

# 运行服务器
if __name__ == "__main__":
    print("Starting MCP server in stdio mode")
    mcp.run(transport="stdio")

代码解析:

  • FastMCP("Demo", debug=True):初始化一个名为“Demo”的 MCP 服务器,启用调试模式以便查看详细日志。
  • @mcp.tool():将 add 函数注册为 MCP 工具,接受两个整数参数并返回其和。
  • mcp.run(transport="stdio"):以 stdio 传输模式启动服务器,适合本地测试。

步骤 3:配置 Cline 或 Cursor

要让 Cline 或 Cursor 识别 MCP 服务器,需配置相应的 JSON 文件:

  • Cline:编辑 cline_mcp_settings.json
  • Cursor:编辑 mcp.json(通常位于项目根目录下的 .cursor 文件夹或用户目录下的 ~/.cursor)。

配置文件内容如下:

{
  "mcpServers": {
    "mcp-demo-server": {
      "command": "uv",
      "args": [
        "--directory",
        "<mcp server directory>",
        "run",
        "server.py"
      ],
      "alwaysAllow": [
        "add"
      ],
      "disabled": false
    }
  }
}

配置说明:

  • <mcp server directory>:替换为 mcp-server-demo 目录的绝对路径,例如 /Users/karaage/mcp-server-demo
  • "command": "uv":使用 uv 运行服务器。
  • "alwaysAllow": ["add"]:允许客户端调用 add 工具。
  • "disabled": false:启用服务器。

保存配置后,Cline 或 Cursor 会自动执行指定命令以启动服务器。

步骤 4:验证服务器运行

在 Cline 或 Cursor 的 MCP 服务器管理界面中,检查服务器状态:

  • 如果显示服务器名称(如 mcp-demo-server)且无错误提示,说明服务器已成功启动。
  • 若需重启服务器(例如代码更改后),点击界面右上角的“重启”按钮(旋转箭头图标)。

步骤 5:测试 MCP 服务器

在 Cline 或 Cursor 的聊天窗口中输入以下指令:

简单计算

使用 MCP 服务器 mcp-demo-server 进行加法计算,例如 3 + 5。

如果配置正确,LLM 会自动调用 add 工具并返回结果(如 8)。 测试用例 1:错误计算 假设我们故意将加法改为减法(a - b),例如计算 5 - 3

LLM 可能会注意到计算逻辑与指令不符,并提示错误。

测试用例 2:复杂计算

再试一个复杂场景,例如计算 (a + b - 1),如 3 + 5 - 1

在这里,LLM 可能直接接受服务器的结果(如 7),而未察觉逻辑错误。这表明 LLM 通常信任 MCP 服务器的输出。

最后

希望本文能为 MCP 初学者提供参考!

参考资料:

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
Hedy
大家好!我是一位前端开发工程师,拥有6年以上的前端开发经验。我熟练掌握HTML、CSS、JavaScript等语言,能够灵活运用各种前端框架,如Vue、React、Uniapp、Flutter等。我注重理论与实践相结合,能够为学员提供丰富的案例和实践项目,并以生动、易懂的语言为学员讲解前端开发的核心知识和技能。我不仅注重传授技能,更关注学员的职业发展,希望通过我的教学,帮助学员成为一名优秀的前端开发工程师。

评论(0)

添加评论