Aller au contenu

Référence du serveur MCP

EmDash inclut un serveur Model Context Protocol (MCP) intégré à l’adresse /_emdash/api/mcp qui expose les opérations de gestion de contenu en tant qu’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.

Le serveur MCP prend en charge 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)Jetons de longue durée ec_pat_* 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 (depuis l’interface d’administration) fonctionnent également mais ne sont pas pratiques pour les clients MCP externes.

Les jetons sont limités par des scopes 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.

ScopeAccorde l’accès à
content:readLister, obtenir, comparer et rechercher du contenu. Lister les termes de taxonomie et les menus.
content:writeCréer, mettre à jour, supprimer, publier, dépublier, planifier, dupliquer et restaurer du contenu. Créer des termes de taxonomie.
media:readLister et obtenir les éléments multimédias.
media:writeMettre à jour et supprimer les métadonnées multimédias.
schema:readLister les collections et obtenir les schémas de collection.
schema:writeCréer et supprimer des collections et des champs.
adminAccès complet à toutes les opérations.

Le scope admin accorde l’accès à tout. L’authentification basée sur les sessions (sans jeton) a également un accès complet basé sur le rôle de l’utilisateur.

En plus des scopes, certains outils nécessitent un rôle RBAC minimum :

OpérationRôle minimum
Opérations sur le contenuAucun minimum (les scopes contrôlent l’accès)
Lecture du schémaÉditeur (40)
Écriture du schémaAdministrateur (50)

Voir le guide d’authentification pour les définitions des rôles.

Le serveur utilise le transport HTTP Streamable en mode sans état. Chaque requête est indépendante — il n’y a pas de sessions ni de connexions de 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 standard JSON-RPC, avec des codes spécifiques MCP pour les échecs de scope et de permissions.

Le serveur expose 33 outils répartis en sept domaines. Chaque outil retourne les résultats sous forme de contenu texte JSON, ou un message d’erreur avec isError: true en cas d’échec.

Lister 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
limitintegerNonNombre maximum d’éléments à retourner (1-100, par défaut 50)
cursorstringNonCurseur de pagination d’une réponse précédente
orderBystringNonChamp de tri (ex. created_at, updated_at)
orderstringNonDirection du tri : asc ou desc (par défaut desc)
localestringNonFiltrer par locale (ex. en, fr). Pertinent uniquement avec i18n.

Scope : content:read | Lecture seule : Oui

Obtenir un seul élément de contenu par ID ou slug. Retourne toutes les valeurs de champ, les métadonnées et un jeton _rev pour le contrôle de concurrence optimiste.

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

Scope : content:read | Lecture seule : Oui

Créer un nouvel élément de contenu. L’objet data doit contenir les valeurs de champ correspondant au schéma de la collection — utilisez schema_get_collection pour vérifier les champs disponibles. Les éléments sont créés en tant que draft par défaut.

ParamètreTypeRequisDescription
collectionstringOuiSlug de la collection
dataobjectOuiValeurs de champ sous forme de paires clé-valeur
slugstringNonSlug d’URL (généré automatiquement à partir du titre si omis)
statusstringNonStatut initial : draft ou published (par défaut draft)
localestringNonLocale pour ce contenu (par défaut la locale par défaut du site)
translationOfstringNonID de l’élément dont ceci est une traduction

Scope : content:write

Mettre à jour un élément de contenu existant. Incluez uniquement les champs que vous souhaitez modifier — les champs non spécifiés restent inchangés.

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

Scope : content:write

Supprimer de manière réversible un élément de contenu 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 de contenu ou slug

Scope : content:write | Destructif : Oui

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

ParamètreTypeRequisDescription
collectionstringOuiIdentifiant de la collection
idstringOuiID ou identifiant de l’élément de contenu

Portée : content:write

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

ParamètreTypeRequisDescription
collectionstringOuiIdentifiant de la collection
idstringOuiID ou identifiant de l’élément de contenu

Portée : content:write | Destructif : Oui

Publier 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’à une nouvelle publication.

