MCP サーバーリファレンス

このページ

EmDash は、/_emdash/api/mcp に組み込みの Model Context Protocol(MCP)サーバーを公開しています。MCP クライアントはこれを使って、コンテンツ、バイライン、スキーマ、メディア、タクソノミー、メニュー、リビジョン、設定の読み取りと管理を行い、サイト全体のエクスポートとインポートを行います。

認証

MCP エンドポイントには Bearer トークンが必要です。EmDash は次のトークンフローをサポートしています。

方法用途
OAuth 2.1 Authorization Code with Proof Key for Code Exchange (PKCE)対話型の MCP クライアント。ユーザーがブラウザーで、要求されたスコープを承認します。
Personal access tokenクライアントや自動化向けの長期間有効なアクセス。トークンには ec_pat_ プレフィックスが付き、管理画面で作成します。
OAuth 2.0 Device Authorization Grantブラウザーでコードを承認するようユーザーに求めるコマンドラインクライアント。emdash login はこのフローを使用します。

セッション Cookie では MCP エンドポイントを認証できません。

スコープ

OAuth トークンとパーソナルアクセストークンは、クライアントが呼び出せるツールを制限します。ユーザーのロールは別途チェックされるため、スコープがユーザーの持たない権限を付与することはありません。

スコープアクセス
content:readコンテンツ、バイライン、タクソノミー、ターム、メニュー、リビジョンの読み取りと検索。下書きに類するコンテンツには、ユーザーの content:read_drafts 権限も必要です。
content:writeコンテンツ、バイライン、リビジョンの作成と変更。既存のトークンとの互換性のため、taxonomies:manage と menus:manage も付与されます。
media:readメディアレコードの読み取り。
media:writeメディアのアップロード、登録、更新、削除。
schema:readコレクションとフィールドの読み取り。
schema:writeコレクションとフィールドの作成、更新、削除。
taxonomies:manageタクソノミー定義とタームの作成、更新、削除。
menus:manageメニューとメニュー項目の作成、更新、削除。
settings:readサイト設定の読み取り。
settings:manageサイト設定の更新。
mcp:tools有効なプラグインが公開する任意の MCP ツールの呼び出し。
mcp:tools:<pluginId>有効な特定の 1 つのプラグインが公開する MCP ツールの呼び出し。
transfer:exportサイト全体をサイトパッケージとしてエクスポートし、ダウンロードする。
transfer:analyzeサイトパッケージをアップロードし、インポート用に分析する。
transfer:executeサイトインポートの開始、進行、キャンセル、破棄。
adminサイト転送ツールを含む、すべてのコアツールの呼び出し。プラグインツールには、引き続き mcp:tools またはプラグイン固有のスコープが必要です。

admin スコープには、transfer:export、transfer:analyze、transfer:execute が含まれます。各転送スコープは、それぞれ自身の操作だけを許可し、管理者ロールを必要とします。エージェントなどのクライアントに、エクスポートやインポートは許可せずにサイトパッケージの分析だけを行わせるには、admin ではなく transfer:analyze を付与してください。

認可コードの同意ページでは、ユーザーが要求されたスコープを取り除けます。EmDash はさらに、リクエストをクライアントの登録済みスコープおよびユーザーのロールと突き合わせて絞り込み、空の付与は拒否します。

ロール要件

次の表は、大まかな機能ごとの最小ロールを示しています。ユーザーが他のユーザーのコンテンツを操作する場合は、所有権のチェックにより、より高いロールが必要になることがあります。

機能最小ロール
公開済みのコンテンツ、メディア、タクソノミー、ターム、メニューの読み取りSubscriber
下書き、スケジュール済みコンテンツ、ゴミ箱、比較、リビジョンの読み取りContributor
コンテンツの作成、またはメディアのアップロードContributor
自分のコンテンツの編集または公開、およびメディアの登録Author
バイライン、タクソノミー、メニュー、またはすべてのユーザーのコンテンツの管理Editor
スキーマまたは設定の読み取りEditor
スキーマまたは設定の変更、コンテンツの完全削除、メディア使用状況の修復Admin
サイト全体のエクスポートまたはインポートAdmin

