Référence du serveur MCP

Sur cette page

EmDash inclut un serveur Model Context Protocol (MCP) intégré à /_emdash/api/mcp qui expose les opérations de gestion de contenu comme outils pour les assistants IA.

Cette page couvre les détails du protocole : authentification, transport, spécifications des outils, découverte OAuth et gestion des erreurs.

Authentification

Le serveur MCP supporte trois méthodes d’authentification :

MéthodeFonctionnement
OAuth 2.1 Authorization Code + PKCEFlux standard pour les clients MCP. L’utilisateur approuve les scopes dans le navigateur.
Personal Access Token (PAT)Tokens ec_pat_* à longue durée de vie créés dans le panneau d’administration.
Device FlowFlux de type CLI où vous approuvez un code dans le navigateur. Utilisé par emdash login.

Les cookies de session (de l’UI d’administration) fonctionnent aussi mais ne sont pas pratiques pour les clients MCP externes.

Scopes

Les tokens ont une portée limitée pour restreindre les opérations qu’un client peut effectuer. Les scopes sont demandés lors de l’autorisation OAuth et appliqués à chaque appel d’outil. Sur la page de consentement du code d’autorisation, tous les scopes demandés sont sélectionnés par défaut ; l’utilisateur peut retirer des scopes avant approbation mais ne peut pas en ajouter que le client n’a pas demandés. L’octroi effectif est aussi restreint par les scopes enregistrés du client et le rôle de l’utilisateur, et EmDash rejette un octroi vide.

ScopeAccorde l’accès à
content:readLister, obtenir, comparer et rechercher du contenu. Lister les taxonomies, termes de taxonomie et menus.
content:writeCréer, mettre à jour, supprimer, publier, dépublier, planifier, déplanifier, dupliquer et restaurer du contenu. Accorde implicitement taxonomies:manage et menus:manage pour la rétrocompatibilité.
media:readLister et obtenir des éléments média.
media:writeEnregistrer (créer), mettre à jour et supprimer les métadonnées média.
schema:readLister les collections et obtenir les schémas de collection.
schema:writeCréer et supprimer des collections et des champs.
taxonomies:manageCréer, mettre à jour et supprimer des termes de taxonomie.
menus:manageCréer, mettre à jour et supprimer des menus de navigation et leurs éléments.
settings:readLire les paramètres du site.
settings:manageMettre à jour les paramètres du site.
mcp:toolsInvoquer des outils MCP explicitement activés de n’importe quel plugin.
mcp:tools:<pluginId>Invoquer des outils MCP explicitement activés d’un plugin.
adminAccès complet à toutes les opérations.

Le scope admin accorde l’accès aux opérations principales, mais pas l’accès MCP des plugins. Les outils de plugins nécessitent toujours mcp:tools ou le scope spécifique au plugin correspondant.

content:write accorde implicitement taxonomies:manage et menus:manage pour que les tokens émis avant la séparation de ces scopes continuent de fonctionner. Les nouveaux tokens devraient demander les scopes granulaires.

Exigences de rôle

En plus des scopes, certains outils nécessitent un rôle RBAC minimum. Les deux doivent être satisfaits — un token avec le bon scope échoue quand même si le rôle de l’utilisateur appelant est trop bas.

Les outils de plugins utilisent la permission déclarée par leur route sous-jacente. Ils sont absents de tools/list tant qu’un administrateur n’a pas activé la surface MCP de ce plugin. Les noms d’outils utilisent la forme déterministe <pluginId>__<localName>, et les invocations sont enregistrées dans le journal d’audit.

OpérationRôle minimum
Lecture de contenuSubscriber (10) pour les éléments publiés ; Contributor (20) pour les brouillons, planifiés, corbeille et révisions
Création de contenuContributor (20)
Éditer/supprimer le sienAuthor (30)
Publier du contenuAuthor (30) pour les siens ; Editor (40) pour agir sur ceux des autres
Lecture de schémaEditor (40)
Écriture de schémaAdmin (50)
Gestion des taxonomiesEditor (40)
Gestion des menusEditor (40)
Lecture des paramètresEditor (40)
Gestion des paramètresAdmin (50)
Upload média (media_upload)Contributor (20)
Enregistrement média (media_create)Author (30)
Réparation d’usage médiaAdmin (50)

Consultez le guide d’authentification pour les définitions de rôles.

Transport