ParamètreTypeRequisDescription
collectionstringOuiIdentifiant de la collection
idstringOuiID ou identifiant de l’élément de contenu

Portée : content:write

Revenir à l’état de brouillon pour un élément publié. Il ne sera plus visible sur le site en ligne mais son contenu est conservé.

ParamètreTypeRequisDescription
collectionstringOuiIdentifiant de la collection
idstringOuiID ou identifiant de l’élément de contenu

Portée : content:write

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

ParamètreTypeRequisDescription
collectionstringOuiIdentifiant de la collection
idstringOuiID ou identifiant de l’élément de contenu
scheduledAtstringOuiDate et heure au format ISO 8601 (ex. 2026-06-01T09:00:00Z)

Portée : content:write

Comparer la version publiée (en ligne) d’un élément de contenu avec son brouillon actuel. Retourne les deux versions et un indicateur signalant s’il y a des différences.

ParamètreTypeRequisDescription
collectionstringOuiIdentifiant de la collection
idstringOuiID ou identifiant de l’élément de contenu

Portée : content:read | Lecture seule : Oui

Supprimer le brouillon actuel et revenir à la dernière version publiée. Fonctionne uniquement sur les éléments qui ont été publiés au moins une fois.

ParamètreTypeRequisDescription
collectionstringOuiIdentifiant de la collection
idstringOuiID ou identifiant de l’élément de contenu

Portée : content:write | Destructif : Oui

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

ParamètreTypeRequisDescription
collectionstringOuiIdentifiant de la collection
limitintegerNonNombre maximum d’éléments (1-100, par défaut 50)
cursorstringNonCurseur de pagination

Portée : content:read | Lecture seule : Oui

Créer une copie d’un élément de contenu existant. Le duplicata est créé en tant que brouillon avec “(Copie)” ajouté au titre et un identifiant généré automatiquement.

ParamètreTypeRequisDescription
collectionstringOuiIdentifiant de la collection
idstringOuiID ou identifiant de l’élément de contenu à dupliquer

Portée : content:write

Obtenir toutes les variantes linguistiques d’un élément de contenu. Retourne le groupe de traduction et un résumé de chaque version linguistique. Pertinent uniquement lorsque l’i18n est activé.

ParamètreTypeRequisDescription
collectionstringOuiIdentifiant de la collection
idstringOuiID ou identifiant de l’élément de contenu

Portée : content:read | Lecture seule : Oui

Lister toutes les collections de contenu définies dans le CMS. Retourne l’identifiant, le libellé, les fonctionnalités prises en charge et les horodatages.

Aucun paramètre.

Portée : schema:read | Rôle minimum : Éditeur | Lecture seule : Oui

Obtenir des informations détaillées sur une collection, y compris toutes les définitions de champs. Les champs décrivent le modèle de contenu : nom, type, contraintes et règles de validation. Utilisez ceci pour comprendre ce que content_create et content_update attendent.

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

Portée : schema:read | Rôle minimum : Éditeur | Lecture seule : Oui

Créer une nouvelle collection de contenu. Cela crée une table de base de données et une définition de schéma. L’identifiant doit être alphanumérique en minuscules avec des tirets bas, commençant par une lettre.

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

Portée : schema:write | Rôle minimum : Administrateur

Supprimer une collection et sa table de base de données. Cette action est irréversible et supprime tout le contenu de la collection.

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

Portée : schema:write | Rôle minimum : Administrateur | Destructif : Oui

Ajouter un nouveau champ au schéma d’une collection. Cela ajoute une colonne à la table de la base de données.

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

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

Pour les types select et multiSelect, fournissez les valeurs autorisées dans validation.options.

Portée : schema:write | Rôle minimum : Admin

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

ParamètreTypeRequisDescription
collectionstringOuiIdentifiant de la collection
fieldSlugstringOuiIdentifiant du champ à supprimer

Portée : schema:write | Rôle minimum : Admin | Destructif : Oui

Liste les fichiers multimédias téléchargés avec filtrage optionnel par type MIME et pagination.

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

