跳到主要内容

MCP 概述

Mastra 支持 Model Context Protocol(MCP)。这是一项用于将 AI Agent 连接到外部 Tool 和资源的开放标准。

使用 MCPClient 连接到 MCP Server。使用 MCPServer 将 Mastra Agent、Tool、Workflow、prompt 和资源暴露给其他兼容 MCP 的系统。

连接到 MCP Server
连接到 MCP Server的直接链接

安装 MCP 包:

npm install @mastra/mcp@latest

使用本地命令或远程 URL 配置各个 Server:

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

export const mcpClient = new MCPClient({
id: 'my-mcp-client',
servers: {
wikipedia: {
command: 'npx',
args: ['-y', 'wikipedia-mcp'],
},
weather: {
url: new URL('https://weather.example.com/mcp'),
requestInit: {
headers: {
Authorization: `Bearer ${process.env.WEATHER_API_KEY}`,
},
},
},
},
})
身份验证

对于受 OAuth 保护的 Server,使用 authenticate() 完成基于浏览器的授权流程。有关配置详情,请参阅 OAuth 身份验证

将已配置 Server 中的 Tool 传给 Agent:

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: `
Use the available MCP tools to answer questions.
Include the source of any information you retrieve.
`,
model: 'openai/gpt-5.6-sol',
tools: await mcpClient.listTools(),
})

静态 Tool 与运行时 Toolset
静态 Tool 与运行时 Toolset的直接链接

根据 Server 配置是否会在请求之间发生变化,选择相应的 Tool 加载方式:

静态 Tool运行时 Toolset
方法await mcpClient.listTools()await mcpClient.listToolsets()
使用场景共享的固定配置按用户或按请求配置
凭据所有请求共享可随请求变化
Agent APIAgent 构造函数中的 toolsgenerate()stream() 中的 toolsets

前面的 Agent 示例使用静态 Tool。如需使用运行时凭据,请为当前请求创建客户端,并在调用 Agent 时传入其 Toolset:

src/handle-request.ts
import { MCPClient } from '@mastra/mcp'
import { mastra } from './mastra'

export async function handleRequest(prompt: string, apiKey: string) {
const userMcpClient = new MCPClient({
servers: {
weather: {
url: new URL('https://weather.example.com/mcp'),
requestInit: {
headers: { Authorization: `Bearer ${apiKey}` },
},
},
},
})

const agent = mastra.getAgent('assistant')
const response = await agent.generate(prompt, {
toolsets: await userMcpClient.listToolsets(),
})

await userMcpClient.disconnect()
return response.text
}

有关完整 API,请参阅 listTools()listToolsets()

Tool 审批
Tool 审批的直接链接

在 Server 上设置 requireToolApproval,要求对该 Server 的所有 Tool 进行审批:

const mcpClient = new MCPClient({
servers: {
github: {
url: new URL('https://github.example.com/mcp'),
requireToolApproval: true,
},
},
})

你也可以提供一个函数,根据 Tool 名称、参数或 annotation 作出决定:

requireToolApproval: ({ toolName }) => toolName.startsWith('delete_')

对于不受你控制的 Server,请将其 Tool annotation 视为不可信提示。有关回调上下文和安全指南,请参阅 Tool 审批

安全性
安全性的直接链接

MCP Server 会代表 Agent 运行代码并返回内容,因此配置它们时应像对待任何其他外部依赖一样谨慎:

  • Stdio 子进程环境:子进程只继承 MCP SDK 筛选后的环境变量白名单(例如 POSIX 上的 PATHHOME),而不是完整的父进程环境。在 Server 上设置 inheritDefaultEnv: false,即可只传递你在 env 中列出的变量。
  • 出站主机限制:当 HTTP Server URL 来自不可信配置时,设置 allowedHosts 来限制客户端可以联系的主机。在默认 fetch 路径上,这还会在发送请求之前阻止重定向跳转;自定义 fetch 则会在请求运行后验证其最终响应 URL,因此当需要阻止出站连接时,它本身必须强制执行重定向策略。
  • Tool 响应可信度:Tool 结果是不可信的模型输入。在内容到达模型前,使用输入和输出 Processor检查或清理内容,并通过 requireToolApproval 限制敏感 Tool。

