EmDash には /_emdash/api/mcp に組み込みの Model Context Protocol (MCP) サーバーが含まれており、コンテンツ管理操作を AI アシスタント向けのツールとして公開します。
このページではプロトコルの詳細をカバーします: 認証、トランスポート、ツール仕様、OAuth ディスカバリー、エラー処理。
認証
MCP サーバーは 3 つの認証方法をサポートします:
| 方法 | 仕組み |
|---|---|
| OAuth 2.1 Authorization Code + PKCE | MCP クライアント向けの標準フロー。ユーザーがブラウザでスコープを承認。 |
| パーソナルアクセストークン (PAT) | 管理パネルで作成した長期有効な ec_pat_* トークン。 |
| デバイスフロー | ブラウザでコードを承認する CLI スタイルのフロー。emdash login で使用。 |
セッション Cookie(管理 UI から)も動作しますが、外部 MCP クライアントには実用的ではありません。
スコープ
トークンにはスコープが設定され、クライアントが実行できる操作を制限します。スコープは OAuth 認可時にリクエストされ、すべてのツール呼び出しで強制されます。
| スコープ | アクセス権限 |
|---|---|
content:read | コンテンツの一覧、取得、比較、検索。タクソノミータームとメニューの一覧。 |
content:write | コンテンツの作成、更新、削除、公開、非公開、スケジュール、複製、復元。タクソノミータームの作成。 |
media:read | メディアアイテムの一覧と取得。 |
media:write | メディアメタデータの更新と削除。 |
schema:read | コレクションの一覧とコレクションスキーマの取得。 |
schema:write | コレクションとフィールドの作成と削除。 |
admin | すべての操作へのフルアクセス。 |
admin スコープはすべてにアクセスできます。セッションベース認証(トークンなし)もユーザーのロールに基づいたフルアクセスを持ちます。
ロール要件
スコープに加え、一部のツールには最小 RBAC ロールが必要です:
| 操作 | 最小ロール |
|---|---|
| コンテンツ操作 | 最小なし(スコープがアクセスを制御) |
| スキーマ読み取り | エディター (40) |
| スキーマ書き込み | 管理者 (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 固有のコードが使われます。
ツール
サーバーは 7 つのドメインにわたる 33 のツールを公開します。各ツールは JSON テキストコンテンツとして結果を返すか、失敗時に isError: true のエラーメッセージを返します。
コンテンツツール
content_list
コレクション内のコンテンツアイテムを任意のフィルタリングとページネーションで一覧表示します。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ(例: posts, pages) |
status | string | No | フィルタ: draft, published, scheduled |
limit | integer | No | 最大返却数(1-100、デフォルト 50) |
cursor | string | No | 前回レスポンスからのページネーションカーソル |
orderBy | string | No | ソートフィールド(例: created_at, updated_at) |
order | string | No | ソート方向: asc または desc(デフォルト desc) |
locale | string | No | ロケールでフィルタ(例: en, fr)。i18n 時のみ関連。 |
スコープ: content:read | 読み取り専用: Yes
content_get
ID またはスラッグで単一のコンテンツアイテムを取得します。すべてのフィールド値、メタデータ、楽観的同時実行制御用の _rev トークンを返します。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
id | string | Yes | コンテンツアイテム ID (ULID) またはスラッグ |
locale | string | No | スラッグ検索用ロケール。ID はグローバルに一意。 |
スコープ: content:read | 読み取り専用: Yes
content_create
新しいコンテンツアイテムを作成します。data オブジェクトにはコレクションのスキーマに一致するフィールド値を含めます — 利用可能なフィールドを確認するには schema_get_collection を使用してください。アイテムはデフォルトで draft として作成されます。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
data | object | Yes | キーバリューペアのフィールド値 |
slug | string | No | URL スラッグ(省略時はタイトルから自動生成) |
status | string | No | 初期ステータス: draft または published(デフォルト draft) |
locale | string | No | コンテンツのロケール(デフォルトはサイトのデフォルト) |
translationOf | string | No | これが翻訳であるアイテムの ID |
スコープ: content:write
content_update
既存のコンテンツアイテムを更新します。変更したいフィールドのみを含めます — 未指定のフィールドは変更されません。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
id | string | Yes | コンテンツアイテム ID またはスラッグ |
data | object | No | 更新するフィールド値 |
slug | string | No | 新しい URL スラッグ |
status | string | No | 新しいステータス: draft または published |
_rev | string | No | 競合検出用の content_get からのリビジョントークン |
スコープ: content:write
content_delete
コンテンツアイテムをゴミ箱に移動してソフトデリートします。content_restore で元に戻すか、content_permanent_delete で永久に削除できます。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
id | string | Yes | コンテンツアイテム ID またはスラッグ |
スコープ: content:write | 破壊的: Yes
content_restore
ゴミ箱からソフトデリートされたコンテンツアイテムを復元します。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
id | string | Yes | コンテンツアイテム ID またはスラッグ |
スコープ: content:write
content_permanent_delete
ゴミ箱のコンテンツアイテムを永久かつ不可逆的に削除します。アイテムは先にゴミ箱にある必要があります。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
id | string | Yes | コンテンツアイテム ID またはスラッグ |
スコープ: content:write | 破壊的: Yes
content_publish
コンテンツアイテムを公開し、サイト上でライブにします。現在の下書きから公開リビジョンを作成します。以降の編集は再公開するまでライブバージョンに影響しない新しい下書きを作成します。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
id | string | Yes | コンテンツアイテム ID またはスラッグ |
スコープ: content:write
content_unpublish
公開されたアイテムを下書きステータスに戻します。ライブサイトでは表示されなくなりますが、コンテンツは保持されます。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
id | string | Yes | コンテンツアイテム ID またはスラッグ |
スコープ: content:write
content_schedule
コンテンツアイテムを将来の公開にスケジュールします。指定された日時に自動的に公開されます。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
id | string | Yes | コンテンツアイテム ID またはスラッグ |
scheduledAt | string | Yes | ISO 8601 日時(例: 2026-06-01T09:00:00Z) |
スコープ: content:write
content_compare
コンテンツアイテムの公開(ライブ)バージョンと現在の下書きを比較します。両方のバージョンと変更があるかどうかのフラグを返します。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
id | string | Yes | コンテンツアイテム ID またはスラッグ |
スコープ: content:read | 読み取り専用: Yes
content_discard_draft
現在の下書きを破棄し、最後の公開バージョンに戻します。少なくとも 1 回公開されたアイテムでのみ動作します。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
id | string | Yes | コンテンツアイテム ID またはスラッグ |
スコープ: content:write | 破壊的: Yes
content_list_trashed
コレクションのゴミ箱にあるソフトデリートされたコンテンツアイテムを一覧表示します。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
limit | integer | No | 最大数(1-100、デフォルト 50) |
cursor | string | No | ページネーションカーソル |
スコープ: content:read | 読み取り専用: Yes
content_duplicate
既存のコンテンツアイテムのコピーを作成します。複製はタイトルに “(Copy)” を追加し、自動生成されたスラッグで下書きとして作成されます。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
id | string | Yes | 複製するコンテンツアイテム ID またはスラッグ |
スコープ: content:write
content_translations
コンテンツアイテムのすべてのロケールバリアントを取得します。翻訳グループと各ロケールバージョンのサマリーを返します。i18n が有効な場合のみ関連します。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
id | string | Yes | コンテンツアイテム ID またはスラッグ |
スコープ: content:read | 読み取り専用: Yes
スキーマツール
schema_list_collections
CMS で定義されたすべてのコンテンツコレクションを一覧表示します。スラッグ、ラベル、サポートされる機能、タイムスタンプを返します。
パラメータなし。
スコープ: schema:read | 最小ロール: エディター | 読み取り専用: Yes
schema_get_collection
フィールド定義を含むコレクションの詳細情報を取得します。フィールドはデータモデルを記述します: 名前、タイプ、制約、バリデーションルール。content_create と content_update が何を期待するかを理解するために使用します。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
slug | string | Yes | コレクションスラッグ(例: posts) |
スコープ: schema:read | 最小ロール: エディター | 読み取り専用: Yes
schema_create_collection
新しいコンテンツコレクションを作成します。データベーステーブルとスキーマ定義を作成します。スラッグは文字で始まる小文字英数字とアンダースコアでなければなりません。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
slug | string | Yes | 一意の識別子(/^[a-z][a-z0-9_]*$/) |
label | string | Yes | 表示名(複数形、例: “Blog Posts”) |
labelSingular | string | No | 単数形の表示名 |
description | string | No | コレクションの説明 |
icon | string | No | 管理 UI のアイコン名 |
supports | string[] | No | 機能: drafts, revisions, preview, scheduling, search(デフォルト: ['drafts', 'revisions']) |
スコープ: schema:write | 最小ロール: 管理者
schema_delete_collection
コレクションとそのデータベーステーブルを削除します。不可逆的で、コレクション内のすべてのコンテンツが削除されます。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
slug | string | Yes | 削除するコレクションスラッグ |
force | boolean | No | コンテンツがあっても強制削除 |
スコープ: schema:write | 最小ロール: 管理者 | 破壊的: Yes
schema_create_field
コレクションのスキーマに新しいフィールドを追加します。データベーステーブルにカラムを追加します。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
slug | string | Yes | フィールド識別子(/^[a-z][a-z0-9_]*$/) |
label | string | Yes | 表示名 |
type | string | Yes | データ型(下記参照) |
required | boolean | No | フィールドが必須か |
unique | boolean | No | 値が一意でなければならないか |
defaultValue | any | No | 新規アイテムのデフォルト値 |
validation | object | No | 制約: min, max, minLength, maxLength, pattern, options |
options | object | No | ウィジェット設定: collection(参照用), rows(テキストエリア用) |
searchable | boolean | No | 全文検索インデックスに含める |
translatable | boolean | No | このフィールドが翻訳可能か(デフォルト true) |
フィールドタイプ: string, text, number, integer, boolean, datetime, select, multiSelect, portableText, image, file, reference, json, slug。
select と multiSelect タイプの場合、validation.options に許可値を提供します。
スコープ: schema:write | 最小ロール: 管理者
schema_delete_field
コレクションからフィールドを削除します。カラムを削除し、そのフィールドのすべてのデータが削除されます。不可逆的です。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
fieldSlug | string | Yes | 削除するフィールドスラッグ |
スコープ: schema:write | 最小ロール: 管理者 | 破壊的: Yes
メディアツール
media_list
アップロードされたメディアファイルを任意の MIME タイプフィルタリングとページネーションで一覧表示します。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
mimeType | string | No | MIME タイププレフィックスでフィルタ(例: image/, application/pdf) |
limit | integer | No | 最大数(1-100、デフォルト 50) |
cursor | string | No | ページネーションカーソル |
スコープ: media:read | 読み取り専用: Yes
media_get
ID で単一のメディアファイルの詳細を取得します。ファイル名、MIME タイプ、サイズ、寸法、代替テキスト、URL を含むメタデータを返します。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
id | string | Yes | メディアアイテム ID |
スコープ: media:read | 読み取り専用: Yes
media_update
アップロードされたメディアファイルのメタデータを更新します。ファイル自体は変更できません。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
id | string | Yes | メディアアイテム ID |
alt | string | No | アクセシビリティ用の代替テキスト |
caption | string | No | キャプションテキスト |
width | integer | No | 画像の幅(ピクセル) |
height | integer | No | 画像の高さ(ピクセル) |
スコープ: media:write
media_delete
メディアファイルを永久に削除します。データベースレコードとストレージからファイルを削除します。このメディアを参照するコンテンツは参照が壊れます。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
id | string | Yes | メディアアイテム ID |
スコープ: media:write | 破壊的: Yes
検索ツール
search
コンテンツコレクション全体の全文検索。コレクションの supports リストに search があり、フィールドが searchable としてマークされている必要があります。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
query | string | Yes | 検索クエリテキスト |
collections | string[] | No | 特定のコレクションスラッグに限定 |
locale | string | No | ロケールで結果をフィルタ |
limit | integer | No | 最大結果数(1-50、デフォルト 20) |
スコープ: content:read | 読み取り専用: Yes
タクソノミーツール
taxonomy_list
すべてのタクソノミー定義(例: カテゴリ、タグ)を一覧表示します。名前、ラベル、階層的かどうか、関連付けられたコレクションを返します。
パラメータなし。
スコープ: content:read | 読み取り専用: Yes
taxonomy_list_terms
タクソノミー内のタームをページネーション付きで一覧表示します。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
taxonomy | string | Yes | タクソノミー名(例: categories, tags) |
limit | integer | No | 最大数(1-100、デフォルト 50) |
cursor | string | No | ページネーションカーソル |
スコープ: content:read | 読み取り専用: Yes
taxonomy_create_term
タクソノミーに新しいタームを作成します。階層的なタクソノミーの場合、parentId を指定して子タームを作成します。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
taxonomy | string | Yes | タクソノミー名 |
slug | string | Yes | URL セーフな識別子 |
label | string | Yes | 表示名 |
parentId | string | No | 親ターム ID(階層タクソノミー用) |
description | string | No | タームの説明 |
スコープ: content:write
メニューツール
menu_list
すべてのナビゲーションメニューを一覧表示します。名前、ラベル、タイムスタンプを返します。
パラメータなし。
スコープ: content:read | 読み取り専用: Yes
menu_get
名前でメニューを取得し、すべてのアイテムを順序付きで含めます。アイテムにはラベル、URL、タイプ、ネスト用の任意の親があります。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
name | string | Yes | メニュー名(例: main, footer) |
スコープ: content:read | 読み取り専用: Yes
リビジョンツール
revision_list
コンテンツアイテムのリビジョン履歴を新しい順に一覧表示します。コレクションが revisions をサポートしている必要があります。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
collection | string | Yes | コレクションスラッグ |
id | string | Yes | コンテンツアイテム ID またはスラッグ |
limit | integer | No | 最大リビジョン数(1-50、デフォルト 20) |
スコープ: content:read | 読み取り専用: Yes
revision_restore
コンテンツアイテムを以前のリビジョンに復元します。現在の下書きを指定されたリビジョンのデータで置き換えます。自動的に公開されません — 必要に応じてその後 content_publish を使用してください。
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
revisionId | string | Yes | 復元するリビジョン ID |
スコープ: content:write
OAuth ディスカバリー
OAuth 2.1 をサポートする MCP クライアントは自動的に認証方法を検出できます。サーバーは 2 つのメタデータドキュメントを公開します:
保護リソースメタデータ
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
}
スコープと権限のエラーは MCP プロトコルエラーをスローします:
{
"jsonrpc": "2.0",
"error": {
"code": -32600,
"message": "Insufficient scope: requires content:write"
},
"id": 1
}
トランスポートレベルのエラー(サーバーの設定ミス、未処理の例外)は、実装の詳細を漏らさずに JSON-RPC エラーコード -32603(Internal error)を返します。