MCPServer
MCPServer
クラスは、既存の Mastra ツールや Agent を Model Context Protocol (MCP) サーバーとして公開する機能を提供します。これにより、任意の MCP クライアント(Cursor、Windsurf、Claude Desktop など)がこれらの機能に接続し、エージェントで利用できるようになります。
ツールやエージェントを Mastra アプリケーション内で直接使用するだけであれば、必ずしも MCP サーバーを作成する必要はありません。この API は、Mastra のツールやエージェントを 外部 の MCP クライアントに公開するためのものです。
stdio(サブプロセス)および SSE(HTTP)MCP トランスポート の両方に対応しています。
Constructor
新しいMCPServer
を作成するには、サーバーに関する基本情報、提供するツール、そしてオプションでツールとして公開したいエージェントを提供する必要があります。
import { openai } from "@ai-sdk/openai";
import { Agent } from "@mastra/core/agent";
import { createTool } from "@mastra/core/tools";
import { MCPServer } from "@mastra/mcp";
import { z } from "zod";
import { dataProcessingWorkflow } from "../workflows/dataProcessingWorkflow";
const myAgent = new Agent({
name: "MyExampleAgent",
description: "A generalist to help with basic questions."
instructions: "You are a helpful assistant.",
model: openai("gpt-4o-mini"),
});
const weatherTool = createTool({
id: "getWeather",
description: "Gets the current weather for a location.",
inputSchema: z.object({ location: z.string() }),
execute: async ({ context }) => `Weather in ${context.location} is sunny.`,
});
const server = new MCPServer({
name: "My Custom Server",
version: "1.0.0",
tools: { weatherTool },
agents: { myAgent }, // this agent will become tool "ask_myAgent"
workflows: {
dataProcessingWorkflow, // this workflow will become tool "run_dataProcessingWorkflow"
}
});
設定プロパティ
コンストラクタは以下のプロパティを持つMCPServerConfig
オブジェクトを受け取ります:
name:
version:
tools:
agents?:
workflows?:
id?:
description?:
repository?:
releaseDate?:
isLatest?:
packageCanonical?:
packages?:
remotes?:
resources?:
prompts?:
エージェントをツールとして公開する
MCPServer
の強力な機能の一つは、Mastra エージェントを自動的に呼び出し可能なツールとして公開できることです。設定の agents
プロパティにエージェントを指定すると、以下のようになります。
-
ツール名: 各エージェントは
ask_<agentKey>
という名前のツールに変換されます。ここで<agentKey>
はagents
オブジェクトでそのエージェントに使用したキーです。例えば、agents: { myAgentKey: myAgentInstance }
のように設定した場合、ask_myAgentKey
という名前のツールが作成されます。 -
ツールの機能:
- 説明: 生成されたツールの説明は次の形式になります: 「エージェント
<AgentName>
に質問します。元のエージェントの指示:<agent description>
」。 - 入力: ツールは
message
プロパティ(文字列)を持つ単一のオブジェクト引数を受け取ります:{ message: "エージェントへの質問" }
。 - 実行: このツールが呼び出されると、対応するエージェントの
generate()
メソッドが、指定されたquery
を渡して実行されます。 - 出力: エージェントの
generate()
メソッドからの直接の結果がツールの出力として返されます。
- 説明: 生成されたツールの説明は次の形式になります: 「エージェント
-
名前の衝突:
tools
設定で明示的に定義されたツールが、エージェント由来のツールと同じ名前を持つ場合(例:ask_myAgentKey
というツールと、myAgentKey
というキーのエージェントが両方存在する場合)、明示的に定義されたツールが優先されます。この場合、エージェントはツールに変換されず、警告が記録されます。
これにより、MCP クライアントが他のツールと同じように自然言語クエリを使ってエージェントとやり取りできるようになります。
エージェントからツールへの変換
agents
設定プロパティにエージェントを指定すると、MCPServer
は各エージェントに対応するツールを自動的に作成します。ツール名は ask_<agentIdentifier>
となり、<agentIdentifier>
は agents
オブジェクトで使用したキーです。
生成されたツールの説明は次のようになります: 「エージェント <agent.name>
に質問します。エージェントの説明: <agent.description>
」。
重要: エージェントがツールに変換されるためには、インスタンス化時の設定で空でない description
文字列プロパティが必ず設定されている必要があります(例: new Agent({ name: 'myAgent', description: 'This agent does X.', ... })
)。description
がない、または空のエージェントを MCPServer
に渡すと、MCPServer
のインスタンス化時にエラーが発生し、サーバーのセットアップが失敗します。
これにより、エージェントの生成機能を MCP 経由ですばやく公開でき、クライアントがエージェントに直接「質問」できるようになります。
メソッド
これらはMCPServer
インスタンスで呼び出すことができる関数で、その動作を制御し情報を取得するためのものです。
startStdio()
このメソッドを使用して、標準入出力(stdio)を使用して通信するようにサーバーを起動します。これは、サーバーをコマンドラインプログラムとして実行する場合の典型的な方法です。
async startStdio(): Promise<void>
以下は、stdioを使用してサーバーを起動する方法です:
const server = new MCPServer({
// example configuration above
});
await server.startStdio();
startSSE()
このメソッドは、MCPサーバーを既存のWebサーバーと統合して、Server-Sent Events(SSE)を通信に使用するのに役立ちます。WebサーバーのコードからSSEまたはメッセージパスへのリクエストを受信したときに、このメソッドを呼び出します。
async startSSE({
url,
ssePath,
messagePath,
req,
res,
}: {
url: URL;
ssePath: string;
messagePath: string;
req: any;
res: any;
}): Promise<void>
以下は、HTTPサーバーのリクエストハンドラー内でstartSSE
を使用する例です。この例では、MCPクライアントはhttp://localhost:1234/sse
であなたのMCPサーバーに接続できます:
import http from "http";
const httpServer = http.createServer(async (req, res) => {
await server.startSSE({
url: new URL(req.url || "", `http://localhost:1234`),
ssePath: "/sse",
messagePath: "/message",
req,
res,
});
});
httpServer.listen(PORT, () => {
console.log(`HTTP server listening on port ${PORT}`);
});
以下は、startSSE
メソッドに必要な値の詳細です:
url:
ssePath:
messagePath:
req:
res:
startHonoSSE()
このメソッドは、MCPサーバーを既存のWebサーバーと統合して、Server-Sent Events(SSE)を通信に使用するのに役立ちます。WebサーバーのコードからSSEまたはメッセージパスへのリクエストを受信したときに、このメソッドを呼び出します。
async startHonoSSE({
url,
ssePath,
messagePath,
req,
res,
}: {
url: URL;
ssePath: string;
messagePath: string;
req: any;
res: any;
}): Promise<void>
以下は、HTTPサーバーのリクエストハンドラー内でstartHonoSSE
を使用する例です。この例では、MCPクライアントはhttp://localhost:1234/hono-sse
であなたのMCPサーバーに接続できます:
import http from "http";
const httpServer = http.createServer(async (req, res) => {
await server.startHonoSSE({
url: new URL(req.url || "", `http://localhost:1234`),
ssePath: "/hono-sse",
messagePath: "/message",
req,
res,
});
});
httpServer.listen(PORT, () => {
console.log(`HTTP server listening on port ${PORT}`);
});
以下は、startHonoSSE
メソッドに必要な値の詳細です:
url:
ssePath:
messagePath:
req:
res:
startHTTP()
このメソッドは、MCPサーバーを既存のWebサーバーと統合して、通信にストリーマブルHTTPを使用するのに役立ちます。WebサーバーがHTTPリクエストを受信したときに、Webサーバーのコードからこれを呼び出します。
async startHTTP({
url,
httpPath,
req,
res,
options = { sessionIdGenerator: () => randomUUID() },
}: {
url: URL;
httpPath: string;
req: http.IncomingMessage;
res: http.ServerResponse<http.IncomingMessage>;
options?: StreamableHTTPServerTransportOptions;
}): Promise<void>
HTTPサーバーのリクエストハンドラー内でstartHTTP
を使用する方法の例を以下に示します。この例では、MCPクライアントはhttp://localhost:1234/http
でMCPサーバーに接続できます:
import http from "http";
const httpServer = http.createServer(async (req, res) => {
await server.startHTTP({
url: new URL(req.url || '', 'http://localhost:1234'),
httpPath: `/mcp`,
req,
res,
options: {
sessionIdGenerator: undefined,
},
});
});
httpServer.listen(PORT, () => {
console.log(`HTTP server listening on port ${PORT}`);
});
startHTTP
メソッドで必要な値の詳細は以下の通りです:
url:
httpPath:
req:
res:
options:
StreamableHTTPServerTransportOptions
オブジェクトを使用すると、HTTPトランスポートの動作をカスタマイズできます。利用可能なオプションは以下の通りです:
sessionIdGenerator:
onsessioninitialized:
enableJsonResponse:
eventStore:
close()
このメソッドはサーバーを閉じ、すべてのリソースを解放します。
async close(): Promise<void>
getServerInfo()
このメソッドはサーバーの基本情報を確認できます。
getServerInfo(): ServerInfo
getServerDetail()
このメソッドはサーバーの詳細情報を確認できます。
getServerDetail(): ServerDetail
getToolListInfo()
このメソッドは、サーバーを作成した際に設定されたツールの一覧を確認できます。読み取り専用のリストで、デバッグ目的に便利です。
getToolListInfo(): ToolListInfo
getToolInfo()
このメソッドは、特定のツールに関する詳細情報を提供します。
getToolInfo(toolName: string): ToolInfo
executeTool()
このメソッドは、特定のツールを実行し、結果を返します。
executeTool(toolName: string, input: any): Promise<any>
getStdioTransport()
startStdio()
でサーバーを開始した場合、これを使用してstdio通信を管理するオブジェクトを取得できます。これは主に内部チェックやテスト用です。
getStdioTransport(): StdioServerTransport | undefined
getSseTransport()
startSSE()
でサーバーを開始した場合、これを使用してSSE通信を管理するオブジェクトを取得できます。getStdioTransport
と同様に、これは主に内部チェックやテスト用です。
getSseTransport(): SSEServerTransport | undefined
getSseHonoTransport()
startHonoSSE()
でサーバーを開始した場合、これを使用してSSE通信を管理するオブジェクトを取得できます。getSseTransport
と同様に、これは主に内部チェックやテスト用です。
getSseHonoTransport(): SSETransport | undefined
getStreamableHTTPTransport()
startHTTP()
でサーバーを開始した場合、これを使用してHTTP通信を管理するオブジェクトを取得できます。getSseTransport
と同様に、これは主に内部チェックやテスト用です。
getStreamableHTTPTransport(): StreamableHTTPServerTransport | undefined
tools()
このMCPサーバーが提供する特定のツールを実行します。
async executeTool(
toolId: string,
args: any,
executionContext?: { messages?: any[]; toolCallId?: string },
): Promise<any>
toolId:
args:
executionContext?:
リソースの取り扱い
MCPリソースとは?
リソースは、Model Context Protocol (MCP) の中核となるプリミティブであり、サーバーがクライアントにデータやコンテンツを公開し、LLMとのやり取りのコンテキストとして利用できるようにします。リソースは、MCPサーバーが提供したいあらゆる種類のデータを表します。例えば:
- ファイルの内容
- データベースのレコード
- APIのレスポンス
- ライブシステムデータ
- スクリーンショットや画像
- ログファイル
リソースは一意のURI(例:file:///home/user/documents/report.pdf
、postgres://database/customers/schema
)で識別され、テキスト(UTF-8エンコード)またはバイナリデータ(base64エンコード)のいずれかを含むことができます。
クライアントは以下の方法でリソースを発見できます:
- 直接リソース: サーバーは
resources/list
エンドポイントを通じて具体的なリソースのリストを公開します。 - リソーステンプレート: 動的なリソースの場合、サーバーはクライアントがリソースURIを構築するためのURIテンプレート(RFC 6570)を公開できます。
リソースを読み取るには、クライアントがURIを指定して resources/read
リクエストを送信します。また、サーバーはリソースリストの変更(notifications/resources/list_changed
)や特定リソースの内容更新(notifications/resources/updated
)について、クライアントがそのリソースを購読している場合に通知することもできます。
より詳細な情報については、公式MCPドキュメントのリソースに関するページ を参照してください。
MCPServerResources
型
resources
オプションは MCPServerResources
型のオブジェクトを受け取ります。この型は、サーバーがリソースリクエストを処理するために使用するコールバックを定義します:
export type MCPServerResources = {
// 利用可能なリソースをリストするコールバック
listResources: () => Promise<Resource[]>;
// 特定のリソースの内容を取得するコールバック
getResourceContent: ({
uri,
}: {
uri: string;
}) => Promise<MCPServerResourceContent | MCPServerResourceContent[]>;
// 利用可能なリソーステンプレートをリストするオプションのコールバック
resourceTemplates?: () => Promise<ResourceTemplate[]>;
};
export type MCPServerResourceContent = { text?: string } | { blob?: string };
例:
import { MCPServer } from "@mastra/mcp";
import type {
MCPServerResourceContent,
Resource,
ResourceTemplate,
} from "@mastra/mcp";
// リソースやリソーステンプレートは通常、動的に取得されます。
const myResources: Resource[] = [
{ uri: "file://data/123.txt", name: "Data File", mimeType: "text/plain" },
];
const myResourceContents: Record<string, MCPServerResourceContent> = {
"file://data.txt/123": { text: "This is the content of the data file." },
};
const myResourceTemplates: ResourceTemplate[] = [
{
uriTemplate: "file://data/{id}",
name: "Data File",
description: "A file containing data.",
mimeType: "text/plain",
},
];
const myResourceHandlers: MCPServerResources = {
listResources: async () => myResources,
getResourceContent: async ({ uri }) => {
if (myResourceContents[uri]) {
return myResourceContents[uri];
}
throw new Error(`Resource content not found for ${uri}`);
},
resourceTemplates: async () => myResourceTemplates,
};
const serverWithResources = new MCPServer({
name: "Resourceful Server",
version: "1.0.0",
tools: {
/* ... your tools ... */
},
resources: myResourceHandlers,
});
クライアントへのリソース変更通知
利用可能なリソースやその内容が変更された場合、サーバーは特定のリソースを購読している接続中のクライアントに通知することができます。
server.resources.notifyUpdated({ uri: string })
特定のリソース(uri
で識別)の内容が更新されたときにこのメソッドを呼び出します。該当するURIを購読しているクライアントには、notifications/resources/updated
メッセージが送信されます。
async server.resources.notifyUpdated({ uri: string }): Promise<void>
例:
// 'file://data.txt' の内容を更新した後
await serverWithResources.resources.notifyUpdated({ uri: "file://data.txt" });
server.resources.notifyListChanged()
利用可能なリソースの全体リストが変更されたとき(例:リソースが追加または削除された場合)にこのメソッドを呼び出します。これにより、クライアントに notifications/resources/list_changed
メッセージが送信され、リソースリストの再取得が促されます。
async server.resources.notifyListChanged(): Promise<void>
例:
// 'myResourceHandlers.listResources' で管理されているリストに新しいリソースを追加した後
await serverWithResources.resources.notifyListChanged();
プロンプト処理
MCPプロンプトとは?
プロンプトは、MCPサーバーがクライアントに公開する再利用可能なテンプレートまたはワークフローです。引数を受け取り、リソースコンテキストを含み、バージョニングをサポートし、LLMインタラクションを標準化するために使用できます。
プロンプトは一意の名前(およびオプションのバージョン)で識別され、動的または静的にできます。
MCPServerPrompts
型
prompts
オプションはMCPServerPrompts
型のオブジェクトを受け取ります。この型は、サーバーがプロンプトリクエストを処理するために使用するコールバックを定義します:
export type MCPServerPrompts = {
// Callback to list available prompts
listPrompts: () => Promise<Prompt[]>;
// Callback to get the messages/content for a specific prompt
getPromptMessages?: ({
name,
version,
args,
}: {
name: string;
version?: string;
args?: any;
}) => Promise<{ prompt: Prompt; messages: PromptMessage[] }>;
};
例:
import { MCPServer } from "@mastra/mcp";
import type { Prompt, PromptMessage, MCPServerPrompts } from "@mastra/mcp";
const prompts: Prompt[] = [
{
name: "analyze-code",
description: "Analyze code for improvements",
version: "v1"
},
{
name: "analyze-code",
description: "Analyze code for improvements (new logic)",
version: "v2"
}
];
const myPromptHandlers: MCPServerPrompts = {
listPrompts: async () => prompts,
getPromptMessages: async ({ name, version, args }) => {
if (name === "analyze-code") {
if (version === "v2") {
const prompt = prompts.find(p => p.name === name && p.version === "v2");
if (!prompt) throw new Error("Prompt version not found");
return {
prompt,
messages: [
{
role: "user",
content: { type: "text", text: `Analyze this code with the new logic: ${args.code}` }
}
]
};
}
// Default or v1
const prompt = prompts.find(p => p.name === name && p.version === "v1");
if (!prompt) throw new Error("Prompt version not found");
return {
prompt,
messages: [
{
role: "user",
content: { type: "text", text: `Analyze this code: ${args.code}` }
}
]
};
}
throw new Error("Prompt not found");
}
};
const serverWithPrompts = new MCPServer({
name: "Promptful Server",
version: "1.0.0",
tools: { /* ... */ },
prompts: myPromptHandlers,
});
プロンプト変更のクライアント通知
利用可能なプロンプトが変更された場合、サーバーは接続されたクライアントに通知できます:
server.prompts.notifyListChanged()
利用可能なプロンプトの全体的なリストが変更された場合(例:プロンプトが追加または削除された場合)にこのメソッドを呼び出します。これにより、クライアントにnotifications/prompts/list_changed
メッセージが送信され、プロンプトのリストを再取得するよう促します。
await serverWithPrompts.prompts.notifyListChanged();
プロンプト処理のベストプラクティス
- 明確で説明的なプロンプト名と説明を使用する。
getPromptMessages
で必要なすべての引数を検証する。- 破壊的変更を予期する場合は
version
フィールドを含める。 version
パラメータを使用して正しいプロンプトロジックを選択する。- プロンプトリストが変更されたときにクライアントに通知する。
- 情報的なメッセージでエラーを処理する。
- 引数の期待値と利用可能なバージョンを文書化する。
例
MCPServerのセットアップとデプロイの実践的な例については、MCPServerのデプロイ例を参照してください。
このページの冒頭の例でも、ツールとエージェントの両方を使用してMCPServer
をインスタンス化する方法を示しています。
関連情報
- MastraでMCPサーバーに接続する方法については、MCPClientドキュメントを参照してください。
- Model Context Protocolの詳細については、@modelcontextprotocol/sdkドキュメント を参照してください。