MCP 連携
Model Context Protocol (MCP) は、アプリケーションが LLM にツールとコンテキストを提供する方法を標準化するオープンプロトコルです。MCP のドキュメントより:
MCP は、アプリケーションが LLM にコンテキストを提供する方法を標準化するオープンプロトコルです。MCP は AI アプリケーションにおける USB‑C ポートのような存在だと考えてください。USB‑C がさまざまな周辺機器やアクセサリにデバイスを接続する標準化された方法を提供するのと同様に、MCP は AI モデルを異なるデータソースやツールに接続する標準化された方法を提供します。
この SDK がサポートする MCP サーバーには 3 種類あります:
- Hosted MCP server tools – OpenAI Responses API によってツールとして利用されるリモート MCP サーバー
- Streamable HTTP MCP servers – Streamable HTTP transport を実装するローカルまたはリモートのサーバー
- Stdio MCP servers – 標準入出力経由でアクセスするサーバー(最もシンプルな選択肢)
ユースケースに応じてサーバータイプを選択してください:
必要なこと | 推奨オプション |
---|---|
公開アクセス可能なリモートサーバーをデフォルトの OpenAI Responses モデルで呼ぶ | 1. Hosted MCP tools |
公開アクセス可能なリモートサーバーを使いつつ、ツール呼び出しはローカルでトリガー | 2. Streamable HTTP |
ローカルで動作する Streamable HTTP サーバーを使う | 2. Streamable HTTP |
OpenAI Responses 以外のモデルで任意の Streamable HTTP サーバーを使う | 2. Streamable HTTP |
標準入出力プロトコルのみをサポートするローカル MCP サーバーを扱う | 3. Stdio |
1. Hosted MCP server tools
Section titled “1. Hosted MCP server tools”Hosted ツールは、往復処理全体をモデル側に押し込みます。あなたのコードが MCP サーバーを呼ぶ代わりに、OpenAI Responses API がリモートのツールエンドポイントを呼び出し、その結果をモデルにストリーミングで返します。
Hosted MCP ツールを使う最も簡単な例がこちらです。hostedMcpTool
ユーティリティ関数にリモート MCP サーバーのラベルと URL を渡します。これは hosted 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);
コネクタ対応の hosted サーバー
Section titled “コネクタ対応の hosted サーバー”Hosted MCP は OpenAI コネクタにも対応しています。serverUrl
を指定する代わりに、コネクタの connectorId
と authorization
トークンを渡します。Responses API が認証を処理し、コネクタのツールを hosted MCP インターフェース経由で公開します。
import { Agent, hostedMcpTool } from '@openai/agents';
const authorization = process.env.GOOGLE_CALENDAR_AUTHORIZATION!;
export const connectorAgent = new Agent({ name: 'Calendar Assistant', instructions: "You are a helpful assistant that can answer questions about the user's calendar.", tools: [ hostedMcpTool({ serverLabel: 'google_calendar', connectorId: 'connector_googlecalendar', authorization, requireApproval: 'never', }), ],});
この例では、GOOGLE_CALENDAR_AUTHORIZATION
環境変数に Google OAuth Playground で取得した OAuth トークンが格納されており、コネクタ対応サーバーが Calendar API を呼び出すことを許可します。ストリーミングもあわせて示す実行可能なサンプルは examples/connectors
を参照してください。
完全に動作するサンプル(Hosted ツール/Streamable HTTP/stdio + ストリーミング、HITL、onApproval)は、GitHub リポジトリの examples/mcp にあります。
2. Streamable HTTP MCP servers
Section titled “2. Streamable HTTP MCP servers”エージェントがローカル/リモートの 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
、fetch
、reconnectionOptions
、sessionId
などの追加の MCP TypeScript‑SDK オプションも受け付けます。詳細は MCP TypeScript SDK リポジトリ とそのドキュメントを参照してください。
3. Stdio MCP servers
Section titled “3. Stdio MCP servers”標準入出力のみを公開するサーバーの場合は、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()
を呼び出します。
ツールのフィルタリング
Section titled “ツールのフィルタリング”createMCPToolStaticFilter
による静的フィルター、またはカスタム関数を渡すことで、各サーバーから公開されるツールを制限できます。両方の方法を示す複合例は次のとおりです:
import { MCPServerStdio, MCPServerStreamableHttp, createMCPToolStaticFilter, MCPToolFilterContext,} from '@openai/agents';
interface ToolFilterContext { allowAll: boolean;}
const server = new MCPServerStdio({ fullCommand: 'my-server', toolFilter: createMCPToolStaticFilter({ allowed: ['safe_tool'], blocked: ['danger_tool'], }),});
const dynamicServer = new MCPServerStreamableHttp({ url: 'http://localhost:3000', toolFilter: async ({ runContext }: MCPToolFilterContext, tool) => (runContext.context as ToolFilterContext).allowAll || tool.name !== 'admin',});
- Model Context Protocol – 公式仕様
- examples/mcp – 上で参照した実行可能デモ