Riferimento server MCP

In questa pagina

EmDash espone un server Model Context Protocol (MCP) integrato su /_emdash/api/mcp. I client MCP lo usano per leggere e gestire contenuti, byline, schemi, media, tassonomie, menu, revisioni e impostazioni, e per esportare o importare l’intero sito.

Autenticazione

L’endpoint MCP richiede un token Bearer. EmDash supporta questi flussi di token:

MetodoUso
OAuth 2.1 Authorization Code with Proof Key for Code Exchange (PKCE)Client MCP interattivi. L’utente approva gli scope richiesti nel browser.
Personal access tokenAccesso a lungo termine per un client o automazione. I token usano il prefisso ec_pat_ e si creano nell’admin.
OAuth 2.0 Device Authorization GrantClient da riga di comando che chiedono all’utente di approvare un codice nel browser. emdash login usa questo flusso.

I cookie di sessione non autenticano l’endpoint MCP.

Scopes

I token OAuth e di accesso personale limitano quali strumenti un client può chiamare. Il ruolo dell’utente viene verificato separatamente: uno scope non concede mai un permesso che l’utente non ha.

ScopeAccesso
content:readLeggere e cercare contenuti, byline, tassonomie, termini, menu e revisioni. I contenuti tipo bozza richiedono anche il permesso content:read_drafts dell’utente.
content:writeCreare e modificare contenuti, byline e revisioni. Concede anche taxonomies:manage e menus:manage per compatibilità con token esistenti.
media:readLeggere record media.
media:writeCaricare, registrare, aggiornare ed eliminare media.
schema:readLeggere collection e campi.
schema:writeCreare, aggiornare ed eliminare collection e campi.
taxonomies:manageCreare, aggiornare ed eliminare definizioni di tassonomia e termini.
menus:manageCreare, aggiornare ed eliminare menu e voci di menu.
settings:readLeggere le impostazioni del sito.
settings:manageAggiornare le impostazioni del sito.
mcp:toolsChiamare strumenti MCP esposti da qualsiasi plugin abilitato.
mcp:tools:<pluginId>Chiamare strumenti MCP esposti da un plugin abilitato.
transfer:exportEsportare l’intero sito come pacchetto sito e scaricarlo.
transfer:analyzeCaricare un pacchetto sito e analizzarlo per l’import.
transfer:executeAvviare, far avanzare, annullare e abbandonare un import di sito.
adminChiamare ogni strumento core, inclusi quelli di trasferimento sito. Gli strumenti plugin richiedono ancora mcp:tools o lo scope specifico del plugin.

Lo scope admin include transfer:export, transfer:analyze e transfer:execute. Ogni scope di trasferimento concede solo le proprie azioni e richiede il ruolo amministratore. Per consentire a un client, ad esempio un agente, di analizzare un pacchetto senza esportare o importare, concedete transfer:analyze invece di admin.

La pagina di consenso del codice di autorizzazione consente all’utente di rimuovere scope richiesti. EmDash interseca anche la richiesta con gli scope registrati del client e il ruolo dell’utente e rifiuta una concessione vuota.

Requisiti di ruolo

La tabella seguente mostra il ruolo minimo per l’ampia capacità. I controlli di proprietà possono richiedere un ruolo superiore quando un utente agisce su contenuti di un altro utente.

CapacitàRuolo minimo
Leggere contenuti pubblicati, media, tassonomie, termini e menuSubscriber
Leggere bozze, contenuti programmati, cestino, confronti e revisioniContributor
Creare contenuti o caricare mediaContributor
Modificare o pubblicare contenuti propri e registrare mediaAuthor
Gestire byline, tassonomie, menu o contenuti di tutti gli utentiEditor
Leggere schemi o impostazioniEditor
Modificare schemi o impostazioni, eliminare definitivamente contenuti o riparare l’uso dei mediaAdmin
Esportare o importare l’intero sitoAdmin

Vedere ruoli utente per le definizioni complete.

Trasporto

Il server usa HTTP Streamable senza stato. Ogni richiesta è indipendente; il server non mantiene una sessione MCP né una connessione Server-Sent Events.

MetodoEndpointComportamento
POST/_emdash/api/mcpAccetta inizializzazione JSON-RPC, elenco strumenti e chiamate strumento.
GET/_emdash/api/mcpRestituisce 405 Method Not Allowed.
DELETE/_emdash/api/mcpRestituisce 405 Method Not Allowed.