有关每个选项的强制执行细节,请参阅 MCPClient 安全性 Reference

MCP Registry
MCP Registry的直接链接

Registry 提供托管或打包的 MCP Server。上述客户端配置适用于 Registry endpoint 和命令。

Registry连接方式说明
Klavis AI托管 HTTP企业身份验证和托管 Server
mcp.run签名 SSE URL将 profile URL 视为密钥
Composio托管 SSE URLURL 通常与单个用户账户绑定
SmitheryCLI 或托管 URL通过 npx 运行本地包
Apify托管 HTTP使用 Apify API token 进行身份验证
AmpersandSSE 或 stdio连接到已配置的 SaaS 集成

将签名 URL、API Key 和 token 存储在环境变量中。按照 Registry 的文档获取每个 Server 的 endpoint、命令和凭据。

暴露 Mastra MCP Server
暴露 Mastra MCP Server的直接链接

创建 MCPServer,将 Mastra 原语暴露给外部 MCP 客户端:

src/mastra/mcp/server.ts
import { MCPServer } from '@mastra/mcp'
import { assistant } from '../agents/assistant'
import { weatherTool } from '../tools/weather'
import { weatherWorkflow } from '../workflows/weather'

export const mcpServer = new MCPServer({
id: 'my-mcp-server',
name: 'My MCP Server',
version: '1.0.0',
agents: { assistant },
tools: { weatherTool },
workflows: { weatherWorkflow },
})

在主 Mastra 实例中注册 Server:

src/mastra/index.ts
import { Mastra } from '@mastra/core/mastra'
import { mcpServer } from './mcp/server'

export const mastra = new Mastra({
mcpServers: { mcpServer },
})
身份验证

使用 OAuth middleware 保护 HTTP MCP Server。有关设置说明,请参阅 OAuth 保护

有关 prompt、资源、transport 和其他 Server 选项,请参阅 MCPServer Reference

构建 MCP App
构建 MCP App的直接链接

MCP Apps extension 让 MCP Tool 能够通过 ui:// 资源提供交互式 HTML 界面。Mastra Studio 会在 Tool 页面和 Agent 对话中以沙盒 iframe 渲染这些 App。

当 Tool 结果适合交互时,例如表单、计算器、颜色选择器或数据可视化,可以使用 MCP App。

定义 App 资源
定义 App 资源的直接链接

content 中返回简短的模型摘要,并将 UI 数据放入 structuredContent。将 _meta.ui.resourceUri 设置为 appResources 中使用的同一个 ui:// URI,以便将 Tool 链接到 App:

src/mastra/mcp/calculator.ts
import { MCPServer } from '@mastra/mcp'
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'

export const calculatorTool = createTool({
id: 'calculatorWithUI',
description: 'Calculate the sum of two numbers',
inputSchema: z.object({
num1: z.number(),
num2: z.number(),
}),
execute: async ({ num1, num2 }) => ({
content: [{ type: 'text', text: 'The result is displayed in the calculator app.' }],
structuredContent: { result: num1 + num2 },
}),
})

calculatorTool._meta = {
ui: { resourceUri: 'ui://calculator/main' },
}

export const calculatorMcpServer = new MCPServer({
id: 'calculator-app-server',
name: 'Calculator App Server',
version: '1.0.0',
tools: { calculatorTool },
appResources: {
'ui://calculator/main': {
name: 'Calculator',
htmlPath: './src/mastra/mcp/calculator.html',
},
},
})

模型会看到 content,而 App 会收到 structuredContent。有关内联 HTML、文件路径、metadata 和内容安全策略选项,请参阅 appResources

