乐于分享
好东西不私藏

MCP 协议:赋能 AI 连接世界的核心通用标准

MCP 协议:赋能 AI 连接世界的核心通用标准

MCP协议:AI连接世界的标准

MCP(Model Context Protocol,模型上下文协议)是Anthropic在2024年底发布的开放协议,旨在为AI模型与外部工具、数据源建立标准化的通信方式。本文深入解析MCP的设计原理、协议架构、以及在AI工程实践中的应用。

一、为什么需要MCP

1.1 AI应用的核心挑战

当前AI应用面临一个根本性问题:AI模型是孤立的——它只能看到训练时的知识,无法直接与外部世界交互。RAG系统解决了知识获取问题,但工具调用、数据写入、多系统协同仍然缺乏统一标准。

典型场景:

  • AI需要从数据库读取实时数据
  • AI需要调用外部API完成特定操作
  • AI需要向多个外部系统写入数据
  • AI需要订阅实时事件流

每个AI应用都在重复造轮子:自定义的工具调用格式、自定义的API适配层、自定义的错误处理。

1.2 MCP的核心价值

MCP的定位是成为”AI世界的USB接口”——提供一个标准化的方式让AI模型与任何外部系统交互。

USB接口解决的问题:
- 不需要为每个设备设计专门的接口
- 设备插上就能用
- 标准化意味着生态化

MCP解决的问题:
- 不需要为每个外部系统设计专门的适配
- 工具接入一次,任何AI模型都能调用
- 标准化促进生态繁荣

二、MCP协议架构

2.1 核心组件

┌─────────────────────────────────────────────────────────────┐
│                      AI Application                          │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                   MCP Client                         │    │
│  │  - 维护与Server的连接                                │    │
│  │  - 序列化/反序列化消息                                │    │
│  │  - 处理协议握手                                      │    │
│  └─────────────────────────────────────────────────────┘    │
└──────────────────────────┬──────────────────────────────────┘
                           │ stdio / HTTP + SSE
┌──────────────────────────▼──────────────────────────────────┐
│                      MCP Server (进程)                       │
│  ┌─────────────────────────────────────────────────────┐    │
│  │              Protocol Engine                          │    │
│  │  - 消息路由                                           │    │
│  │  - 能力协商                                           │    │
│  │  - 错误处理                                           │    │
│  └─────────────────────────────────────────────────────┘    │
│  ┌─────────────────────────────────────────────────────┐    │
│  │               Tool Handler                           │    │
│  │  - 暴露工具清单                                       │    │
│  │  - 执行工具调用                                       │    │
│  │  - 返回结果格式化                                     │    │
│  └─────────────────────────────────────────────────────┘    │
│  ┌─────────────────────────────────────────────────────┐    │
│  │               Resource Handler                       │    │
│  │  - 管理可读取的资源                                   │    │
│  │  - 处理资源订阅                                      │    │
│  │  - 内容缓存                                          │    │
│  └─────────────────────────────────────────────────────┘    │
└──────────────────────────┬──────────────────────────────────┘
                           │
┌──────────────────────────▼──────────────────────────────────┐
│                    External Systems                          │
│  - REST APIs    - Databases    - File Systems    - etc.    │
└─────────────────────────────────────────────────────────────┘

2.2 通信协议

MCP支持两种传输方式:

stdio模式(适合本地/CLI工具):

AI App → MCP Client → stdin → MCP Server → External System
         ↑                      ↓
         └────── stdout ←───────┘

HTTP + SSE模式(适合远程服务):

AI App → MCP Client ──── HTTP POST /message ──→ MCP Server
         ↑                                              ↓
         └──────── SSE (Server-Sent Events) ←──────────┘

2.3 消息类型

MCP定义了四种核心消息类型:

// 1. Initialize - 握手协商
{"jsonrpc""2.0""id"1"method""initialize",
"params": {
"protocolVersion""2024-11-05",
"capabilities": {"roots": {}, "tools": {}},
"clientInfo": {"name""claude-desktop""version""1.0"}
 }}

{"jsonrpc""2.0""id"1"result": {
"protocolVersion""2024-11-05",
"capabilities": {"tools": {}, "resources": {}},
"serverInfo": {"name""filesystem-server""version""1.0"}
 }}