Le risposte usano JSON-RPC 2.0. Chiamate tools/list per ottenere gli schemi di input e le annotazioni MCP attuali prima di costruire una richiesta strumento.

Inventario strumenti

L’inventario seguente corrisponde agli strumenti statici restituiti da tools/list. Il titolo registrato è incluso perché i client possono mostrarlo al posto del nome strumento.

Strumenti contenuto

ToolRegistered titleRequired scope
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

Strumenti byline

ToolRegistered titleRequired scope
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

Strumenti schema

ToolRegistered titleRequired scope
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

Strumenti media

ToolRegistered titleRequired scope
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

Strumento di ricerca

ToolRegistered titleRequired scope
searchSearch Contentcontent:read

Strumenti tassonomia

ToolRegistered titleRequired scope
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

Strumenti menu

ToolRegistered titleRequired scope
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

Strumenti revisione

ToolRegistered titleRequired scope
revision_listList Revisionscontent:read
revision_restoreRestore Revisioncontent:write

Strumenti impostazioni

ToolRegistered titleRequired scope
settings_getGet Site Settingssettings:read
settings_updateUpdate Site Settingssettings:manage

Strumenti trasferimento sito

transfer:* indica uno tra transfer:export, transfer:analyze o transfer:execute. Lo scope admin soddisfa ogni requisito in questa tabella.

ToolRegistered titleRequired scope
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 e site_import_start accettano anche un token senza lo scope quando un admin approva la richiesta. Per l’operazione avviata da una richiesta approvata, site_export_status, site_import_status, site_import_resume e site_import_receipt accettano lo stesso token senza lo scope.

Usare gli schemi strumento

tools/list restituisce per ogni strumento descrizione, schema di input JSON e annotazioni. Leggete tali metadati prima di costruire una chiamata così il client usa campi, valori consentiti e limiti supportati dalla versione EmDash installata.

Ad esempio, un client che aggiorna un articolo chiama prima content_get e conserva il _rev restituito. Può poi inviare questa richiesta 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"
		}
	}
}

Il risultato è restituito come testo JSON nel primo blocco contenuto. Uno strumento con schema di output può restituire lo stesso valore anche in structuredContent.

Ciclo di vita contenuti e byline

Il riferimento al ciclo di vita dei contenuti definisce stato, revisione, permessi, conflitti e comportamento degli hook condivisi da MCP, REST, CLI e pannello admin.

content_get restituisce un valore _rev opaco. Passatelo a content_update, content_publish, content_unpublish, content_schedule o content_discard_draft. Un valore obsoleto restituisce un conflitto; rileggete l’elemento prima di riprovare.

content_update è un aggiornamento parziale: i campi omessi mantengono i valori attuali. Aggiornare un elemento pubblicato prepara una bozza mentre la versione live resta invariata. Usate content_compare per rivedere valori live e bozza, poi chiamate content_publish per rendere live la bozza o content_discard_draft per rimuoverla. content_delete sposta un elemento nel cestino; solo content_permanent_delete rimuove definitivamente un elemento nel cestino.

Le byline sono crediti riutilizzabili di autore o collaboratore. byline_create può creare un credito ospite o collegare una byline a un utente CMS. Passate l’ID byline restituito nell’input bylines accettato da content_create e content_update. Eliminare una byline rimuove quel credito dai contenuti e lo cancella come byline principale.

Le scritture MCP non partecipano al blocco modifica voce dell’admin. Il controllo _rev protegge le operazioni che lo accettano, ma altri strumenti di scrittura possono modificare una voce mentre un editor la tiene aperta.

Traduzioni

Gli strumenti di traduzione di contenuti, byline, termini di tassonomia e menu restituiscono ogni variante locale nel gruppo di traduzione pertinente. Usate l’input translationOf dello strumento di creazione quando lo schema lo prevede; tools/list è autorevole per i campi richiesti.

content_translations accetta collection e ID o slug del contenuto. Gli strumenti di traduzione byline, termine e menu accettano l’ID di un record o l’ID condiviso del gruppo di traduzione. Un utente senza accesso alle bozze vede solo traduzioni di contenuti pubblicati.

Schemi, media, tassonomie e menu

Gli strumenti schema modificano la struttura del database. Usate schema_get_collection prima di creare contenuti o modificare campi; restituisce nomi campo, tipi, vincoli e regole di validazione disponibili. L’eliminazione di collection e campi rimuove contenuti memorizzati o valori di campo e non può essere annullata.

