Model Context Protocol(MCP)详解和开发教程

Model Context Protocol(MCP)

Model Context Protocol(MCP)是由 Anthropic 开发的开源协议,专注于构建安全且可解释的生成式 AI 系统。

MCP 的诞生源于解决 LLM 应用的一个关键限制,即它们与外部数据源和工具的隔离问题。

LLM 应用的一个核心关注点是数据传输,即如何将数据提供给 LLM 进行推理。这一直是 RAG 和微调的目标,同时也是 MCP 的目标。

MCP 的主要目的是标准化 LLM 应用如何连接到不同的系统,如下图所示:

图片

图片来源:

https://github.com/modelcontextprotocol/servers

AI Agent 在获取数据时面临一个挑战,换句话说,就是如何将 AI Agent 或基于 LLM 的应用集成到外部数据源中。

为了实现无缝集成,已经有许多尝试,例如利用 GUI、Web 浏览器和 Web 搜索等方式。

这些方法各有优劣。

图片

MCP 有潜力成为一个通用接口,可以将其视为 AI 领域的虚拟/软件版 USB-C。

它能够在 LLM/AI Agent 与外部资源之间实现无缝、安全且可扩展的数据交换。

MCP 采用客户端-服务器架构,其中 MCP 主机(AI 应用)与 MCP 服务器(数据/工具提供方)进行通信。

开发者可以使用 MCP 构建可复用、模块化的连接器,并利用针对主流平台的预构建服务器,从而打造一个由社区驱动的生态系统。

MCP 的开源特性鼓励创新,允许开发者扩展其功能,同时通过精细化权限控制等特性确保安全性。

最终,MCP 旨在将 AI Agent 从孤立的聊天机器人转变为具备上下文感知能力、可互操作且深度集成于数字环境的系统。

Anthropic 的 Model Context Protocol(MCP)是一个开源协议,用于将 LLM 连接到上下文、工具和提示词。它支持越来越多的服务器(server),可以用于连接各种工具或数据源。

Anthropic 在发布 MCP 时,公开了详细的 Model Context Protocol 规范以及支持多种语言的 SDK,详见:https://github.com/modelcontextprotocol。

整个规范,可以分几个大块来了解:协议架构、协议基本消息类型、协议生命周期管理、协议的传输层

image-20250319095717310

 

1. 协议之架构

Model Context Protocol (MCP) 采用 client-host-server 架构,每个 host 可以运行多个client实例。

这种架构使用户能够在各个应用程序中集成人工智能能力,同时保持清晰的安全边界并隔离关注点。

MCP 基于 JSON-RPC 构建,提供了一种有状态的会话协议,专注于上下文交换和 clients 与servers之间的采样协调。

JSON-RPC 2.0 规范: https://www.jsonrpc.org/specification

1.1 基本组件

image-20250318111741456

 

Host

Host进程充当容器和协调者(比如Cline,cursor等):

  • 创建和管理多个客户端实例

  • 控制客户端连接权限和生命周期

  • 协调 AI/LLM 集成和采样

  • 管理Clients之间的上下文聚合

Clients

每个客户端由Host创建,并保持一个独立的 server 连接(比如由Cline代码内嵌的SDK Client):

  • 和每个 server 建立一个有状态的会话

  • 处理协议协商和能力交换

  • 双向路由协议消息

  • 管理订阅和通知

  • 维护 servers 之间的安全边界

host 应用程序创建并管理多个 clients,每个 client 与特定 server 之间具有一对一的关系。

Servers

server 提供专业的上下文和能力:

  • 通过 MCP 原语暴露resources、tools 和prompts

  • 通过client 提供的接口请求sampling

  • 可以是本地进程或远程服务

1.2 基本消息类型

MCP 定义了基于 JSON-RPC 2.0 的三种核心消息类型:

  • Requests: 双向消息,带有方法和参数,期望有响应

  • Responses: 匹配特定请求 ID 的成功结果或错误

  • Notifications: 无需回复的单向消息

1.3 能力协商

Model Context Protocol 使用了一种基于能力(capability-based)的协商机制,在初始化阶段,clients和servers会明确声明它们支持的功能,而这些能力决定了在会话期间可以使用哪些协议特性和原语(primitives)