将 App 连接到 Studio
将 App 连接到 Studio的直接链接

在 HTML 资源中使用 @modelcontextprotocol/ext-appsApp 类。在调用 connect() 前注册事件处理程序:

src/mastra/mcp/calculator.html
<!doctype html>
<html>
<body>
<p id="result">Waiting for input</p>
<button id="recalculate">Recalculate</button>

<script type="module">
import { App } from 'https://cdn.jsdelivr.net/npm/@modelcontextprotocol/ext-apps/+esm'

const app = new App({ name: 'Calculator', version: '1.0.0' })
let toolInput

app.ontoolinput = params => {
toolInput = params.arguments
}

document.querySelector('#recalculate').addEventListener('click', async () => {
const result = await app.callServerTool({
name: 'calculatorWithUI',
arguments: toolInput,
})
document.querySelector('#result').textContent = JSON.stringify(result)

await app.sendMessage({
role: 'user',
content: [{ type: 'text', text: 'Explain the recalculated result.' }],
})
})

await app.connect()
</script>
</body>
</html>

Guest 端 API 分别负责交互的不同部分:

API用途
app.ontoolinput接收 Host 端 Tool 调用传入的参数
app.callServerTool()从 iframe 内部调用 MCP Tool
app.sendMessage()向对话中添加用户消息并开始新的模型轮次
app.connect()注册事件处理程序后连接到 Host

交互遵循以下顺序:

  1. Agent 调用 Tool。
  2. Tool 返回面向模型的 content 和面向 UI 的 structuredContent
  3. Studio 渲染关联的 App 资源。
  4. App 接收 Tool 输入,并可调用 Server Tool 或发送对话消息。

有关所有 Guest 端方法和生命周期 hook,请参阅外部 App API Reference

注册 MCP App
注册 MCP App的直接链接

对于本地 App,将 Tool 传给 Agent,并在 Mastra 上注册其 MCP Server:

src/mastra/index.ts
import { Agent } from '@mastra/core/agent'
import { Mastra } from '@mastra/core/mastra'
import { calculatorMcpServer, calculatorTool } from './mcp/calculator'

const calculatorAgent = new Agent({
id: 'calculator-agent',
name: 'Calculator Agent',
instructions: 'Use the calculator tool for arithmetic.',
model: 'openai/gpt-5-mini',
tools: { calculatorTool },
})

export const mastra = new Mastra({
agents: { calculatorAgent },
mcpServers: { calculatorMcpServer },
})

对于实现了 MCP App 的外部 MCP Server,使用 MCPClient.listTools() 加载其 Tool 并注册代理,以便 Studio 解析远程 App 资源:

src/mastra/remote-apps.ts
import { Agent } from '@mastra/core/agent'
import { Mastra } from '@mastra/core/mastra'
import { mcpClient } from './mcp/client'

const tools = await mcpClient.listTools()
const mcpServers = mcpClient.toMCPServerProxies()

const agent = new Agent({
id: 'remote-app-agent',
name: 'Remote App Agent',
instructions: 'Use the available remote tools.',
model: 'openai/gpt-5-mini',
tools,
})

export const mastra = new Mastra({
agents: { agent },
mcpServers,
})

通过 listTools() 加载的 Tool 会在 _meta.ui 中包含 serverId,使 Studio 无需扫描每个 Server 即可解析相应的 App 资源。有关代理配置详情,请参阅 toMCPServerProxies()

Sandbox 安全性
Sandbox 安全性的直接链接

Mastra Studio 使用 @mcp-ui/client,通过 Sandbox 代理加载 App HTML,并使用 postMessage 通过 JSON-RPC 进行通信。

App iframe 允许使用脚本、表单和弹出窗口,但无法访问父页面的 DOM、Cookie 或存储。Host 控制与 Guest App 的所有通信。

后续步骤
后续步骤的直接链接