Le serveur utilise le transport Streamable HTTP en mode sans état. Chaque requête est indépendante — il n’y a pas de sessions ni de connexions longue durée.

  • POST /_emdash/api/mcp — Envoyer des appels d’outils JSON-RPC
  • GET /_emdash/api/mcp — Retourne 405 (pas de SSE en mode sans état)
  • DELETE /_emdash/api/mcp — Retourne 405 (pas de session à fermer)

Les réponses suivent le format JSON-RPC 2.0. Les erreurs utilisent les codes d’erreur JSON-RPC standard, avec des codes spécifiques MCP pour les échecs de scope et permission.

Outils

Le serveur expose des outils dans huit domaines : contenu, schéma, média, recherche, taxonomies, menus, révisions et paramètres. Chaque outil retourne des résultats en contenu texte JSON, ou un message d’erreur avec isError: true en cas d’échec.

Outils de contenu

content_list

Liste les éléments de contenu d’une collection avec filtrage et pagination optionnels.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection (ex. posts, pages)
statusstringNonFiltre : draft, published ou scheduled
limitintegerNonMax. éléments à retourner (1-100, défaut 50)
cursorstringNonCurseur de pagination d’une réponse précédente
orderBystringNonChamp de tri (ex. created_at, updated_at)
orderstringNonDirection de tri : asc ou desc (défaut desc)
localestringNonFiltrer par locale (ex. en, fr). Pertinent uniquement avec i18n.

Scope : content:read | Lecture seule : Oui

content_get

Obtient un élément de contenu unique par ID ou slug. Retourne toutes les valeurs de champs, métadonnées et un token _rev pour la concurrence optimiste.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
idstringOuiID de l’élément (ULID) ou slug
localestringNonLocale pour la recherche par slug. Les IDs sont globalement uniques.

Scope : content:read | Lecture seule : Oui

content_create

Crée un nouvel élément de contenu. L’objet data doit contenir des valeurs de champs correspondant au schéma de la collection — utilisez schema_get_collection pour vérifier quels champs sont disponibles. Les éléments sont créés comme draft par défaut.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
dataobjectOuiValeurs de champs en paires clé-valeur
slugstringNonSlug URL (auto-généré du titre si omis)
statusstringNonStatut initial : draft ou published (défaut draft)
localestringNonLocale pour ce contenu (défaut : défaut du site)
translationOfstringNonID de l’élément dont c’est une traduction

Scope : content:write

content_update

Met à jour un élément de contenu existant. N’incluez que les champs à modifier — les champs non spécifiés restent inchangés.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
idstringOuiID de l’élément ou slug
dataobjectNonValeurs de champs à mettre à jour
slugstringNonNouveau slug URL
statusstringNonNouveau statut : draft ou published
_revstringNonToken de révision de content_get pour la détection de conflits

Scope : content:write

content_delete

Supprime un élément de contenu de manière réversible en le déplaçant vers la corbeille. Utilisez content_restore pour annuler, ou content_permanent_delete pour le supprimer définitivement.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
idstringOuiID de l’élément ou slug

Scope : content:write | Destructif : Oui

content_restore

Restaure un élément supprimé de manière réversible depuis la corbeille.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
idstringOuiID de l’élément ou slug

Scope : content:write

content_permanent_delete

Supprime définitivement et irréversiblement un élément de la corbeille. L’élément doit d’abord être dans la corbeille.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
idstringOuiID de l’élément ou slug

Scope : content:write | Destructif : Oui

content_publish

Publie un élément de contenu, le rendant visible sur le site. Crée une révision publiée à partir du brouillon actuel. Les modifications ultérieures créent un nouveau brouillon sans affecter la version en ligne jusqu’à re-publication.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
idstringOuiID de l’élément ou slug

Scope : content:write

content_unpublish

Remet un élément publié en statut brouillon. Il ne sera plus visible sur le site en ligne mais son contenu est préservé.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
idstringOuiID de l’élément ou slug

Scope : content:write

content_schedule

Planifie un élément de contenu pour publication future. Il sera automatiquement publié à la date/heure spécifiée.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
idstringOuiID de l’élément ou slug
scheduledAtstringOuiDate/heure ISO 8601 (ex. 2026-06-01T09:00:00Z)

Scope : content:write

content_unschedule

Annule une publication précédemment planifiée. L’élément garde son statut actuel ; seul le timestamp scheduledAt est effacé. Idempotent — appeler sur un élément non planifié est un no-op.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
idstringOuiID de l’élément ou slug

Scope : content:write

content_compare

Compare la version publiée (en ligne) d’un élément avec son brouillon actuel. Retourne les deux versions et un indicateur de changements.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
idstringOuiID de l’élément ou slug