image-20250318101138574

 

 

2. 协议规范之基本消息类型

所有在 MCP clients 和 servers 之间的消息必须遵循 JSON-RPC 2.0 规范。该协议定义了三种基本类型的消息:

消息类型

描述

约束

Requests

用于具体操作的消息,比如查询所有Tool、调用Tool等,支持的所有类型详见2.1.1

必须包含唯一的 ID 和方法名称

Responses

应答Requests

必须包含与请求相同的 ID

Notifications

单向消息,不需要回复

不得包含 ID

2.1 Requests(消息请求)

Requests可以从Client端或者Server端发起

格式要求:

{
  jsonrpc: "2.0";
  id: string | number;
  method: string;
  params?: {
    [key: string]: unknown;
  };
}
  • 请求必须包含一个字符串或整数类型的 ID。

  • ID 不能为 null 。

  • 请求 ID 在同一会话中不得被请求者之前使用过。

2.1.1 Requests的关键业务类型:

Request method

发起方

响应方

描述

initialize

Client

Server

初始化会话

tools/list

Client

Server

发现可用的工具

tools/call

Client

Server

调用工具

resources/list

Client

Server

发现可用的资源

resources/read

Client

Server

要获取资源内容

resources/templates/list

Client

Server

发现可用的参数化资源

resources/subscribe

Client

Server

以订阅特定资源,并在其发生变化时接收通知

prompts/list

Client

Server

发现可用的提示词

prompts/get

Client

Server

要获取特定的提示词

roots/list

Server

Client

列出Server有权限访问Client的文件系统Root节点,暴露目录和文件

sampling/createMessage

Server

Client

使Server能够利用 AI 能力的生成能力

2.2 Responses(消息应答)

Responses是对requests的回复。

格式要求:

{
  jsonrpc: "2.0";
  id: string | number;
  result?: {
    [key: string]: unknown;
  }
  error?: {
    code: number;
    message: string;
    data?: unknown;
  }
}
  • Responses 必须包含与其对应 request 相同的 ID。

  • 必须设置 result 或 error 之一。不得同时出现。

  • 错误代码必须是整数。

2.3 Notifications(通知)

Notifications是从client 发送到server 或反向发送的。不需要回复。

格式要求:

{
  jsonrpc: "2.0";
  method: string;
  params?: {
    [key: string]: unknown;
  };
}

通知不得包含 ID。

2.4 举例:Client获取Server Tool列表

image-20250319093602810

 

要查询可用的工具,Client发送一个 tools/list 请求

Request(请求)

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {
    "cursor": "optional-cursor-value"
  }
}

Response(响应)

{
  "jsonrpc": "2.0",
"id": 1,
"result": {
    "tools": [
      {
        "name": "get_weather",
        "description": "Get current weather information for a location",
        "inputSchema": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "City name or zip code"
            }
          },
          "required": ["location"]
        }
      }
    ],
    "nextCursor": "next-page-cursor"
  }
}

3. 协议规范之生命周期管理

MCP定义了client-server连接的严格生命周期,确保了能力协商和状态管理。

image-20250318103231454

 

  1. Initialization(初始化): 能力协商和协议版本一致

  2. Operation(操作): 正常的协议通信

  3. Shutdown(关闭): 连接的优雅关闭

3.1 Initialization(初始化):

初始化阶段必须是 client 和 server 之间的第一次交互。在此阶段,client 和 server确定协议版本兼容性、交换和协商各自的能力、分享实施细节。

由client 发送一个包含 initialize 请求来启动此阶段,包含:

  • 支持的协议版本

  • Client 能力

  • Client 信息

{
  "jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "roots": {
        "listChanged": true
      },
      "sampling": {}
    },
    "clientInfo": {
      "name": "ExampleClient",
      "version": "1.0.0"
    }
  }
}

server 必须响应其自身的能力和信息:

{
  "jsonrpc": "2.0",
"id": 1,
"result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "logging": {},
      "prompts": {
        "listChanged": true
      },
      "resources": {
        "subscribe": true,
        "listChanged": true
      },
      "tools": {
        "listChanged": true
      }
    },
    "serverInfo": {
      "name": "ExampleServer",
      "version": "1.0.0"
    }
  }
}

