For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
主要導覽

建置 MCP 伺服器

為外掛程式加入即時資料和受控工具。

當外掛程式的使用案例需要即時資料、身分驗證、受控動作,或需要在你管理的基礎架構上執行程式碼時,請加入 MCP 伺服器。伺服器會定義 ChatGPT 和 Codex 可用的工具,不一定要回傳自訂 UI。

從你的 使用案例清單中列出的支援目標著手。每個工具都應協助完成 明確的使用者目標,並且只提供達成 該目標所需的資料和動作。

先建置工具。伺服器能在沒有自訂 UI 的情況下運作後,你就可以為 MCP 伺服器 加入 UI,以支援需要 視覺互動的工作流程。

選擇 MCP 軟體開發套件

官方軟體開發套件提供結構描述輔助工具、伺服器骨架,以及可串流的 HTTP 傳輸:

安裝符合伺服器技術堆疊的 SDK:

# TypeScript
npm install @modelcontextprotocol/sdk zod

# Python
pip install mcp

建立伺服器

建立 MCP 伺服器,並設定穩定的名稱和版本:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

const server = new McpServer({
  name: "acme-projects",
  version: "1.0.0",
});

MCP 伺服器也可以在初始化時回傳 instructions 欄位。 ChatGPT 和 Codex 會將這些指示與工具的 中繼資料搭配使用。

使用伺服器指示提供跨工具適用的指引,例如必要的工具呼叫順序或共用的速率限制。請將最重要的細節放在前 512 個字元內。不要重複每個工具的說明,也不要嘗試改變模型的個性。

const server = new McpServer(
  { name: "acme-projects", version: "1.0.0" },
  {
    instructions:
      "Before updating a project, call get_project to confirm its ID and current status.",
  }
);

根據使用者目標定義工具

為外掛程式必須支援的每種不同動作各建立一個工具。優先採用 專注於單一操作的工具,例如 list_projectsget_projectupdate_project,而不是將許多不相關的模式集中在一個工具中。

每個工具都需要:

  • 以動作為導向的名稱,以及易於閱讀的標題。
  • 說明何時應使用該工具的描述。
  • 明確的輸入結構描述。
  • 在工具回傳結構化資料時提供輸出結構描述。
  • 準確的安全性註記。
  • 負責檢查請求授權並執行操作的處理常式。

模型會根據這些中繼資料決定是否呼叫工具,以及如何呼叫。請將名稱、描述、結構描述和註記視為外掛程式對使用者呈現的行為的一部分。

import { z } from "zod";

server.registerTool(
  "list_projects",
  {
    title: "List projects",
    description:
      "Use this when the user wants to find or review projects in their Acme workspace.",
    inputSchema: {
      status: z.enum(["active", "archived"]).optional(),
    },
    outputSchema: {
      projects: z.array(
        z.object({
          id: z.string(),
          name: z.string(),
          status: z.string(),
        })
      ),
    },
    annotations: {
      readOnlyHint: true,
      openWorldHint: false,
      destructiveHint: false,
    },
  },
  async ({ status }) => {
    const projects = await listProjects({ status });

    return {
      structuredContent: { projects },
      content: [
        {
          type: "text",
          text: `Found ${projects.length} projects.`,
        },
      ],
    };
  }
);

在沒有 UI 的情況下回傳實用結果

工具結果可以包含:

  • structuredContent:精簡的資料,供模型檢視並用於後續的 呼叫。
  • content:協助模型回答使用者的文字或其他 MCP 內容。
  • _meta:不向模型公開的用戶端專用資料。

回傳足夠的資訊,讓模型不依賴元件也能完成工作流程。在結構化結果中使用穩定的識別碼,讓後續工具能參照相同的記錄。

不要在工具結果中放入機密資訊、存取權杖或不必要的個人資料。 _meta 只是對模型隱藏資料,不能取代 授權或安全儲存機制。

從 MCP 伺服器匯入技能

如果你想將技能的指示和輔助檔案與伺服器一起進行版本管理及部署, 請設定 MCP 伺服器來提供技能。在提交外掛程式時, 掃描工具 會將這些技能的靜態快照匯入 草稿。

OpenAI 目前僅支援 SEP-2640 技能擴充功能草案中範圍有限的靜態功能子集。 這項提案尚未納入 MCP 穩定版規格。

在伺服器初始化時的能力宣告中 加入 io.modelcontextprotocol/skills

{
  "capabilities": {
    "extensions": {
      "io.modelcontextprotocol/skills": {}
    }
  }
}

這項宣告必須放在 capabilities.extensions 之下。OpenAI 不會 辨識早期的 experimental 宣告。

列出技能及其資源

支援可分頁的 skills/list 方法。每個項目都必須包含:

  • 指向技能 SKILL.mduri
  • frontmatter,其中包含解析 SKILL.md 前置中繼資料後取得的所有項目。 請包含 namedescription 項目。
  • 完整的 resources 清單,包含 SKILL.md 和所有輔助檔案。
  • 每個資源的 SHA-256 摘要,格式為 sha256:<64 lowercase hexadecimal characters>

