mcpField
M
migrate-oai-app

migrate-oai-app

github.com/modelcontextprotocol開発3.0k1.1k 回インストール1 日前に更新
リポジトリ

migrate-oai-app について

既存の OpenAI Apps SDK アプリを MCP Apps SDK に移行する開発者向けのスキルです。サーバーとクライアントの変更、CSP のオリジン調査、機能差、動作確認を扱います。

主な機能

  1. 01サーバー側の登録方式を対応付け
  2. 02App イベントハンドラーへ移行
  3. 03CSP オリジンの調査と設定
  4. 04未対応機能を確認
  5. 05basic-host で動作を検証

活用シーン

  1. 01既存の OpenAI App を移行
  2. 02クライアント側のグローバル API を置換
  3. 03埋め込み UI の通信先を確認

MCP 対応

OpenAI Apps から MCP Apps SDK への移行を案内し、MCP のツール・リソース登録と App のイベントライフサイクルを扱います。移行後の UI は MCP リソースとしてサンドボックス iframe 内で動作します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/modelcontextprotocol/ext-apps --skill migrate-oai-app

インストール後、Claude Code で/migrate-oai-appを入力して読み込まれたか確認します。

詳細

OpenAI App から MCP への移行

既存の OpenAI Apps SDK アプリケーションを MCP Apps SDK(@modelcontextprotocol/ext-apps)に移行します。MCP Apps SDK は、会話型クライアントでインタラクティブな UI を実現する、標準化されたオープンなプロトコルを提供します。

ベストプラクティス

  • バージョン番号を手動で記述するのではなく、パッケージマネージャーを使って依存関係を追加してください(例:npm install、pnpm add、yarn add)。これにより、パッケージマネージャーが互換性のある最新バージョンを解決できます。記憶を頼りにバージョン番号を指定しないでください。
  • 最後の TODO 項目として、次の文言をそのまま追加してください:「このスキルの『完了前』チェックリストを読み直し、各チェックボックスに個別に対応してから、この TODO を完了としてマークしてください。対応した内容もそれぞれ記載してください。」

リファレンスコードの取得

完全な移行ドキュメントと動作するサンプルを参照するには、SDK リポジトリをクローンしてください。

git clone --branch "v$(npm view @modelcontextprotocol/ext-apps version)" --depth 1 https://github.com/modelcontextprotocol/ext-apps.git /tmp/mcp-ext-apps
移行リファレンスガイド

「移行前/移行後」の対応表がある移行リファレンスガイドを読んでください:/tmp/mcp-ext-apps/docs/migrate_from_openai_apps.md

API リファレンス(ソースファイル)