Scope : content:read | Lecture seule : Oui

content_discard_draft

Abandonne le brouillon actuel et revient à la dernière version publiée. Ne fonctionne que sur des éléments publiés au moins une fois.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
idstringOuiID de l’élément ou slug

Scope : content:write | Destructif : Oui

content_list_trashed

Liste les éléments supprimés de manière réversible dans la corbeille d’une collection.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
limitintegerNonMax. éléments (1-100, défaut 50)
cursorstringNonCurseur de pagination

Scope : content:read | Lecture seule : Oui

content_duplicate

Crée une copie d’un élément existant. Le doublon est créé comme brouillon avec « (Copie) » ajouté au titre et un slug auto-généré.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
idstringOuiID ou slug de l’élément à dupliquer

Scope : content:write

content_translations

Obtient toutes les variantes de locale d’un élément de contenu. Retourne le groupe de traduction et un résumé de chaque version de locale. Pertinent uniquement quand i18n est activé.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
idstringOuiID de l’élément ou slug

Scope : content:read | Lecture seule : Oui

Outils de schéma

schema_list_collections

Liste toutes les collections de contenu définies dans le CMS.

Aucun paramètre.

Scope : schema:read | Rôle minimum : Editor | Lecture seule : Oui

schema_get_collection

Obtient des informations détaillées sur une collection y compris toutes les définitions de champs.

ParamètreTypeRequisDescription
slugstringOuiSlug de la collection (ex. posts)

Scope : schema:read | Rôle minimum : Editor | Lecture seule : Oui

schema_create_collection

Crée une nouvelle collection de contenu. Crée une table de base de données et une définition de schéma.

ParamètreTypeRequisDescription
slugstringOuiIdentifiant unique (/^[a-z][a-z0-9_]*$/)
labelstringOuiNom d’affichage (pluriel)
labelSingularstringNonNom d’affichage singulier
descriptionstringNonDescription de cette collection
iconstringNonNom d’icône pour l’UI d’admin
supportsstring[]NonFonctionnalités : drafts, revisions, preview, scheduling, search (défaut : ['drafts', 'revisions'])

Scope : schema:write | Rôle minimum : Admin

schema_delete_collection

Supprime une collection et sa table de base de données. Irréversible et supprime tout le contenu.

ParamètreTypeRequisDescription
slugstringOuiSlug de la collection à supprimer
forcebooleanNonForcer la suppression même si la collection a du contenu

Scope : schema:write | Rôle minimum : Admin | Destructif : Oui

schema_create_field

Ajoute un nouveau champ au schéma d’une collection.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
slugstringOuiIdentifiant du champ (/^[a-z][a-z0-9_]*$/)
labelstringOuiNom d’affichage
typestringOuiType de données (voir ci-dessous)
requiredbooleanNonSi le champ est obligatoire
uniquebooleanNonSi les valeurs doivent être uniques
defaultValueanyNonValeur par défaut pour les nouveaux éléments
validationobjectNonContraintes : min, max, minLength, maxLength, pattern, options
optionsobjectNonConfig widget : collection (pour les références), rows (pour textarea)
searchablebooleanNonInclure dans l’index de recherche plein texte
translatablebooleanNonSi ce champ est traduisible (défaut true)

Types de champs : string, text, number, integer, boolean, datetime, select, multiSelect, portableText, image, file, reference, json, slug.

Scope : schema:write | Rôle minimum : Admin

schema_delete_field

Supprime un champ d’une collection. Supprime la colonne et toutes les données. Irréversible.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
fieldSlugstringOuiSlug du champ à supprimer

Scope : schema:write | Rôle minimum : Admin | Destructif : Oui

Outils média

media_list

Liste les fichiers média uploadés avec filtrage optionnel par type MIME et pagination.

ParamètreTypeRequisDescription
mimeTypestringNonFiltrer par préfixe de type MIME (ex. image/, application/pdf)
limitintegerNonMax. éléments (1-100, défaut 50)
cursorstringNonCurseur de pagination

Scope : media:read | Lecture seule : Oui

media_upload

Upload un fichier média depuis des données encodées en base64 ou une URL externe et l’enregistre dans la bibliothèque de médias.

ParamètreTypeRequisDescription
filenamestringOuiNom de fichier avec extension (ex. cover.png)
base64stringUn des deux base64 / urlContenu du fichier encodé en base64
urlstringUn des deux base64 / urlURL http(s) publique pour récupérer le fichier
contentTypestringAvec base64Type MIME (ex. image/png)
altstringNonTexte alternatif pour l’accessibilité

