MCP 連携
Model Context Protocol (MCP) は、アプリケーションが LLM にツールとコンテキストを提供する方法を標準化するオープンプロトコルです。MCP ドキュメントからの引用:
MCP は、アプリケーションが LLM にコンテキストを提供する方法を標準化するオープンプロトコルです。MCP は AI アプリケーションにおける USB-C ポートのようなものだと考えてください。USB-C がさまざまな周辺機器やアクセサリを接続するための標準化された方法を提供するのと同様に、MCP は AI モデルを多様なデータソースやツールへ接続するための標準化された方法を提供します。
この SDK がサポートする MCP サーバーには 3 種類あります。
- リモート MCP サーバーツール – OpenAI Responses API からツールとして呼び出されるリモート MCP サーバー
- Streamable HTTP MCP サーバー – Streamable HTTP トランスポート を実装するローカルまたはリモートサーバー
- Stdio MCP サーバー – 標準入力 / 出力でアクセスするサーバー(最もシンプル)
ユースケースに応じてサーバータイプを選択してください。
必要なこと | 推奨オプション |
---|---|
既定の OpenAI Responses モデルで、公開アクセス可能なリモートサーバーを呼び出したい | 1. リモート MCP ツール |
公開アクセス可能なリモートサーバーを使用しつつ、ツール呼び出しをローカルでトリガーしたい | 2. Streamable HTTP |
ローカルで稼働する Streamable HTTP サーバーを使用したい | 2. Streamable HTTP |
OpenAI Responses 以外のモデルで Streamable HTTP サーバーを使用したい | 2. Streamable HTTP |
標準 I/O プロトコルのみをサポートするローカル MCP サーバーを使用したい | 3. Stdio |
1. リモート MCP サーバーツール
Section titled “1. リモート MCP サーバーツール”リモートツールでは、往復の処理全体がモデル内部で行われます。あなたのコードが MCP サーバーを呼び出す代わりに、OpenAI Responses API がリモートツールのエンドポイントを呼び出し、その結果をモデルへストリームします。
以下はリモート MCP サーバーツールを使用する最もシンプルな例です。hostedMcpTool
ユーティリティ関数にリモート MCP サーバーのラベルと URL を渡すことで、リモート MCP サーバーツールを簡単に作成できます。
import { Agent, hostedMcpTool } from '@openai/agents';
export const agent = new Agent({ name: 'MCP Assistant', instructions: 'You must always use the MCP tools to answer questions.', tools: [ hostedMcpTool({ serverLabel: 'gitmcp', serverUrl: 'https://gitmcp.io/openai/codex', }), ],});
その後、run
関数(もしくはカスタマイズした Runner
インスタンスの run
メソッド)でエージェントを実行できます。
import { run } from '@openai/agents';import { agent } from './hostedAgent';
async function main() { const result = await run( agent, 'Which language is the repo I pointed in the MCP tool settings written in?', ); console.log(result.finalOutput);}
main().catch(console.error);
インクリメンタルな MCP 実行結果をストリーミングするには、Agent
を実行するときに stream: true
を渡します。
import { run } from '@openai/agents';import { agent } from './hostedAgent';
async function main() { const result = await run( agent, 'Which language is the repo I pointed in the MCP tool settings written in?', { stream: true }, );
for await (const event of result) { if ( event.type === 'raw_model_stream_event' && event.data.type === 'model' && event.data.event.type !== 'response.mcp_call_arguments.delta' && event.data.event.type !== 'response.output_text.delta' ) { console.log(`Got event of type ${JSON.stringify(event.data)}`); } } console.log(`Done streaming; final result: ${result.finalOutput}`);}
main().catch(console.error);
承認フロー(オプション)
Section titled “承認フロー(オプション)”機密性の高い操作については、個々のツール呼び出しに人間の承認を要求できます。requireApproval: 'always'
または、ツール名ごとに 'never'
/ 'always'
を指定するオブジェクトを渡してください。
ツール呼び出しが安全かどうかをプログラムで判断できる場合は、onApproval
コールバック を使用して承認 / 拒否できます。人間の承認が必要な場合は、ローカルの関数ツールと同様に interruptions
を利用した 人間の介入(HITL)アプローチ を使えます。
import { Agent, run, hostedMcpTool, RunToolApprovalItem } from '@openai/agents';
async function main(): Promise<void> { const agent = new Agent({ name: 'MCP Assistant', instructions: 'You must always use the MCP tools to answer questions.', tools: [ hostedMcpTool({ serverLabel: 'gitmcp', serverUrl: 'https://gitmcp.io/openai/codex', // 'always' | 'never' | { never, always } requireApproval: { never: { toolNames: ['search_codex_code', 'fetch_codex_documentation'], }, always: { toolNames: ['fetch_generic_url_content'], }, }, }), ], });
let result = await run(agent, 'Which language is this repo written in?'); while (result.interruptions && result.interruptions.length) { for (const interruption of result.interruptions) { // Human in the loop here const approval = await confirm(interruption); if (approval) { result.state.approve(interruption); } else { result.state.reject(interruption); } } result = await run(agent, result.state); } console.log(result.finalOutput);}
import { stdin, stdout } from 'node:process';import * as readline from 'node:readline/promises';
async function confirm(item: RunToolApprovalItem): Promise<boolean> { const rl = readline.createInterface({ input: stdin, output: stdout }); const name = item.rawItem.name; const params = item.rawItem.providerData?.arguments; const answer = await rl.question( `Approve running tool (mcp: ${name}, params: ${params})? (y/n) `, ); rl.close(); return answer.toLowerCase().trim() === 'y';}
main().catch(console.error);
動作する完全なサンプル(リモートツール / Streamable HTTP / Stdio + ストリーミング、HITL、onApproval)は GitHub リポジトリの examples/mcp にあります。
2. Streamable HTTP MCP サーバー
Section titled “2. Streamable HTTP MCP サーバー”エージェントがローカルまたはリモートの Streamable HTTP MCP サーバーと直接やり取りする場合は、サーバーの url
、name
、および任意の設定を指定して MCPServerStreamableHttp
をインスタンス化します。
import { Agent, run, MCPServerStreamableHttp } from '@openai/agents';
async function main() { const mcpServer = new MCPServerStreamableHttp({ url: 'https://gitmcp.io/openai/codex', name: 'GitMCP Documentation Server', }); const agent = new Agent({ name: 'GitMCP Assistant', instructions: 'Use the tools to respond to user requests.', mcpServers: [mcpServer], });
try { await mcpServer.connect(); const result = await run(agent, 'Which language is this repo written in?'); console.log(result.finalOutput); } finally { await mcpServer.close(); }}
main().catch(console.error);
コンストラクターでは authProvider
、requestInit
、reconnectionOptions
、sessionId
など、MCP TypeScript SDK の追加オプションも指定できます。詳細は MCP TypeScript SDK リポジトリ とそのドキュメントを参照してください。
3. Stdio MCP サーバー
Section titled “3. Stdio MCP サーバー”標準 I/O しか公開していないサーバーの場合は、fullCommand
を指定して MCPServerStdio
をインスタンス化します。
import { Agent, run, MCPServerStdio } from '@openai/agents';import * as path from 'node:path';
async function main() { const samplesDir = path.join(__dirname, 'sample_files'); const mcpServer = new MCPServerStdio({ name: 'Filesystem MCP Server, via npx', fullCommand: `npx -y @modelcontextprotocol/server-filesystem ${samplesDir}`, }); await mcpServer.connect(); try { const agent = new Agent({ name: 'FS MCP Assistant', instructions: 'Use the tools to read the filesystem and answer questions based on those files. If you are unable to find any files, you can say so instead of assuming they exist.', mcpServers: [mcpServer], }); const result = await run(agent, 'Read the files and list them.'); console.log(result.finalOutput); } finally { await mcpServer.close(); }}
main().catch(console.error);
その他の注意点
Section titled “その他の注意点”Streamable HTTP と Stdio サーバーでは、Agent
が実行されるたびに list_tools()
を呼び出して利用可能なツールを取得することがあります。この往復はとくにリモートサーバーではレイテンシーを増加させるため、MCPServerStdio
または MCPServerStreamableHttp
に cacheToolsList: true
を渡して結果をメモリにキャッシュできます。
ツール一覧が変更されないと確信できる場合のみ有効にしてください。あとでキャッシュを無効化するには、サーバーインスタンスで invalidateToolsCache()
を呼び出します。
- Model Context Protocol – 公式仕様
- examples/mcp – 上記で参照した実行可能デモ