ロールの完全な定義は、ユーザーロールを参照してください。

トランスポート

サーバーはステートレスな Streamable HTTP を使用します。各リクエストは独立しており、サーバーは MCP セッションや Server-Sent Events 接続を保持しません。

メソッドエンドポイント動作
POST/_emdash/api/mcpJSON-RPC の初期化、ツール一覧の取得、ツール呼び出しを受け付けます。
GET/_emdash/api/mcp405 Method Not Allowed を返します。
DELETE/_emdash/api/mcp405 Method Not Allowed を返します。

レスポンスは JSON-RPC 2.0 を使用します。ツールのリクエストを組み立てる前に、tools/list を呼び出して、現在の入力スキーマと MCP アノテーションを取得してください。

ツール一覧

次の一覧は、tools/list が返す静的ツールと一致しています。クライアントがツール名の代わりにタイトルを表示することがあるため、登録済みのタイトルも掲載しています。

コンテンツツール

ツール登録済みタイトル必要なスコープ
content_listList Contentcontent:read
content_getGet Contentcontent:read
content_createCreate Contentcontent:write
content_updateUpdate Contentcontent:write
content_deleteDelete Content (Trash)content:write
content_restoreRestore Contentcontent:write
content_permanent_deletePermanently Delete Contentcontent:write
content_publishPublish Contentcontent:write
content_unpublishUnpublish Contentcontent:write
content_scheduleSchedule Contentcontent:write
content_unscheduleCancel Scheduled Publicationcontent:write
content_compareCompare Live vs Draftcontent:read
content_discard_draftDiscard Draftcontent:write
content_list_trashedList Trashed Contentcontent:read
content_duplicateDuplicate Contentcontent:write
content_translationsGet Content Translationscontent:read

バイラインツール

ツール登録済みタイトル必要なスコープ
byline_listList Bylinescontent:read
byline_getGet Bylinecontent:read
byline_createCreate Bylinecontent:write
byline_updateUpdate Bylinecontent:write
byline_deleteDelete Bylinecontent:write
byline_translationsList Byline Translationscontent:read

スキーマツール

ツール登録済みタイトル必要なスコープ
schema_list_collectionsList Collectionsschema:read
schema_get_collectionGet Collection Schemaschema:read
schema_list_block_typesList Block Typesschema:read
schema_get_block_typeGet Block Typeschema:read
schema_create_block_typeCreate Block Typeschema:write
schema_update_block_typeUpdate Block Typeschema:write
schema_activate_block_type_versionActivate Block Type Versionschema:write
schema_create_collectionCreate Collectionschema:write
schema_delete_collectionDelete Collectionschema:write
schema_update_collectionUpdate Collectionschema:write
schema_create_fieldAdd Field to Collectionschema:write
schema_delete_fieldRemove Field from Collectionschema:write
schema_update_fieldUpdate Fieldschema:write

メディアツール

ツール登録済みタイトル必要なスコープ
media_listList Mediamedia:read
media_createConfirm Signed Media Uploadmedia:write
media_uploadUpload Mediamedia:write
media_getGet Media Itemmedia:read
media_updateUpdate Media Metadatamedia:write
media_deleteDelete Mediamedia:write
media_usage_repairRepair Media Usage Indexadmin

検索ツール

ツール登録済みタイトル必要なスコープ
searchSearch Contentcontent:read

タクソノミーツール

ツール登録済みタイトル必要なスコープ
taxonomy_listList Taxonomiescontent:read
taxonomy_getGet Taxonomy Definitioncontent:read
taxonomy_createCreate Taxonomy Definitiontaxonomies:manage
taxonomy_updateUpdate Taxonomy Definitiontaxonomies:manage
taxonomy_deleteDelete Taxonomy Definitiontaxonomies:manage
taxonomy_list_termsList Taxonomy Termscontent:read
taxonomy_create_termCreate Taxonomy Termtaxonomies:manage
taxonomy_update_termUpdate Taxonomy Termtaxonomies:manage
taxonomy_delete_termDelete Taxonomy Termtaxonomies:manage
taxonomy_term_translationsList Term Translationscontent:read