成功初始化后,client 必须发送一个 initialized 通知以表明它已准备好开始正常操作:

{
  "jsonrpc": "2.0",
  "method": "notifications/initialized"
}
3.1.1 版本协商

在 initialize 请求中,client 必须发送其支持的协议版本。这应该是client 支持的最新版本。

如果server支持请求的协议版本,则必须以相同的版本进行响应。否则,server必须以其支持的其他协议版本进行响应。这应该是server支持的最新版本。

如果client 不支持server响应中的版本,则应该断开连接。

3.1.2 能力协商

client 和server 在会话期间将提供哪些可选的协议功能。

关键能力包括:

类别

能力

描述

Client

roots

提供文件系统根目录的能力

Client

sampling

支持LLM采样请求

Client

experimental

描述对非标准实验特性的支持

Server

prompts

提供提示模板

Server

resources

提供可读的资源

Server

tools

公开可调用的工具

Server

logging

发出结构化日志消息

Server

experimental

描述对非标准实验特性的支持

3.2 Operation(操作)

在操作阶段,client 和 server 根据协商的能力交换消息。

遵守协商的协议版本

仅使用成功协商的能力

3.3 Shutdown(关闭)

在关闭阶段,连接被优雅地终止。

client 发送断开连接通知

server 关闭连接

清理相关资源

4. 协议规范之传输层

MCP 目前定义了两种标准的 client-server通信传输机制:stdio(标准输入输出)和基于 SSE 的 HTTP。客户端应尽可能支持 stdio。

此外,客户端和服务器也可以以可插拔的方式实现自定义传输机制。

5. 参考

https://spec.modelcontextprotocol.io/specification/2024-11-05/

Model Context Protocol(MCP)开发教程

MCP为连接AI应用与数据源提供了一个通用的开放标准,用单一协议取代了碎片化的集成。通过这个机制, 能力小的AI应用会变成更强的应用

image-20250313132742878

 

在整个MCP的架构中,我们的AI应用(如Cline)作为MCP Hosts,通过内部的MCP Client去接入不同的MCP Server,从而达到增强能力的目的

image-20250313150255764

 

根据MCP协议,当AI应用连接到MCP Server后,能够获取多种能力,比如Tool,Prompts、Resources等

image-20250313155456430

 

详细内容见:一文说清楚让LangChain大佬“开战”的MCP是什么?

1. 常见AI应用对MCP Server能力的支持情况

目前MCP还在发展过程中,我们可以通过官方看到常见AI应用目前可以使用的能力情况。

应用对于Tool能力的使用,目前是最广泛的:

image-20250316110101508

 

 

2. 代码实现MCP Server

我们要实现一个简单的server,他将有一个tool,可以通过订单号查询物流信息。

这个server在整个架构中的位置,就是下图中绿色的块:

image-20250316182302250

 

2.1 配置环境

首先,让我们安装 uv 并设置我们的 Python 项目和环境:

安装uv工具(windows)

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

重新开启一个终端,并确认uv已经安装成功

PS G:\workspace\idea\py\hello-mcp-server> uv version
uv 0.6.6 (c1a0bb85e 2025-03-12)

在macos/linux环境中安装uv

curl -LsSf https://astral.sh/uv/install.sh | sh

uv是一个用 Rust 编写的极快的 Python 包和项目管理器。

官网:https://github.com/astral-sh/uv

创建项目,初始化环境:

# 初始化项目
uv init hello-mcp-server

# 创建Python虚拟环境
cd hello-mcp-server
uv venv

# 激活虚拟环境
.venv\Scripts\activate

# 安装依赖
uv add mcp[cli] 

image-20250316173515759

 

2.2  新建MCP Server : hello_mcp_server.py

我们新建一个Server,并增加tool来模拟通过订单号查询物流信息的功能

2.2.1 定义一个server

导入包并定义mcp实例

"""
pip install mcp[cli]
"""
from mcp.server.fastmcp import FastMCP
from pydantic import Field

