MCP 两边:Client 与 Server
MCPClient(消费方)
Agent 作为 MCP Client 连上远程 MCP Server,把 Server 暴露的 tool / resource / prompt 动态注入自己。
MCPServer(提供方)
把 Mastra Agent、Workflow、Tool 暴露成 MCP Server,给 Claude Desktop、Cursor、n8n 等 MCP 客户端调用。
作为 Client:接外部 MCP 工具
import { MCPClient } from '@mastra/mcp'; const mcp = new MCPClient({ servers: { filesystem: { command: 'npx', args: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp/sandbox'], }, github: { url: new URL('https://mcp.github.com/sse'), requestInit: { headers: { Authorization: `Bearer ${GH_TOKEN}` } }, }, }, }); // 取出所有 server 的工具注入 Agent const tools = await mcp.getTools(); export const devAgent = new Agent({ name: 'dev', instructions: '...', model: anthropic('claude-sonnet-4-6'), tools, // 现在有 filesystem + github 全部工具 });
两种 transport 都支持:stdio(本地进程)和 HTTP/SSE(远程)。每轮对话会自动刷新 tool 列表,MCP Server 新增工具无需重启 Agent。
作为 Server:暴露给 Claude Desktop
// src/mastra/server.ts import { MCPServer } from '@mastra/mcp'; import { chefAgent } from './agents/chef'; import { kbSearchTool } from './tools/kb'; import { researchFlow } from './workflows/research'; export const server = new MCPServer({ name: 'gufa-mcp', version: '1.0.0', agents: { chefAgent }, // Agent 被暴露为 ask_chefAgent tool tools: { kbSearchTool }, // 原生 tool workflows: { researchFlow }, // Workflow 被暴露为 run_researchFlow tool }); // stdio 方式(给 Claude Desktop) await server.startStdio();
// ~/Library/Application Support/Claude/claude_desktop_config.json { "mcpServers": { "gufa-mcp": { "command": "node", "args": ["/abs/path/dist/server.js"] } } }
重启 Claude Desktop,它会看到你的 Agent、Tool、Workflow 全部变成可调用工具。
HTTP/SSE 模式(远程)
import express from 'express'; const app = express(); app.get('/sse', server.sseHandler()); app.post('/message', server.messageHandler()); app.listen(3000);
OpenTelemetry:三条腿都跑标准
import { Mastra } from '@mastra/core'; export const mastra = new Mastra({ agents: { ... }, telemetry: { enabled: true, serviceName: 'gufa-agent', sampling: { type: 'ratio', probability: 1 }, export: { type: 'otlp', endpoint: 'https://otel.langfuse.com/v1/traces', headers: { Authorization: `Bearer ${LANGFUSE_KEY}` }, }, }, });
Mastra 自动为 Agent.generate、Tool.execute、Workflow.step 创建 span,带以下属性:
ai.model/ai.provider/ai.usage.*mastra.agent.id/mastra.workflow.id/mastra.step.idmastra.runtimeContext.*(你自己挂的 userId、tenantId)resource.id/thread.id(memory 相关)
接 Langfuse
import { LangfuseExporter } from 'langfuse-vercel'; telemetry: { enabled: true, serviceName: 'gufa-agent', export: { type: 'custom', exporter: new LangfuseExporter({ publicKey: process.env.LANGFUSE_PUBLIC_KEY!, secretKey: process.env.LANGFUSE_SECRET_KEY!, baseUrl: 'https://cloud.langfuse.com', }), }, },
Langfuse dashboard 显示:每条会话的完整 trace、每步模型调用的 prompt/completion、token 花费、延迟、自定义 tag。对做 A/B 测试、逐次排查 bad case 极有用。
接 Braintrust
import { BraintrustExporter } from 'braintrust-otel'; export: { type: 'custom', exporter: new BraintrustExporter({ apiKey: process.env.BRAINTRUST_KEY!, projectName: 'gufa', }), },
接 Arize / Phoenix(自托管)
export: {
type: 'otlp',
endpoint: 'http://localhost:6006/v1/traces', // Phoenix 默认端口
},
日志与 Logger
import { PinoLogger } from '@mastra/loggers'; export const mastra = new Mastra({ ..., logger: new PinoLogger({ name: 'Mastra', level: 'info', }), });
Mastra 内置 Pino,所有 info/debug/error 走同一 logger;自定义 Tool 也可以通过 mastra.getLogger() 写日志,自动带 traceId 关联。
评估与告警联动
- Langfuse 支持基于 trace 打分(人工/LLM judge),历史看 Eval 趋势
- 规则告警:p95 latency > 10s、cost > $1/conv、某 tool 失败率 > 5%
- 接 PagerDuty / Slack,遇到异常自动通知
本章小结
- MCPClient 让 Agent 能用任意 MCP Server 的 tool
- MCPServer 让 Agent/Workflow/Tool 能被 Claude Desktop、Cursor 调用
- OTel 一套配置,导出 Langfuse / Braintrust / Phoenix 都行
- span 自带 ai.* 与 mastra.* 属性,排查维度丰富
- Logger 内置 Pino,和 trace 自动关联