Usate media_upload per inviare byte codificati in base64. I caricamenti sono soggetti ai limiti di dimensione e tipo MIME configurati; byte identici possono restituire un elemento media esistente con deduplicated: true.

media_create conferma un caricamento in sospeso creato tramite POST /_emdash/api/media/upload-url. Caricate il file con l’URL firmata restituita, poi chiamate media_create dallo stesso account utente con il storageKey restituito. Lo strumento verifica che il file memorizzato esista e corrisponda alla dimensione indicata quando è stata richiesta l’URL di caricamento prima di renderlo disponibile nella libreria media.

Le definizioni di tassonomia descrivono la classificazione e le collection a cui si applica; i termini sono i valori individuali assegnati ai contenuti. I termini gerarchici possono usare parentId, ma un genitore deve appartenere alla stessa tassonomia e non può creare un ciclo. Creare o aggiornare un termine con parentId in una tassonomia non gerarchica restituisce VALIDATION_ERROR. Un termine con figli deve averli rimossi o spostati prima dell’eliminazione.

menu_set_items sostituisce l’elenco completo delle voci di un menu in un’operazione atomica. L’ordine dell’array diventa l’ordine del menu. Il parentIndex di una voce annidata punta a una voce precedente nello stesso array; posizionate ogni genitore prima dei figli.

media_usage_repair può elaborare una collection o tutte le collection e può richiedere molto tempo su un sito grande. Gli stati complete, partial, failed e stale sono risposte strumento riuscite. Ispezionate stato e conteggi restituiti invece di affidarvi a isError; autenticazione, validazione e errori di esecuzione imprevisti impostano isError: true.

Trasferimento sito

Gli strumenti site_* esportano un intero sito come pacchetto sito e importano un pacchetto in un sito vuoto. Avviano e guidano operazioni e restituiscono riepiloghi limitati. Non trasportano mai byte del pacchetto, media, contenuti dei record, indirizzi email dei principal né URL di download. Scaricate un export e caricate un pacchetto per l’import con la CLI o l’API REST, poi riferite l’operazione per ID.

Ogni strumento di trasferimento richiede il ruolo Admin. Il ruolo è verificato prima dello scope; un chiamante non admin riceve INSUFFICIENT_PERMISSIONS e non viene creata alcuna richiesta di approvazione.

Export

site_export_start accetta comments (predefinito true) e restituisce la nuova operazione. site_export_status esegue un passo di export limitato a ogni chiamata e riporta l’operazione e nextRequestInMs. Richiamate dopo quel ritardo finché nextRequestInMs non è null. Passate advance: false per leggere lo stato senza eseguire un passo. Al completamento dell’export, il risultato include anche totals: conteggi record per tipo, conteggio e byte media, e conteggio e byte file del pacchetto.

Import

Caricate prima il pacchetto. emdash site import <file> --analyze della CLI carica, analizza e stampa l’ID operazione.

site_import_analyze esegue un passo di analisi limitato per chiamata. Ripetete finché nextRequestInMs non è null; il risultato include allora un riepilogo piano con packageDigest, planDigest, executable, conteggi, dimensioni, principal, decisioni, trasformazioni, avvisi e blocker. Ogni trasformazione è elencata come code, kind del record se presente, e count, senza ID o valori a cui si applica. Principal, avvisi e blocker elencano al massimo 50 elementi ciascuno, con il conteggio totale in total. I principal sono elencati senza indirizzi email, con ID utente destinazione suggeriti e mappati attualmente. Passate decisions per mappare i principal agli ID utente destinazione (o null) e scegliere titolo e tagline del pacchetto o destinazione. Ogni modifica produce un nuovo planDigest.

site_import_start prende l’ID operazione e i packageDigest e planDigest dell’ultimo piano. Il piano non deve avere blocker. Lo strumento ha destructiveHint: true: una volta avviato, l’import scrive sul sito e blocca altre scritture finché non completa o un amministratore lo abbandona. Mostrate il piano all’utente e ottenete conferma prima di chiamarlo.

site_import_resume esegue un passo di import limitato e riporta operazione e nextRequestInMs. Chiamatelo finché nextRequestInMs non è null; è sicuro ripetere dopo una disconnessione. site_import_status riporta operazione e conteggi file caricati senza far avanzare l’import. site_import_receipt restituisce la ricevuta completa, incluso receiptDigest, al completamento dell’import.