# Initialize FastMCP server
mcp = FastMCP("hello-mcp-server", log_level="ERROR")

2.2.2 定义工具

通过@mcp.tool()注解,把一个函数注册为Tool

# 注册工具的装饰器,可以很方便的把一个函数注册为工具
@mcp.tool()
asyncdef query_logistics(order_id: str = Field(description="订单号")) -> str:
    """查询物流信息。当用户需要根据订单号查询物流信息时,调用此工具
    
    Args:
        order_id: 订单号
    
    Returns:
        物流信息的字符串描述
    """
    # 统一的物流信息数据
    tracking_info = [
        {"time": "2024-01-20 10:00:00", "status": "包裹已揽收", "location": "深圳转运中心"},
        {"time": "2024-01-20 15:30:00", "status": "运输中", "location": "深圳市"},
        {"time": "2024-01-21 09:00:00", "status": "到达目的地", "location": "北京市"},
        {"time": "2024-01-21 14:00:00", "status": "派送中", "location": "北京市朝阳区"},
        {"time": "2024-01-21 16:30:00", "status": "已签收", "location": "北京市朝阳区三里屯"}
    ]

    # 格式化物流信息
    result = f"物流单号:{order_id}\n\n物流轨迹:\n"
    for item in tracking_info:
        result += f"[{item['time']}] {item['status']} - {item['location']}\n"

    return result
2.2.3 使用 MCP Inspector 进行测试

MCP Inspector 是一个用于测试和调试 MCP 服务器的交互式开发工具。

https://modelcontextprotocol.io/docs/tools/inspector

启动MCP Inspector:

执行命令:mcp dev hello_mcp_server.py

(hello-mcp-server) PS G:\workspace\idea\py\hello-mcp-server> mcp dev hello_mcp_server.py
Starting MCP inspector...
Proxy server listening on port 3000

🔍 MCP Inspector is up and running at http://localhost:5173 🚀

通过浏览器打开http://localhost:5173

连接MCP Server:

点击“Connect”启动MCP Server并建立连接

1.使用标准输入输出作为传输层

2.使用命令是uv

3.uv命令的参数

image-20250316175443639

 

查询所有的Tool:

1.点击“Tools”能力标签

2.点击“List Tools”,查询server中所有的tool(调用了协议的tools/list 端点)

3.显示出所有的tool

image-20250316175807655

 

执行Tool:

1.选择需要测试的tool

2.输入入参:ORDER-123456,点击“Run Tool”(调用了协议的tools/call 端点)

3.Tool成功返回结果

image-20250316180238204

 

3. 使用Cline测试Server

打开Cline,点击上边的“MCP Server”

image-20250316162255264

 

选择“Installed”

image-20250316162350271

 

点击“Configure MCP Servers”

image-20250316162427475

 

右边会弹出配置文件

image-20250316162548292

 

将自己刚写的服务器相关配置填进去,保存

"hello-mcp-server": {
"name": "第一个MCP服务",
"key": "hello-mcp-server",
"command": "uv",       
"args": [
    "--directory",
    "G:\\workspace\\idea\\py\\hello-mcp-server\\",
    "run",
    "--with",
    "mcp",
    "mcp",
    "run",
    "hello_mcp_server.py"
  ],
"disabled": false,
"autoApprove": []
}

整个完整命令相当于:

uv --directory G:\workspace\idea\py\hello-mcp-server\ run --with mcp mcp run hello_mcp_server.py

分为3段:

  1. uv --directory G:\workspace\idea\py\hello-mcp-server\

    指定工作目录

  2. run --with mcp

    运行时必须要有mcp包被安装

  3. mcp run hello_mcp_server.py

    使用mcp启动server

左边会生成对应的服务列表,点击“Done”退出

image-20250316163505171

 

在Cline对话框中输入提示词:查一下订单为“ORDER-123456”的物流信息

image-20250316164300009

 

Cline开始调用MCP Server,点击“Approve”同意

image-20250316164312436

 

MCP Server调用成功

image-20250316164321595

 

3.1 Cline连接MCP Server的相关Client源码

Cline(相当于MCP架构中的Host)源码中,MCP相关的代码在src/services/mcp/McpHub.ts中,MCP Clinet连接MCP  Server的代码在connectToServer:

