一個新的作業系統?ChatGPT 應用程式與應用程式 SDK(基於 MCP):解鎖新平台

作者:Boxu Li 於 Macaron
介紹:
ChatGPT 中的應用程式現在允許第三方開發者構建嵌入在聊天介面的互動迷你應用程式。這些應用程式不會將用戶引導到網站或手機應用程式,而是在對話中運行,並利用模型的推理來驅動操作。早期的合作夥伴如 Canva、Coursera、Expedia 和 Zillow 展示了用戶如何在不離開 ChatGPT 的情況下,要求播放列表、設計海報或搜尋房地產[1]。新的 Apps SDK 基於模型上下文協議 (MCP),這是一個開放標準,允許模型與外部工具和用戶介面互動[2]。此博客深入探討基於 MCP 的應用程式架構,解釋 SDK 的功能,逐步講解如何構建應用程式,探索用戶如何發現和使用應用程式,並討論隱私和安全考量。在整個過程中,我們引用官方文件和可信賴的新聞報導,以確保分析的可靠性。
理解模型上下文協議 (MCP)
為什麼開放標準很重要
「模型上下文協議」是應用程式 SDK 的基礎。根據開發者文件,每個應用程式 SDK 整合都使用 MCP 伺服器來曝光「工具」、處理驗證並打包在 ChatGPT 中呈現的結構化資料和 HTML[2]。MCP 是一個開放標準——任何人都可以用任何語言實作伺服器並連接例如 GPT-4 或 Codex 的模型。開源性質意味著沒有供應商鎖定;同一個應用程式理論上可以在任何實作此協議的 AI 平台上運行。這種開放性鼓勵了社群貢獻並促進了一個類似早期網路的生態系統,在那裡像 HTTP 這樣的標準使網站可以互操作。
伺服器、工具和資源
一個 MCP 伺服器會曝光一個或多個「工具」。一個工具定義了模型可能調用的動作,例如「創建看板」、「搜尋房子」或「生成播放列表」。每個工具都有一個「機器名稱」、一個人性化的標題和一個「JSON 結構」來告訴模型它接受哪些參數。當 ChatGPT 決定應調用工具時,它會向伺服器發送一個結構化調用。伺服器執行邏輯——無論是查詢 API、執行計算或與資料庫互動——然後返回一個「工具回應」。這個回應包含三個欄位:
- structuredContent – 向模型顯示的數據,描述當前狀態。例如,看板可能包括列和任務的數組[3]。
- content – 可選的文字,助理回應用戶時使用。這可以總結結果或指導用戶。
- _meta – 模型不可見的隱藏元數據。開發人員使用此來存儲用於 UI 元件的 ID 或列表。例如,板例使用 tasksById 映射在 _meta 中維護任務詳細信息,而不將其公開給模型[4]。
工具還可以通過引用 ui:// URL 來參考 資源,例如 HTML 模板或圖像。服務器會在啟動時註冊這些資源。文檔警告,由於資源被 OpenAI 的基礎設施緩存,開發人員應該在文件名中包含構建哈希來對其進行版本控制[5]。否則,部署後用戶可能會看到過時的 UI。
結構化內容與元數據
在 structuredContent 和 _meta 之間的區別是關鍵的。根據文件,structuredContent 對模型是可見的,並用於豐富 UI 元件;_meta 對模型是隱藏的,可能包含額外的 UI 資料,例如下拉選單的列表[3]。透過分離可見和隱藏資料,開發者可以保護敏感資訊免於模型接觸,同時仍然能渲染豐富的介面。這種設計也鼓勵最小化資料共享;只暴露完成任務所需的資料,符合隱私原則。
認證與會話
當使用者首次調用應用程式時,伺服器可能需要進行身份驗證。Apps SDK 支援 OAuth 2.1 流程;開發者指定範圍並將使用者重定向至身份提供者。一旦用戶授權,應用程式獲取一個令牌並可以存取用戶的資料。伺服器的工作是管理會話狀態,通常將令牌儲存在與用戶 ChatGPT 帳號關聯的資料庫中。這確保後續工具調用可以重複使用會話而不需要再次提示用戶。
安全原則
OpenAI 強調「最小特權」、「明確用戶同意」和「深度防禦」[6]。應用程式應僅請求所需的最小權限,用戶必須明確授權數據共享;模型本身絕不應猜測憑證。數據保留受到限制:結構化內容僅在用戶提示處於活動狀態時保留,且日誌在與開發者共享前會被編輯[6]。應用元件的網路存取受到內容安全政策的限制;iframe 無法存取任意的瀏覽器 API,且所有 HTTP 請求必須來自伺服器而非客戶端[7]。這可以防止跨站腳本攻擊和令牌的外洩。
Apps SDK:在 ChatGPT 中構建真實應用程式

