Skip to content

第 14 章 · 构建 MCP Server

本章目标:回顾 MCP 协议角色分工,学会用 MCPServer 把 Mastra 的 agents/tools/workflows 暴露给外部系统,并让 Mastra 作为客户端接入第三方 MCP 服务。

14.1 两种角色

Mastra 在 MCP 生态中可以扮演双向角色(@mastra/mcp 包):

  • MCPClient——连接别人的 MCP server,把它们的工具接进你的 Agent;
  • MCPServer——把你的 agents/tools/workflows/prompts/resources 发布为标准 MCP 接口,供 Claude Code、Cursor 等任何 MCP 客户端使用。

14.2 作为客户端接入

typescript
// src/mastra/mcp/client.ts
import { MCPClient } from '@mastra/mcp'

export const mcpClient = new MCPClient({
  id: 'my-mcp-client',
  servers: {
    // 本地进程型 server:通过命令启动
    wikipedia: {
      command: 'npx',
      args: ['-y', 'wikipedia-mcp'],
    },
    // 远程 HTTP server:带认证头
    weather: {
      url: new URL('https://weather.example.com/mcp'),
      requestInit: {
        headers: { Authorization: `Bearer ${process.env.WEATHER_API_KEY}` },
      },
    },
  },
})

把工具交给 Agent:

typescript
// src/mastra/agents/assistant.ts
import { Agent } from '@mastra/core/agent'
import { mcpClient } from '../mcp/client'

export const assistant = new Agent({
  id: 'assistant',
  name: 'Assistant',
  instructions: '使用可用的 MCP 工具回答问题,并注明信息来源。',
  model: 'openai/gpt-5-mini',
  tools: await mcpClient.listTools(), // 静态加载所有工具
})

14.3 静态工具 vs 运行时工具集

方式API适用场景
静态mcpClient.listTools()所有请求共享固定配置
运行时mcpClient.listToolsets()按用户/请求注入不同凭据
typescript
// 每个用户用自己的 API Key 连接远程 MCP
export async function handleRequest(prompt: string, userKey: string) {
  const perUserClient = new MCPClient({
    servers: {
      weather: {
        url: new URL('https://weather.example.com/mcp'),
        requestInit: { headers: { Authorization: `Bearer ${userKey}` } },
      },
    },
  })
  return assistant.generate(prompt, {
    toolsets: await perUserClient.listToolsets(),
  })
}

OAuth 保护的 server 可用 authenticate() 走浏览器授权流程。

14.4 把自己的能力发布为 MCPServer

typescript
// src/mastra/index.ts
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  agents: { support: supportAgent },
  workflows: { refundFlow },
})

// 通过 MCPServer 配置暴露(挂到独立 HTTP 入口)
export const mcpServer = new MCPServer({
  id: 'company-mcp',
  name: 'Company Tools',
  version: '1.0.0',
  agents: { support: supportAgent },     // agent 作为资源暴露
  workflows: { refundFlow },             // workflow 变成可调用工具
})

配置后,Claude Code 或 Cursor 里添加该 URL 即可直接调用你的客服 Agent 和退款流程。

本章小结

  • @mastra/mcp 同时提供客户端与服务端能力;
  • 静态工具用 listTools(),按请求凭据用 listToolsets() + toolsets
  • MCPServer 能把 agents/workflows 标准化暴露给整个 MCP 生态;
  • OAuth 场景走 authenticate() 浏览器授权。

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. MCPClient 与 MCPServer 的职责分别是?

2. 每个请求需要不同凭据访问 MCP server 时应使用?

3. 本地命令型 MCP server 在配置中通过什么字段声明?

4. 把 workflow 通过 MCPServer 暴露后,外部客户端能做什么?

🛠️ 动手实践

  1. 用 MCPClient 接入一个公开的 Wikipedia MCP server,让 Agent 回答百科问题。
  2. 把你写的退款 workflow 通过 MCPServer 暴露,在 Claude Code 中调用一次。
  3. 实现按用户凭据的运行时工具集:两个不同 token 的用户各自查询各自的天气服务。