Mentre un import è in esecuzione, e dopo fallimento o annullamento finché non viene abbandonato, ogni altro strumento che può scrivere fallisce con TRANSFER_IMPORT_IN_PROGRESS. Include gli strumenti plugin. Gli strumenti annotati readOnlyHint: true e gli otto strumenti site_* continuano a funzionare, e initialize e tools/list non sono mai bloccati. Durante l’attivazione uso media, gli strumenti di scrittura falliscono allo stesso modo con MEDIA_USAGE_ACTIVATION_IN_PROGRESS.

I riepiloghi operazione includono id, kind, state, stage, progress, packageDigest, planDigest, error ({ code } o null) e timestamp. progress è { done, total } passi, più records scritti finora da un export, e bytesDone e bytesTotal quando noti. Gli strumenti MCP non possono annullare o abbandonare un import; usate l’API REST.

Approvazioni

Un token con admin o lo scope di trasferimento necessario non chiede mai approvazione. Per un token senza l’uno o l’altro, ad esempio un agente con solo transfer:analyze, site_export_start e site_import_start si eseguono quando un amministratore approva la richiesta:

  1. La prima chiamata senza scope crea una richiesta di approvazione in sospeso e fallisce con TRANSFER_APPROVAL_REQUIRED. Testo del messaggio e _meta.details portano approvalId e expiresAt. Richiamare con gli stessi argomenti e senza approvalId restituisce la stessa richiesta aperta.
  2. Un amministratore approva sotto Richieste di approvazione in Impostazioni → Transfer, o con l’endpoint di approvazione solo sessione dell’API REST. I token API non possono approvare richieste.
  3. Il client ripete la chiamata con gli stessi argomenti e l’approvalId. L’approvazione si consuma quando quella chiamata avvia l’operazione. Se l’operazione non parte, il client può riprovare con lo stesso approvalId finché non scade.

Una richiesta è legata a utente, token, azione e argomenti esatti: opzioni export, o ID operazione import e entrambi i digest. Una richiesta in sospeso scade 15 minuti dopo la creazione, una approvata 15 minuti dopo l’approvazione. Una chiamata con argomenti diversi o altro token, o con approvazione negata, scaduta o usata, fallisce con TRANSFER_APPROVAL_INVALID.

site_import_start verifica digest, stato operazione e blocker del piano prima di creare una richiesta, così un amministratore viene chiesto di approvare solo un import eseguibile. Un’approvazione richiede un ID token; un chiamante senza riceve INSUFFICIENT_SCOPE.

Dopo una chiamata approvata che avvia un’operazione, lo stesso utente e token possono chiamare site_export_status, o site_import_status, site_import_resume e site_import_receipt, per quell’operazione senza lo scope.

Strumenti plugin

Un amministratore deve abilitare la superficie MCP di ogni plugin. Gli strumenti abilitati compaiono in tools/list come <pluginId>__<localName> e richiedono mcp:tools o mcp:tools:<pluginId> per chiamate autenticate con token. EmDash verifica anche il permesso dichiarato dalla route plugin e registra plugin, strumento, route e attore nel log di audit.

Poiché gli strumenti plugin dipendono dall’installazione, non fanno parte dell’inventario statico sopra.

Scoperta OAuth

I client MCP scoprono il server di autorizzazione dai metadati della risorsa protetta:

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

La risposta identifica /_emdash/api/mcp come risorsa protetta e collega al server di autorizzazione. I client leggono poi i metadati a:

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

Quel documento fornisce gli endpoint attuali di autorizzazione, token, registrazione e autorizzazione dispositivo, scope supportati, tipi di grant e il metodo PKCE S256. Usate i valori scoperti invece di codificare fisse le route del protocollo OAuth.

Una richiesta MCP non autenticata restituisce 401 con l’URL di scoperta:

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

Errori

Un fallimento strumento ha isError: true. Il primo blocco testo inizia con un codice stabile, e _meta.code lo ripete per client che leggono metadati strutturati:

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

I fallimenti di autenticazione usano codici come INSUFFICIENT_SCOPE e INSUFFICIENT_PERMISSIONS. I fallimenti di trasporto usano il codice errore interno JSON-RPC -32603 e non espongono l’eccezione sottostante.