OpenAIのResponses APIでは、リモートMCPサーバーをtoolsへ登録するだけで、モデルから外部ツールを呼び出せます。
前回の「MCPとFunction Callingの違い」では設計上の使い分けを整理しました。今回は実装編として、PythonからMCPサーバーへ接続する最小コード、利用ツールの制限、承認フローまでを順番に解説します。
この記事を読むと、次のことが分かります。
- Responses APIへリモートMCPサーバーを登録する方法
allowed_toolsで使えるツールを限定する方法require_approvalで人間の承認を挟む方法- OAuthが必要なコネクターとの違い
- 本番運用で避けたい設定

Responses APIのMCP連携とは
Responses APIには、組み込みツールの一種としてmcpがあります。自分で関数の実行処理を書くFunction Callingとは異なり、OpenAI APIがリモートMCPサーバーからツール一覧を取得し、必要に応じて呼び出します。
基本構成は次の4要素です。
| 要素 | 役割 |
|---|---|
type |
mcpを指定する |
server_label |
応答内でサーバーを識別する名前 |
server_url |
リモートMCPサーバーのURL |
require_approval |
ツール実行前の承認ルール |
リモートMCPサーバーは外部システムです。プロンプトや機密データが送られる可能性があるため、信頼できる運営元・コード・権限範囲を確認してから接続してください。
Pythonの実行環境を準備する
OpenAI SDKをインストールする
Python 3.10以降を想定します。仮想環境を有効にしたうえで、OpenAI SDKを更新します。
pip install -U openai
APIキーを環境変数へ設定する
APIキーはコードへ直接書かず、環境変数OPENAI_API_KEYへ保存します。
export OPENAI_API_KEY="your-api-key"
OpenAI()は、この環境変数を自動的に読み込みます。GitHubへ公開するファイルやNotebookへAPIキーを貼り付けないようにしましょう。
MCPサーバーへ接続する最小コード
まずは、OpenAI公式ドキュメントでも例示されているデモ用MCPサーバーへ接続します。以下はダイスを振るツールだけを許可した最小例です。
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5.6",
tools=[
{
"type": "mcp",
"server_label": "dmcp",
"server_description": "ダイス計算を行うデモ用MCPサーバー",
"server_url": "https://dmcp-server.deno.dev/mcp",
"allowed_tools": ["roll"],
"require_approval": "never",
}
],
input="2d4+1を計算してください",
)
print(response.output_text)
この例では説明を単純にするため、承認を省略しています。require_approval: "never"は、信頼済みの読み取り専用ツールなど、影響範囲を理解できている場合に限定してください。
実行時に起きること
- APIがMCPサーバーからツール一覧を取得する
- モデルが入力内容から
rollの利用を判断する - MCPサーバーがツールを実行する
- 実行結果を踏まえてモデルが最終回答を生成する
Function Callingのように、ツール呼び出しを受け取って自分のPythonコードで関数を実行し、その結果をAPIへ返す処理は不要です。
Responses API自体の基本は「OpenAI Responses API入門」、アプリ内関数を呼びたい場合は「Function Calling入門」も参考にしてください。
allowed_toolsで利用範囲を限定する
すべてのツールを公開しない
MCPサーバーによっては、数十個のツールを提供しています。すべてをモデルへ見せると、選択精度だけでなく、コストや待ち時間にも影響します。
利用するツールが決まっている場合は、allowed_toolsで許可リストを指定します。
mcp_tool = {
"type": "mcp",
"server_label": "knowledge_server",
"server_url": "https://example.com/mcp",
"allowed_tools": ["search_documents", "read_document"],
"require_approval": "always",
}
この設定では、サーバー側に削除・更新ツールが存在しても、モデルへ読み込まれるのはsearch_documentsとread_documentだけです。
最小権限で考える
本番環境では「使うかもしれない」ツールを並べるのではなく、ユースケースごとに必要なツールだけを渡すのが基本です。
- 調査エージェント:検索・読み取りだけ
- 社内アシスタント:閲覧と下書き作成まで
- 更新エージェント:対象リソースを限定し、承認を必須化
- 削除・購入・送信:原則として自動承認しない
MCPツールの実行前に承認を入れる
外部送信やデータ更新など、結果を元に戻しにくい処理には人間の承認を挟みます。




