全部技能

mcp-builder (anthropics/skills)

指導用 Python 或 TypeScript 建構 MCP 伺服器,將外部服務包裝成設計良好的工具。

mcp-builder:透過補上命名、標註與非同步,把 MCP 伺服器從 3.6 提升到 4.6/5,但一句話檢查清單只花 68% 的 Token 就拿到 4.9

視情況推薦安全

Codex CLI · gpt-6-astra

21.6 / 30

相對未使用技能的提升:+1.04 · 視情況推薦 · 18 次執行

視情況推薦:總分 21.6/30 低於 22。推薦條件為總分至少 22/30、產出品質至少 3.5、提升幅度至少 +1.0。

SOTA

透過

使用 Codex 測試。

涵蓋 Codex, Claude Code

Codex CLI 0.166(SOTA 等級):18 次評分執行。依我們的等級規則,在這裡通過也涵蓋 Claude Code;但這不代表第二等級的結果。

分數

每個維度為 0 到 5 分,六個維度相加即為滿分 30 的總分。每個維度都是 5 分最好。成本 5 分代表便宜又快速;安裝 5 分代表容易安裝。

觸發可靠性
5.0
相對未使用技能的提升
3.0
產出品質
4.6
Token 與時間成本
3.0
安裝與可攜性
3.0
安全性
3.0

安全審查

安全

靜態掃描:8 CRITICAL / 13 HIGH / 7 MEDIUM。人工審查:可在無網路沙箱中安全執行(已說明掃描器的發現;內附腳本從未執行)。掃描結果不能證明技能一定安全。

安裝

npx skills@latest add anthropics/skills --skill mcp-builder

來源

固定 Commit: ca45fc496a3436251f191354091d557da31c15b5

測試日期: 2026-11-02