Portée : media:read | Lecture seule : Oui

Obtient les détails d’un seul fichier multimédia par ID. Retourne les métadonnées incluant le nom de fichier, le type MIME, la taille, les dimensions, le texte alternatif et l’URL.

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

Portée : media:read | Lecture seule : Oui

Met à jour les métadonnées d’un fichier multimédia téléchargé. Le fichier lui-même ne peut pas être modifié.

ParamètreTypeRequisDescription
idstringOuiID de l’élément multimédia
altstringNonTexte alternatif pour l’accessibilité
captionstringNonTexte de légende
widthintegerNonLargeur de l’image en pixels
heightintegerNonHauteur de l’image en pixels

Portée : media:write

Supprime définitivement un fichier multimédia. Supprime l’enregistrement de la base de données et le fichier du stockage. Les contenus référençant ce média auront des références cassées.

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

Portée : media:write | Destructif : Oui

Recherche en texte intégral dans les collections de contenu. Les collections doivent avoir search dans leur liste supports et les champs doivent être marqués comme searchable.

ParamètreTypeRequisDescription
querystringOuiTexte de la requête de recherche
collectionsstring[]NonLimiter la recherche à des identifiants de collections spécifiques
localestringNonFiltrer les résultats par langue
limitintegerNonNombre maximum de résultats (1-50, par défaut 20)

Portée : content:read | Lecture seule : Oui

Liste toutes les définitions de taxonomie (ex. catégories, étiquettes). Retourne le nom, le libellé, l’indicateur hiérarchique et les collections associées.

Aucun paramètre.

Portée : content:read | Lecture seule : Oui

Liste les termes d’une taxonomie avec pagination.

ParamètreTypeRequisDescription
taxonomystringOuiNom de la taxonomie (ex. categories, tags)
limitintegerNonNombre maximum d’éléments (1-100, par défaut 50)
cursorstringNonCurseur de pagination

Portée : content:read | Lecture seule : Oui

Crée un nouveau terme dans une taxonomie. Pour les taxonomies hiérarchiques, spécifiez un parentId pour créer un terme enfant.

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

Portée : content:write

Liste tous les menus de navigation. Retourne le nom, le libellé et les horodatages.

Aucun paramètre.

Portée : content:read | Lecture seule : Oui

Obtient un menu par son nom, incluant tous ses éléments dans l’ordre. Les éléments ont un libellé, une URL, un type et un parent optionnel pour l’imbrication.

ParamètreTypeRequisDescription
namestringOuiNom du menu (ex. main, footer)

Portée : content:read | Lecture seule : Oui

Liste l’historique des révisions pour un élément de contenu, du plus récent au plus ancien. Nécessite que la collection prenne en charge revisions.

ParamètreTypeRequisDescription
collectionstringOuiIdentifiant de la collection
idstringOuiID ou identifiant de l’élément de contenu
limitintegerNonNombre maximum de révisions (1-50, par défaut 20)

Portée : content:read | Lecture seule : Oui

Restaure un élément de contenu à une révision précédente. Remplace le brouillon actuel par les données de la révision spécifiée. Non publié automatiquement — utilisez content_publish par la suite si nécessaire.

ParamètreTypeRequisDescription
revisionIdstringOuiID de la révision à restaurer

Portée : content:write

Les clients MCP qui prennent en charge OAuth 2.1 peuvent découvrir automatiquement comment s’authentifier. Le serveur publie deux documents de métadonnées :

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"
}

Lorsqu’une requête non authentifiée atteint le point de terminaison MCP, le serveur renvoie :

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

Cela déclenche le flux de découverte standard du client MCP.

Les erreurs d’outil sont renvoyées sous forme de contenu texte avec isError: true :

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

Les erreurs de portée et de permission génèrent des erreurs de protocole MCP :

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

Les erreurs au niveau du transport (mauvaise configuration du serveur, exceptions non gérées) renvoient le code d’erreur JSON-RPC -32603 (Erreur interne) sans divulguer de détails d’implémentation.