当社独自のアクセス統計は常に有効です。Google Analyticsは、公開ページ(ログイン後のワークスペースは対象外)の利用状況を把握するためのもので、許可をいただいた場合のみ有効になります。詳しくは プライバシーポリシーをご覧ください。

リモートMCP連携の受け入れ確認:ディスカバリーで証明できることと、まだ検証が必要なこと

キー不要の検出プローブで初期化、通知、ツールカタログを確認したうえで、Claude、ChatGPT、Cursorそれぞれのネットワーク要件と認証要件を検証します。プロトコル上で見えることを、3つのクライアントすべてでのエンドユーザーテストと取り違えないためです。

製品ステータスの更新(2026-10-09確認、北京時間):本記事に記載の6つのツール一覧は、2026-09-04時点の過去の観測結果です。everyinfra_chatは2026-09-12に汎用テキストAPIとともに提供を終了しましたが、現在はAI APIで再び利用できます(チャージ後は無料、ストリーミング非対応)。データクレンジングツールは提供を終了しました。最新のツール一覧は、必ず稼働中のMCPサーバーに対する検出(tools/list)から取得してください。

クライアントにMCPアドレスを入力してツール名が表示されれば一歩前進ですが、それだけではまだ、キーを正しく渡せるか、実際の呼び出しが許可されたスコープ内に収まるか、エラーをクライアントが認識できるか、返されるデータがタスクの要件を満たすか、という問いには答えられません。

本ドキュメントでは、EveryInfraのリモートエンドポイントを例に、連携の受け入れ確認をプロトコル検出、認証方式の適合確認、クライアント動作、業務結果という4つのレイヤーに分けます。まずキー不要の検出プローブを示し、次に3つのクライアントについて「アドレスを入力すれば十分」と一括りにできない理由を説明します。これは検証済みの範囲を明示した連携ガイドであり、Claude、ChatGPT、Cursorのすべてへの導入に成功したと宣言するものではありません。

1つのリモートアドレス、4つの独立した検証レイヤー

ここで確認するエントリポイントはhttps://api.everyinfra.com/mcpです。プロトコル検出では、サーバーが自身をどう記述し、どのツールを公開しているかが分かります。認証方式の適合確認では、クライアントが承認済みの認証情報を取得し、渡す方法を確定します。クライアント側の受け入れ確認では、ツールが実際に現在のセッションに取り込まれるかを確認し、業務上の受け入れ確認では、実際の結果とエラーを検証します。

4つのレイヤーは個別に記録してください。サーバーが初期化に応答しても、クライアントがその後の通知を受理したとは限りません。クライアントがカタログを参照できても、業務上の権限があるとは限りません。ツールがコンテンツを返しても、業務上のエラーがないとは限りません。「接続成功」という1つのブール値ですべてを表さないでください。

同様に、MCPとRESTは異なる連携方式です。RESTのサンプルは業務上のセマンティクスの検証には役立ちますが、クライアントがMCPの認証、コンテンツブロック、エラー、確認フローを正しく処理できることを単独で証明するものではありません。

初期化の後に続く通知

本記事では、この検出パスをMCPプロトコルバージョン2025-06-18に照らして確認しています。これがすべてのクライアントにとって最新または唯一のバージョンだと主張するものではありません。クライアントはまずinitializeを送信してサーバーが選択したバージョンを確認し、次にnotifications/initializedを送信してから、ツール検出に進みます。以降のHTTPリクエストには、ネゴシエートされたプロトコルバージョンを含める必要があります。プロトコルライフサイクル

Streamable HTTPの通知が受理された場合は、レスポンスボディなしでHTTP 202を返す必要があります。初期化時にサーバーがMcp-Session-Idを返した場合、クライアントは以降のリクエストでもそれを保持しなければなりません。そのレスポンスヘッダーがない場合、クライアント側でセッションIDを生成してはなりません。リクエストへのレスポンスはJSONまたはSSEで返される場合があり、実際のクライアントはプロトコルが要求するトランスポート形式をサポートしている必要があります。トランスポート仕様

以下のスクリプトは、このサーバーが使用するJSONレスポンスの分岐のみを確認するもので、汎用のMCPクライアントではありません。SSE、ページネーションが必要なカタログ、サポート外のバージョンに遭遇した時点で停止し、その先の受け入れ確認は本格的なクライアントに委ねます。単一のJSONオブジェクトを解析するだけでプロトコル全体をカバーできるとはみなしません。

