MCP 伺服器參考

本頁內容

EmDash 內建一個 Model Context Protocol(MCP)伺服器,位於 /_emdash/api/mcp,將內容管理操作以工具形式公開給 AI 助手使用。

本頁涵蓋通訊協定詳情:驗證、傳輸、工具規格、OAuth 探索與錯誤處理。

驗證

MCP 伺服器支援三種驗證方式:

方式運作方式
OAuth 2.1 授權碼 + PKCEMCP 用戶端的標準流程。使用者在瀏覽器中核准 scope。
個人存取權杖(PAT)在管理後台建立的長期 ec_pat_* 權杖。
裝置流程CLI 風格流程,在瀏覽器中核准驗證碼。由 emdash login 使用。

工作階段 cookie(來自管理 UI)也可使用,但對外部 MCP 用戶端不太實用。

Scope

權杖使用 scope 來限制用戶端可執行的操作。Scope 在 OAuth 授權期間請求,並在每次工具呼叫時強制執行。

Scope授予存取權限
content:read列出、取得、比較與搜尋內容。列出分類法詞彙與選單。
content:write建立、更新、刪除、發布、取消發布、排程、複製與還原內容。建立分類法詞彙。
media:read列出與取得媒體項目。
media:write更新與刪除媒體中繼資料。
schema:read列出集合與取得集合 schema。
schema:write建立與刪除集合與欄位。
admin所有操作的完整存取權。

admin scope 授予所有操作的存取權。基於工作階段的驗證(無權杖)也擁有基於使用者角色的完整存取權。

角色要求

除了 scope 之外,部分工具需要最低 RBAC 角色:

操作最低角色
內容操作無最低要求(由 scope 控制存取)
Schema 讀取編輯(40)
Schema 寫入管理員(50)

角色定義見驗證指南

傳輸

伺服器使用無狀態模式的 Streamable HTTP 傳輸。每個請求都是獨立的——沒有工作階段或長連線。

  • POST /_emdash/api/mcp — 傳送 JSON-RPC 工具呼叫
  • GET /_emdash/api/mcp — 回傳 405(無狀態模式下無 SSE)
  • DELETE /_emdash/api/mcp — 回傳 405(無工作階段可關閉)

回應遵循 JSON-RPC 2.0 格式。錯誤使用標準 JSON-RPC 錯誤碼,並以 MCP 特定碼表示 scope 與權限失敗。

工具

伺服器公開 33 個工具,涵蓋七個領域。每個工具以 JSON 文字內容回傳結果,失敗時則回傳帶有 isError: true 的錯誤訊息。

內容工具

content_list

列出集合中的內容項目,支援選用的篩選與分頁。