メニューツール

ツール登録済みタイトル必要なスコープ
menu_listList Menuscontent:read
menu_getGet Menu with Itemscontent:read
menu_translationsList Menu Translationscontent:read
menu_createCreate Menumenus:manage
menu_updateUpdate Menumenus:manage
menu_deleteDelete Menumenus:manage
menu_set_itemsSet Menu Itemsmenus:manage

リビジョンツール

ツール登録済みタイトル必要なスコープ
revision_listList Revisionscontent:read
revision_restoreRestore Revisioncontent:write

設定ツール

ツール登録済みタイトル必要なスコープ
settings_getGet Site Settingssettings:read
settings_updateUpdate Site Settingssettings:manage

サイト転送ツール

transfer:* は、transfer:export、transfer:analyze、transfer:execute のいずれか 1 つを意味します。admin スコープは、この表のすべての要件を満たします。

ツール登録済みタイトル必要なスコープ
site_transfer_capabilitiesGet Site Transfer Capabilitiestransfer:*
site_export_startStart Site Exporttransfer:export
site_export_statusGet Site Export Statustransfer:export
site_import_analyzeAnalyze Site Importtransfer:analyze
site_import_startStart Site Importtransfer:execute
site_import_statusGet Site Import Statustransfer:*
site_import_resumeResume Site Importtransfer:execute
site_import_receiptGet Site Import Receipttransfer:*

site_export_start と site_import_start は、管理者がリクエストを承認した場合、そのスコープを持たないトークンも受け付けます。承認されたリクエストが開始した操作については、site_export_status、site_import_status、site_import_resume、site_import_receipt も、そのスコープを持たない同じトークンを受け付けます。

ツールスキーマの利用

tools/list は、各ツールの説明、JSON 入力スキーマ、アノテーションを返します。呼び出しを組み立てる前にこのメタデータを読み、クライアントがインストール済みの EmDash のバージョンでサポートされているフィールド、許可される値、制限を使用するようにしてください。

たとえば、記事を更新するクライアントは、まず content_get を呼び出して、返された _rev を保持します。その後、次の JSON-RPC リクエストを送信できます。

{
	"jsonrpc": "2.0",
	"id": 2,
	"method": "tools/call",
	"params": {
		"name": "content_update",
		"arguments": {
			"collection": "articles",
			"id": "01JARTICLE0000000000000000",
			"data": { "title": "Updated title" },
			"_rev": "opaque-revision-token"
		}
	}
}

結果は、最初のコンテンツブロックに JSON テキストとして返されます。出力スキーマを持つツールは、同じ値を structuredContent にも返すことがあります。

コンテンツライフサイクルとバイライン

コンテンツライフサイクルのリファレンスでは、MCP、REST、CLI、管理パネルで共通する、状態、リビジョン、権限、競合、フックの動作を定義しています。

content_get は、不透明な _rev 値を返します。これを content_update、content_publish、content_unpublish、content_schedule、content_discard_draft に渡してください。古い値を渡すと競合が返されるため、再試行する前にアイテムを読み直してください。

content_update は部分更新です。省略したフィールドは現在の値のまま残ります。公開済みのアイテムを更新すると、公開中のバージョンは変更されないまま、下書きがステージングされます。content_compare で公開中の値と下書きの値を確認し、content_publish で下書きを公開するか、content_discard_draft で下書きを削除します。content_delete はアイテムをゴミ箱に移動します。ゴミ箱内のアイテムを完全に削除できるのは、content_permanent_delete だけです。