/tmp/mcp-ext-apps/src/* の JSDoc ドキュメントを直接読んでください:

ファイル内容
src/app.tsApp クラス、ハンドラー、ライフサイクル
src/server/index.tsregisterAppTool、registerAppResource
src/spec.types.ts型定義
src/react/useApp.tsxReact アプリ用の useApp フック
src/react/use*.ts*React アプリ用のその他の use* フック
フロントエンドフレームワークのサンプル

フロントエンドフレームワーク別に整理された基本的な SDK の使用例は、/tmp/mcp-ext-apps/examples/basic-server-{framework}/ を参照してください:

テンプレート主なファイル
basic-server-vanillajs/server.ts、src/mcp-app.ts、mcp-app.html
basic-server-react/server.ts、src/mcp-app.tsx(useApp フックを使用)
basic-server-vue/server.ts、src/App.vue
basic-server-svelte/server.ts、src/App.svelte
basic-server-preact/server.ts、src/mcp-app.tsx
basic-server-solid/server.ts、src/mcp-app.tsx

CSP の調査

MCP Apps の HTML はウェブページではなく MCP リソースとして提供され、同一オリジンのサーバーを持たないサンドボックス化された iframe 内で実行されます。すべてのオリジンを CSP に宣言する必要があります。JS/CSS バンドルを配信するオリジンも対象です(開発環境では localhost、本番環境では CDN)。オリジンが不足していても、エラーは表示されません。

移行コードを書く前に、アプリをビルドし、参照しているすべてのオリジンを調査してください。

  1. 既存のビルドコマンドを使ってアプリをビルドします
  2. 生成された HTML、CSS、JS を検索し、すべてのオリジンを調べます(「外部」オリジンだけではありません。すべてのネットワークリクエストに CSP の許可が必要です)
  3. 見つかった各オリジンについて、ソースまでたどります:
    • 定数に由来する場合 → 共通(開発環境と本番環境で同じ)
    • 環境変数または条件分岐に由来する場合 → その仕組みを記録し、開発環境と本番環境の両方の値を特定します
  4. 独自にリクエストを行う可能性のあるサードパーティライブラリ(分析、エラートラッキングなど)がないか確認します

調査結果を記録し、次の3つのリストに分けて、各オリジンが共通、開発環境のみ、本番環境のみのどれに該当するか記載してください。

  • resourceDomains:画像、フォント、スタイル、スクリプトを配信するオリジン
  • connectDomains:API/fetch リクエストのオリジン
  • frameDomains:ネストされた iframe のオリジン

オリジンが見つからない場合、アプリにカスタム CSP ドメインは必要ない可能性があります。

CORS の設定

MCP クライアントはクロスオリジンリクエストを送信します。Express を使用している場合は、app.use(cors()) で対応できます。

生の HTTP サーバーでは、標準的な CORS を設定し、さらに次の項目を設定してください。

  • 許可するヘッダー:mcp-session-id、mcp-protocol-version、last-event-id
  • 公開するヘッダー:mcp-session-id

主な概念上の変更点

サーバー側

生の server.registerTool()/server.registerResource() ではなく、registerAppTool() と registerAppResource() のヘルパーを使用してください。これらのヘルパーは MCP Apps のメタデータ形式を自動的に処理します。

サーバー側の対応表については、/tmp/mcp-ext-apps/docs/migrate_from_openai_apps.md を参照してください。

クライアント側

基本的なパラダイムの変化は、OpenAI ではコードの実行前に値が設定される同期グローバルオブジェクト(window.openai.toolInput、window.openai.theme)を使用するのに対し、MCP Apps では非同期イベントハンドラーを備えた App インスタンスを使用することです。

主な違い:

  • connect() を呼び出す前に、App インスタンスを作成してハンドラー(ontoolinput、ontoolresult、onhostcontextchanged)を登録します。(接続直後にイベントが発生する可能性があるため、先にハンドラーを登録する必要があります。)
  • ハンドラーを介してツールデータにアクセスします。app.ontoolinput は window.openai.toolInput に、app.ontoolresult は window.openai.toolOutput に対応します。
  • app.getHostContext() を介してホスト環境(テーマ、ロケールなど)にアクセスします。

React アプリでは、useApp フックがこのライフサイクルを自動的に管理します。パターンについては basic-server-react/ を参照してください。

クライアント側の対応表については、/tmp/mcp-ext-apps/docs/migrate_from_openai_apps.md を参照してください。

MCP Apps ではまだ利用できない機能

以下の OpenAI 機能には、まだ MCP の同等機能がありません。

サーバー側:

OpenAI 機能状況/回避策
_meta["openai/toolInvocation/invoking"] / _meta["openai/toolInvocation/invoked"]進行状況インジケーターはまだ利用できません
_meta["openai/widgetDescription"]動的なコンテキストには app.updateModelContext() を使用します

クライアント側:

OpenAI 機能状況/回避策
window.openai.widgetState / setWidgetState()localStorage またはサーバー側の状態を使用します
window.openai.uploadFile() / getFileDownloadUrl()ファイル操作はまだ利用できません
window.openai.requestModal() / requestClose()モーダル管理はまだ利用できません
window.openai.viewまだ利用できません

完了前の確認事項

以下のチェックリストの各項目を、時間をかけて丁寧に確認してください。

  • サーバー側に OpenAI のパターンが残っていないか検索し、移行します。

    パターン意味
    "openai/古いメタデータキー → _meta.ui.*
    text/html+skybridge古い MIME タイプ → RESOURCE_MIME_TYPE 定数
    text/html;profile=mcp-app新しい MIME タイプですが、RESOURCE_MIME_TYPE 定数の使用を推奨します
    _domains" または _domains:snake_case の CSP → camelCase(connect_domains → connectDomains)
  • クライアント側に OpenAI のパターンが残っていないか検索し、移行します。

    パターン意味
    window.openai.toolInput古いグローバル → ontoolinput ハンドラー内の params.arguments
    window.openai.toolOutput古いグローバル → ontoolresult 内の params.structuredContent
    window.openai古いグローバル API → App インスタンスのメソッド
  • CSP の調査で特定した各オリジンが、registerAppResource() の CSP 設定のどこに記載されているかを確認します。CSP の調査で特定したすべてのオリジン(全環境共通、開発環境のみ、本番環境のみ)を CSP 設定に含める必要があります。MCP Apps の HTML は、同一オリジンのサーバーがないサンドボックス化された iframe 内で実行されます。CSP 設定に含まれていないオリジンがあれば、今すぐ追加してください。

  • CSP の調査で特定した条件付き(開発環境のみ、本番環境のみ)の各オリジンについて、同じ設定項目(環境変数、設定ファイルなど)が実行時 URL と CSP エントリーの両方を制御している箇所を確認します。条件付きにすべきオリジンが CSP にハードコードされている場合は、今すぐ修正してください。アプリは本番環境で使用できる状態でなければなりません。

テスト

basic-host を使用する

basic-host のサンプルで移行したアプリをテストします。

# Terminal 1: Build and run your server
npm run build && npm run serve

# Terminal 2: Run basic-host (from cloned repo)
cd /tmp/mcp-ext-apps/examples/basic-host
npm install
SERVERS='["http://localhost:3001/mcp"]' npm run start
# Open http://localhost:8080
実行時の動作を確認する

アプリが basic-host で読み込まれたら、以下を確認します。

  1. アプリがコンソールエラーなしで読み込まれる
  2. ontoolinput ハンドラーがツールの引数を受け取って実行される
  3. ontoolresult ハンドラーがツールの結果を受け取って実行される

コメント