1回目のリクエストで承認要求を受け取る
require_approvalをalwaysにすると、モデルがツールを選んだ時点でmcp_approval_requestが返ります。
from openai import OpenAI
client = OpenAI()
mcp_tool = {
"type": "mcp",
"server_label": "dmcp",
"server_description": "ダイス計算を行うデモ用MCPサーバー",
"server_url": "https://dmcp-server.deno.dev/mcp",
"allowed_tools": ["roll"],
"require_approval": "always",
}
first = client.responses.create(
model="gpt-5.6",
tools=[mcp_tool],
input="2d4+1を計算してください",
)
approval_request = next(
item for item in first.output
if item.type == "mcp_approval_request"
)
print(approval_request.name)
print(approval_request.arguments)
アプリ側では、ツール名・引数・接続先を表示し、ユーザーに実行可否を確認します。引数をそのまま信用せず、自分のアプリ側でも許可範囲を検証してください。
承認結果をResponses APIへ返す
承認された場合は、previous_response_idとmcp_approval_responseを使って処理を継続します。
second = client.responses.create(
model="gpt-5.6",
tools=[mcp_tool],
previous_response_id=first.id,
input=[
{
"type": "mcp_approval_response",
"approval_request_id": approval_request.id,
"approve": True,
}
],
)
print(second.output_text)
拒否する場合はapproveをFalseにします。承認画面を閉じた場合や一定時間操作がない場合も、拒否として扱う設計が安全です。
コネクターを使う場合
OpenAIが管理するコネクターも、Responses API上ではtype: "mcp"として扱います。リモートMCPサーバーとの主な違いは、server_urlではなくconnector_idとOAuthアクセストークンを使う点です。
import os
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5.6",
tools=[
{
"type": "mcp",
"server_label": "google_calendar",
"connector_id": "connector_googlecalendar",
"authorization": os.environ["GOOGLE_CALENDAR_OAUTH_ACCESS_TOKEN"],
"require_approval": "always",
}
],
input="今日の予定を確認してください",
)
アクセストークンもAPIキーと同様に機密情報です。ログやエラーメッセージ、ブラウザへ返すレスポンスへ含めないでください。
よくあるエラーと確認ポイント
MCPサーバーへ接続できない
server_urlが外部から到達できるか- HTTPS証明書が有効か
- サーバーがResponses APIから利用できるリモートMCP形式か
- 認証ヘッダーやOAuthトークンが必要ではないか
ローカルPCのlocalhostは、そのままではOpenAI APIから接続できません。非公開・社内ネットワーク上のサーバーには、対応する安全な接続方法が必要です。
ツールが選ばれない
server_descriptionと各ツールの説明が曖昧だと、モデルが利用場面を判断しづらくなります。ツール名だけでなく「何ができるか」「いつ使うか」「何を返すか」を具体的に記述します。
応答が遅い・コストが増えた
公開するツール数が多すぎないか確認してください。allowed_toolsで対象を絞り、会話内では取得済みのmcp_list_tools情報を文脈に維持すると、毎回のツール一覧取得を避けやすくなります。
本番運用前のチェックリスト
- ✅ 接続先MCPサーバーの運営元とコードを確認した
- ✅
allowed_toolsで必要なツールだけを許可した - ✅ 更新・送信・購入・削除には承認を設定した
- ✅ ツール引数をアプリ側でも検証した
- ✅ APIキーとOAuthトークンを環境変数で管理した
- ✅ タイムアウト・再試行・失敗時の動作を決めた
- ✅ ツール名、承認結果、処理時間を監査ログへ残した
- ✅ エラー表示から機密情報を除外した
まとめ
Responses APIからMCPサーバーを使う最小構成は、toolsへtype: "mcp"、server_label、server_urlを登録するだけです。
ただし、本番利用で重要なのは接続できることより、接続範囲を制御できることです。
allowed_toolsで公開するツールを絞る- 影響のある処理は
require_approvalで止める - ツール引数と権限をアプリ側でも検証する
- 信頼できるMCPサーバーだけを利用する
まずは読み取り専用ツール1個から試し、監査ログと承認画面を確認してから対象を増やすと安全です。


コメント