没有它,你的 AI 代理毫无用处
为什么 MCP 是人工智能领域的 USB-C。
你已经构建了一个AI代理。也许甚至是个好代理。提示词写得精炼,模型响应快,回复也很自然。
但接着有人让它去检查Salesforce里的客户记录,或者拉取最新的Jira工单,又或者搜索内部文档。
而你漂亮的代理却……做不到。
这是每个AI平台最终都会撞上的集成问题。你的代理需要手,需要眼睛,需要能真正接入你的业务系统。没有这些,你只是在运行一个昂贵的聊天机器人。
传统解决方案?为每一个想连接的服务编写自定义API包装器:读他们的文档,处理他们的认证,对付他们的速率限制,祈祷他们下个月别改端点。然后对下一个服务重复,再下一个。
Model Context Protocol 彻底改变了这个局面。
MCP真正解决了什么
想想USB-C出现之前的USB。你有Mini-USB、Micro-USB、苹果专用接口,还有一抽屉只对特定设备管用的线缆。USB-C不只是增加了一个新接头——它建立了一个标准,从此任何线缆都能用在任何设备上。
MCP正在为AI工具集成做同样的事。
不需要编写自定义代码来把代理连到Salesforce、HubSpot、GitHub或其他任何服务;你只需要实现一次这个协议(或者下载一个预构建的服务器),任何兼容MCP的代理就能立刻跟它通信。
协议负责通信层。你只需要定义你的工具做什么,以及它们需要什么数据。
设置多个集成
Mastra通过 MCPClient 原生支持MCP。你可以连接本地工具(以子进程运行)和远程服务(运行在自己的基础设施上)。
下面是一个连接地图、天气和本地Wikipedia搜索的典型配置:
import { MCPClient } from '@mastra/mcp';
export const mcpClient = new MCPClient({ id: 'navigation-mcp', servers: { // Local tool (Stdio) wikipedia: { command: 'npx', args: ['-y', 'wikipedia-mcp'], }, // Maps & Navigation (Remote/HTTP) googleMaps: { url: new URL(process.env.GOOGLE_MAPS_MCP_URL!), requestInit: { headers: { Authorization: `Bearer ${process.env.GOOGLE_MAPS_API_KEY}`, }, }, }, // Weather Service Integration weather: { url: new URL(process.env.WEATHER_MCP_URL!), requestInit: { headers: { 'X-API-Key': process.env.WEATHER_API_KEY!, }, }, }, },});客户端管理连接生命周期,处理本地工具的进程生成,并维护远程服务器的HTTP连接。你不需要直接操作socket或stdio。
将工具连接到智能体
一旦配置好 MCP 客户端,将这些工具交给智能体就很简单了:
import { Agent } from '@mastra/core/agent';import { mcpClient } from '../mcp';
export const navigationDirectionsAgent = new Agent({ id: 'navigation-directions-agent', name: 'Navigation & Directions Assistant', instructions: `You are a helpful navigation assistant that provides route planning and travel advice. - Always confirm the start and destination locations - Use Google Maps tools to find optimal routes - Check weather conditions along the route - Provide estimated travel times and suggest alternatives if weather is poor - Include relevant details like traffic, road conditions, and points of interest - Keep responses clear and actionable`, model: 'openai/gpt-5.5', tools: await mcpClient.listTools(), // <--- This is the magic line});当用户询问:“从旧金山到太浩湖的最佳路线是什么,我需要担心天气吗?”
智能体读取可用的工具定义,意识到它拥有 Google Maps 路线规划和天气预报工具,用正确的参数执行它们,并回答出最佳路线以及沿途的当前天气状况。
你没有编写一行 Google Maps API 代码或天气服务集成。
按用户认证
这里有一个容易犯的安全错误:硬编码凭据。
如果你在环境变量中放入一个 Google Maps API 密钥然后收工,每个用户共享相同的配额和速率限制。更重要的是,如果你使用存储用户偏好(如保存的地点或常用路线)的服务,每个人都会看到相同的数据。这在演示中没问题。但在生产环境中是隐患。
Mastra 支持你动态创建带有用户特定凭据的 MCP 客户端,并在请求时传递它们的工具集。你仍然处理常规的 SaaS 管道工作:安全地存储令牌、刷新令牌,以及决定哪些用户可以连接哪些服务。
async function handleUserRequest(userPrompt: string, userCredentials: UserCreds) { // Create a client for THIS specific user const userMcp = new MCPClient({ id: `maps-${userCredentials.userId}`, servers: { googleMaps: { url: new URL(process.env.GOOGLE_MAPS_MCP_URL!), requestInit: { headers: { // User's specific API key or token Authorization: `Bearer ${userCredentials.mapsApiKey}`, 'X-User-ID': userCredentials.userId, }, }, }, }, });
try { const agent = mastra.getAgent('navigationDirectionsAgent');
// Inject tools at runtime const response = await agent.generate(userPrompt, { toolsets: await userMcp.listToolsets(), });
return response; } finally { await userMcp.disconnect(); }}每个用户获得自己独立的工具集,带自己的 API 配额和偏好。用户 A 的保存位置保持私有,用户 B 的路线历史分开。这就是多租户 SaaS 智能体在实际中的工作方式。
构建复合工具
有时你需要将多个 MCP 工具组合成一个单一操作。或许你想规划一条路线,同时考虑实时交通和沿途天气状况。
你可以将 MCP 工具包装在自定义工具定义中:
import { createTool } from '@mastra/core/tools';import { z } from 'zod';
type DirectionsResult = { waypoints: Array<{ latitude: number; longitude: number }>; [key: string]: unknown;};
type ForecastResult = { alerts?: unknown[]; severe?: boolean;};
export const smartRouteTool = createTool({ id: 'smart-route-planner', description: 'Plans optimal route considering traffic and weather conditions', inputSchema: z.object({ origin: z.string(), destination: z.string(), }), outputSchema: z.object({ route: z.record(z.string(), z.unknown()), weatherAlerts: z.array(z.unknown()), recommendation: z.string(), }), execute: async ({ origin, destination }, executionContext) => { const tools = await mcpClient.listTools();
// 1. Get base route from Google Maps const routeData = await tools.googleMaps_getDirections.execute( { origin, destination }, executionContext, ) as DirectionsResult;
// 2. Check weather along the route const weatherData = await tools.weather_getForecast.execute( { coordinates: routeData.waypoints }, executionContext, ) as ForecastResult;
// 3. Return enhanced route with weather warnings return { route: routeData, weatherAlerts: weatherData.alerts ?? [], recommendation: weatherData.severe ? 'Consider delaying trip' : 'Safe to travel', }; },});当前的 Mastra 工具首先接收经过验证的输入,然后接收执行上下文。将该上下文传递给发现到的 MCP 工具可以保留请求范围内的状态、追踪和取消。上面的名称和结果类型只是示例约定;请使用你实际连接的 MCP 服务器所通告的名称和模式。
这为你提供了细粒度的控制,精确控制工具之间如何交互,同时仍然利用 MCP 协议完成繁重的工作。
审批应在工具边界进行
MCP 让工具连接更简单。但这并不意味着每个工具都应该无摩擦运行。
Mastra 的 MCPClient 可以在服务器级别要求审批,可以是针对该服务器上的每个工具,也可以按调用动态要求审批:
export const githubMcp = new MCPClient({ id: 'github-mcp', servers: { github: { url: new URL(process.env.GITHUB_MCP_URL!), requireToolApproval: ({ toolName, annotations }) => { if (annotations?.readOnlyHint) return false; if (toolName.includes('delete_')) return true; return annotations?.destructiveHint ?? true; }, }, },});这种审批仍应被视为应用策略,而非魔法咒语。MCP 工具注解来自受信任的服务器,是有用的提示;但它们本身并非安全边界。对于第三方服务器,请将默认行为设为保守,在智能体修改任何重要内容之前进行询问。
由此延伸
为 AI 智能体需要交互的每个服务编写自定义 API 客户端从来都不是可持续的做法。它扩展性差、频繁出错,并且将你的平台与特定实现绑定在一起。
MCP 并不能解决所有集成难题——认证依然复杂,速率限制仍然重要,而且并非所有服务都已提供 MCP 服务器。但它奠定了一个基础,让构建智能体平台的痛苦大大减少。
如果你正在设计一个需要与外部服务交互的 AI 系统,理解 MCP 很可能值得你花时间。