はじめに:著者:Boxu Li
ChatGPT のアプリ は、サードパーティの開発者がチャットインターフェース内で動作するインタラクティブなミニアプリケーションを構築できるようにします。ユーザーをウェブサイトやモバイルアプリに移動させるのではなく、これらのアプリは会話内で実行され、モデルの推論を活用してアクションを促します。Canva、Coursera、Expedia、Zillow といった初期のパートナーは、ChatGPT を離れることなくプレイリストを求めたり、ポスターをデザインしたり、不動産を検索したりする方法をデモンストレーションしました[1]。新しい Apps SDK は、外部ツールやユーザーインターフェースとモデルが連携することを可能にするオープンスタンダードである Model Context Protocol (MCP) を基に構築されています[2]。このブログでは、MCP ベースのアプリのアーキテクチャを深く掘り下げ、SDK の機能を説明し、アプリをステップバイステップで構築する方法を解説し、ユーザーがアプリを発見して使用する方法を探り、プライバシーとセキュリティの考慮事項について議論します。分析を信頼できるソースに基づけるために、公式ドキュメントや信頼できるジャーナリズムを随所に引用しています。
「モデルコンテキストプロトコル」は、Apps SDKの基盤です。開発者向けのドキュメントによれば、すべてのApps SDKの統合は、MCPサーバーを使用してツールを公開し、認証を処理し、ChatGPTで表示される構造化データとHTMLのパッケージを処理します[2]。MCPはオープンスタンダードであり、誰でも任意の言語でサーバーを実装し、GPT-4やCodexのようなモデルと接続することができます。オープンソースの性質により、ベンダーロックインがなく、理論的には同じアプリがプロトコルを実装する任意のAIプラットフォームで動作することができます。このオープン性はコミュニティの貢献を促進し、HTTPのような標準が互換性のあるウェブサイトを可能にした初期のウェブに類似したエコシステムを育成します。
MCPサーバーは一つ以上のツールを公開します。ツールはモデルが呼び出す可能性のあるアクションを定義し、「カンバンボードを作成する」、「家を検索する」、「プレイリストを生成する」といったものが含まれます。各ツールはマシン名、人間に優しいタイトル、およびモデルが受け入れる引数を示すJSONスキーマで説明されます。ChatGPTがツールを呼び出すべきだと判断すると、サーバーに構造化された呼び出しを送信します。サーバーは、そのロジックを実行し、APIのクエリ、計算の実行、データベースとのやり取りなどを行い、その後ツールレスポンスを返します。このレスポンスには3つのフィールドが含まれています。
ツールはまた、ui:// URLを参照することで、HTMLテンプレートや画像などのリソースを参照することもできます。サーバーはこれらのリソースを起動時に登録します。ドキュメントでは、リソースはOpenAIのインフラによってキャッシュされるため、開発者はファイル名にビルドハッシュを含めてバージョン管理を行うように警告しています[5]。そうでなければ、ユーザーはデプロイ後に古いUIを見ることになるかもしれません。
structuredContent と _meta の区別は重要です。ドキュメントによると、structuredContent はモデルに表示され、UI コンポーネントを活用するために使用されます。一方、_meta はモデルから隠されており、ドロップダウンメニューのリストなど、UI のための追加データを含むことがあります。可視データと非可視データを分けることで、開発者はモデルから機密情報を保護しつつ、リッチなインターフェースを提供できます。この設計はまた、必要最小限のデータ共有を促進します。タスクを完了するために必要な情報のみが公開され、プライバシー原則に沿っています。
ユーザーがアプリを初めて呼び出すとき、サーバーはユーザーの認証を必要とする場合があります。Apps SDK は OAuth 2.1 フローをサポートしており、開発者はスコープを指定し、ユーザーをアイデンティティプロバイダーにリダイレクトします。ユーザーが同意を与えると、アプリはトークンを取得し、ユーザーのデータにアクセスできます。サーバーの役割はセッション状態を管理することであり、多くの場合、ユーザーの ChatGPT アカウントにキーを持つデータベースにトークンを保存することで行います。これにより、後続のツール呼び出しがユーザーに再度プロンプトを表示することなくセッションを再利用できるようになります。
OpenAIは「最小特権」、「明示的なユーザー同意」、「多層防御」を強調しています。アプリは必要最低限の権限のみを要求し、ユーザーはデータ共有を明示的に許可しなければなりません。モデル自体が認証情報を推測することはありません。データ保持は制限されており、構造化されたコンテンツはユーザーのプロンプトがアクティブな間のみ保持され、ログは開発者と共有される前に編集されます。アプリコンポーネントのネットワークアクセスはコンテンツセキュリティポリシーによって制限されており、iframeは任意のブラウザAPIにアクセスできず、すべてのHTTPリクエストはクライアントではなくサーバーから発信されなければなりません。これにより、クロスサイトスクリプティングやトークンの流出が防止されます。
アプリSDKは、MCPを慣用的なクライアントライブラリ(現在はPythonとTypeScript)とスキャフォルディングツールでラップします。アプリを作成する際には、ツールを定義し、UIテンプレートを登録し、サーバーロジックを実装します。サーバーは自身のインフラストラクチャ上で実行可能で、任意のフレームワーク(FastAPI、Expressなど)を使用できますが、MCPエンドポイントを実装する必要があります。OpenAIは、ローカルでの呼び出しをテストするための開発サーバーと「MCP Inspector」を提供しています。
開発者は、ロジックとユーザーインターフェースの両方をデザインします。UIは通常、Reactで書かれ、静的リソースにコンパイルされます。それらはChatGPT内のサンドボックス化されたiframe内で提供されます。このiframe内で、開発者はホストと対話するためにグローバルなwindow.openaiオブジェクトにアクセスできます。カスタムUXを構築するガイドによれば、このAPIは以下を提供します:
これらのAPIにより、開発者はモデルの推論と同期したリッチなインタラクティブコンポーネントを構築できます。例えば、ユーザーがカンバンボードのタスクを新しい列にドラッグした場合、コンポーネントはcallToolを送信してサーバーを更新し、新しい状態を永続させ、その後新しいstructuredContentを返すことができます。一方、モデルは高レベルのボード状態のみを認識し、UIはドラッグ&ドロップなどの詳細を処理します。
In the server code you register a tool and its template. For instance, in a TypeScript server you might write:
import { Tool, StructuredToolResponse } from "@openai/apps";
// Register UI template
server.registerResource("ui://kanban-board/abc123", buildHtml());
// Define tool schema
const createBoard: Tool = {
name: "createKanbanBoard",
description: "Create a new kanban board with given tasks and columns",
inputSchema: z.object({
title: z.string(),
columns: z.array(z.object({ name: z.string() })),
tasks: z.array(z.object({ name: z.string(), columnIndex: z.number() }))
}),
async execute(input, ctx): Promise<StructuredToolResponse> {
// compute board state
const columns = input.columns.map((col, i) => ({
id: i,
title: col.name,
taskIds: input.tasks.filter(t => t.columnIndex === i).map((_t, idx) => idx)
}));
const tasksById = input.tasks.map((task, id) => ({ id, name: task.name }));
return {
content: `Created board '${input.title}'`,
structuredContent: { title: input.title, columns },
_meta: { tasksById, uiTemplate: "ui://kanban-board/abc123" }
};
}
};
The _meta field includes tasksById for hidden metadata and uiTemplate referencing the registered HTML. When ChatGPT receives this response, it will render the template with the structured content. The window.openai.toolOutput object in the component can then read the board data and display it.
リソースとしてのUIテンプレートがOpenAIのサーバーにキャッシュされるため、開発者はui://識別子に一意のハッシュやバージョンを含めるべきです。ドキュメントでは、パスを更新せずに新バージョンをデプロイすると、キャッシュの影響でユーザーが古いUIを見続ける可能性があると注意しています[5]。ベストプラクティスとして、コミットSHAまたはビルドIDをURLに埋め込むことが推奨されます。これにより、各デプロイメントで新しいリソースが確実に提供されます。
コンポーネントはしばしば状態を保持する必要があります。例えば、プレイリストアプリではユーザーが曲をお気に入りに追加でき、そのお気に入りはユーザーが別の質問をしたときでも残るべきです。setWidgetState()メソッドは、structuredContentの外部にデータを保存し、ターンをまたいで持続させます[8]。モデルはこの状態を確認せず、プライバシーが確保されます。
アプリがユーザーに明確化の質問をする必要がある場合もあります。sendFollowupTurn()メソッドを使用すると、コンポーネントが新しいプロンプトをChatGPTに送信でき、モデルが質問したかのようにトランスクリプトに表示されます[8]。これは、例えば旅行予約アプリが「何泊滞在しますか?」とホテルを選択した後にユーザーに質問するような、多段階のワークフローに役立ちます。
In this section we will build a simple Task Tracker app that demonstrates the core concepts of the Apps SDK. The app will let a user create tasks and organise them into categories. We choose this example because it is generic, easy to extend and showcases structured content, metadata, custom UI and tool calls.
First install the TypeScript SDK and scaffolding tool:
npm install -g @openai/apps-generator
apps init task-tracker
cd task-tracker
npm install
This command scaffolds a project with a server, a React frontend and build scripts. The server uses Express and the @openai/apps library. Run npm run dev to start the development server; the project includes an MCP Inspector that opens in your browser and simulates ChatGPT calling your app.
Open src/server.ts and define a tool called createTasks. The tool accepts an array of tasks and returns structured content grouping them by category. It also provides a summary in the content field.
import { Tool, StructuredToolResponse } from "@openai/apps";
export const createTasks: Tool = {
name: "createTasks",
description: "Create a list of tasks grouped by category",
inputSchema: z.object({ tasks: z.array(z.object({ name: z.string(), category: z.string() })) }),
async execute({ tasks }): Promise<StructuredToolResponse> {
const categories = Array.from(new Set(tasks.map(t => t.category)));
const grouped = categories.map(category => ({
name: category,
taskIds: tasks.filter(t => t.category === category).map((_, i) => i)
}));
const tasksById = tasks.map((task, id) => ({ id, name: task.name, category: task.category }));
return {
content: `Created ${tasks.length} tasks in ${categories.length} categories`,
structuredContent: { categories: grouped },
_meta: { tasksById, uiTemplate: "ui://task-tracker/1.0.0" }
};
}
};
Register the template before using it:
server.registerResource("ui://task-tracker/1.0.0", fs.readFileSync(path.join(__dirname, "../dist/index.html"), "utf8"));
server.registerTool(createTasks);
Next open src/frontend/App.tsx. This React component will read the structuredContent and display categories and tasks. It will also allow users to mark tasks as complete and persist that state using setWidgetState.
import { useEffect, useState } from "react";
declare global {
interface Window {
openai: any;
}
}
export default function App() {
const [complete, setComplete] = useState<{ [id: string]: boolean }>(() => window.openai.widgetState?.complete || {});
const output = window.openai.toolOutput;
const tasksById = output?._meta?.tasksById || [];
const categories = output?.structuredContent?.categories || [];
// persist completion state
useEffect(() => {
window.openai.setWidgetState({ complete });
}, [complete]);
return (
<div className="task-tracker">
{categories.map((cat: any, ci: number) => (
<div key={ci} className="category">
<h3>{cat.name}</h3>
<ul>
{cat.taskIds.map((tid: number) => (
<li key={tid}>
<label>
<input type="checkbox" checked={complete[tid]} onChange={() => setComplete(prev => ({ ...prev, [tid]: !prev[tid] }))} />
{tasksById[tid].name}
</label>
</li>
))}
</ul>
</div>
))}
</div>
);
}
This component uses window.openai.toolOutput to access the structuredContent and _meta fields. It stores completion state in widgetState so that checking a box persists even when the user continues the conversation. On subsequent tool calls, the component can fetch new tasks or update existing ones. This demonstrates how to combine model reasoning with client‑side interactions.
Run npm run dev again and open the MCP Inspector. In the prompt area, type:
@task‑tracker create a list of tasks: buy milk in shopping, finish report in work, call mom in personal
The inspector will show the structured content and render the task list UI. You can check tasks off; the state persists across turns. You can then ask ChatGPT: “Remind me of my tasks later.” Because the model retains context, it can call the tool again, display the UI and summarise your progress.