private async connectToServer(name: string, config: StdioServerParameters): Promise<void> {
  ...

try {
   // 创建新的MCP客户端实例,设置客户端名称和版本信息
   const client = new Client(
    {
     name: "Cline",
     version: this.providerRef.deref()?.context.extension?.packageJSON?.version ?? "1.0.0",
    },
    {
     capabilities: {},        // 客户端没有给服务端暴露能力
    },
   )

   // 创建标准输入输出传输实例,配置命令、参数和环境变量
   // 这个是我们配置文件的内容
   const transport = new StdioClientTransport({
    command: config.command,
    args: config.args,
    env: {
     ...config.env,
     ...(process.env.PATH ? { PATH: process.env.PATH } : {}),
    },
    stderr: "pipe", 
   })

            ......
            
   // 启动传输层,建立实际的进程间通信通道
   await transport.start()
   
   ...

   // 建立MCP客户端连接
   // 连接成功后更新服务器状态为已连接,清除错误信息
   // 初始化并获取服务器提供的工具和资源列表
   await client.connect(transport)
   connection.server.status = "connected"
   connection.server.error = ""

   // 初始化获取工具资源列表
   connection.server.tools = awaitthis.fetchToolsList(name)
   connection.server.resources = awaitthis.fetchResourcesList(name)
   connection.server.resourceTemplates = awaitthis.fetchResourceTemplatesList(name)
  } catch (error) {
   ......
  }
 }

到目前为止我们实现了一个能提供Tool能力的MCP Server

 

开源MCP服务

1. glama 各种开源MCP服务

https://glama.ai/mcp/servers

0

2. cursor.directory 可以检索

https://cursor.directory/

0

3. http://mcp.so

0

### Model Context Protocol (MCP) API 的定义 #### Model Context Protocol (MCP) Model Context Protocol 是一种用于描述模型上下文交互的协议,旨在通过标准化的方式传递数据及其语义背景。它通常涉及复杂的结构化数据交换,并支持动态调整通信中的元数据实际数据[^1]。 MCP 不仅关注数据本身,还强调数据的上下文环境以及如何解释这些数据。 #### Application Programming Interface (API) Application Programming Interface 则是一个更广泛的术语,指一组规则工具,允许不同的软件应用程序之间相互通信。API 定义了请求服务端响应的标准格式,使得开发者可以轻松集成不同服务的功能而不必理解其内部实现细节[^2]。 --- ### 主要区别 | 方面 | **Model Context Protocol (MCP)** | **API** | |---------------------|--------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------| | **核心目标** | 提供一种机制来传输带有上下文的数据,确保接收方能够正确理解处理发送过来的信息. | 提供接口让外部程序访问特定功能或数据集,简化应用间互动过程[^2]. | | **复杂度** | 更加注重于数据的意义与其关联关系,在某些情况下可能涉及到较为复杂的配置文件或者额外的消息头字段说明等内容. | 相对比之下更为简单明了;只需要遵循既定的方法签名即可完成调用操作[^2]. | | **适用场景** | 常见于机器学习框架、人工智能平台等领域当中,当需要精确表达训练样本特征向量所处的具体情境时尤为有用. | 几乎适用于任何类型的软硬件产品开发过程中——无论是移动客户端还是云端服务器都可以利用 RESTful APIs 来互相协作工作[^2]. | 值得注意的是,虽然两者都属于技术层面的概念范畴之内,但是它们各自侧重点完全不同:前者偏向理论研究方向探索未知可能性边界;后者则更多体现在工程实践上面解决现实世界里的具体需求问题上。 ```python # 示例代码展示了一个简单的 API 调用方式 import requests response = requests.get('https://api.example.com/data') data = response.json() print(data) # 对应到 MCP 中,则可能是如下形式(假设基于 JSON-RPC 实现) mcp_request = { "jsonrpc": "2.0", "method": "getContextData", "params": {"context_id": 123}, "id": 1 } result = requests.post('https://mcp.example.com/', json=mcp_request).json() print(result['result']) ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZhaoYingChao88

整理不易,还请多多支持,谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值