使用 skill:// URI 慣例。包含 SKILL.md 的目錄名稱必須 與技能名稱相同。例如:

{
  "skills": [
    {
      "uri": "skill://dice-roller/tabletop-dice/SKILL.md",
      "frontmatter": {
        "name": "tabletop-dice",
        "description": "Roll one or more dice and report each result and the total."
      },
      "resources": [
        {
          "uri": "skill://dice-roller/tabletop-dice/SKILL.md",
          "digest": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
        },
        {
          "uri": "skill://dice-roller/tabletop-dice/references/notation.md",
          "digest": "sha256:abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
        }
      ]
    }
  ],
  "nextCursor": "optional-next-page-cursor"
}

範例摘要示範了必要的格式。對於文字資源,請計算 content.text 的 UTF-8 位元組的雜湊值。對於 blob 資源,請先對 content.blob 進行 base64 解碼,再計算解碼後位元組的雜湊值。

也要針對每個列出的 SKILL.md URI 支援 skills/get。回傳的 skill 物件 必須與 skills/list 的完整項目結構相同。

使用下列請求參數:

  • 對於第一次 skills/list 請求,接受空物件({})。
  • 對於後續每次 skills/list 請求,接受先前回傳的游標,例如 { "cursor": "next-page-cursor" }
  • 對於 skills/get,接受目錄中的 URI,例如 { "uri": "skill://dice-roller/tabletop-dice/SKILL.md" }

回傳所有列出的資源

針對資訊清單中的每個 URI 支援 resources/read。每次必須恰好回傳一個 內容項目,且其 URI 必須與請求相符。OpenAI 接受 UTF-8 文字或 以 base64 編碼的 blob。

匯入時,OpenAI 會驗證下列事項:

  • OpenAI 能擷取所有列出的資源,並確認其摘要。
  • 擷取的 SKILL.md 前置中繼資料與目錄項目完全相符。
  • 資源路徑安全、不重複,且沒有正規化衝突。
  • 完整技能符合匯入限制。

匯入工具最多接受分布於 10 頁目錄中的五個技能,且技能名稱不得重複。每個技能最多可包含 100 個檔案,大小限制如下:

內容上限
SKILL.md256 KiB
每個輔助檔案1 MiB
單一技能的所有資源5 MiB
單次掃描產生的技能封存檔8 MiB

封存檔的合計大小限制包含 ZIP 封裝所需的額外空間。

若任何項目未通過驗證或超出限制, 掃描工具 仍會傳回 伺服器的工具,但不會更新草稿中匯入的技能。 請修正伺服器後重新掃描。

從 MCP 匯入的技能是提交當時的快照, 並非執行階段的即時資源。修改技能後,請再次執行 掃描工具 , 審查匯入的技能,然後提交新的外掛程式版本。完整流程請參閱 提交外掛程式

對請求進行身分驗證與授權

當工具讀取私人資料或代表使用者執行動作時,請加入身分驗證。 在 MCP 伺服器中對每個請求強制執行授權檢查; 切勿依賴模型判斷使用者是否具有存取權。

如需瞭解 OAuth 探索、安全性方案 與授權挑戰,請參閱驗證使用者身分

若要改善多帳戶的使用體驗,請提供需要身分驗證的 唯讀帳戶資料工具,並以 _meta["openai/profile"]: true 標記。 OpenAI 會使用帳戶資料,以一致的方式識別已連線的帳戶, 協助使用者區分帳戶。請根據請求中已驗證的憑證 取得帳戶資料,並確保每次工具呼叫都受限於這些憑證的授權範圍。即使沒有帳戶資料工具, 使用者仍可連線至多個帳戶。如需結構描述與實作範例,請參閱 支援多個帳戶

工具註記與引導測試

根據實際行為設定註記:

  • readOnlyHint:僅在工具無法變更狀態時設為 true
  • destructiveHint:當工具可能造成無法復原或難以復原的結果時, 設為 true
  • openWorldHint:當工具會存取公開網際網路或範圍不固定的外部實體時,設為 true, 包括透過網頁搜尋等唯讀動作進行的存取。 若工具僅限於存取範圍明確的私人帳戶或工作區,則可將此值設為 false,即使該服務託管於外部也一樣。

註記可協助 ChatGPT 和 Codex 選擇適當的確認與安全行為。 註記無法取代伺服器中的授權、驗證或確認機制。

當伺服器需要原始工具呼叫未提供的結構化資訊時,請使用 MCP 引導測試。 引導測試應聚焦於使用者在合理情況下能提供的資訊。 請勿用它來收集機密資訊或繞過正常的身分驗證。

公司知識相容性

公司知識可使用 MCP 伺服器的唯讀工具。 若要讓外掛程式符合公司知識來源的資格,請實作 searchfetch 工具的標準輸入結構描述,並為其他唯讀工具加上 readOnlyHint: true 註記。