検出専用の診断スクリプト

fetchが組み込まれているNode.js 22以降を使用してください。スクリプトは環境変数からキーを読み取らず、tools/callを送信せず、クライアントのインストールや変更も行いません。出力にはステータス、ツール名、互換性の問題のみを残し、サーバーの説明文に含まれる製品の宣伝文句は表示しません。

Bash・コピー可能なサンプル
node --input-type=module <<'JS'
const endpoint = 'https://api.everyinfra.com/mcp';
const supportedVersion = '2025-06-18';
const headers = {
  'Content-Type': 'application/json',
  Accept: 'application/json, text/event-stream',
};
const issues = [];
async function post(message) {
  const response = await fetch(endpoint, {
    method: 'POST', headers, redirect: 'error',
    body: JSON.stringify(message),
    signal: AbortSignal.timeout(20000),
  });
  return { response, text: await response.text() };
}
function rpcResult(reply, id) {
  if (reply.response.status !== 200) {
    throw new Error('RPC HTTP ' + reply.response.status);
  }
  if (!reply.response.headers.get('content-type')?.includes('application/json')) {
    throw new Error('This probe only handles JSON; use a full MCP client');
  }
  const body = JSON.parse(reply.text);
  if (body.jsonrpc !== '2.0' || body.id !== id ||
      body.error || !body.result || typeof body.result !== 'object') {
    throw new Error('Invalid or failed RPC response');
  }
  return body.result;
}
const initReply = await post({
  jsonrpc: '2.0', id: 1, method: 'initialize',
  params: {
    protocolVersion: supportedVersion, capabilities: {},
    clientInfo: { name: 'bip-discovery-only', version: '1.0' },
  },
});
const init = rpcResult(initReply, 1);
if (init.protocolVersion !== supportedVersion ||
    init.serverInfo?.name !== 'EveryInfra' || !init.capabilities?.tools) {
  throw new Error('Unexpected version, server or tool capability');
}
headers['MCP-Protocol-Version'] = init.protocolVersion;
const session = initReply.response.headers.get('mcp-session-id');
if (session) headers['Mcp-Session-Id'] = session;
const notification = await post({
  jsonrpc: '2.0', method: 'notifications/initialized',
});
if (notification.response.status !== 202) {
  throw new Error('Initialization notification was not accepted');
}
const notificationBytes = Buffer.byteLength(notification.text);
if (notificationBytes !== 0) issues.push('notification_body_not_empty');
// Continue discovery for diagnosis only; never enter a business call.
const listed = rpcResult(await post({
  jsonrpc: '2.0', id: 2, method: 'tools/list', params: {},
}), 2);
if (!Array.isArray(listed.tools) || listed.tools.length === 0 ||
    listed.tools.some(tool => !tool.name || tool.inputSchema?.type !== 'object') ||
    listed.nextCursor) {
  throw new Error('Incomplete or unexpected tool list');
}
console.log(JSON.stringify({
  observedAt: new Date().toISOString(),
  protocolVersion: init.protocolVersion,
  sessionHeaderPresent: Boolean(session),
  notificationStatus: notification.response.status,
  notificationBodyBytes: notificationBytes,
  toolNames: listed.tools.map(tool => tool.name),
  issues,
  businessCallPerformed: false,
  hostAcceptanceVerified: false,
}, null, 2));
if (issues.length) process.exitCode = 2;
JS

終了コード0は、この限定的な検出チェックで不一致が見つからなかったことを示すだけであり、公開可能であることや、3つのクライアントでの受け入れ確認が成功したことを意味するものでは決してありません。終了コード2は、カタログは取得できたもののプロトコル上の不一致があることを示します。それ以外のエラーでは実行が終了します。接続の失敗と、検出成功後の互換性の問題は分けて扱ってください。

今回の検出で確認できたことと判明した問題

2026年9月4日20:43(中国標準時)に認証なしで再確認したところ、初期化はHTTP 200とプロトコルバージョン2025-06-18を返し、セッションIDのレスポンスヘッダーは提供されませんでした。ツールカタログは次の6つのツール名を返しました。

  • everyinfra_list_capabilities
  • everyinfra_call_api
  • everyinfra_chat
  • everyinfra_list_captcha_types
  • everyinfra_solve_captcha
  • everyinfra_search

