跳到主要内容

MCP

什么是 MCP

MCP,全称 Model Context Protocol(模型上下文协议)

是一种用于将 AI 应用程序连接到外部系统的开源标准。

使用 MCP,Claude 或 ChatGPT 等 AI 应用程序可以连接到数据源(例如本地文件、数据库)、工具(例如搜索引擎、计算器)和工作流程,从而使它们能够访问关键信息并执行任务。

可以将 MCP 视为人工智能应用的 USB-C 接口。正如 USB-C 提供了一种连接电子设备的标准化方式一样,MCP 也提供了一种将人工智能应用连接到外部系统的标准化方式。

MCP 与 Function Calling 的区别

  • MCP(Model Context Protocol),模型上下文协议
  • Function Calling(函数调用)

这两种技术都旨在增强 AI 模型与外部数据的交互能力,但 MCP 不止可以增强 AI 模型,还可以连接其他的应用系统。

架构

MCP 采用 client-server 架构

其中 MCP host(例如 Claude Code 或 Claude Desktop 等 AI 应用)与一个或多个 MCP server 建立连接。

MCP host 通过为每个 MCP server 创建一个 MCP client 来实现。

每个 MCP client 与其对应的 MCP server 保持专用连接。

  • 使用 STDIO 传输的本地 MCP server 通常服务于单个 MCP client
  • 使用 Streamable HTTP 传输的远程 MCP server 通常服务于多个 MCP client

MCP 架构的关键参与者包括:

  • MCP Host: 用于协调和管理一个或多个 MCP 客户端的 AI 应用程序
  • MCP Server: 提供工具或数据源的外部服务。可以是本地的(例如文件系统、数据库)或远程的(例如 GitHub、API)。
  • MCP Client: 在 MCP Host 中运行的组件,用于与 MCP Server 通信。

MCP Server

MCP Server 过三个基本组成部分提供功能

  • 资源(Resources):类似文件的数据,可以被客户端读取,如 API 响应或文件内容。
  • 工具(Tools):可以被 LLM 调用的函数(需要用户批准)。
  • 提示(Prompts):预先编写的模板,帮助用户完成特定任务。

MCP Client

MCP client 充当 LLM 和 MCP server 之间的桥梁,MCP client 的工作流程如下:

  • MCP client 首先从 MCP server 获取可用的工具列表。
  • 将用户的查询连同工具描述通过 function calling 一起发送给 LLM。
  • LLM 决定是否需要使用工具以及使用哪些工具。
  • 如果需要使用工具,MCP client 会通过 MCP server 执行相应的工具调用。
  • 工具调用的结果会被发送回 LLM。
  • LLM 基于所有信息生成自然语言响应。
  • 最后将响应展示给用户。

通信机制

MCP 协议支持两种主要的通信机制:基于标准输入输出的本地通信和基于SSE(Server-Sent Events)的远程通信。

这两种机制都使用 JSON-RPC 2.0 格式进行消息传输,确保了通信的标准化和可扩展性。

  • 本地通信:通过 stdio 传输数据,适用于在同一台机器上运行的客户端和服务器之间的通信。
  • 远程通信:利用 SSE 与 HTTP 结合,实现跨网络的实时数据传输,适用于需要访问远程资源或分布式部署的场景。

怎么使用和开发 MCP Server

使用

根据 客户端(claude code opencode 等)提供的方式,添加 mcp 即可

一般都是在配置文件里 加一个 mcp 项,例如:

{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/files"]
},
"git": {
"command": "uvx",
"args": ["mcp-server-git", "--repository", "path/to/git/repo"]
}
}
}

开发

以 Python 为例 官方提供了基础包

# 初始化项目
uv init mcp_getting_started
cd mcp_getting_started

# 创建虚拟环境并进入虚拟环境
uv venv
.venv\Scripts\activate.bat

# 安装依赖
uv add "mcp[cli]" httpx openai

import httpx
from mcp.server import FastMCP

# # 初始化 FastMCP 服务器
app = FastMCP('web-search')

@app.tool()
async def web_search(query: str) -> str:
"""
搜索互联网内容

Args:
query: 要搜索内容

Returns:
搜索结果的总结
"""

