本手册综合整理自:
- 知乎 – MCP (Model Context Protocol),一篇就够了。 — 作者 LastWhisper
- CSDN – 一文搞懂 MCP:从入门到实战(含本地项目 MCP Server 示例) — 作者 AI架构师易筋
整理时间:2026-06-14
目录
- MCP 是什么?
- 为什么需要 MCP?
- MCP 架构详解
- MCP 工作原理(调用流程)
- MCP 与 Function Call 的关系
- MCP 与主流 Agent 框架的关系
- MCP 实战:搭建本地项目 MCP Server
- MCP Server 开发最佳实践
- 参考架构与最佳实践
- 常见问题与讨论
- 总结与学习路径
- 参考资源
1. MCP 是什么?
1.1 官方定义
MCP(Model Context Protocol,模型上下文协议)是由 Anthropic 于 2024 年 11 月 25 日 提出的开放协议,用于标准化大语言模型(LLM)与外部数据源、工具和应用之间的通信方式。
1.2 一句话理解
MCP 就是AI 世界的「USB-C」接口 — 一个通用的中间协议层,让不同的 AI 模型通过相同的接口连接各种外设(数据源/工具)。
1.3 类比帮助理解
| 领域 | 类比 | 说明 |
|---|---|---|
| 浏览器世界 | HTTP + API | 统一的数据传输和接口调用标准 |
| 数据库世界 | SQL | 统一的数据查询和操作语言 |
| AI + 工具世界 | MCP | 统一的大模型与外部工具交互协议 |
1.4 MCP 让模型做到的事
有了 MCP,大模型不再只是「会聊天」,而是可以:
- ✅ 读写文件、本地项目代码
- ✅ 访问数据库、搜索引擎、内部 API
- ✅ 调用自动化脚本、测试、构建流水线
- ✅ 在受控范围内操作本地/企业系统
💡 一句话总结:MCP 让模型从「只能说」变成「能干活」。
2. 为什么需要 MCP?
2.1 没有 MCP 之前的问题
问题一:手工 Prompt 的局限
在 MCP 之前,要让 AI 使用外部信息,通常的做法是:
- 人工从数据库筛选信息
- 手动粘贴到 prompt 中
- 当问题变复杂时,手工操作变得极其困难
问题二:Function Call 的平台依赖
许多 LLM 平台(如 OpenAI、Google)引入了 Function Call 功能,让模型可以自动调用预设函数。但存在以下问题:
- 平台依赖性强:不同平台的 Function Call API 实现差异大
- OpenAI 的调用方式与 Google 的不兼容
- 切换模型时需要重写适配代码
- 扩展性不足:新增工具需调整接口或重新训练
- 安全性模糊:难以审核与合规
2.2 MCP 的三大优势
| 优势 | 说明 |
|---|---|
| 🌐 生态丰富 | 提供大量现成 MCP Server 插件,可直接使用 |
| 🔗 统一标准 | 不限制于特定 AI 模型,支持 MCP 的模型可灵活切换 |
| 🔒 数据安全 | 敏感数据留在本地,不必全部上传云端 |
3. MCP 架构详解
3.1 三大核心组件
MCP 由三个核心组件构成:
┌────────────────────────────────────────────────────────────┐
│ Host(主机) │
│ 用户直接接触的应用程序,如 Claude Desktop、VS Code、Cursor │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ MCP Client(客户端) │ │
│ │ Host 内置的客户端,负责与 MCP Server 建立连接 │ │
│ │ 管理一个或多个 Server 连接 │ │
│ └──────────────┬───────────────────────────────────────┘ │
└─────────────────┼──────────────────────────────────────────┘
│ MCP 协议(JSON-RPC 双向流)
┌─────────────┼─────────────┐
│ │ │
┌───▼───┐ ┌───▼───┐ ┌───▼───┐
│ MCP │ │ MCP │ │ MCP │
│ Server │ │ Server │ │ Server │
│ (文件) │ │ (数据库)│ │ (API) │
└───────┘ └───────┘ └───────┘
| 组件 | 角色 | 示例 |
|---|---|---|
| Host(主机) | 用户直接接触的应用程序 | Claude Desktop、VS Code、Cursor |
| Client(客户端) | Host 内置,管理 MCP 连接 | 每个 Host 有一个 MCP Client |
| Server(服务器) | 执行实际操作的服务器 | 文件系统 MCP Server、数据库 MCP Server |
3.2 MCP Server 提供的三种功能类型
| 类型 | 说明 | 类比 | 例子 |
|---|---|---|---|
| Tools(工具) | 可被 LLM 调用的函数(需用户授权) | 文件系统的「执行」 | run_sql、search_docs、create_file |
| Resources(资源) | 可浏览的数据或状态 | 文件系统的「读取」 | 文件、数据库表、知识库、项目结构 |
| Prompts(提示) | 预先编写的模板,帮助完成特定任务 | 快捷指令 | generate_unit_test、summarize_contract |
3.3 一次完整的调用流程示例
场景:用户在 Claude Desktop 中询问 "我桌面上有哪些文档?"
用户提问
│
▼
Claude Desktop (Host)
│
▼
Claude 模型分析 → 确定需要文件信息
│
▼
MCP Client 激活 → 连接到「文件系统 MCP Server」
│
▼
MCP Server 执行文件扫描操作
│
▼
返回结果给 MCP Client
│
▼
Claude 模型处理结果 → 生成自然语言回答
│
▼
显示在 Claude Desktop 上
4. MCP 工作原理(调用流程)
4.1 模型如何选择工具?
MCP 的核心机制是 Prompt Engineering。模型并不是”智能感知”到有哪些可用工具,而是通过 将工具的结构化描述以文本形式传递给模型,让模型了解可用工具并做出选择。
完整调用流程
第 1 步:初始化所有 MCP Server
第 2 步:获取所有工具的列表(listTools)
第 3 步:将每个工具的 name + description + input_schema 格式化为文本
第 4 步:构建 system prompt,包含工具列表和 few-shot 示例
第 5 步:system prompt + 用户消息 一起发送给 LLM
第 6 步:LLM 分析后决定:
├── 无需工具 → 直接生成自然语言回复
└── 需要工具 → 输出结构化 JSON(工具名 + 参数)
第 7 步:客户端执行工具(callTool)
第 8 步:工具执行结果再次发给 LLM
第 9 步:LLM 结合结果生成最终回答
4.2 工具描述的来源
使用 @mcp.tool() 装饰器时:
函数名 → 工具名(name)
函数 docstring → 工具描述(description)
函数参数 → 工具参数(input_schema,JSON Schema)
4.3 代码层面的实现原理
以下为 MCP 官方 Python SDK 的简化代码,展示核心逻辑:
# ===== 获取所有工具 =====
all_tools = []
for server in self.servers:
tools = await server.list_tools()
all_tools.extend(tools)
# ===== 将工具描述格式化为文本 =====
tools_description = "\n".join(
[tool.format_for_llm() for tool in all_tools]
) # ===== 构建 system prompt ===== system_message = ( “You are a helpful assistant with access to these tools:\n\n” f”{tools_description}\n” “Choose the appropriate tool based on the user’s question. ” “If no tool is needed, reply directly.\n\n” “IMPORTANT: When you need to use a tool, you must ONLY respond with ” “the exact JSON object format below, nothing else:\n” ‘{“tool”: “tool-name”, “arguments”: {…}}\n\n’ “After receiving a tool’s response:\n” “1. Transform the raw data into a natural, conversational response\n” “2. Keep responses concise but informative\n” ) # ===== 发送给 LLM ===== messages = [{“role”: “system”, “content”: system_message}] messages.append({“role”: “user”, “content”: user_input}) llm_response = self.llm_client.get_response(messages)
4.4 关键结论
- 🔑 工具文档至关重要 — 精心编写的名称、docstring 和参数说明直接影响模型选择效果
- 🔑 任何模型都适配 MCP — 因为基于 prompt,但非 Claude 模型效果可能不如 Claude(未经专门训练)
- 🔑 无效调用会被跳过 — 代码中有异常处理,不会因错误的 tool call 崩溃
- 🔑 执行结果会回传 — 工具执行结果会和上下文一起重新发给模型,生成最终回答
5. MCP 与 Function Call 的关系
5.1 核心区别
| 维度 | Function Call | MCP |
|---|---|---|
| 性质 | 模型能力(API 特性) | 通信协议(标准) |
| 平台依赖 | 每个平台不同 | 统一标准 |
| 工具发现 | 手动硬编码 | 自动发现(listTools) |
| 工具开发 | 每个平台各写一套 | 写一次,到处用 |
| 扩展性 | 需调整模型接口 | 新增 MCP Server 即可 |
5.2 正确理解
MCP 和 Function Call 不是二选一的关系,而是调用链上的两个环节。
- Function Call 是模型内部机制:模型决定要不要调用函数、生成参数
- MCP 是外部协议标准:定义函数怎么描述、怎么被发现、怎么执行
两者可以叠加使用:底层用 MCP 管理工具,上层用 Function Call 做模型选择。
5.3 一句话总结社区观点
「自己用是 Function Call,开发给别人用就是 MCP。」— 夜Xer(知乎评论)
6. MCP 与主流 Agent 框架的关系
6.1 一句话对比
| 技术 | 定位 |
|---|---|
| MCP | 标准化协议,解决「模型 ↔ 工具/数据」怎么连 |
| LangGraph | Agent / 工作流编排框架,有状态图描述复杂流程 |
| CrewAI | 多 Agent 协作框架,像组织团队那样组织 Agent |
| AutoGen | 多 Agent 对话与协作框架,偏研究和复杂协作模式 |
6.2 抽象层级对比
┌──────────────────────────────────┐
│ 入口层(ChatGPT / IDE / 前端)│
├──────────────────────────────────┤
│ 编排层(LangGraph / CrewAI) │
├──────────────────────────────────┤
│ 能力层 ─ MCP(统一的工具协议) │
├──────────────────────────────────┤
│ MCP Server(DB / 文件 / API) │
└──────────────────────────────────┘
6.3 MCP 不是竞品,是底座
MCP 不代表 LangGraph / CrewAI / AutoGen,它们是完全不同的层级:
- MCP = 能力层(工具协议)
- LangGraph / CrewAI / AutoGen = 编排层(流程与 Agent 逻辑)
💡 组合拳架构:你可以只实现一套 MCP Server,然后在 LangGraph、CrewAI、AutoGen 中通用,也支持直接接入 ChatGPT / Claude / IDE。
6.4 典型选型建议
| 场景 | 推荐方案 |
|---|---|
| 工具层标准化 | ✅ 优先铺 MCP,作为统一能力层 |
| 多步骤、有状态流程 | ✅ LangGraph(持久化、回溯、人工审核) |
| 多角色团队协作 | ✅ CrewAI(调研→撰写→审核→发布) |
| 多 Agent 协作研究 | ✅ AutoGen |
7. MCP 实战:搭建本地项目 MCP Server
7.1 环境准备
# 创建项目目录
mkdir mcp-local-project
cd mcp-local-project
# 创建虚拟环境
python -m venv .venv
# Windows 激活
.venv\Scripts\activate
# macOS / Linux 激活
source .venv/bin/activate
# 安装 MCP SDK
pip install "mcp[cli]"
7.2 编写 MCP Server(Python)
以下是一个完整的 MCP Server 示例,将本地项目目录暴露为工具和资源:
# server.py
"""
针对本地项目的 MCP Server 示例:
- 使用 FastMCP(官方 Python SDK)
- 暴露项目文件浏览 / 阅读 / 搜索为 MCP 工具和资源
"""
import os
from pathlib import Path
from typing import List, Dict
from mcp.server.fastmcp import FastMCP
# ====== 配置项目根目录 ======
BASE_DIR = Path(
os.getenv("MCP_PROJECT_ROOT", Path(__file__).parent)
).resolve()
def _safe_path(relative: str) -> Path:
"""防止目录穿越:确保路径在 BASE_DIR 内"""
candidate = (BASE_DIR / relative).resolve()
if not str(candidate).startswith(str(BASE_DIR)):
raise ValueError("路径越界:只能访问项目根目录之下的文件")
return candidate
# 创建 MCP Server
mcp = FastMCP(name="LocalProjectServer", json_response=True)
# ====== 工具 1:列出项目文件 ======
@mcp.tool()
def list_project_files(
subdir: str = ".",
max_files: int = 100,
) -> List[str]:
"""
列出项目目录下的文件(相对路径)。
- subdir: 相对项目根目录的子目录
- max_files: 最多返回多少个文件
"""
root = _safe_path(subdir)
if not root.exists():
raise FileNotFoundError(f"子目录不存在: {subdir}")
files: List[str] = []
for path in root.rglob("*"):
if path.is_file():
rel = path.relative_to(BASE_DIR).as_posix()
files.append(rel)
if len(files) >= max_files:
break
return files
# ====== 工具 2:读取单个文件 ======
@mcp.tool()
def read_project_file(
path: str,
max_bytes: int = 20000,
) -> str:
"""
读取项目中的某个文本文件。
- path: 文件相对项目根目录的路径
- max_bytes: 最多返回多少字节内容
"""
file_path = _safe_path(path)
if not file_path.is_file():
raise FileNotFoundError(f"文件不存在: {path}")
data = file_path.read_text(encoding="utf-8", errors="replace")
if len(data) > max_bytes:
data = data[:max_bytes] + "\n\n...[内容已截断]..."
return data
# ====== 工具 3:在项目中搜索 ======
@mcp.tool()
def search_in_project(
pattern: str,
max_results: int = 20,
) -> List[Dict[str, str]]:
"""
在项目中做简单的字符串搜索(不区分大小写)。
- pattern: 要搜索的子串
- max_results: 最多返回多少条匹配结果
"""
if not pattern:
raise ValueError("pattern 不能为空")
results: List[Dict[str, str]] = []
lower_pattern = pattern.lower()
allowed_suffixes = {".py", ".md", ".txt", ".json", ".yaml", ".yml", ".toml"}
for f in BASE_DIR.rglob("*"):
if not f.is_file():
continue
if f.suffix and f.suffix.lower() not in allowed_suffixes:
continue
try:
text = f.read_text(encoding="utf-8", errors="ignore")
except Exception:
continue
idx = text.lower().find(lower_pattern)
if idx == -1:
continue
start = max(0, idx - 80)
end = min(len(text), idx + len(pattern) + 80)
snippet = text[start:end].replace("\n", " ")
results.append({
"path": f.relative_to(BASE_DIR).as_posix(),
"snippet": snippet,
})
if len(results) >= max_results:
break
return results
# ====== 资源:项目 README ======
@mcp.resource("project://readme")
def project_readme() -> str:
"""返回项目根目录下的 README 内容"""
for name in ("README.md", "readme.md", "README.txt", "Readme.md"):
candidate = BASE_DIR / name
if candidate.exists():
return candidate.read_text(encoding="utf-8", errors="replace")
return "未在项目根目录找到 README 文件。"
if __name__ == "__main__":
mcp.run(transport="streamable-http")
7.3 运行与测试
# 1. 设置项目根目录
# Windows PowerShell:
$env:MCP_PROJECT_ROOT="C:\Users\您的用户名\您的项目目录"
# macOS / Linux:
export MCP_PROJECT_ROOT=/path/to/your/project
# 2. 启动 MCP Server
python server.py
# 默认在 http://localhost:8000/mcp 暴露 MCP 端点
# 3. 使用 MCP Inspector 调试(推荐)
npx -y @modelcontextprotocol/inspector
# 4. 在浏览器中打开 Inspector →
# 填写 MCP Server URL: http://localhost:8000/mcp
# 连接后可查看 listTools / listResources / 手动调用工具
7.4 接入 Claude Desktop
编辑 claude_desktop_config.json(macOS 路径:~/Library/Application Support/Claude/):
{
"mcpServers": {
"local-project-server": {
"command": "python",
"args": [
"/path/to/your/server.py"
],
"env": {
"MCP_PROJECT_ROOT": "/path/to/your/project"
}
}
}
}
7.5 接入 ChatGPT / IDE / Agent 框架
在支持 MCP 的客户端中配置 MCP Server 地址(http://localhost:8000/mcp),之后模型就可以:
- 直接阅读本地项目代码
- 根据上下文自动调用搜索工具
- 结合文件内容提供重构 / 修复 / 文档建议
7.6 扩展思路
在上述基础上可以添加更多工具:
run_tests()— 运行测试(pytest/npm test),返回摘要build_project()— 触发构建(严格白名单)get_api_endpoints()— 解析路由,导出 API 列表search_legal_clauses()— 合同模板结构化检索
⚠️ 设计原则:
- 所有文件访问走
_safe_path,限制在 BASE_DIR 内 - 有副作用的操作走白名单
- 工具参数结构化、类型明确,利于模型构造正确参数
8. MCP Server 开发最佳实践
8.1 Anthropic 推荐的 LLM 辅助开发法
使用 LLM 帮助你生成 MCP Server 的步骤:
Step 1:引入领域知识(Domain Knowledge)
把以下信息作为上下文提供给 LLM:
- 访问 MCP 官方文档
- 复制 MCP Python SDK 或 TypeScript SDK 的 README
Step 2:描述你的需求
打造一个 MCP 服务器,它能够:
- 连接到我的 PostgreSQL 数据库
- 将表格结构作为资源开放出来
- 提供运行只读 SQL 查询的工具
- 包含常见数据分析任务的引导
Step 3:LLM 生成代码,手动测试 → 调试 → 上线
8.2 MCP Server 开发原则
- 安全性先行
- 限制文件访问范围(如
_safe_path模式) - 有副作用的操作设白名单
- 敏感操作需用户授权
- 工具描述要精细
- 命名清晰:工具名见名知意
- 写完整的 docstring
- 参数定义准确,标注 required/optional
- 错误处理要完善
- 参数校验、路径校验
- 返回明确的错误信息
- 异常不崩溃
- 输入输出结构化
- 输入参数用明确定义的类型
- 输出尽量结构化,便于模型处理
9. 参考架构与最佳实践
9.1 推荐的企业级架构
┌─────────────────────────────────────────────┐
│ 入口层(User Entry) │
│ ChatGPT · Claude · VS Code · Cursor │
│ 企业内部前端 · Slack/钉钉 Bot │
├─────────────────────────────────────────────┤
│ 编排层(Orchestration) │
│ LangGraph · CrewAI · AutoGen │
│ 负责流程编排、有状态管理、多 Agent 协作 │
├─────────────────────────────────────────────┤
│ 能力层(MCP 协议层) │
│ 统一的工具发现、调用、通信标准 │
├──────────┬──────────┬──────────┬───────────┤
│ DB MCP │ FS MCP │ API MCP │ 三方 MCP │
│ 数据库 │ 文件系统 │ 项目能力 │ 第三方API │
│ 访问 │ 文档库 │ 代码审查 │ 邮件/日程 │
└──────────┴──────────┴──────────┴───────────┘
9.2 典型企业 MCP Server 矩阵
| MCP Server | 功能 | 适用场景 |
|---|---|---|
db-mcp-server | 封装数据库访问(只读查询、Schema 浏览) | BI 分析、数据报表 |
fs-mcp-server | 封装文件系统/文档库 | 代码审查、文档管理 |
project-mcp-server | 封装本地项目能力 | IDE 辅助、代码审查 |
thirdparty-mcp-server | 封装第三方 API | 邮件、日程、CRM 操作 |
9.3 项目迁移建议
从「会用大模型」迈向「打造 AI 能力平台」:
- ✅ 在真实项目中改造示例 MCP Server
- ✅ 接入 IDE / Agent 框架
- ✅ 逐步把日常重复工作迁移到 MCP + Agent 上
10. 常见问题与讨论
Q1:MCP 和裸的 Function Call 到底有什么区别?
MCP 本质上是 Function Call 的标准封装。区别在于:
- Function Call 是模型的能力(每个平台各写一套)
- MCP 是工具管理协议(写一次,到处用)
当你有多个模型、多个入口时,MCP 的价值就体现出来了。
Q2:如果工具有成百上千个,MCP 还能用吗?
这是 MCP 当前的一个挑战。当工具太多时:
- 上下文塞不下所有工具描述
- 模型在大量工具中选择时鲁棒性下降
解决方案:
- 分层检索(树状结构,先分大类再选小类)
- 动态加载(根据上下文只暴露相关工具)
- 工具分类 + 路由机制
Q3:MCP 和 ReAct 有什么关系?
MCP 本质上就是 ReAct 模式的应用(ReAct = Reasoning + Acting,2023 年已有)。MCP 的优势在于标准化和生态建设。
Q4:MCP 是否必须用 Claude?
不是。任何支持 MCP 的模型都可以用。但 Claude 对 MCP 有专门训练(自家的协议),体验最好。
Q5:MCP Server 可以远程部署吗?
可以。MCP 支持两种传输方式:
- stdio — 本地进程间通信(本地开发)
- HTTP + SSE — 远程服务器通信(生产环境)
11. 总结与学习路径
11.1 核心要点总结
| 维度 | 内容 |
|---|---|
| 本质 | 统一的协议标准,AI 世界的”USB-C”接口 |
| 价值 | 解决 Function Call 平台依赖,提供统一、开放、安全的工具调用 |
| 架构 | Host → Client → Server 三层架构 |
| 原理 | 基于 Prompt Engineering 的工具选择和调用 |
| 使用 | 普通用户直接使用现成 MCP Server,零门槛 |
| 开发 | Python/TypeScript SDK,工具开发相对简单 |
| 生态 | 处于发展初期,但已有大量现成 Server |
11.2 推荐学习路径
第 1 步:理解概念(本文档 📖)
→ 了解 MCP 是什么、为什么需要
第 2 步:体验现有 MCP Server(🔌)
→ 使用官方 Filesystem / Database Server
→ 配置 Claude Desktop 或 Cursor 体验
第 3 步:动手开发(💻)
→ 用 Python SDK 写一个简单的 MCP Server
→ 用 MCP Inspector 调试
第 4 步:接入框架(🔗)
→ 接入 LangGraph / CrewAI / 自定义应用
第 5 步:生产部署(🚀)
→ 安全加固、错误处理、性能优化
12. 参考资源
官方资源
| 资源 | 链接 |
|---|---|
| MCP 官方文档 | https://modelcontextprotocol.io/ |
| MCP Python SDK | https://github.com/modelcontextprotocol/python-sdk |
| MCP TypeScript SDK | https://github.com/modelcontextprotocol/typescript-sdk |
| 官方 MCP Servers | https://github.com/modelcontextprotocol/servers |
| Anthropic MCP 公告 | https://www.anthropic.com/news/model-context-protocol |
MCP Server 市场
| 资源 | 链接 |
|---|---|
| Awesome MCP Servers | https://github.com/punkpeye/awesome-mcp-servers |
| MCP Servers 网站 | https://mcpservers.org/ |
| MCP Market(国内) | http://mcpmarket.cn |
开发调试工具
| 工具 | 说明 |
|---|---|
| MCP Inspector | npx -y @modelcontextprotocol/inspector — Web 界面调试 |
| MCP CLI | 通过 mcp 命令本地调试 Server |
最后更新:2026-06-14
Happy Learning! 🚀 祝你学习愉快!








文章不错支持一下,非常喜欢