我們測了什麼

  • 書店 API 的 Python MCP 伺服器 — 撰寫 server.py:一個給書店庫存 REST API 用的 Python MCP 伺服器(base URL 來自環境變數,bearer token 來自環境變數)。工具:搜尋書籍、取得單一本書、更新某本書的庫存、刪除一本書。使用官方 mcp Python SDK(FastMC…
  • 天氣 API 的 TypeScript MCP 伺服器 — 撰寫 src/index.ts 與 package.json:一個給天氣 REST API 用的 TypeScript MCP 伺服器(base URL 與 API key 來自環境變數)。工具:取得某城市目前天氣、取得 5 天天氣預報、列出已儲存的地點、刪除已儲存的地點。使用官方 MC…
  • 修復一個倉促寫成的 MCP 伺服器 — server.py 是我們倉庫 API 的 MCP 伺服器,能用但當初寫得很倉促。請修正它,讓它遵循良好的 MCP 伺服器實務。就地編輯 server.py,並讓它繼續與同一個 API 溝通。這裡沒有網路,也不能安裝套件;只要寫…

優點

  • 相對未使用技能,平均分數從 3.57 提升到 4.61(+1.04)。
  • 技能即使未被點名也會被採用:6/6 次實驗組執行都讀取了技能檔案。
  • 使用技能後的絕對品質很高:4.61 / 5。

缺點

  • 一句話提示得分 4.88,使用技能則為 4.61(-0.27)。
  • Token 用量是未使用技能的 1.51 倍。
  • 每個任務的每個組別 n=2;約 1 分以內的差異屬於雜訊。

評測

在專用的 Windows 測試電腦上使用 Codex CLI 0.166(gpt-6-astra,低推理),每次執行都建立全新的暫存專案與暫存的 HOME/TMPDIR/快取,分別安裝技能(實驗組)、未安裝技能(對照組),或未安裝技能但把技能的核心要求濃縮成一句話附在提示詞後(一句話提示組);每個任務的每個組別執行 2 次,關閉網路,封鎖 /tmp 寫入。提示詞從未提到技能(下方註明的措辭除外)。三個任務:為書店 REST API 撰寫 Python MCP 伺服器、為天氣 API 撰寫 TypeScript MCP 伺服器,以及把一個現成、草率寫成的 server.py 修正到符合良好實務。整個過程不需要網路(代理無法安裝 MCP SDK,只會寫程式碼)。實驗組的提示詞與對照組相同。

三組對照

組別平均分數(0-5)每次執行 Token 用量
未使用技能3.5773k
一句話提示4.8875k
使用技能4.61110k

以 Codex CLI 執行 18 次,採規則式檢查評分,不經 LLM 評審。總分 21.6 / 30,評級為 視情況推薦。

判定:視情況而定(21.6 / 30)。 來源:anthropics/skills,skills/mcp-builder,固定於提交 ca45fc4。安裝:npx skills@latest add anthropics/skills --skill mcp-builder。授權條款: 專有:anthropics/skills LICENSE.txt(原始碼可見;僅限評估,不得轉散布)。

這是什麼

anthropics/skills 的 mcp-builder 技能:建構 Model Context Protocol 伺服器的指南(研究與規劃、實作、審查與測試、撰寫評測)。它附有 Python(FastMCP)與 TypeScript 的語言指南、MCP 最佳實務筆記,以及兩個用來對伺服器執行評測的輔助腳本。專有授權(原始碼可見)。

我們如何測試

在專用 Windows 測試 PC 上使用 Codex CLI 0.166(gpt-6-astra,低推理),每次執行都使用全新的暫存專案與暫存 HOME/TMPDIR/快取,安裝技能(實驗組)、未安裝(對照組),或未安裝但將技能核心要求濃縮成一句話附加在提示詞後(一句話提示組),每個任務每組執行 2 次,網路關閉,/tmp 寫入封鎖。提示詞從未提及技能(以下註明的措辭除外)。

三項任務:為書店 REST API 寫一個 Python MCP 伺服器、為天氣 API 寫一個 TypeScript MCP 伺服器,以及修正既有的草率 server.py 使其遵循良好實務。全程不需要網路(agent 無法安裝 MCP SDK;它只寫程式碼)。技能組的提示詞與對照組相同。

  1. 書店 API 的 Python MCP 伺服器 — 寫 server.py:一個用 Python 為書店庫存 REST API 打造的 MCP 伺服器(base URL 來自環境,bearer token 來自環境)。工具:搜尋書籍、取得一本書、更新某本書的庫存、刪除一本書。使用官方 mcp Python SDK(FastMC…
  2. 天氣 API 的 TypeScript MCP 伺服器 — 寫 src/index.ts 與 package.json:一個用 TypeScript 為天氣 REST API 打造的 MCP 伺服器(base URL 與 API key 來自環境)。工具:取得某城市的目前天氣、取得 5 天預報、列出已儲存的地點、刪除已儲存的地點。使用官方 MC…
  3. 修復倉促寫成的 MCP 伺服器 — server.py 是我們倉庫 API 的 MCP 伺服器,能運作但寫得很倉促。修正它,使其遵循良好的 MCP 伺服器實務。就地編輯 server.py,並讓它繼續連接同一個 API。這裡沒有網路,也不能安裝套件;只要寫…

評分方式為程式化檢查(隱藏測試/預埋問題召回/限制條件檢查/視情況進行渲染與 OCR),每次執行 0–5 分。沒有任何 LLM 評審決定分數。

結果

提供給第三組的一句話提示:「像專家一樣設計 MCP 伺服器:一致、以服務為前綴且以動作命名的工具名稱(例如 bookstore_search_books)、具型別的輸入結構(Pydantic 或 Zod)並附欄位說明、註解(readOnlyHint、destructiveHint、idempotentHint)、分頁與大小限制的結果、可據以行動的錯誤訊息、金鑰只從環境變數取得、非同步 I/O,且使用 stdio 傳輸時不得輸出任何東西到 stdout。」

任務對照組分數一句話提示使用技能對照組 Token 數一句話提示 Token 數使用技能 Token 數技能讀取
t1-python1.434.644.260k64k97k2/2
t2-typescript4.295.04.6460k55k100k2/2
t3-fix5.05.05.097k106k133k2/2

平均分數:未使用技能 3.57,使用技能 4.61(差異 +1.04)。每次執行 Token 數:73k 對 110k(1.51 倍);時間 80 秒對 89 秒。一句話提示組:4.88(技能相較一句話提示的增益:-0.27;一句話提示相較無技能的增益:+1.31);一句話提示每次執行 75k Token,因此技能的成本是一句話提示的 1.47 倍。

實際發生了什麼

  • 在關鍵之處,技能確實有幫助:兩個從零開始的伺服器中,對照組漏掉基本功(工具名稱有共用服務前綴:2/4 次;工具註解如 readOnlyHint:2/2 次 Python 執行;非同步工具:2/2 次 Python 執行;可據以行動的錯誤訊息:2/2 次 Python 執行)。平均分數:對照組 3.57、技能 4.61。
  • 一句話提示組表現比技能好:4.88,18 次執行只漏一項檢查,而技能組漏了 5 項。那句話列出檢查所看的相同性質,因此是短提示的上限,但每次執行只花 75k Token,技能 110k、對照組 73k。
  • 技能組有一個真實缺陷:兩次 TypeScript 實驗組執行都為新的 @modelcontextprotocol/server 套件產生了 createServer(),卻從未啟動傳輸(沒有 stdio 或 Streamable HTTP),因此伺服器檔案照原樣無法啟動;對照組與一句話提示組的執行都有包含傳輸。
  • 在修復任務中,三組得分相同(六次執行全部 9/9 檢查通過):給定既有的伺服器,原生 Codex 就已經套用了這些做法。
  • 技能載入很重:SKILL.md 加上參考指南;實驗組執行在專案的 .agents 資料夾留下約 12 個技能檔案並讀了指南,1.5 倍 Token 就花在這裡。它的輔助腳本(評測框架)沒有在離線沙箱中執行。

各面向分數

面向分數原因
1_輸出品質4.61

使用技能時平均分數 4.61/5(程式化檢查,見各任務 表格)。

2_相較無技能的提升3.04

相較未使用技能的 3.57,+1.04 分(每項任務 n=2;約 1 分以下 屬於雜訊)。

3_觸發5.0技能檔案在 6/6 次實驗組執行中被讀取。
4_指令可攜性3

龐大的參考資料集,分散在語言指南中;輔助腳本需要 Python 套件與執行中的伺服器。

5_效率31.51 倍 Token(每次執行 110k 對 73k)與 1.11 倍時間(89 秒對 80 秒)。
6_安全性與衛生3

掃描器標記 8 CRITICAL / 13 HIGH,全部經脈絡確認:範例伺服器 程式碼與輔助腳本中的環境變數傳遞;專有授權。

這項測試的限制

  • 對程式碼文字做規則式檢查;沒有任何產生的伺服器真的被啟動或連上用戶端。
  • 沒有網路:agent 無法安裝或匯入 MCP SDK,因此 API 細節(例如新的 v2 TypeScript 套件)未經驗證。
  • 技能的評測步驟(產生問題並對伺服器執行)未被實際演練。
  • 每項任務每組 n = 2:約 1 分以下的差異屬於雜訊。
  • 規則式評分只能衡量檢查看得到的部分;無法評判品味,也無法判斷結果是否為最佳可能。

安全性

見 security.md。掃描:CRITICAL 8 / HIGH 13 / MEDIUM 7。判定:可安全執行(網路關閉的沙箱)。乾淨的掃描結果不能證明技能安全。

總結

對於從零開始的伺服器,技能在命名、註解、非同步與錯誤處理上明顯勝過沒有指引的 agent,代價是 1.5 倍 Token。一句簡短的檢查清單就能以更少 Token 得到相同性質,且沒有缺少傳輸的缺陷,因此安裝它是為了參考指南與一致性,而不是為了超越好提示詞的品質躍進。

完整紀錄

執行日誌:mcp-builder (Codex CLI, network off, per-run temp HOME/TMPDIR, one row per graded run.)
欄位:任務、組-輪次、得分(0-5)、token、秒、通過的檢查、代理開啟的 skill 檔案。

t1-python control-1: 得分 1.79, token 51610, 秒 53.2, 檢查 4/9, 未開啟
t1-python control-2: 得分 1.07, token 69259, 秒 98.6, 檢查 3/9, 未開啟
t1-python oneliner-1: 得分 5.0, token 74072, 秒 101.3, 檢查 9/9, 未開啟
t1-python oneliner-2: 得分 4.29, token 54692, 秒 126.2, 檢查 8/9, 未開啟
t1-python treatment-1: 得分 3.39, token 101809, 秒 72.0, 檢查 6/9, 開啟 mcp-builder
t1-python treatment-2: 得分 5.0, token 93275, 秒 66.9, 檢查 9/9, 開啟 mcp-builder
t2-typescript control-1: 得分 4.29, token 52126, 秒 59.1, 檢查 8/9, 未開啟
t2-typescript control-2: 得分 4.29, token 69042, 秒 61.5, 檢查 8/9, 未開啟
t2-typescript oneliner-1: 得分 5.0, token 55412, 秒 104.3, 檢查 9/9, 未開啟

18 次執行、3 個產出檔案

範例產出

SOTA · 装了 skill:server.py(t1-python,第 1 次,Codex)

"""Bookstore MCP server (Python 3.10+, official mcp SDK, httpx, Pydantic 2). Required environment variables: BOOKSTORE_BASE_URL: API root, e.g. https://inventory.example.com/api/v1 BOOKSTORE_API_TOKEN: bearer token (without the 'Bearer ' prefix) Assumed REST contract (adjust paths/fields here to match your API): GET /books?q=...&limit=...&offset=... -> JSON search results GET /books/{book_id} -> JSON book PATCH /books/{book_id}/stock body: {"stock": nonnegative integer} DELETE /books/{book_id} Updates and deletes may return JSON or an empty success response. Search pagination and response shape are supplied by the upstream API. Run with `python server.py` in an environment with the dependencies installed. Transport is stdio; stdout is reserved for MCP protocol messages. """ import os from contextlib import asynccontextmanager from dataclasses import dataclass from typing import Annotated, Any, AsyncIterator from urllib.parse import quote, urlsplit import httpx from mcp.server.fastmcp import Context, FastMCP from mcp.server.fastmcp.exceptions import ToolError from pydantic import Field @dataclass class AppState: client: httpx.AsyncClient @asynccontextmanager async def lifespan(server: FastMCP) -> AsyncIterator[AppState]: base_url = os.environ.get("BOOKSTORE_BASE_URL", "").strip() token = os.environ.get("BOOKSTORE_API_TOKEN", "").strip() if not base_url or not token: raise RuntimeError("Set BOOKSTORE_BASE_URL and BOOKSTORE_API_TOKEN.") try: parsed = urlsplit(base_url) valid = ( parsed.scheme in {"http", "https"} and bool(parsed.hostname) and parsed.username is None and parsed.password is None and not parsed.query and not parsed.fragment ) parsed.port # Validate a supplied port without exposing the URL. except ValueError: valid = False if not valid: raise RuntimeError("BOOKSTORE_BASE_URL must be an HTTP(S) API root without credentials, query, or fragment.") if any(ord(char) < 33 or ord(char) > 126 for char in token): raise RuntimeError("BOOKSTORE_API_TOKEN must contain printable ASCII without whitespace.") async with httpx.AsyncClient( base_url=base_url.rstrip("/") + "/", headers={"Authorization": f"Bearer {token}", "Accept": "application/json"}, timeout=httpx.Timeout(30.0, connect=10.0), follow_redirects=False, trust_env=False, ) as client: yield AppState(client=client) mcp = FastMCP("bookstore_mcp", lifespan=lifespan) BookId = Annotated[str, Field(min_length=1, max_length=256, description="Book identifier, e.g. 'book-123'.")] def book_path(book_id: str) -> str: if not book_id.strip() or book_id in {".", ".."}: raise ToolError("Provide a nonblank book identifier other than '.' or '..'.") return "books/" + quote(book_id, safe="") async def api_request( ctx: Context, method: str, path: str, *, params: dict[str, Any] | None = None, payload: dict[str, Any] | None = None, ) -> dict[str, Any]: state: AppState = ctx.r [... excerpt: first 3200 of 7129 characters]

檢視 Pro