參數類型必填說明
collectionstring集合 slug(例如 postspages
statusstring篩選:draftpublishedscheduled
limitinteger回傳的最大項目數(1-100,預設 50)
cursorstring前一個回應的分頁游標
orderBystring排序欄位(例如 created_atupdated_at
orderstring排序方向:ascdesc(預設 desc
localestring按語系篩選(例如 enfr)。僅在啟用 i18n 時相關。

Scope: content:read | 唯讀:

content_get

透過 ID 或 slug 取得單一內容項目。回傳所有欄位值、中繼資料和用於樂觀並行控制的 _rev 權杖。

參數類型必填說明
collectionstring集合 slug
idstring內容項目 ID(ULID)或 slug
localestring用於 slug 查詢的語系。ID 全域唯一。

Scope: content:read | 唯讀:

content_create

建立新的內容項目。data 物件應包含符合集合 schema 的欄位值——使用 schema_get_collection 檢查可用欄位。項目預設以 draft 狀態建立。

參數類型必填說明
collectionstring集合 slug
dataobject欄位值的鍵值對
slugstringURL slug(省略時從標題自動產生)
statusstring初始狀態:draftpublished(預設 draft
localestring此內容的語系(預設為網站預設值)
translationOfstring此項目為其翻譯的項目 ID

Scope: content:write

content_update

更新現有內容項目。僅包含你要變更的欄位——未指定的欄位保持不變。

參數類型必填說明
collectionstring集合 slug
idstring內容項目 ID 或 slug
dataobject要更新的欄位值
slugstring新的 URL slug
statusstring新狀態:draftpublished
_revstring來自 content_get 的修訂權杖,用於衝突偵測

Scope: content:write

content_delete

透過移至回收桶來軟刪除內容項目。使用 content_restore 復原,或使用 content_permanent_delete 永久移除。

參數類型必填說明
collectionstring集合 slug
idstring內容項目 ID 或 slug

Scope: content:write | 破壞性:

content_restore

從回收桶還原軟刪除的內容項目。

參數類型必填說明
collectionstring集合 slug
idstring內容項目 ID 或 slug

Scope: content:write

content_permanent_delete

永久且不可逆地刪除已移至回收桶的內容項目。項目必須先在回收桶中。

參數類型必填說明
collectionstring集合 slug
idstring內容項目 ID 或 slug

Scope: content:write | 破壞性:

content_publish

發布內容項目,使其在網站上線。從目前草稿建立已發布的修訂版。後續編輯會建立新草稿,不影響線上版本,直到重新發布為止。

參數類型必填說明
collectionstring集合 slug
idstring內容項目 ID 或 slug

Scope: content:write

content_unpublish

將已發布的項目恢復為草稿狀態。它將不再在線上網站中顯示,但內容會保留。

參數類型必填說明
collectionstring集合 slug
idstring內容項目 ID 或 slug

Scope: content:write

content_schedule

排程內容項目在未來發布。它將在指定的日期/時間自動發布。

參數類型必填說明
collectionstring集合 slug
idstring內容項目 ID 或 slug
scheduledAtstringISO 8601 日期時間(例如 2026-06-01T09:00:00Z

Scope: content:write

content_compare

比較內容項目的已發布(線上)版本與目前草稿。回傳兩個版本以及指示是否有變更的旗標。

參數類型必填說明
collectionstring集合 slug
idstring內容項目 ID 或 slug

Scope: content:read | 唯讀:

content_discard_draft

捨棄目前草稿並恢復到最後發布的版本。僅適用於至少發布過一次的項目。

參數類型必填說明
collectionstring集合 slug
idstring內容項目 ID 或 slug

Scope: content:write | 破壞性:

content_list_trashed

列出集合回收桶中已軟刪除的內容項目。

參數類型必填說明
collectionstring集合 slug
limitinteger最大項目數(1-100,預設 50)
cursorstring分頁游標

Scope: content:read | 唯讀:

content_duplicate

建立現有內容項目的副本。副本以草稿建立,標題附加「(Copy)」,slug 自動產生。

參數類型必填說明
collectionstring集合 slug
idstring要複製的內容項目 ID 或 slug

Scope: content:write

content_translations

取得內容項目的所有語系變體。回傳翻譯群組和每個語系版本的摘要。僅在啟用 i18n 時相關。

參數類型必填說明
collectionstring集合 slug
idstring內容項目 ID 或 slug

Scope: content:read | 唯讀:

Schema 工具

schema_list_collections

列出 CMS 中定義的所有內容集合。回傳 slug、標籤、支援的功能和時間戳記。

無參數。

Scope: schema:read | 最低角色: 編輯 | 唯讀:

schema_get_collection

取得集合的詳細資訊,包括所有欄位定義。欄位描述資料模型:名稱、類型、約束和驗證規則。使用此工具了解 content_createcontent_update 預期的內容。

參數類型必填說明
slugstring集合 slug(例如 posts

Scope: schema:read | 最低角色: 編輯 | 唯讀:

schema_create_collection

建立新的內容集合。這會建立資料庫表和 schema 定義。slug 必須是以字母開頭的小寫英數字加底線。

參數類型必填說明
slugstring唯一識別碼(/^[a-z][a-z0-9_]*$/
labelstring顯示名稱(複數,例如「Blog Posts」)
labelSingularstring單數顯示名稱
descriptionstring此集合的說明
iconstring管理 UI 的圖示名稱
supportsstring[]功能:draftsrevisionspreviewschedulingsearch(預設:['drafts', 'revisions']

Scope: schema:write | 最低角色: 管理員

schema_delete_collection

刪除集合及其資料庫表。此操作不可逆,會刪除集合中的所有內容。

參數類型必填說明
slugstring要刪除的集合 slug
forceboolean即使集合有內容也強制刪除

Scope: schema:write | 最低角色: 管理員 | 破壞性:

schema_create_field

在集合的 schema 中新增欄位。這會在資料庫表中新增一個欄。

參數類型必填說明
collectionstring集合 slug
slugstring欄位識別碼(/^[a-z][a-z0-9_]*$/
labelstring顯示名稱
typestring資料類型(見下方)
requiredboolean欄位是否為必填
uniqueboolean值是否必須唯一
defaultValueany新項目的預設值
validationobject約束:minmaxminLengthmaxLengthpatternoptions
optionsobject小工具設定:collection(用於參照)、rows(用於文字區域)
searchableboolean包含在全文搜尋索引中
translatableboolean此欄位是否可翻譯(預設 true)

欄位類型:stringtextnumberintegerbooleandatetimeselectmultiSelectportableTextimagefilereferencejsonslug

對於 selectmultiSelect 類型,在 validation.options 中提供允許的值。

Scope: schema:write | 最低角色: 管理員

schema_delete_field

從集合中移除欄位。這會刪除該欄位中的欄和所有資料。不可逆。

參數類型必填說明
collectionstring集合 slug
fieldSlugstring要移除的欄位 slug

Scope: schema:write | 最低角色: 管理員 | 破壞性:

媒體工具

media_list

列出已上傳的媒體檔案,支援選用的 MIME 類型篩選與分頁。

參數類型必填說明
mimeTypestring按 MIME 類型前綴篩選(例如 image/application/pdf
limitinteger最大項目數(1-100,預設 50)
cursorstring分頁游標

Scope: media:read | 唯讀:

media_get

透過 ID 取得單一媒體檔案的詳情。回傳包括檔名、MIME 類型、大小、尺寸、替代文字和 URL 的中繼資料。

參數類型必填說明
idstring媒體項目 ID

Scope: media:read | 唯讀:

media_update

更新已上傳媒體檔案的中繼資料。檔案本身無法變更。

參數類型必填說明
idstring媒體項目 ID
altstring無障礙替代文字
captionstring說明文字
widthinteger圖片寬度(像素)
heightinteger圖片高度(像素)

Scope: media:write

media_delete

永久刪除媒體檔案。移除資料庫記錄和儲存中的檔案。參照此媒體的內容會出現斷裂參照。

參數類型必填說明
idstring媒體項目 ID

Scope: media:write | 破壞性:

搜尋工具

跨內容集合的全文搜尋。集合必須在 supports 列表中包含 search,且欄位必須標記為 searchable

參數類型必填說明
querystring搜尋查詢文字
collectionsstring[]限制搜尋的特定集合 slug
localestring按語系篩選結果
limitinteger最大結果數(1-50,預設 20)

Scope: content:read | 唯讀:

分類法工具

taxonomy_list

列出所有分類法定義(例如分類、標籤)。回傳名稱、標籤、是否階層式,以及關聯的集合。

無參數。

Scope: content:read | 唯讀:

taxonomy_list_terms

列出分類法中的詞彙,支援分頁。

參數類型必填說明
taxonomystring分類法名稱(例如 categoriestags
limitinteger最大項目數(1-100,預設 50)
cursorstring分頁游標

Scope: content:read | 唯讀:

taxonomy_create_term

在分類法中建立新詞彙。對於階層式分類法,指定 parentId 以建立子詞彙。

參數類型必填說明
taxonomystring分類法名稱
slugstringURL 安全識別碼
labelstring顯示名稱
parentIdstring父詞彙 ID(用於階層式分類法)
descriptionstring詞彙說明

Scope: content:write

選單工具

列出所有導覽選單。回傳名稱、標籤和時間戳記。

無參數。

Scope: content:read | 唯讀:

透過名稱取得選單,包含所有項目的順序。項目具有標籤、URL、類型和選用的父項以進行巢狀。

參數類型必填說明
namestring選單名稱(例如 mainfooter

Scope: content:read | 唯讀:

修訂工具

revision_list

列出內容項目的修訂歷史記錄,最新在前。集合必須支援 revisions

參數類型必填說明
collectionstring集合 slug
idstring內容項目 ID 或 slug
limitinteger最大修訂數(1-50,預設 20)

Scope: content:read | 唯讀:

revision_restore

將內容項目還原到先前的修訂版。用指定修訂版的資料取代目前草稿。不會自動發布——如需要請在之後使用 content_publish

參數類型必填說明
revisionIdstring要還原的修訂 ID

Scope: content:write

OAuth 探索

支援 OAuth 2.1 的 MCP 用戶端可以自動探索驗證方式。伺服器發布兩份中繼資料文件:

受保護資源中繼資料

GET /.well-known/oauth-protected-resource
{
  "resource": "https://example.com/_emdash/api/mcp",
  "authorization_servers": ["https://example.com/_emdash"],
  "scopes_supported": [
    "content:read", "content:write",
    "media:read", "media:write",
    "schema:read", "schema:write",
    "admin"
  ],
  "bearer_methods_supported": ["header"]
}

授權伺服器中繼資料

GET /_emdash/.well-known/oauth-authorization-server
{
  "issuer": "https://example.com/_emdash",
  "authorization_endpoint": "https://example.com/_emdash/oauth/authorize",
  "token_endpoint": "https://example.com/_emdash/api/oauth/token",
  "scopes_supported": ["content:read", "content:write", "..."],
  "response_types_supported": ["code"],
  "grant_types_supported": [
    "authorization_code",
    "refresh_token",
    "urn:ietf:params:oauth:grant-type:device_code"
  ],
  "code_challenge_methods_supported": ["S256"],
  "token_endpoint_auth_methods_supported": ["none"],
  "device_authorization_endpoint": "https://example.com/_emdash/api/oauth/device/code"
}

當未驗證的請求到達 MCP 端點時,伺服器回傳:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://example.com/.well-known/oauth-protected-resource"

這會觸發標準的 MCP 用戶端探索流程。

錯誤處理

工具錯誤以帶有 isError: true 的文字內容回傳:

{
  "content": [{ "type": "text", "text": "Collection 'nonexistent' not found" }],
  "isError": true
}

Scope 與權限錯誤會拋出 MCP 通訊協定錯誤:

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32600,
    "message": "Insufficient scope: requires content:write"
  },
  "id": 1
}

傳輸層錯誤(伺服器設定錯誤、未處理的例外)回傳 JSON-RPC 錯誤碼 -32603(內部錯誤),不會洩漏實作細節。