第4章 MCP 工具实践¶
学习目标¶
- 掌握通过 MCP 调用向量数据库、浏览器、文件系统等常用工具
- 了解社区主流 MCP Server 的能力与选型
- 能够自定义开发业务专用的 MCP 工具
- 理解多工具集成时的命名、冲突与上下文管理
- 构建一个具备多工具协同能力的实用 Agent
问题导入¶
前三章我们理解了 MCP 的概念、Server 开发与 Client 集成。但"会造工具"和"用好工具"是两回事。一个真实的 Agent 往往需要同时操作:本地文件(读配置)、向量数据库(做检索)、浏览器(抓网页)、代码仓库(查 PR)。如果每个工具都自己写 Server,工作量巨大。好在 MCP 社区已经沉淀了一批高质量的开源 Server,本卷的核心价值之一就是"复用生态"。
本章我们将调用几个真实场景下的 MCP Server,并演示如何把自定义业务工具纳入同一套体系,最终构建一个多工具协同的 Agent。
核心概念¶
1. 常用 MCP Server 推荐¶
社区(如 modelcontextprotocol/servers 仓库)已提供大量官方与第三方 Server:
| Server | 能力 | 传输 | 典型用途 |
|---|---|---|---|
| filesystem | 读写本地文件 | stdio | 读取配置、代码、日志 |
| postgres / sqlite | 数据库查询 | stdio | 业务数据检索 |
| puppeteer / playwright | 浏览器自动化 | stdio | 网页抓取、表单填写 |
| github | 仓库、PR、Issue 操作 | stdio/HTTP | 代码协作 |
| slack | 消息读写 | HTTP | 团队协作 |
| brave-search / fetch | 网页搜索 | HTTP | 实时信息检索 |
| chroma / qdrant | 向量数据库 | stdio/HTTP | RAG 检索 |
选型原则:优先用官方维护的 Server,社区贡献的需审查代码;远程能力选 HTTP,本地能力选 stdio。
2. 文件系统 Server¶
filesystem Server 把指定目录暴露为可读写的资源与工具,是本地 Agent 的"瑞士军刀"。
from agents.mcp import MCPServerStdio
fs_server = MCPServerStdio(
params={
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"],
}
)
它暴露 read_file、write_file、list_directory 等工具,以及 file://{path} 资源。注意通过参数限定可访问目录,避免越权。
3. 向量数据库 Server(RAG 集成)¶
RAG 场景下,Agent 需要语义检索知识库。chroma 或 qdrant 的 MCP Server 把"插入向量""查询相似"封装为工具。
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("rag-tools")
@mcp.tool()
async def search_kb(query: str, top_k: int = 3) -> list[dict]:
"""在知识库中语义检索相关片段"""
# 调用底层向量库 SDK(伪代码)
results = await chroma_collection.query(query_texts=[query], n_results=top_k)
return [{"text": d, "score": s} for d, s in zip(results["documents"][0], results["distances"][0])]
这样 Agent 在回答用户问题时,模型会自动决定调用 search_kb 检索知识库,再基于结果回答。
4. 浏览器 Server¶
playwright MCP Server 让 Agent 能"看"网页、点击按钮、填表单。常用于"帮我把这个网页的关键信息提取出来"或"在 OA 系统提交一条请假申请"。
browser_server = MCPServerStdio(
params={"command": "npx", "args": ["-y", "@executeautomation/playwright-mcp-server"]}
)
5. 自定义工具开发¶
当社区 Server 不能满足时,自研是最直接的路径。常见自定义场景:内部 ERP 接口、专有算法、合规审计。开发流程见第 2 章,关键是把"业务能力"映射为"模型可理解的工具描述"。
6. 多工具集成注意事项¶
- 工具数量:单个 Agent 工具数建议 ≤ 15,过多会让模型选择困难。
- 命名规范:用业务前缀避免冲突,如
hr_query_employee、finance_query_budget。 - 上下文压缩:工具结果过大时应在 Server 端截断或摘要,避免吃满上下文窗口。
- 依赖管理:本地 stdio Server 用
npx/uvx按需拉起,避免环境冲突。
原理图¶
flowchart TB
Agent["Agent(多工具协同)"]
subgraph Local["本地工具(stdio)"]
FS["filesystem<br/>读写文件"]
DB["sqlite<br/>业务数据"]
RAG["chroma<br/>知识库检索"]
end
subgraph Remote["远程工具(HTTP)"]
GH["github<br/>代码协作"]
SL["slack<br/>团队消息"]
WEB["playwright<br/>浏览器"]
end
Agent <--> FS
Agent <--> DB
Agent <--> RAG
Agent <-.HTTP.-> GH
Agent <-.HTTP.-> SL
Agent <-.HTTP.-> WEB
User["用户:帮我查最新 PR 并总结知识库相关文档"] --> Agent
Agent -->|1. 查 PR| GH
Agent -->|2. 检索文档| RAG
Agent -->|3. 写总结| FS
Agent -->|4. 通知团队| SL
classDef agent fill:#e3f2fd,stroke:#1976d2
classDef local fill:#fff3e0,stroke:#f57c00
classDef remote fill:#f3e5f5,stroke:#7b1fa2
class Agent,User agent
class Local,FS,DB,RAG local
class Remote,GH,SL,WEB remote
图:多工具集成——Agent 同时挂载本地与远程 MCP Server,按用户意图编排调用顺序
示例代码¶
下面是一个集成文件系统、知识库检索、自定义工具的多工具 Agent。
# multi_tool_agent.py
# pip install openai-agents mcp chromadb
import asyncio
from pathlib import Path
from agents import Agent, Runner
from agents.mcp import MCPServerStdio
from mcp.server.fastmcp import FastMCP
# ---------- 1. 自定义知识库 Server ----------
rag = FastMCP("kb-server")
@rag.tool()
async def search_kb(query: str, top_k: int = 3) -> str:
"""在产品知识库中检索相关文档片段"""
# 演示用静态数据,实际接 chroma/qdrant
docs = [
{"id": 1, "text": "退款政策:7 天内无理由退款,需提供订单号。"},
{"id": 2, "text": "发票申请:在订单详情页点击'申请发票'。"},
{"id": 3, "text": "会员等级:白银/黄金/铂金,按年消费升级。"},
]
# 简单关键词匹配(生产用向量检索)
hits = [d for d in docs if query in d["text"]][:top_k]
return "\n".join(f"[{d['id']}] {d['text']}" for d in hits) or "未找到相关文档"
# ---------- 2. 启动自定义 Server 为子进程 ----------
# 实际工程中 rag_server.py 单独文件,这里演示连接方式
async def make_rag_server():
return MCPServerStdio(
params={"command": "python", "args": ["rag_server.py"]}
)
async def make_fs_server():
return MCPServerStdio(
params={
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "./workspace"],
}
)
# ---------- 3. 构建多工具 Agent ----------
async def main():
rag_server = await make_rag_server()
fs_server = await make_fs_server()
await rag_server.connect()
await fs_server.connect()
agent = Agent(
name="客服助手",
instructions=(
"你是企业客服助手。回答用户问题时:\n"
"1. 先用知识库工具检索相关政策;\n"
"2. 如需保存记录,用文件工具写到 ./workspace/ 目录;\n"
"3. 回答要简洁并注明来源文档 ID。"
),
model="gpt-4.1",
mcp_servers=[rag_server, fs_server],
)
result = await Runner.run(
agent, "我想退款,订单号 TKT-1234,帮我查一下政策并记录到文件。"
)
print(result.final_output)
await rag_server.cleanup()
await fs_server.cleanup()
if __name__ == "__main__":
asyncio.run(main())
说明:
search_kb是自研工具,封装企业知识库检索逻辑。filesystemServer 来自社区,Agent 自动获得文件读写能力。- 模型会按 system prompt 的指引,先检索政策再写文件,实现多工具协同。
企业案例¶
案例 1:工具生态建设¶
某大型企业构建内部"MCP 工具市场",按业务域分类发布 Server:HR 域(查员工、查考勤)、财务域(查预算、查报销)、研发域(查 PR、查 CI)。每个 Server 由对应业务团队维护,Agent 平台统一接入。新业务上 Agent 时,"挑工具"像"逛应用商店"。
案例 2:研发效能 Agent¶
研发团队的 Agent 同时挂载 github、playwright、filesystem、chroma 四个 Server。开发者说"帮我把这个 PR 的改动跑一遍冒烟测试并截图存档",Agent 会:拉 PR diff(github)→ 启动本地测试 → 截图(playwright)→ 保存到报告目录(filesystem)→ 检索历史同类问题(chroma)。
案例 3:智能运维巡检¶
运维 Agent 挂载 sqlite(查 CMDB)、playwright(抓监控大盘)、自定义"告警确认"Server。每天定时巡检,发现异常自动截图存证并创建工单,把人工巡检时间从 2 小时降到 10 分钟。
常见问题¶
Q1:npx 拉起 Server 很慢怎么办?
首次 npx 会下载包,慢时可预先 npm i -g 全局安装,或用 uvx 管理 Python Server。生产环境建议把 Server 打成镜像,避免运行时拉取。
Q2:工具结果太大撑爆上下文怎么办? 在 Server 端做摘要或分页,返回"概要 + 总数",需要详情时再用第二个工具翻页。也可在 Client 端做截断。
Q3:本地 stdio Server 和远程 HTTP Server 能混用吗? 可以。Agent SDK 支持同时挂载不同传输的 Server,工具名通过 Server 名前缀消歧。
Q4:如何评估一个社区 Server 是否安全? 看维护方(官方优先)、Star 数、最近提交、是否有审计。重点检查它访问了哪些资源、是否外发数据。生产环境建议自建镜像并锁定版本。
Q5:自定义工具该用同步还是异步?
IO 密集型(HTTP、DB、文件)用 async def;CPU 密集型可用同步函数,SDK 会放到线程池。避免在异步函数里写阻塞调用。
面试题¶
1. 列举 3 个常用 MCP Server 及用途。 答:filesystem(本地文件读写)、chroma(向量检索/RAG)、playwright(浏览器自动化)。
2. 多工具集成时如何避免工具名冲突?
答:用业务前缀命名工具(如 hr_query);Agent SDK 也会用 Server 名做前缀消歧;按场景分组加载 Server,控制单 Agent 工具数。
3. 如何把 RAG 集成进 MCP?
答:把向量库的"插入""检索"封装为 MCP Server 的工具,Agent 调用 search_kb 时由 Server 内部执行向量查询并返回片段。
4. 工具结果过大如何处理? 答:Server 端摘要/分页返回概要,Client 端可截断,必要时用第二个工具翻页取详情。
5. 自定义 MCP 工具开发的要点? 答:清晰的 docstring(模型选工具的依据)、Pydantic 校验参数、IO 用异步、敏感操作加审批、结果适度精简。
练习题¶
- 用
filesystemServer 构建一个 Agent,让它读取./workspace/notes.md并总结要点写到summary.md。 - 自研一个
calculatorMCP Server,提供加减乘除工具,让 Agent 能解决"帮我算一下这个订单的总价"类问题。 - 集成
chroma向量库,把本卷前 3 章的 Markdown 灌入,构建一个能回答"MCP 是什么"的 RAG Agent。
小结¶
本章聚焦实战,演示了如何用社区 MCP Server(文件系统、浏览器、向量库)与自定义工具构建多工具协同 Agent。核心要点:优先复用社区生态;自定义工具要写好描述与校验;多工具注意命名与上下文压缩;按业务域组织工具市场。下一章我们将转向安全维度,讨论工具调用的审批、权限与审计。