バイラインは、再利用可能な著者や寄稿者のクレジットです。byline_create は、ゲストのクレジットを作成することも、バイラインを CMS ユーザーにリンクすることもできます。1 人のユーザーが持てるバイラインは、ロケールごとに 1 つだけです。translationOf で作成した翻訳は、userId を渡さない限り、元のバイラインのユーザーを引き継ぎます。null を渡すと、その翻訳はユーザーにリンクされません。返されたバイライン ID を、content_create と content_update が受け付ける bylines 入力に渡してください。バイラインを削除すると、そのクレジットがコンテンツから取り除かれ、メインのバイラインとしての設定もクリアされます。

別のユーザーが管理画面でエントリを開いていて、その編集ロックを保持している間、content_update、content_delete、content_publish、content_unpublish、content_schedule、content_unschedule、content_discard_draft、revision_restore は ENTRY_LOCKED で失敗し、エラーには保持者が示されます。アイテムを読み直しても、この拒否は解除されません。強制的に書き込むには、overrideLock: true を渡します。

翻訳

コンテンツ、バイライン、タクソノミーターム、メニューの翻訳ツールは、該当する翻訳グループ内のすべてのロケールのバリアントを返します。作成ツールのスキーマに translationOf 入力がある場合は、それを使用してください。必須フィールドについては tools/list が正となります。

content_translations は、コレクションと、コンテンツ ID またはスラグを受け付けます。バイライン、タクソノミーターム、メニューの翻訳ツールは、1 件のレコードの ID か、共有の翻訳グループ ID のどちらかを受け付けます。下書きへのアクセス権を持たないユーザーには、公開済みのコンテンツの翻訳だけが表示されます。

スキーマ、メディア、タクソノミー、メニュー

スキーマツールは、データベースの構造を変更します。コンテンツを作成したりフィールドを変更したりする前に、schema_get_collection を使用してください。このツールは、利用可能なフィールド名、型、制約、バリデーションルールを返します。コレクションとフィールドの削除は、保存されているコンテンツやフィールドの値を削除し、元に戻せません。

base64 エンコードされたバイト列を送信するには、media_upload を使用します。アップロードは、設定されたサイズと MIME タイプの制限の対象となり、同一のバイト列は、deduplicated: true とともに既存のメディアアイテムを返すことがあります。

media_create は、POST /_emdash/api/media/upload-url で作成された保留中のアップロードを確定します。返された署名付き URL でファイルをアップロードし、同じユーザーアカウントから、返された storageKey を指定して media_create を呼び出してください。このツールは、保存されたファイルが存在し、アップロード URL のリクエスト時に指定されたサイズと一致することを確認してから、メディアライブラリで使えるようにします。

タクソノミー定義は分類方法と、それが適用されるコレクションを記述します。タームは、コンテンツに割り当てられる個々の値です。階層型のタームでは parentId を使えますが、親は同じタクソノミーに属している必要があり、循環を作ることはできません。階層型ではないタクソノミーで parentId を指定してタームを作成または更新すると、VALIDATION_ERROR が返されます。子を持つタームは、子を削除または移動してからでないと削除できません。

menu_set_items は、1 回のアトミックな操作で、メニューの項目リスト全体を置き換えます。配列の順序がメニューの順序になります。ネストされた項目の parentIndex は、同じ配列内でそれより前にある項目を指すため、すべての親を子より前に配置してください。

media_usage_repair は、1 つのコレクションまたはすべてのコレクションを処理でき、大規模なサイトでは長時間実行されることがあります。complete、partial、failed、stale の各ステータスは、成功したツールレスポンスです。isError に頼らず、返されたステータスと件数を確認してください。認証、バリデーション、予期しない実行の失敗では、isError: true が設定されます。

サイト転送

site_* ツールは、サイト全体をサイトパッケージとしてエクスポートし、パッケージを空のサイトにインポートします。これらのツールは操作を開始して進行させ、上限のある要約を返します。パッケージのバイト列、メディア、レコードの内容、プリンシパルのメールアドレス、ダウンロード URL は、決して扱いません。エクスポートのダウンロードと、インポート用のパッケージのアップロードは、CLI または REST API で行い、その後は ID で操作を参照します。

