あなたのAIエージェントはこれがないと役に立たない
MCPがAIにおけるUSB-Cである理由。
AIエージェントを構築した。おそらく悪くないものだ。プロンプトは洗練され、モデルは高速で、応答も自然に感じる。
しかし、誰かがSalesforceの顧客レコードを確認してほしいと頼む。あるいは最新のJiraチケットを取得してほしい、あるいは社内ドキュメントを検索してほしいと言う。
そして、その美しいエージェントは……何もできない。
これが、すべてのAIプラットフォームがいずれ直面する統合問題だ。エージェントには「手」が必要だ。実際のビジネスシステムを覗き込む「目」が必要だ。それらがなければ、高価なチャットボットを動かしているに過ぎない。
従来の解決策は?接続したいサービスごとにカスタムAPIラッパーを書くこと。ドキュメントを読み、認証を処理し、レート制限に対処し、来月エンドポイントが変更されないことを祈る。そして次のサービスでも同じことを繰り返す。また次のサービスでも。
Model Context Protocolは、この計算を根本的に変える。
MCPが実際に解決する問題
USB-C以前のUSBを思い出してほしい。Mini-USB、Micro-USB、Apple独自のコネクタ、そして特定のデバイスでしか使えないケーブルが引き出しに溢れていた。USB-Cは単に新しいコネクタを追加したのではない——どんなケーブルでもどんなデバイスでも使える標準を確立したのだ。
MCPはAIツール統合においてまったく同じことをしている。
Salesforce、HubSpot、GitHub、その他のサービスにエージェントを接続するためのカスタムコードを書く代わりに、プロトコルを一度実装する(またはプレビルドのサーバーをダウンロードする)だけで、MCP互換のどのエージェントでも即座に通信できるようになる。
プロトコルが通信レイヤーを処理する。あなたはツールが何をし、どんなデータが必要かを定義するだけだ。
複数の統合をセットアップする
MastraはMCPClientを通じてネイティブなMCPサポートを提供している。ローカルツール(子プロセスとして実行)とリモートサービス(独自のインフラで実行)の両方に接続できる。
Google Mapsによるルーティング、天気サービス、ローカルのWikipedia検索に接続する本番環境に近い構成例を示す:
import { MCPClient } from '@mastra/mcp';
export const mcpClient = new MCPClient({ servers: { // ローカルツール(Stdio) wikipedia: { command: 'npx', args: ['-y', 'wikipedia-mcp'], }, // 地図&ナビゲーション(リモート/HTTP) googleMaps: { url: new URL(process.env.GOOGLE_MAPS_MCP_URL!), requestInit: { headers: { Authorization: `Bearer ${process.env.GOOGLE_MAPS_API_KEY}`, }, }, }, // 天気サービス統合 weather: { url: new URL('https://mcp.weatherapi.dev/v1'), requestInit: { headers: { 'X-API-Key': process.env.WEATHER_API_KEY!, }, }, }, },});クライアントは接続ライフサイクルを管理し、ローカルツールのプロセススパンニングを処理し、リモートサーバーへのHTTP接続を維持する。ソケットやstdioを直接触る必要はない。
ツールをエージェントに接続する
MCPクライアントの設定が完了すれば、これらのツールをエージェントに渡すのは簡単だ:
import { Agent } from '@mastra/core/agent';import { openai } from '@ai-sdk/openai';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'), tools: await mcpClient.getTools(), // <--- これが魔法の行});ユーザーが「サンフランシスコからレイクタホへの最適なルートは?天気は大丈夫?」と聞いたとする。
エージェントは利用可能なツール定義を読み取り、Google Mapsのルーティングと天気予報ツールにアクセスできることを認識し、正しいパラメータでそれらを実行し、最適なルートと沿線の現在の天気状況を返答する。
Google Maps APIコードも天気サービス統合も一行も書いていない。
ユーザーごとの認証
ここでやりがちなセキュリティ上の間違いがある。認証情報のハードコーディングだ。
環境変数に一つのGoogle Maps APIキーを入れて終わりにすると、すべてのユーザーが同じクォータとレート制限を共有することになる。さらに重要なのは、ユーザー設定(保存した場所やお気に入りルートなど)を保存するサービスを使っている場合、全員が同じデータを見ることになるということだ。これはデモでは問題ない。しかし本番環境では責任問題になる。
Mastraはユーザー固有の認証情報でMCPクライアントを動的に作成することでこれを処理する:
async function handleUserRequest(userPrompt: string, userCredentials: UserCreds) { // この特定ユーザー向けのクライアントを作成 const userMcp = new MCPClient({ servers: { googleMaps: { url: new URL(process.env.GOOGLE_MAPS_MCP_URL!), requestInit: { headers: { // ユーザー固有のAPIキーまたはトークン Authorization: `Bearer ${userCredentials.mapsApiKey}`, 'X-User-ID': userCredentials.userId, }, }, }, }, });
const agent = mastra.getAgent('navigationDirectionsAgent');
// 実行時にツールを注入 const response = await agent.generate(userPrompt, { toolsets: await userMcp.getToolsets(), });
return response;}各ユーザーは自分専用のAPIクォータと設定を持つ独立したツールセットを得る。ユーザーAの保存した場所はプライベートのままで、ユーザーBのルート履歴は分離されている。これがマルチテナントSaaSエージェントの実際の動き方だ。
複合ツールの構築
複数のMCPツールを一つの操作に組み合わせたい場合がある。例えば、リアルタイムの交通情報と沿線の天気状況の両方を考慮したルートを計画したい場合。
MCPツールをカスタムツール定義でラップできる:
export const smartRouteTool = createTool({ id: 'smart-route-planner', description: 'Plans optimal route considering traffic and weather conditions', execute: async ({ context, mastra }) => { // 生のツールを取得 const tools = await mcpClient.getTools();
// 1. Google Mapsから基本ルートを取得 const routeData = await tools.googleMaps_getDirections.execute({ context: { origin: context.origin, destination: context.destination } });
// 2. ルート沿いの天気を確認 const weatherData = await tools.weather_getForecast.execute({ context: { coordinates: routeData.waypoints } });
// 3. 天気警告付きの拡張ルートを返す return { ...routeData, weatherAlerts: weatherData.alerts, recommendation: weatherData.severe ? 'Consider delaying trip' : 'Safe to travel' }; },});これにより、MCPプロトコルの力を活用しながら、ツール間の相互作用をきめ細かく制御できる。
これが向かう先
AIエージェントが通信する必要があるすべてのサービスに対してカスタムAPIクライアントを書くことは、決して持続可能ではなかった。スケールが悪く、頻繁に壊れ、プラットフォームを特定の実装に縛り付ける。
MCPはすべての統合課題を解決するわけではない——認証は依然として複雑で、レート制限は依然として重要であり、すべてのサービスがMCPサーバーを持っているわけではない。しかし、エージェントプラットフォームの構築を大幅に楽にする基盤を確立している。
外部サービスとやり取りする必要があるAIシステムを設計しているなら、MCPを理解しておく価値はあるだろう。
リソース
シリーズを読む
- LLMルーティング
- セキュリティ&ガードレール
- MCP&ツール統合(この記事)
- ワークフロー&メモリ