ただし、初期化完了通知がHTTP 202を返した際、レスポンスボディは空ではなくJSONのnullでした。これは前述のバージョンにおける通知レスポンスの要件を満たしていません。カタログは引き続き読み取れますが、それだけではすべてのクライアントがこの不一致を許容することの証明にはなりません。スクリプトはこれを黙って無視するのではなく、明示的に報告すべきです。

今回は業務ツールを呼び出しておらず、この不一致によってクライアントが失敗するかどうかも確認していません。今後、このようなレスポンスの不一致にはサービスのメンテナーが対処し、実際のクライアントで再テストする必要があります。現時点で裏付けられる記述は「公開の検出パスで6つのツールを確認し、通知レスポンスに不一致がある」というものであり、「MCPと完全に互換」と書くことはできません。

2026-09-08に同じ無料の検出プロセスを再度実行したところ、カタログは8つのツールを返し、新たに追加された2つはデータクレンジングツールでした。初期化完了通知はHTTP 202でレスポンスボディは0バイトだったため、9月4日のレスポンスの不一致は今回の再確認では再現しませんでした。この更新で決着したのは公開の検出レイヤーにおける以前の観測結果のみであり、Claude、ChatGPT、Cursorが認証や実際の業務呼び出しを完了したことを意味するものではありません。

Cursor:設定によるヘッダー指定のサポートと実際の権限の個別検証

Cursorの公式ドキュメントでは、リモートサーバー向けにurlとheadersの設定が用意されており、環境変数からの補間をサポートしています。以下は、ユーザーの承認後に使用する設定形式です。今回はユーザー設定への書き込みも、実際のクライアントからの呼び出しの検証も行っていません。Cursor MCPドキュメント

JSON・コピー可能なサンプル
{
  "mcpServers": {
    "everyinfra": {
      "url": "https://api.everyinfra.com/mcp",
      "headers": {
        "Authorization": "Bearer ${env:EVERYINFRA_API_KEY}"
      }
    }
  }
}

プロジェクトの現在のサーバーコードにはBearerヘッダーの解析処理が含まれていますが、ソースコードにこのパスが存在しても、特定のキーが現時点で使用できることの証明にはなりません。実際の連携に向けて準備する際は、クライアントのプロセスが指定した環境変数を読み取れることを確認し、キーの業務上の権限を検証してください。実際の値を、バージョン管理下の設定、スクリーンショット、エラーレポートに書き込まないでください。

その後、現在のバージョンのCursorでカタログを更新し、ツールを個別に選択して、ユーザーによる確認を残しておきます。カタログが表示されるからといって、すべてのツールで自動実行を有効にしないでください。業務上の権限を持つキーを、すべての操作に対する長期的な承認として扱うべきではありません。

Claude:リモートコネクタはローカルネットワークを経由しない

Claudeのリモートコネクタに関する公式ドキュメントには、Claude Desktopのリモートコネクタを含め、リクエストはAnthropicのクラウドから送信されると記載されています。これは、デスクトップのローカル設定で行うローカルMCP構成とは異なる仕組みです。そのため、ローカルからアドレスにアクセスできても、証明されるのはローカルの経路のみであり、クラウドのコネクタからもアクセスできることの証明にはなりません。Claudeリモートコネクタの説明

連携にあたっては、現在のアカウントと組織の権限に応じてコネクタのエントリポイントを確認したうえで、サービスとクライアントの双方がサポートする認証フローを検証してください。公式ドキュメントにあるOAuthの設定を、「任意のBearer APIキーを入力できる」と言い換えることはできません。認証モデルが一致しない場合は、まずサービス側の対応または管理された適合方式を設計し、受け入れ確認を行う必要があります。汎用的な代替手段としてシークレットをURLに詰め込むことはできません。

このアカウントで検証していない、一連のクリック操作を示すスクリーンショットや「追加すれば成功する」といった手順は、ここでは掲載していません。コネクタの追加、認可、最終確認はアカウントの状態を変更するため、ユーザーの承認を得てから実行してください。プロトコル検証は、こうした証跡の代わりにはなりません。

ChatGPTとOpenAI API:異なる2つの連携エントリポイント

ChatGPTプラグインのMCP認証に関する公式ドキュメントでは、OAuth、認証なし、ハイブリッド認証が挙げられています。ハイブリッド認証では、ディスカバリーを認証なしで行い、各ツールのセキュリティ宣言に従って認証方式を選択します。キーなしでディスカバリーできても、すべての業務ツールを認証なしで呼び出せるわけではありません。ChatGPTの開発者モード