// 2. Tools/List - 列出可用工具
{"jsonrpc""2.0""id"2"method""tools/list"}

{"jsonrpc""2.0""id"2"result": {
"tools": [
     {"name""read_file""description""读取文件内容",
"inputSchema": {"type""object""properties": {
"path": {"type""string"}
      }}},
     {"name""write_file""description""写入文件内容",
"inputSchema": {"type""object""properties": {
"path": {"type""string"},
"content": {"type""string"}
      }}}
   ]
 }}

// 3. Tools/Call - 调用工具
{"jsonrpc""2.0""id"3"method""tools/call",
"params": {
"name""read_file",
"arguments": {"path""/etc/passwd"}
 }}

{"jsonrpc""2.0""id"3"result": {
"content": [{"type""text""text""root:x:0:0:root:/root:/bin/bash\n..."}]
 }}

// 4. Resources - 资源访问
{"jsonrpc""2.0""id"4"method""resources/list"}

{"jsonrpc""2.0""id"4"result": {
"resources": [
     {"uri""file:///project/config.yaml""name""Config""mimeType""application/yaml"}
   ]
 }}

三、MCP Server开发

3.1 Python SDK实现

from mcp.server.fastmcp import FastMCP

# 初始化MCP Server
mcp = FastMCP("filesystem-server")

@mcp.tool()
defread_file(path: str, encoding: str = "utf-8") -> str:
"""读取文件内容"""
with open(path, 'r', encoding=encoding) as f:
return f.read()

