コンテンツにスキップ

MCP 連携

Model Context Protocol (MCP) は、アプリケーションが LLM にツールとコンテキストを提供する方法を標準化するオープンプロトコルです。MCP ドキュメントからの引用:

MCP は、アプリケーションが LLM にコンテキストを提供する方法を標準化するオープンプロトコルです。MCP は AI アプリケーションにおける USB-C ポートのようなものだと考えてください。USB-C がさまざまな周辺機器やアクセサリを接続するための標準化された方法を提供するのと同様に、MCP は AI モデルを多様なデータソースやツールへ接続するための標準化された方法を提供します。

この SDK がサポートする MCP サーバーには 3 種類あります。

  1. リモート MCP サーバーツールOpenAI Responses API からツールとして呼び出されるリモート MCP サーバー
  2. Streamable HTTP MCP サーバーStreamable HTTP トランスポート を実装するローカルまたはリモートサーバー
  3. 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

リモートツールでは、往復の処理全体がモデル内部で行われます。あなたのコードが MCP サーバーを呼び出す代わりに、OpenAI Responses API がリモートツールのエンドポイントを呼び出し、その結果をモデルへストリームします。

以下はリモート MCP サーバーツールを使用する最もシンプルな例です。hostedMcpTool ユーティリティ関数にリモート MCP サーバーのラベルと URL を渡すことで、リモート MCP サーバーツールを簡単に作成できます。

hostedAgent.ts
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 メソッド)でエージェントを実行できます。

Run with hosted MCP tools
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 を渡します。

Run with hosted MCP tools (streaming)
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);

機密性の高い操作については、個々のツール呼び出しに人間の承認を要求できます。requireApproval: 'always' または、ツール名ごとに 'never' / 'always' を指定するオブジェクトを渡してください。

ツール呼び出しが安全かどうかをプログラムで判断できる場合は、onApproval コールバック を使用して承認 / 拒否できます。人間の承認が必要な場合は、ローカルの関数ツールと同様に interruptions を利用した 人間の介入(HITL)アプローチ を使えます。

Human in the loop with hosted MCP tools
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 にあります。

エージェントがローカルまたはリモートの Streamable HTTP MCP サーバーと直接やり取りする場合は、サーバーの urlname、および任意の設定を指定して MCPServerStreamableHttp をインスタンス化します。

Run with Streamable HTTP MCP servers
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);

コンストラクターでは authProviderrequestInitreconnectionOptionssessionId など、MCP TypeScript SDK の追加オプションも指定できます。詳細は MCP TypeScript SDK リポジトリ とそのドキュメントを参照してください。

標準 I/O しか公開していないサーバーの場合は、fullCommand を指定して MCPServerStdio をインスタンス化します。

Run with Stdio MCP servers
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);

Streamable HTTPStdio サーバーでは、Agent が実行されるたびに list_tools() を呼び出して利用可能なツールを取得することがあります。この往復はとくにリモートサーバーではレイテンシーを増加させるため、MCPServerStdio または MCPServerStreamableHttpcacheToolsList: true を渡して結果をメモリにキャッシュできます。

ツール一覧が変更されないと確信できる場合のみ有効にしてください。あとでキャッシュを無効化するには、サーバーインスタンスで invalidateToolsCache() を呼び出します。