このツールカタログでは、ツールレベルのsecuritySchemesや_metaフィールドは確認されませんでした。これはこのレスポンスだけを確認した結果であり、サービス全体の認証実装を完全に監査したものではありません。ただし、ディスカバリーが成功しただけではChatGPTのハイブリッド認証の要件を満たしているとは言えないことを示すには十分です。

OpenAI Responses APIのリモートMCP設定はさらに別の経路で、server_url、ツールの選択、認証、呼び出しの承認などのパラメータを含みます。これはChatGPTの画面内での設定手順ではありません。APIでリクエストを構築しただけでは、Webインターフェースが接続済みであることの証明にはなりません。OpenAI MCPおよびコネクタガイド

今回はドキュメントの確認のみで、OpenAI APIでの業務リクエストの実行や、ユーザー向けの開発者モードの有効化は行っていません。今後この経路を使う場合は、リモートサービスに送信するデータの範囲を別途レビューし、機密性の高い呼び出しには承認ステップを維持してください。

認証設計では、公式のMCPセキュリティベストプラクティスのチュートリアルも別途確認してください。このページは2025-11-25のドキュメントパスにあり、トークンの対象は正しいサービスでなければならないと説明し、未検証のトークンのパススルーを避けるよう求めています。ただし、サードパーティのキーを汎用的なMCP認証情報に変えるものではなく、上記で2025-06-18版に基づいて行ったディスカバリーの確認に代わるものでもありません。

HTTP 200の後に確認すべき2つの結果レイヤー

MCPのプロトコルエラーはトップレベルのJSON-RPC errorに現れることがあり、ツールの実行エラーはresult.isErrorで表されることもあります。HTTP 200やテキストブロックの有無だけで業務上の成功と判断するのは不十分です。ツールとエラーの仕様

実運用では、ツールが返すデータ構造も確認してください。出力が想定どおりのオブジェクトか、空または一部のみになっていないか、非同期タスクに追加の照会が必要か、といった点です。複数のコンテンツブロックは各ツールのドキュメントに記載されたレスポンスに従って処理し、最初のテキストブロックにすべてのメタデータが含まれていると想定しないでください。課金、使用量、残高は実際の業務レスポンスで確認する必要があります。カタログのディスカバリーは、業務呼び出しの精算を証明するものではありません。

送信、購入、申請など副作用を伴う操作では、クライアントにツールが表示されることと、ユーザーが実行を許可したことは別です。呼び出し前に対象とパラメータを確認し、再試行前に初回の結果を確認できているか判断してください。このドキュメントのキーなしの検証は、意図的にこのレイヤーには踏み込んでいません。

次の連携担当者に引き継ぐ受け入れ記録

クライアントごとに、製品とバージョン、実行場所、通信方式と認証方式、インストール・認可の証跡、実際のツール名、マスキング済みの入力、結果のステータス、エラーを個別に記録してください。観測日時と許可された呼び出し範囲を記録し、生のキーは保存しないでください。成功したサンプル、明示的な失敗、結果が不明なものは分けて記録してください。

記録方法については、OWASPのロギングガイドにあるイベント相関とデータ除外の原則を参考にできます。同一の操作に関するイベントを関連付ける一方で、トークン、セッション、顧客コンテンツ全体をデバッグ用の添付ファイルに書き込まないようにしてください。ログは受け入れ証跡の一部にすぎず、実際のクライアントの挙動確認に代わるものではありません。

今回完了したのは、公開ディスカバリーとドキュメントの差異の検証です。通知でボディが空になる問題の修正、3つのクライアントへのインストールと認証、認可済みの業務呼び出し、失敗時の表示の受け入れ確認はまだ完了していません。これらの各項目について証跡が得られて初めて、チュートリアルの表現を「検証待ちの設定」から「指定バージョンでテストに合格済み」に変更できます。

まずこの記事のディスカバリースクリプトを実行し、現在のインターフェースと記録が引き続き一致しているかを確認してから、チームが選定したクライアントごとに作業を進めてください。互換性リストを埋めるためだけに、3つのアカウントを同時に変更したり、未検証の設定をコピーしたりしないでください。EveryInfraドキュメントの入り口

参考資料 LF-10