Scope : media:write | Rôle minimum : Contributor

media_create

Enregistre un fichier média déjà uploadé dans le stockage.

ParamètreTypeRequisDescription
filenamestringOuiNom de fichier original
mimeTypestringOuiType MIME
storageKeystringOuiChemin/clé de stockage
sizeintegerNonTaille du fichier en octets
widthintegerNonLargeur de l’image en pixels
heightintegerNonHauteur de l’image en pixels
contentHashstringNonHash du contenu du fichier
blurhashstringNonBlurhash pour les placeholders d’image
dominantColorstringNonCouleur dominante hexadécimale

Scope : media:write | Rôle minimum : Author

media_get

Obtient les détails d’un fichier média par ID.

ParamètreTypeRequisDescription
idstringOuiID de l’élément média

Scope : media:read | Lecture seule : Oui

media_update

Met à jour les métadonnées d’un fichier média. Le fichier lui-même ne peut pas être changé.

ParamètreTypeRequisDescription
idstringOuiID de l’élément média
altstringNonTexte alternatif
captionstringNonLégende
widthintegerNonLargeur en pixels
heightintegerNonHauteur en pixels

Scope : media:write

media_delete

Supprime définitivement un fichier média.

ParamètreTypeRequisDescription
idstringOuiID de l’élément média

Scope : media:write | Destructif : Oui

media_usage_repair

Répare les index d’utilisation de médias dans le contenu pour une collection ou toutes les collections.

ParamètreTypeRequisDescription
scope"collection" | "all"OuiRéparer une collection ou toutes
collectionstringPour le scope collectionSlug de la collection

Scope : admin | Rôle minimum : Admin

Outil de recherche

Recherche plein texte dans les collections de contenu.

ParamètreTypeRequisDescription
querystringOuiTexte de recherche
collectionsstring[]NonLimiter à des slugs de collection spécifiques
localestringNonFiltrer par locale
limitintegerNonMax. résultats (1-50, défaut 20)

Scope : content:read | Lecture seule : Oui

Outils de taxonomie

taxonomy_list

Liste toutes les définitions de taxonomie.

Aucun paramètre.

Scope : content:read | Lecture seule : Oui

taxonomy_list_terms

Liste les termes d’une taxonomie avec pagination.

ParamètreTypeRequisDescription
taxonomystringOuiNom de la taxonomie
limitintegerNonMax. éléments (1-100, défaut 50)
cursorstringNonCurseur de pagination

Scope : content:read | Lecture seule : Oui

taxonomy_create_term

Crée un nouveau terme dans une taxonomie.

ParamètreTypeRequisDescription
taxonomystringOuiNom de la taxonomie
slugstringOuiIdentifiant URL-safe
labelstringOuiNom d’affichage
parentIdstringNonID du terme parent (pour les taxonomies hiérarchiques)
descriptionstringNonDescription du terme

Scope : taxonomies:manage | Rôle minimum : Editor

taxonomy_update_term

Met à jour un terme existant dans une taxonomie.

ParamètreTypeRequisDescription
taxonomystringOuiNom de la taxonomie
termSlugstringOuiSlug actuel du terme
slugstringNonNouveau slug
labelstringNonNouveau nom d’affichage
parentIdstring | nullNonNouvel ID parent ; null pour détacher
descriptionstringNonNouvelle description

Scope : taxonomies:manage | Rôle minimum : Editor

taxonomy_delete_term

Supprime définitivement un terme d’une taxonomie.

ParamètreTypeRequisDescription
taxonomystringOuiNom de la taxonomie
termSlugstringOuiSlug du terme à supprimer

Scope : taxonomies:manage | Rôle minimum : Editor | Destructif : Oui

Outils de menu

Liste les menus de navigation.

ParamètreTypeRequisDescription
localestringNonFiltrer par locale

Scope : content:read | Lecture seule : Oui

Obtient un menu par nom avec tous ses éléments dans l’ordre.

ParamètreTypeRequisDescription
namestringOuiNom du menu (ex. main, footer)
localestringNonLocale pour résoudre le menu

Scope : content:read | Lecture seule : Oui

Crée un nouveau menu de navigation.

ParamètreTypeRequisDescription
namestringOuiIdentifiant stable (/^[a-z][a-z0-9_]*$/)
labelstringOuiNom d’affichage pour l’admin
localestringNonLocale pour ce menu
translationOfstringNonID de menu existant pour cette variante de locale

