MCP 集成:什么时候接外部工具,什么时候暴露能力
问题场景
Tool 适合把本项目里的函数交给 Agent 使用。但很多能力已经存在于外部系统:GitHub、文档库、数据库、浏览器、企业内部服务。此时有两种选择:
- 用普通 Tool 直接写 API 调用。
- 用 MCP 接入或暴露一组工具。
MCP 的价值是让工具生态有统一协议。Mastra 同时支持 MCPClient 和 MCPServer。
两个方向
| 方向 | Mastra 类 | 作用 |
|---|---|---|
| 接入外部能力 | MCPClient | 把外部 MCP server 的工具加载给 Agent |
| 暴露本项目能力 | MCPServer | 把 Mastra tools、agents、workflows 暴露给 MCP 客户端 |
mermaid
flowchart LR
A[Study Agent] --> B[MCPClient]
B --> C[外部 Docs MCP]
B --> D[GitHub MCP]
B --> E[浏览器 MCP]
F[Cursor / Claude / 其他 Agent] --> G[MCPServer]
G --> H[searchCourseTool]
G --> I[studyPlanWorkflow]
G --> J[studyAgent]MCPClient:加载外部工具
官方文档说明,MCPClient 可以连接本地命令或远程 URL。静态场景可以在 Agent 定义时 await mcp.listTools(),多租户场景更适合每次请求用 listToolsets()。
ts
import { MCPClient } from '@mastra/mcp'
const docsMcp = new MCPClient({
id: 'docs-mcp',
servers: {
docs: {
command: 'npx',
args: ['-y', 'some-docs-mcp'],
},
},
})
export const researchAgent = new Agent({
id: 'research-agent',
model: 'openai/gpt-5.4',
tools: await docsMcp.listTools(),
})如果每个用户有不同凭证,不要把工具静态挂在 Agent 上。应在请求时创建 MCPClient,并把 toolsets 传给 .generate() 或 .stream()。
MCPServer:暴露本项目能力
MCPServer 用来把本项目能力开放出去:
ts
import { MCPServer } from '@mastra/mcp'
export const studyMcpServer = new MCPServer({
id: 'study-mcp-server',
name: 'Study Agent MCP Server',
version: '1.0.0',
agents: { studyAgent },
tools: { searchCourseTool },
workflows: { studyPlanWorkflow },
})然后在 Mastra 实例中注册:
ts
export const mastra = new Mastra({
mcpServers: { studyMcpServer },
})这样其他 MCP 客户端可以发现并调用 Study Agent 的工具和工作流。
静态工具和动态工具
| 方式 | 适合 | 风险 |
|---|---|---|
await mcp.listTools() | 单用户、固定配置、CLI | 用户间凭证无法隔离 |
await mcp.listToolsets() | SaaS、多租户、用户自带凭证 | 每次请求要管理连接生命周期 |
对于 vibe coding 项目,建议先从静态工具开始验证,再在真正有多用户需求时改动态 toolsets。
工具审批
官方 MCP 文档说明,MCP server 定义中也可以要求工具审批。接入外部系统时,这一点很关键:
| 外部工具 | 默认风险 | 建议 |
|---|---|---|
| 搜索文档 | 低 | 可直接执行 |
| 创建 GitHub issue | 中 | 根据项目权限审批 |
| 发送邮件 | 高 | 必须审批 |
| 删除文件或记录 | 高 | 必须审批 |
| 执行命令 | 高 | 默认禁用或强审批 |
Vibe coding 提示词
text
请帮我判断 Study Agent 是否应该用 MCP。
需求:
- [列出外部系统]
- [列出是否需要读/写/删除]
- [说明是否多用户]
请输出:
1. 哪些能力用普通 Tool。
2. 哪些能力用 MCPClient。
3. 是否需要 MCPServer 暴露本项目能力。
4. 静态 listTools 还是动态 listToolsets。
5. 哪些工具必须 requireToolApproval。
不要直接写代码。验证方式
| 验证项 | 方法 |
|---|---|
| 外部 server 可连接 | 启动时列出 tools |
| 工具名称清楚 | 检查 Studio 或 stream 中 toolName |
| 多用户凭证隔离 | 两个用户不能复用彼此 token |
| 写操作审批 | stream 中出现 approval 事件 |
| 连接及时释放 | 请求结束后 disconnect |
常见错误
| 错误 | 后果 | 修复 |
|---|---|---|
| 能用普通 Tool 却先上 MCP | 复杂度增加 | 本地函数先用 Tool |
多用户场景静态 listTools() | 凭证串用 | 改成请求级 listToolsets() |
| 外部写操作不审批 | Agent 可直接造成副作用 | server 或 tool 级审批 |
| 把私密 MCP URL 写进文档 | 凭证泄露 | 用环境变量和 .env.example |
小练习
为 Study Agent 设计一个「连接 GitHub 仓库学习资料」方案。先列出只读工具和写工具,再决定哪些走 MCP、哪些需要人工确认。