すべての転送ツールには Admin ロールが必要です。ロールはスコープより先にチェックされるため、管理者ではない呼び出し元は INSUFFICIENT_PERMISSIONS を受け取り、承認リクエストは作成されません。

エクスポート

site_export_start は comments(デフォルトは true)を受け付け、新しい操作を返します。site_export_status は、呼び出しごとに上限のあるエクスポートのステップを 1 つ実行し、操作と nextRequestInMs を報告します。nextRequestInMs が null になるまで、その遅延の後に再度呼び出してください。ステップを実行せずにステータスだけを読み取るには、advance: false を渡します。エクスポートが完了すると、結果には totals も含まれます。これは、種類ごとのレコード数、メディアの数とバイト数、パッケージのファイル数とバイト数です。

インポート

先にパッケージをアップロードしてください。CLI の emdash site import <file> --analyze は、パッケージをアップロードして分析し、操作 ID を出力します。

site_import_analyze は、呼び出しごとに上限のある分析ステップを 1 つ実行します。nextRequestInMs が null になるまで繰り返してください。その後、結果には、packageDigest、planDigest、executable、件数、サイズ、プリンシパル、決定事項、変換、警告、ブロッカーを含む、プランの要約が含まれます。各変換は、その code、レコードの kind(ある場合)、count として列挙され、適用対象の ID や値は含まれません。プリンシパル、警告、ブロッカーは、それぞれ最大 50 件まで列挙され、全件数は total に入ります。プリンシパルはメールアドレスなしで列挙され、推奨されるターゲットユーザー ID と、現在マッピングされているターゲットユーザー ID が示されます。decisions を渡すと、プリンシパルをターゲットユーザー ID(または null)にマッピングし、パッケージ側かターゲット側のタイトルとタグラインを選択できます。変更のたびに、新しい planDigest が生成されます。

site_import_start は、操作 ID と、最新のプランの packageDigest および planDigest を受け取ります。プランにブロッカーがあってはいけません。このツールには destructiveHint: true が設定されています。開始すると、インポートはサイトに書き込みを行い、完了するか管理者が破棄するまで、他の書き込みをブロックします。呼び出す前に、ユーザーにプランを提示して確認を得てください。

site_import_resume は、上限のあるインポートのステップを 1 つ実行し、操作と nextRequestInMs を報告します。nextRequestInMs が null になるまで呼び出してください。切断後に繰り返しても安全です。site_import_status は、インポートを進めずに、操作とアップロード済みファイルの数を報告します。site_import_receipt は、インポートが完了した後に、receiptDigest を含む完全なレシートを返します。

インポートの実行中、および失敗またはキャンセルの後、破棄されるまでの間は、書き込みが可能な他のすべてのツールが TRANSFER_IMPORT_IN_PROGRESS で失敗します。これにはプラグインツールも含まれます。readOnlyHint: true が付いたツールと 8 つの site_* ツールは引き続き動作し、initialize と tools/list がブロックされることはありません。メディア使用状況のアクティベーション中は、書き込みツールが同様に MEDIA_USAGE_ACTIVATION_IN_PROGRESS で失敗します。

操作の要約には、id、kind、state、stage、progress、packageDigest、planDigest、error({ code } または null)、タイムスタンプが含まれます。progress は { done, total } のステップ数で、判明している場合は、エクスポートがここまでに書き込んだレコード数である records と、bytesDone および bytesTotal も含まれます。MCP ツールではインポートのキャンセルや破棄はできません。REST API を使用してください。

承認