async with httpx.AsyncClient() as client:
response = await client.post(
'https://open.bigmodel.cn/api/paas/v4/tools',
headers={'Authorization': '换成你自己的API KEY'},
json={
'tool': 'web-search-pro',
'messages': [
{'role': 'user', 'content': query}
],
'stream': False
}
)

res_data = []
for choice in response.json()['choices']:
for message in choice['message']['tool_calls']:
search_results = message.get('search_result')
if not search_results:
continue
for result in search_results:
res_data.append(result['content'])

return '\n\n\n'.join(res_data)
提示

MCP 为我们提供了一个 @mcp.tool() 我们只需要将实现函数用这个装饰器装饰即可。函数名称将作为工具名称,参数将作为工具参数,并通过注释来描述工具与参数,以及返回

调试

使用官方提供的 Inspector 可视化工具来调试我们的服务器。

我们可以通过两种方法来运行Inspector:

  • 通过 npx:
    npx -y @modelcontextprotocol/inspector <command> <arg1> <arg2>
    npx -y @modelcontextprotocol/inspector uv run web_search.py
  • 通过 mcp dev
    mcp dev PYTHONFILE
    mcp dev web_search.py

然后,我们打开这个地址,点击左侧的 Connect 按钮,即可 连接我们刚写的服务。 然后我们切换到 Tools 栏中,点击 List Tools 按钮即可看到我们刚写的工具,我们就可以开始进行调试啦。

开发 MCP 客户端

todo

问题

MCP 与传统 REST/gRPC 的区别?

  • 答要:MCP 面向“LLM 交互”,强调能力发现、上下文优先、结构化元数据、对话期事件/日志与能力协商;REST/gRPC 面向通用服务通信,缺少对 LLM 使用场景的语义内建。
  • 实践:可以把 REST/gRPC 封装为 MCP Tool/Resource,通过 MCP 统一鉴权、审计、速率与 UI 呈现;避免在多 Agent 层写重复胶水。
  • 关键词:LLM 友好、能力协商、上下文优先、封装整合。

MCP 为什么能促进多 Agent?

  • 答要:通过标准化能力与上下文描述,避免每个框架重复集成 N 套 API;多 Agent 在“图或对话”中共享同一批 MCP 资源与工具,且具备一致的审计与权限治理。
  • 实践:把检索/知识库/业务动作都以 MCP 对外,LangGraph/CrewAI/AutoGen 各自的 Agent 通过统一适配器调用,降低异构耦合。
  • 关键词:能力复用、编排、统一治理、低耦合。

MCP 的消息/接口是如何组织的?

  • 答要:以“能力发现→资源/工具/提示元数据→调用/订阅→日志/通知→采样/补全”的循环组织,支持在单会话内协商能力与传输细节。
  • 实践:Server 在握手时声明 Capabilities;Client 依据能力决定是否开启 resources.subscribe、是否显示进度/日志;调用 Tool/读取 Resource 返回结构化内容并产生事件。
  • 关键词:能力发现、会话内协商、事件通知、结构化。

会话/上下文如何跨调用传递?

  • 答要:通过注入的 Context[ServerSession, ...] 在 Tool 执行期访问会话属性、报告日志与进度;客户端可在 UI 中渲染这些信息并做交互引导。
  • 示例:Python 进度
    @mcp.tool()
    async def long_running_task(task_name: str, ctx: Context[ServerSession, None], steps: int = 5) -> str:
    await ctx.info(f"Starting: {task_name}")
    for i in range(steps):
    await ctx.report_progress(progress=(i+1)/steps, total=1.0, message=f"Step {i+1}/{steps}")
    await ctx.debug(f"Completed step {i+1}")
    return f"Task '{task_name}' completed"

SSE 现状与迁移策略?

  • 答要:SSE 已弃用;新项目直接用 Streamable HTTP;存量系统短期双栈提供回退,测试覆盖“优先 HTTP、失败回退 SSE”的路径。
  • 参考:research/sources/ts_sdk_readme.md 1214–1309 附近注释与示例。