Scope : menus:manage | Rôle minimum : Editor

Met à jour le label d’un menu.

ParamètreTypeRequisDescription
namestringOuiNom du menu à mettre à jour
labelstringOuiNouveau label d’affichage
localestringNonLocale du menu à mettre à jour

Scope : menus:manage | Rôle minimum : Editor

Supprime un menu et tous ses éléments. Irréversible.

ParamètreTypeRequisDescription
namestringOuiNom du menu à supprimer
localestringNonLocale du menu à supprimer

Scope : menus:manage | Rôle minimum : Editor | Destructif : Oui

Remplace la liste complète des éléments d’un menu en un seul appel. Atomique.

ParamètreTypeRequisDescription
namestringOuiNom du menu
localestringNonLocale du menu
itemsMenuItem[]OuiListe ordonnée d’éléments de menu

Chaque MenuItem a :

ChampTypeRequisDescription
labelstringOuiTexte d’affichage
typestringOuiUn de custom, page, post, taxonomy, collection
customUrlstringNonURL pour type: "custom"
referenceCollectionstringNonSlug de collection cible
referenceIdstringNonID de contenu/terme cible
titleAttrstringNonAttribut HTML title
targetstringNonAttribut HTML target
cssClassesstringNonClasses CSS séparées par des espaces
parentIndexintegerNonIndex du parent dans le tableau

Scope : menus:manage | Rôle minimum : Editor

Outils de révision

revision_list

Liste l’historique des révisions d’un élément, plus récente en premier.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
idstringOuiID de l’élément ou slug
limitintegerNonMax. révisions (1-50, défaut 20)

Scope : content:read | Lecture seule : Oui

revision_restore

Restaure un élément à une révision précédente. N’est pas automatiquement publié — utilisez content_publish ensuite si nécessaire.

ParamètreTypeRequisDescription
revisionIdstringOuiID de la révision à restaurer

Scope : content:write

Outils de paramètres

Paramètres du site — titre, slogan, logo, favicon, URL canonique, taille de page par défaut, formatage de date et heure, identifiants sociaux et valeurs SEO par défaut.

settings_get

Obtient tous les paramètres du site.

Aucun paramètre.

Scope : settings:read | Rôle minimum : Editor | Lecture seule : Oui

settings_update

Met à jour un ou plusieurs paramètres du site. Mise à jour partielle.

ParamètreTypeRequisDescription
titlestringNonTitre du site
taglinestringNonDescription courte
logoMediaRefNonRéférence média du logo ({ mediaId, alt? })
faviconMediaRefNonRéférence média du favicon
urlstringNonURL canonique du site. Chaîne vide pour effacer.
postsPerPageintegerNonTaille de page par défaut (1-100)
dateFormatstringNonFormat de date
timezonestringNonIdentifiant de fuseau horaire IANA
socialobjectNonIdentifiants sociaux — twitter, github, facebook, instagram, linkedin, youtube
seoobjectNonValeurs SEO par défaut

L’objet seo accepte :

ChampTypeDescription
titleSeparatorstringSéparateur entre titre de page et titre du site
defaultOgImageMediaRefImage Open Graph par défaut
robotsTxtstringCorps personnalisé de robots.txt
googleVerificationstringToken de vérification Google Search Console
bingVerificationstringToken de vérification Bing Webmaster Tools

Scope : settings:manage | Rôle minimum : Admin

Découverte OAuth

La plupart des clients MCP gèrent cela automatiquement ; cette section est pour construire un client MCP directement contre EmDash.

Métadonnées de la ressource protégée

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",
    "taxonomies:manage", "menus:manage",
    "settings:read", "settings:manage",
    "admin"
  ],
  "bearer_methods_supported": ["header"]
}

Métadonnées du serveur d’autorisation

GET /.well-known/oauth-authorization-server/_emdash
{
  "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"
}

Quand une requête non authentifiée atteint le point de terminaison MCP :

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

Gestion des erreurs

Les erreurs d’outils sont retournées comme contenu texte avec isError: true. Le message est préfixé d’un [CODE] stable :

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

Les erreurs de scope et de permission utilisent la même enveloppe :

{
  "content": [
    { "type": "text", "text": "[INSUFFICIENT_SCOPE] Insufficient scope: requires content:write" }
  ],
  "isError": true,
  "_meta": { "code": "INSUFFICIENT_SCOPE" }
}

Les erreurs au niveau du transport retournent le code d’erreur JSON-RPC -32603 (Erreur interne) sans divulguer les détails d’implémentation.