ChatGPT surfaces apps when it believes they can assist the user. There are two primary discovery modes. Named mention occurs when the user explicitly mentions the app name at the beginning of a prompt; in this case, the app will be surfaced automatically[9]. For instance, “@Spotify create a workout playlist” immediately invokes the Spotify integration. The user must place the app name at the start; otherwise the assistant may treat it as part of the conversation.
In‑conversation discovery happens when the model infers that an app could help based on context. The documentation explains that the model evaluates the conversation context, prior tool results and the user’s linked apps to determine which app might be relevant[9]. For example, if you are discussing travel plans, ChatGPT might suggest the Expedia app to book flights. The algorithm uses metadata like tool descriptions and keywords to match the conversation with potential actions[10]. Developers can improve discoverability by writing action‑oriented descriptions and clear UI component names.
OpenAI plans to release an app directory where users can browse and discover new apps[10]. Each listing will include the app name, description, supported prompts and any onboarding instructions. Users can also access the launcher via the “+” button in chat; this shows a menu of available apps based on context. These entry points will help less technical users find and enable apps without memorising names.
ユーザーが初めてアプリを起動すると、ChatGPTがオンボーディングフローを開始します。モデルは、ユーザーにアカウントを接続するよう求め(必要に応じて)、アプリが必要とするデータについて説明します。開発者ガイドラインでは、アプリがユーザーのプライバシーを尊重し、予測可能に動作し、明確なポリシーを持つことが強調されています。ユーザーは明示的に許可を与えるか拒否する必要があり、無断でデータにアクセスすることはありません。一度接続されると、アプリは以降のやり取りでもリンクを維持できますが、ユーザーは常に接続を解除し、許可を取り消すことができます。
OpenAI の アプリ開発者ガイドライン は、エコシステムが安全で信頼できる状態を維持するためのいくつかの原則を定めています。アプリは正当なサービスを提供し、明確なプライバシーポリシーとデータ保持の実践を持ち、使用ポリシーを遵守する必要があります[11]。データ収集を最小限に抑え、機密の個人情報を保存せず、ユーザーの同意なしにデータを共有してはなりません[12]。アプリは予測可能に動作し、有害または誤解を招く内容を生成するようにモデルを操作してはなりません。
ガイドラインでは、アプリはその機能に必要なデータのみを収集し、健康記録や政府のIDのような機密データを要求または保存してはならないことが強調されています[12]。モデルに送信する構造化されたコンテンツには秘密を含めてはならず、隠されたメタデータにはユーザートークンや個人情報を保存してはなりません。開発者は、OAuthで取得したトークンに対して強力な暗号化と安全な保存を実装する必要があります。サーバーはユーザーセッション間の厳格な境界を維持し、一人のユーザーのデータが別のユーザーのコンテキストに漏れないようにしなければなりません。
「セキュリティとプライバシーガイド」は、プラットフォームに組み込まれた防御メカニズムを説明しています。中心的な原則として、最小特権と明示的なユーザー同意を強調しています[6]。データ保持は制限されており、開発者がアクセスできるログは個人を特定できる情報を削除して編集されており、構造化されたコンテンツはプロンプトが必要とする期間だけ保持されます[6]。iframe内からのネットワークアクセスはコンテンツセキュリティポリシーによって制限されており、外部へのフェッチはサーバーを通じて行われ、無許可のクロスオリジンリクエストを防ぎます[7]。認証には業界標準のOAuthフローと短時間有効のトークンを使用しています。開発者は、運用準備を維持するためにセキュリティレビュー、バグ報告チャネル、インシデント監視を実施することが求められています[7]。
アプリは幅広いオーディエンスに適したものでなければなりません。ガイドラインでは、長文コンテンツや複雑な自動化、広告を提供するアプリを禁止しています[13]。たとえば、30分のビデオを提供したり、ChatGPT内でソーシャルネットワーク全体を再現したりするアプリは不適切です。このプラットフォームは、会話の流れを補完する簡潔なインタラクションを推奨しています。違反すると、拒否や削除につながる可能性があります。
ChatGPTをサードパーティアプリに開放することで、OpenAIはユーザーとサービスの間の「インテントレイヤー」としての地位を確立しています。開発者は、個別のウェブやモバイルアプリを構築することなく、チャットインターフェイスを通じて数百万のユーザーにリーチできるようになりました。アプリは摩擦を減らす可能性があります。アプリをダウンロードしたりウェブサイトを訪問したりする代わりに、ユーザーは会話の中でサービスを言及するだけです。これにより、ツールへのアクセスが民主化され、小規模な開発者にとって競争の場が均等になります。
早期のパートナーシップは可能性を示しています。ユーザーはChatGPTに質問しながらCourseraの講義を視聴したり、Canvaでポスターをデザインしたり、Expediaの旅行オプションやZillowの不動産リストを閲覧したり、Spotifyのプレイリストを生成したり、Figmaでアイデアを図解したりできます。アプリはチャット内で動作するため、モデルは要約、分析、推奨を生成し、静的なコンテンツをインタラクティブなレッスンに変えることができます。また、アプリはインラインカード、フルスクリーン、ピクチャーインピクチャーなど、複数の表示モードを提供し、さまざまなタスクに柔軟性を与えます。
アプリを使う際にコンテキストを切り替える必要がない能力は、人々のサービスとの関わり方を再構築する可能性があります。ChatGPTは単なるチャットボットではなく、インテントのためのユニバーサルオペレーティングシステムになります。ケイシー・ニュートンが指摘したように、これにより個別のアプリを起動するのではなく、必要なことをただ言うだけで済むようになります[16]。この変化を、App Storeやブラウザの立ち上げに似た、機能と競争を集約する単一のプラットフォームと比較するアナリストもいます。
しかし、この変革はコントロールと権力に関する疑問を呼び起こします。ChatGPTがどのアプリを表示するかを決定する場合、それがゲートキーパーになる可能性があります。ニュートンは、ユーザーの好みに基づいて構築された「AIグラフ」が、ソーシャルネットワークよりも深刻なプライバシーリスクを生む可能性があると警告しています[16]。経済的インセンティブがアプリの配置やランキングを支払うことのできる企業に有利に働く可能性があります。開発者はユーザーとの関係を所有するのではなく、ChatGPT向けに設計するプレッシャーを感じるかもしれません。プラットフォームが透明で公正であることを維持し、信頼を保つことが重要です。
アプリは個人データ—位置情報、連絡先、支払い方法—にアクセスできるため、規制当局はChatGPTを通じたデータの流れを精査する可能性があります。開発者は、プラットフォームが欧州連合でまだ利用できないにもかかわらず、GDPRのようなプライバシー法を遵守しなければなりません。OpenAIは、より詳細なプライバシー管理と収益化オプションを約束しており、チャット内で即時チェックアウトを可能にするエージェンティックコマースプロトコルを含みます。このエコシステムの成功は、堅牢なセキュリティ、明確なユーザーの同意、公平な経済モデルに依存します。
Apps SDKはまだプレビュー段階にあり、多くの機能はまだ詳細を詰める必要があります。開発者のロードマップには次の事項が含まれています:
ChatGPTのアプリとMCPベースのアプリSDKの導入は、ソフトウェアとの関わり方における大きな変革を示しています。サードパーティのアプリケーションを直接チャットインターフェースに組み込むことで、OpenAIは自然言語、推論、インタラクティブなUIを融合させた新しいプラットフォームを作り出しました。モデルコンテキストプロトコルは、モデルがツールを呼び出し、コンポーネントをレンダリングするためのオープンで標準化された方法を提供します。また、アプリSDKは、サーバー通信、UI統合、状態管理を処理することで開発を簡素化します。タスクトラッカーのようなステップバイステップの例は、厳格なデータ境界とプライバシーを維持しながら、役立つアプリを簡単に構築できることを示しています。
しかし、この革新には責任が伴います。開発者はユーザーのプライバシー、安全性、公平性を優先したガイドラインに従わなければなりません[11][12]。最小特権や明示的な同意といったセキュリティメカニズムがユーザーを保護します[6]。同時に、業界の観察者は、このプラットフォームが新しい形式のゲートキーピングやプライバシーのリスクを生む可能性があると警告しています[16]。エコシステムが成熟する中で、透明性、オープンスタンダード、コミュニティの関与が、ChatGPTのアプリプラットフォームが日常のタスクにおける革新的で信頼されるレイヤーになるかどうかを決定します。
[1] AI軍拡競争最新情報: ChatGPTがSpotifyやZillowとのチャット接続を可能に
[2] [3] [4] [5] サーバーをセットアップしてください
https://developers.openai.com/apps-sdk/build/mcp-server
https://developers.openai.com/apps-sdk/guides/security-privacy
[8] カスタムUXを構築してください
https://developers.openai.com/apps-sdk/build/custom-ux
https://developers.openai.com/apps-sdk/concepts/user-interaction
https://developers.openai.com/apps-sdk/app-developer-guidelines/
[13] ChatGPTアプリが公開中: 最初に試せるものはこちら | The Verge
https://www.theverge.com/news/793081/chagpt-apps-sdk-spotify-zillow-openai
[14] OpenAI DevDay 2025: ChatGPTがアプリを取得、開発者向けのAgentKit、そして安価なGPTモデル
[15] OpenAI、ChatGPTがZillow、Canva、Spotifyなどのサードパーティアプリを起動・実行できるApps SDKを発表 | VentureBeat
https://venturebeat.com/ai/openai-announces-apps-sdk-allowing-chatgpt-to-launch-and-run-third-party
[16] 新しいプラットフォーム、馴染みのリスク: ZillowとExpediaがOpenAIのChatGPTアプリ展開に賭ける – GeekWire
[17] OpenAI DevDay: ChatGPTアプリ、AgentKit、CodexのGAリリース - SD Times
https://sdtimes.com/ai/openai-devday-chatgpt-apps-agentkit-and-ga-release-of-codex/
[18] OpenAIはChatGPTを普遍的なアプリフロントエンドにしたい - Ars Technica
https://arstechnica.com/ai/2025/10/openai-wants-to-make-chatgpt-into-a-universal-app-frontend/