開發者體驗
Apps SDK 將 MCP 包裝在慣用的客戶端庫中(目前為 Python 和 TypeScript)以及腳手架工具中。當您創建應用程式時,您需要定義工具、註冊 UI 模板並實現伺服器邏輯。伺服器可以在您自己的基礎設施上運行,並使用任何框架(如 FastAPI、Express 等),但必須實現 MCP 端點。OpenAI 提供開發伺服器和一個 MCP Inspector 用於在本地測試呼叫。
開發人員設計邏輯和使用者介面。UI 通常使用 React 編寫並編譯為靜態資源。它們在 ChatGPT 的沙盒 iframe 中提供。在此 iframe 中,開發人員可以訪問全局的 window.openai 物件來與主機互動。根據 自定義 UX 構建 指南,此 API 提供:
- 全域變數 – displayMode、maxHeight、theme 和 locale 提供有關佈局和樣式的資訊給元件[8]。
- 工具載荷 – toolInput、toolOutput 和 widgetState 允許讀取參數、結果和在渲染過程中持續的狀態[8]。
- 動作 – setWidgetState() 保存跨信息的持續狀態;callTool() 觸發伺服器動作;sendFollowupTurn() 發送後續提示給模型;requestDisplayMode() 要求進入全螢幕或畫中畫模式[8]。
- 事件 – 元件可以訂閱 openai:set_globals 當主機更新佈局或主題時,以及 openai:tool_response 當工具呼叫解決時[8]。
這些 API 讓開發者能夠構建豐富的互動元件,保持與模型推理同步。例如,如果使用者將任務拖到看板中的新列,元件可發送 callTool 來更新伺服器,保存新狀態,然後返回新結構化內容。同時,模型僅看到高層次的看板狀態;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]。這對於多步驟工作流程很有用:例如,一個旅遊預訂應用程式可能在使用者選擇飯店後詢問「您會停留幾晚?」。
Building Your First App: Step‑By‑Step Guide
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.
- Set up the MCP Server
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.
- Define the Tool
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);
- Build the Custom UI
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.
- Testing and Iterating
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.
How Users Discover and Use Apps