admin または必要な転送スコープを持つトークンは、承認を求められません。どちらも持たないトークン(たとえば transfer:analyze だけを付与されたエージェント)の場合、site_export_start と site_import_start は、管理者がリクエストを承認すると実行されます。

  1. スコープなしでの最初の呼び出しは、保留中の承認リクエストを作成し、TRANSFER_APPROVAL_REQUIRED で失敗します。メッセージのテキストと _meta.details に、approvalId とその expiresAt が含まれます。同じ引数で approvalId なしに再度呼び出すと、同じ未処理のリクエストが返されます。
  2. 管理者は、Settings → Transfer の Approval requests でリクエストを承認するか、REST API のセッション専用の承認エンドポイントで承認します。API トークンではリクエストを承認できません。
  3. クライアントは、同じ引数と approvalId を指定して、呼び出しを繰り返します。その呼び出しが操作を開始した時点で、承認は使い切られます。操作の開始に失敗した場合、クライアントは、期限が切れるまで同じ approvalId で再試行できます。

リクエストは、ユーザー、トークン、アクション、そして正確な引数(エクスポートのオプション、またはインポートの操作 ID と 2 つのダイジェスト)に紐づけられます。保留中のリクエストは作成から 15 分で、承認済みのリクエストは承認から 15 分で期限切れになります。引数が異なる呼び出し、別のトークンでの呼び出し、または拒否済み、期限切れ、使用済みの承認を指定した呼び出しは、TRANSFER_APPROVAL_INVALID で失敗します。

site_import_start は、リクエストを作成する前に、ダイジェスト、操作の状態、プランのブロッカーをチェックします。そのため、管理者に承認を求めるのは、実行可能なインポートだけです。承認にはトークン ID が必要なので、トークン ID を持たない呼び出し元は INSUFFICIENT_SCOPE を受け取ります。

承認された呼び出しが操作を開始した後は、同じユーザーとトークンが、その操作に対して、スコープなしで site_export_status、または site_import_status、site_import_resume、site_import_receipt を呼び出せます。

プラグインツール

管理者は、各プラグインの MCP サーフェスを有効にする必要があります。有効なツールは、tools/list に <pluginId>__<localName> として表示され、トークン認証された呼び出しには mcp:tools または mcp:tools:<pluginId> が必要です。EmDash はさらに、プラグインのルートが宣言する権限をチェックし、プラグイン、ツール、ルート、実行者を監査ログに記録します。

プラグインツールはインストールごとに異なるため、上記の静的な一覧には含まれません。

OAuth ディスカバリー

MCP クライアントは、保護されたリソースのメタデータから認可サーバーを検出します。

GET /.well-known/oauth-protected-resource

このレスポンスは、/_emdash/api/mcp を保護されたリソースとして示し、認可サーバーへのリンクを含みます。クライアントは続いて、次の場所でそのメタデータを読み取ります。

GET /.well-known/oauth-authorization-server/_emdash

このドキュメントは、現在の認可、トークン、登録、デバイス認可の各エンドポイント、サポートされているスコープ、グラントタイプ、S256 PKCE メソッドを提供します。OAuth プロトコルのルートをハードコードせず、検出された値を使用してください。

認証されていない MCP リクエストは、ディスカバリー URL を含む 401 レスポンスを返します。

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

エラー

ツールの失敗には isError: true が付きます。最初のテキストブロックは安定したコードで始まり、構造化メタデータを読むクライアントのために、_meta.code が同じコードを繰り返します。

{
	"content": [{ "type": "text", "text": "[NOT_FOUND] Collection 'articles' not found" }],
	"isError": true,
	"_meta": { "code": "NOT_FOUND" }
}

エントリの編集ロックによる拒否では、_meta.details に保持者の情報が含まれます。

{
	"content": [{ "type": "text", "text": "[ENTRY_LOCKED] Ada is holding this entry" }],
	"isError": true,
	"_meta": {
		"code": "ENTRY_LOCKED",
		"details": {
			"userId": "01JB...",
			"userName": "Ada",
			"acquiredAt": "2026-05-01T09:12:04.117Z",
			"expiresAt": "2026-05-01T09:19:04.117Z"
		}
	}
}

認証の失敗では、INSUFFICIENT_SCOPE や INSUFFICIENT_PERMISSIONS などのコードが使われます。トランスポートの失敗では、JSON-RPC の内部エラーコード -32603 が使われ、内部の例外は公開されません。