@mcp.tool()
defwrite_file(path: str, content: str) -> dict:
"""写入文件内容"""
with open(path, 'w', encoding='utf-8'as f:
        f.write(content)
return {"success"True"path": path, "bytes": len(content)}

@mcp.tool()
deflist_directory(path: str) -> list[dict]:
"""列出目录内容"""
import os
    items = []
for item in os.listdir(path):
        full_path = os.path.join(path, item)
        items.append({
"name": item,
"type""dir"if os.path.isdir(full_path) else"file",
"size": os.path.getsize(full_path) if os.path.isfile(full_path) elseNone
        })
return items

@mcp.resource("file://{path}")
deffile_resource(path: str) -> str:
"""动态资源访问"""
with open(path, 'r'as f:
return f.read()

# 启动服务器
if __name__ == "__main__":
    mcp.run()

3.2 带复杂参数的工具

@mcp.tool()
defsearch_codebase(
    query: str,
    file_pattern: str = "*.py",
    case_sensitive: bool = False,
    max_results: int = 50
)
 -> list[dict]:

"""
    在代码库中搜索代码

    Args:
        query: 搜索关键词
        file_pattern: 文件名模式 (glob格式)
        case_sensitive: 是否区分大小写
        max_results: 最大返回结果数
    """

import glob
import os

    results = []
for file_path in glob.glob(file_pattern, recursive=True):
ifnot os.path.isfile(file_path):
continue

try:
with open(file_path, 'r', encoding='utf-8', errors='ignore'as f:
                lines = f.readlines()

for i, line in enumerate(lines):
if case_sensitive:
                    match = query in line
else:
                    match = query.lower() in line.lower()

if match:
                    results.append({
"file": file_path,
"line": i + 1,
"content": line.strip(),
"context": lines[max(0, i-2):i] + lines[i+1:min(len(lines), i+3)]
                    })

if len(results) >= max_results:
return results
except Exception:
continue

return results

3.3 流式响应工具

from typing import AsyncIterator

@mcp.tool()
asyncdefstream_log_tail(
    path: str,
    lines: int = 100
)
 -> AsyncIterator[dict]:

"""流式读取日志文件最后N行"""
import asyncio

with open(path, 'r'as f:
        all_lines = f.readlines()

    last_lines = all_lines[-lines:]

for line in last_lines:
yield {"content": line.strip()}
await asyncio.sleep(0.1)  # 模拟实时推送

四、MCP Client集成

4.1 Python Client实现

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import asyncio

classMCPClient:
def__init__(self, server_command: list[str]):
        self.server_command = server_command

asyncdefinitialize(self):
        server_params = StdioServerParameters(
            command=self.server_command[0],
            args=self.server_command[1:]
        )

asyncwith stdio_client(server_params) as (read, write):
            self.session = ClientSession(read, write)
await self.session.initialize()

# 获取服务器能力
            response = await self.session.get_server_capabilities()
            print(f"Server capabilities: {response.capabilities}")

asyncdeflist_tools(self) -> list[dict]:
        response = await self.session.list_tools()
return [tool.model_dump() for tool in response.tools]

asyncdefcall_tool(
        self,
        tool_name: str,
        arguments: dict
    )
 -> dict:

        result = await self.session.call_tool(tool_name, arguments)
return result.content[0].model_dump()

# 使用示例
asyncdefmain():
    client = MCPClient(["python""filesystem_server.py"])
await client.initialize()

# 列出可用工具
    tools = await client.list_tools()
    print("Available tools:", [t["name"for t in tools])

# 调用工具
    result = await client.call_tool("read_file", {"path""/tmp/test.txt"})
    print("File content:", result["text"])

asyncio.run(main())

4.2 与LangChain集成

from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

# 初始化MCP客户端,连接多个服务器
client = MultiServerMCPClient({
"filesystem": {
"command""python",
"args": ["/path/to/filesystem_server.py"]
    },
"database": {
"command""python",
"args": ["/path/to/database_server.py"]
    }
})

# 获取所有工具
tools = client.get_tools()

# 创建Agent
llm = ChatOpenAI(model="gpt-4o")
agent = create_react_agent(llm, tools)

# 运行Agent
result = agent.invoke({
"messages": [{"role""user""content""读取/tmp/config.yaml文件并总结关键配置"}]
})

五、生产环境最佳实践

5.1 Server健康检查

import asyncio
from mcp import ClientSession
from mcp.client.stdio import stdio_client

classMCPClientWithHealthCheck:
def__init__(self, server_params, health_check_timeout: float = 5.0):
        self.server_params = server_params
        self.health_check_timeout = health_check_timeout
        self._session = None

asyncdefhealth_check(self) -> bool:
"""检查MCP Server是否可用"""
try:
asyncwith stdio_client(self.server_params) as (read, write):
                session = ClientSession(read, write)
await asyncio.wait_for(
                    session.initialize(),
                    timeout=self.health_check_timeout
                )

# 尝试列出工具
await session.list_tools()
returnTrue
except asyncio.TimeoutError:
returnFalse
except Exception as e:
            print(f"Health check failed: {e}")
returnFalse

asyncdefget_session(self) -> ClientSession:
if self._session isNone:
asyncwith stdio_client(self.server_params) as (read, write):
                self._session = ClientSession(read, write)
await self._session.initialize()
return self._session

5.2 错误处理与重试

import asyncio
from mcp.error import MCPError

classResilientMCPClient:
def__init__(self, server_params, max_retries: int = 3):
        self.server_params = server_params
        self.max_retries = max_retries

asyncdefcall_with_retry(
        self,
        tool_name: str,
        arguments: dict
    )
 -> dict:

        last_error = None

for attempt in range(self.max_retries):
try:
asyncwith stdio_client(self.server_params) as (read, write):
                    session = ClientSession(read, write)
await session.initialize()

                    result = await session.call_tool(tool_name, arguments)
return result.content[0].model_dump()

except MCPError as e:
# 协议级错误,不重试
raise(f"MCP protocol error: {e}")
except Exception as e:
                last_error = e
if attempt < self.max_retries - 1:
await asyncio.sleep(2 ** attempt)  # 指数退避
continue

raise RuntimeError(f"Failed after {self.max_retries} attempts: {last_error}")

5.3 安全考虑

MCP的工具调用执行在Server进程中,需要注意:

# Server端:输入验证
@mcp.tool()
defdelete_file(path: str) -> dict:
"""删除文件(需要严格的安全检查)"""
import os

# 禁止删除系统关键路径
    forbidden_paths = ["/""/etc""/usr""/bin""/sbin""/var"]
    abs_path = os.path.abspath(path)

for forbidden in forbidden_paths:
if abs_path.startswith(forbidden):
raise ValueError(f"Cannot delete files in {forbidden}")

# 禁止跨目录删除
if".."in path:
raise ValueError("Path traversal not allowed")

# 检查文件是否存在
ifnot os.path.exists(abs_path):
return {"success"False"error""File not found"}

    os.remove(abs_path)
return {"success"True"path": path}

六、主流MCP Server生态

6.1 官方及社区Server

Server
功能
维护方
filesystem
本地文件系统访问
Anthropic官方
slack
Slack消息读写
Anthropic官方
github
GitHub API操作
Anthropic官方
puppeteer
浏览器自动化
社区
postgresql
PostgreSQL查询
社区
Brave Search
网页搜索
社区

6.2 Server发现与配置

// claude_desktop_config.json
{
"mcpServers": {
"filesystem": {
"command""npx",
"args": ["-y""@anthropic/mcp-server-filesystem"],
"config": {
"allowedDirectories": ["/Users/me/projects""/tmp"]
      }
    },
"github": {
"command""npx",
"args": ["-y""@anthropic/mcp-server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN""ghp_xxxx"
      }
    },
"postgresql": {
"command""uvx",
"args": ["mcp-server-postgres""--host""localhost""--port""5432"],
"env": {
"DATABASE_URL""postgresql://user:pass@localhost/mydb"
      }
    }
  }
}

七、协议演进与未来

MCP协议仍处于活跃开发中,以下是值得关注的方向:

7.1 采样能力(Prompt Caching的未来)

当前协议支持Server向Client”推送”数据的能力有限。未来版本可能会增强双向通信能力。

7.2 多Agent协作

MCP的设计天然支持多Agent场景:

  • 多个AI Agent通过各自的MCP Client连接同一Server
  • Server作为协调者管理资源访问冲突
  • 支持Agent间的消息传递
# 多Agent共享MCP Server
classSharedMCPBridge:
def__init__(self, server):
        self.server = server
        self.agents = {}

defregister_agent(self, agent_id: str, client_session):
        self.agents[agent_id] = client_session

asyncdefbroadcast(self, message: dict, from_agent: str):
"""向所有Agent广播消息"""
for agent_id, session in self.agents.items():
if agent_id != from_agent:
await session.send_notification("agent/message", message)

总结

MCP协议代表了AI应用架构的一个重要演进方向:

核心价值:

  • 标准化:统一的工具调用协议
  • 生态化:一次实现,到处可用
  • 安全性:清晰的权限边界

工程实践要点:

  • Server端做好输入验证和权限控制
  • Client端实现健康检查和重试机制
  • 生产环境注意监控工具调用延迟和错误率
  • 合理设计工具粒度,避免过度抽象

随着MCP生态的成熟,我们可以期待看到更多标准化的工具Server出现,AI应用的开发效率将显著提升。

文末福利

在产业智能化深度推进的当下,每一个真实场景,都是AI价值落地的核心土壤。
从大模型爆发到行业渗透,从概念验证到生产级部署,AI不再只是技术圈的狂欢,而是企业降本增效、重构竞争力的关键变量。
然而,理想很丰满,现实却很骨感——大量企业在AI转型中卡在“最后一公里”:数据散落各处、模型难以私有化、智能体无法协同、成本失控、安全存疑……
真正能落地的AI,不是调用几个API接口,而是扎根于业务痛点、生长于私有环境的系统工程。
为精准收集全行业AI转型的真实卡点与需求,帮助更多技术人、企业、机构突破“想用却用不好”的困境,马哥教育正式发起【AI转型痛点征集】活动!
AI转型痛点征集
01 参与方式
在本推文评论区留言,分享你在AI转型中遇到的具体痛点、有哪些疑问或想法,越具体、越真实越好。
02 活动时间
4月20日起
03 参与福利
只要参与,即可领取AI转型干货大礼包,包含:
🎁《1小时搭建1人公司–专家agent提示词合集》
🎁《小白玩转Python –零基础7天入门训练营》
04 领取方式
评论区留言后,扫码添加课程顾问,凭评论截图领取。
注:活动最终解释权归马哥教育所有。如有疑问,欢迎咨询课程顾问。