Named Mention and In‑Conversation Discovery
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.
對話中發現發生在模型根據上下文推斷某應用程式可能有幫助時。文檔解釋說,模型會評估對話上下文、先前工具結果和用戶的連結應用程式,以確定哪個應用程式可能相關[9]。例如,如果你正在討論旅行計劃,ChatGPT 可能建議使用 Expedia 應用程式來預訂航班。該算法使用工具描述和關鍵詞等元數據來將對話與潛在行動匹配[10]。開發者可以通過撰寫行動導向的描述和清晰的 UI 元件名稱來提高可發現性。
目錄和啟動器
OpenAI 計劃推出一個應用程式目錄,用戶可以在其中瀏覽和發現新應用程式[10]。每個列表將包括應用程式名稱、描述、支持的提示和任何入門說明。用戶還可以通過聊天中的「+」按鈕訪問啟動器;這會根據上下文顯示可用應用程式的菜單。這些入口點將幫助不太熟悉技術的用戶找到並啟用應用程式,而無需記住名稱。
入門和同意
首次啟動應用程式時,ChatGPT 會啟動入門流程。模型會要求使用者連接他們的帳戶(如有需要),並解釋應用程式所需的資料。開發者指南強調應用程式必須尊重使用者的隱私,行為可預測且具備清晰的政策[11]。使用者必須明確授予或拒絕許可;絕無默默存取資料的情形。一旦連接後,應用程式可在後續互動中保持連結,但使用者始終有能力斷開和撤銷許可。
隱私、安全與負責任的設計
值得信賴的應用程式原則
OpenAI 的「應用程式開發者指南」定義了若干原則,以確保生態系統保持安全和可信。應用程式必須提供合法的服務,擁有清晰的隱私政策和數據保存做法,並遵守使用政策[11]。應盡量減少數據收集,避免存儲敏感個人信息,並且在未經同意的情況下不得分享用戶數據[12]。應用程式必須具備可預測的行為;不得操控模型以產生有害或誤導性內容。
數據邊界與最小化
指南強調應用程式應僅收集其功能所需的數據,並且不得請求或儲存敏感數據,如健康記錄或政府身份證明[12]。發送給模型的結構化內容不應包含機密資訊;隱藏的元數據不應儲存用戶代碼或私人資訊。開發人員必須對通過OAuth獲得的任何代碼實施強加密和安全儲存。伺服器應保持用戶會話之間的嚴格界限;一個用戶的數據絕不應洩露到另一個用戶的環境中。
SDK中的安全措施
「安全與隱私指南」概述了平台內建的防禦機制。其強調最小權限和明確的用戶同意為核心原則[6]。數據保留受到限制;開發者可訪問的日誌會被編輯以刪除個人識別信息,結構化內容僅在提示需要時保留[6]。iframe內的網絡訪問受到內容安全政策的限制;外部抓取必須通過服務器進行,防止未授權的跨來源請求[7]。身份驗證採用行業標準的OAuth流程,使用短期有效的令牌。開發者需要實施安全審查、錯誤報告渠道和事件監控以保持運營準備[7]。
公平性與適當性
應用程式必須適合廣泛的受眾。指導方針禁止提供長篇內容、複雜自動化或廣告的應用程式[13]。例如,應用程式不應嘗試提供30分鐘的視頻或在ChatGPT中複製整個社交網絡。該平台鼓勵簡潔的互動,以補充對話流程。違反規定可能會導致拒絕或移除。
機會與考慮
開發者的新分發渠道
通過向第三方應用程式開放ChatGPT,OpenAI將自己定位為用戶與服務之間的“意圖層”。開發者現在可以通過聊天界面接觸到數百萬用戶,而無需構建單獨的網頁或移動應用程式。應用程式有潛力降低摩擦:用戶只需在對話中提到服務,而不是下載應用程式或訪問網站。這可能會使工具的使用更為普及,並為小型開發者創造公平競爭的環境。
早期合作展示了可能性:用戶可以在觀看 Coursera 講座時向 ChatGPT 提問;在 Canva 中設計海報;瀏覽 Expedia 旅行選項或 Zillow 房地產列表;生成 Spotify 播放列表;或使用 Figma 繪製想法圖[14][13]。因為應用程式在聊天內運行,模型可以總結、分析並生成推薦,將靜態內容轉化為互動式課程。這些應用程式還提供多種顯示模式——內嵌卡片、全螢幕或畫中畫——為不同任務提供靈活性[15]。
改變用戶期望
能夠在不切換上下文的情況下使用應用程式,可能會重新塑造人們與服務互動的方式。ChatGPT 不僅僅是一個聊天機器人,而是成為一個意圖的通用操作系統。正如 Casey Newton 所觀察的,這讓我們從啟動獨立應用程式轉變為簡單地陳述我們的需求[16]。一些分析師將這一轉變比作 App Store 或瀏覽器的推出:一個整合功能和競爭的平台。
然而,這種轉變也帶來了關於控制和權力的問題。如果 ChatGPT 決定顯示哪些應用程式,它可能成為一個門檻。Newton 警告說,基於用戶偏好的「AI 圖譜」可能帶來比社交網路更嚴重的隱私風險[16]。經濟激勵可能導致需要付費才能獲得應用程式的展示或排名。開發者可能會感到被迫為 ChatGPT 設計,而不是擁有與用戶的關係。保持平台的透明和公平性對於維持信任至關重要。
法規與道德影響
因為應用程式可以存取個人數據——例如位置、聯絡人、付款方式——因此監管機構可能會審查數據如何通過 ChatGPT 流動。開發者必須遵守隱私法律,例如 GDPR,儘管該平台尚未在歐盟提供[17]。OpenAI 已承諾提供更細緻的隱私控制和貨幣化選項,包括一種代理商務協議,允許在聊天中立即結帳[18]。這個生態系統的成功將取決於強大的安全性、明確的用戶同意和公平的經濟模型。
未來方向與研究
Apps SDK 仍在預覽階段,許多功能仍需完善。開發者的路線圖包括:
- 提交和審查流程 – 目前開發者可以建構應用程式,但無法公開上架。正式的審查流程將確保遵循指導方針並建立信任。
- 收入分成和貨幣化 – OpenAI 暗示了一種代理商務協議,可能允許用戶直接在聊天中購買商品[18]。這為電子商務帶來了機會,但也引發了有關費用、排名和競爭的問題。
- 開發者工具 – 更多的語言和框架、改進的調試工具和更簡單的部署管道將降低進入門檻。MCP 的開放標準性質可能會促進社群驅動的實現和托管提供商。
- 互操作性 – 由於 MCP 是開放的,其他平台或模型可以採用它。這可能促成一個跨模型的應用程式生態系統,開發者可以一次撰寫,隨處運行。對代理協議和上下文共享標準化的研究將是重要的。
- 安全研究 – 評估如何防止提示注入、惡意代碼或用戶數據的濫用仍然是研究的主要領域。關於對抗 LLM 整合應用程式的對抗性攻擊的論文將提供最佳實踐和指導方針。
結論:一個新作業系統的誕生
引入 ChatGPT 中的應用程式 和 基於 MCP 的應用程式 SDK 標誌著我們與軟體互動方式的重大轉變。透過將第三方應用程式直接帶入聊天介面,OpenAI 創造了一個融合自然語言、推理和互動式 UI 的新平台。模型上下文協議 提供了一種開放、標準化的方式讓模型調用工具和呈現元件;應用程式 SDK 通過處理伺服器通信、UI 整合和狀態管理來簡化開發。像 任務追蹤器 這樣的逐步範例展示了如何輕鬆構建有用的應用程式,同時保持嚴格的數據界限和隱私。
然而,這項創新也伴隨著責任。開發者必須遵循以用戶隱私、安全和公平為優先的指導方針[11][12]。像最低權限和明確同意這樣的安全機制保護用戶[6]。同時,業界觀察者警告說,該平台可能會創造新的把關和隱私風險[16]。隨著生態系統的成熟,透明度、開放標準和社區參與將決定ChatGPT的應用平台是否能成為日常任務的一個變革性、值得信賴的層次。
[1] AI 軍備競賽最新消息:ChatGPT 現在讓用戶可以在聊天中連接 Spotify 和 Zillow
https://developers.openai.com/apps-sdk/build/mcp-server
https://developers.openai.com/apps-sdk/guides/security-privacy
[8] 建立自訂用戶體驗
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 開發者日 2025:ChatGPT 獲得應用程式、開發者用 AgentKit,以及更便宜的 GPT 模型
[15] OpenAI 宣布推出 Apps SDK,使 ChatGPT 可以啟動和運行第三方應用程式,如 Zillow、Canva、Spotify | 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 開發日: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/