對於模型應引用的來源,請傳回使用者可開啟的絕對 URL。 將內部文件識別碼保留在結果的 id 欄位中。 如需瞭解必要的結構描述與結果格式,請參閱 建置用於 ChatGPT 與 API 整合的 MCP 伺服器

在本機執行與測試

提供可串流的 HTTP 端點,通常位於 /mcp,然後使用 MCP Inspector 檢查:

npx @modelcontextprotocol/inspector

在 Inspector UI 中,選取 Streamable HTTP ,並輸入 http://localhost:3000/mcp

使用 Inspector 執行下列檢查:

  1. 確認初始化成功。
  2. 審查伺服器指示與宣告的工具清單。
  3. 分別使用具代表性的輸入與無效輸入呼叫每個工具。
  4. 驗證結構描述、結果、錯誤與註記。
  5. 確認存取私人資料與執行寫入動作時,皆會強制執行授權檢查。

接著,在 開發人員模式中將伺服器連接至 ChatGPT, 並執行使用案例清單中的直接、間接、邊界情況與超出範圍的請求。

部署端點

若要提交公開外掛程式,請將 MCP 伺服器部署於穩定且 可公開存取的 HTTPS 端點。安全 MCP 通道 可在開發人員模式中連接私人 MCP 伺服器, 但不符合公開提交的要求。

正式環境端點必須:

  • 支援 MCP 的可串流 HTTP 傳輸。
  • 透過穩定的 URL 回應,通常以 /mcp 結尾。
  • 滿足外掛程式工作流程的延遲與可用性需求。
  • 能夠連線至所需的服務與資料存放區。
  • 維持身分驗證與授權界線。
  • 針對失敗的初始化與工具呼叫產生日誌和指標。

若 MCP 伺服器必須維持私人存取,請部署公開的 HTTPS 代理伺服器, 將 MCP 請求轉送至私人伺服器。使用 由 OpenAI 管理的 mTLS 驗證 ChatGPT 的 MCP 用戶端身分;當外掛程式 需要使用者身分驗證時,請使用 OAuth 2.1。若網路需要 IP 允許清單, 請使用已公布的 ChatGPT 連接器 IP 範圍, 並自動更新允許清單。IP 允許清單無法取代 身分驗證或授權。

公開端點必須保持可存取,以供外掛程式審查與 網域驗證。 公開提交時,請勿僅使用安全 MCP 通道, 也不可使用臨時通道或本機端點。

選擇基礎設施

您可以將 MCP 伺服器部署至無伺服器、容器、邊緣或傳統應用程式基礎設施。 請根據下列條件選擇平台:

  • 對執行環境與相依套件的支援。
  • 串流回應行為。
  • 冷啟動與請求延遲。
  • 對所需服務的網路存取能力。
  • 資料駐留與合規要求。
  • 機密資訊管理。
  • 日誌記錄、追蹤與警示。
  • 對回復與版本管理的支援。

若伺服器也託管選用的 UI 資源, 請將這些資源部署於元件的 內容安全政策所允許的穩定來源。

設定正式環境端點

部署前:

  1. 透過主機的機密資訊管理系統設定正式環境憑證。
  2. 設定授權伺服器與允許的重新導向行為。
  3. 為成本高昂或對外可見的工具設定逾時與速率限制。
  4. 移除偵錯回應與不必要的個人資料。
  5. 確認日誌不含存取權杖或敏感的工具結果。

部署後,使用 MCP Inspector 呼叫正式環境端點。 驗證初始化、伺服器指示、工具、結構描述、註記、 身分驗證、結果與錯誤。

規劃更新

讓已發布的工具名稱與結構描述保持回溯相容。新增欄位或工具時,不要破壞既有契約。 若中繼資料有所變更,請重新整理開發人員模式的連線, 並在提交前重新執行評估集。

對於選用的 UI,當 HTML、JavaScript 或 CSS 的變更可能導致快取元件無法正常運作時, 請在資源識別碼中加入版本資訊。

新增選用的 UI

確認工具可完整執行端到端流程後,再判斷是否有使用案例需要視覺互動。 表格、地圖、可編輯的行程表或比較檢視可能適合搭配 UI。 查詢、狀態檢查或背景動作通常不需要 UI。

接著請參閱為 MCP 伺服器新增 UI,以 註冊 MCP Apps 資源,並將其與選定的工具建立關聯。

安全性提醒

  • 將所有工具輸入視為不受信任的資料。
  • 在伺服器端驗證參數,並強制執行授權檢查。
  • 對會產生重大影響的寫入動作要求確認。
  • 不要在工具的中繼資料或結果中包含機密資訊或敏感資料。
  • 在日誌中記錄足以調查失敗原因的上下文,但不要記錄憑證或 不必要的個人資料。
  • 對耗用大量資源或外部可見的動作實施速率限制。