Referencia del servidor MCP

En esta página

EmDash incluye un servidor Model Context Protocol (MCP) integrado en /_emdash/api/mcp que expone operaciones de gestión de contenido como herramientas para asistentes de IA.

Esta página cubre los detalles del protocolo: autenticación, transporte, especificaciones de herramientas, descubrimiento OAuth y manejo de errores.

Autenticación

El servidor MCP soporta tres métodos de autenticación:

MétodoCómo funciona
OAuth 2.1 Authorization Code + PKCEFlujo estándar para clientes MCP. El usuario aprueba scopes en el navegador.
Personal Access Token (PAT)Tokens ec_pat_* de larga duración creados en el panel de administración.
Device FlowFlujo tipo CLI donde apruebas un código en el navegador. Usado por emdash login.

Las cookies de sesión (de la UI de administración) también funcionan pero no son prácticas para clientes MCP externos.

Scopes

Los tokens tienen alcance limitado para restringir qué operaciones puede realizar un cliente. Los scopes se solicitan durante la autorización OAuth y se aplican en cada llamada a herramienta. En la página de consentimiento del código de autorización, todos los scopes solicitados están seleccionados por defecto; el usuario puede quitar scopes antes de aprobar pero no puede añadir scopes que el cliente no solicitó. La concesión efectiva también está restringida por los scopes registrados del cliente y el rol del usuario, y EmDash rechaza una concesión vacía.

ScopeConcede acceso a
content:readListar, obtener, comparar y buscar contenido. Listar taxonomías, términos de taxonomía y menús.
content:writeCrear, actualizar, eliminar, publicar, despublicar, programar, desprogramar, duplicar y restaurar contenido. Concede implícitamente taxonomies:manage y menus:manage para compatibilidad retroactiva con tokens emitidos antes de que existieran esos scopes.
media:readListar y obtener elementos multimedia.
media:writeRegistrar (crear), actualizar y eliminar metadatos multimedia.
schema:readListar colecciones y obtener esquemas de colección.
schema:writeCrear y eliminar colecciones y campos.
taxonomies:manageCrear, actualizar y eliminar términos de taxonomía.
menus:manageCrear, actualizar y eliminar menús de navegación y sus elementos.
settings:readLeer configuraciones del sitio.
settings:manageActualizar configuraciones del sitio.
mcp:toolsInvocar herramientas MCP explícitamente habilitadas de cualquier plugin.
mcp:tools:<pluginId>Invocar herramientas MCP explícitamente habilitadas de un plugin.
adminAcceso completo a todas las operaciones.

El scope admin concede acceso a operaciones principales, pero no concede acceso MCP de plugins. Las herramientas de plugins siempre requieren mcp:tools o el scope específico del plugin correspondiente. La autenticación basada en sesión tiene acceso basado en el rol del usuario y la habilitación explícita del admin del plugin.

content:write concede implícitamente taxonomies:manage y menus:manage para que los tokens de acceso personal emitidos antes de la separación de esos scopes sigan funcionando sin re-emisión. Los nuevos tokens deberían solicitar los scopes granulares.

Requisitos de rol

Además de los scopes, algunas herramientas requieren un rol RBAC mínimo. Ambos deben cumplirse — un token con el scope correcto aún falla si el rol del usuario llamante es demasiado bajo.

Las herramientas de plugins usan el permiso declarado por su ruta subyacente. Están ausentes de tools/list hasta que un administrador habilite la superficie MCP de ese plugin. Los nombres de herramientas usan la forma determinista <pluginId>__<localName>, y las invocaciones se registran en el log de auditoría con procedencia de plugin, herramienta, ruta y actor.

OperaciónRol mínimo
Lectura de contenidoSubscriber (10) para elementos publicados; Contributor (20) para borradores, programados, papelera y revisiones
Creación de contenidoContributor (20)
Editar/eliminar propioAuthor (30)
Publicar contenidoAuthor (30) para propios; Editor (40) para actuar sobre elementos de otros
Lectura de esquemaEditor (40)
Escritura de esquemaAdmin (50)
Gestión de taxonomíasEditor (40)
Gestión de menúsEditor (40)
Lectura de configuraciónEditor (40)
Gestión de configuraciónAdmin (50)
Subir multimedia (media_upload)Contributor (20)
Registrar multimedia (media_create)Author (30)
Reparación de uso multimediaAdmin (50)

Consulta la guía de autenticación para definiciones de roles.

Transporte

El servidor usa el transporte Streamable HTTP en modo sin estado. Cada solicitud es independiente — no hay sesiones ni conexiones de larga duración.

  • POST /_emdash/api/mcp — Enviar llamadas de herramienta JSON-RPC
  • GET /_emdash/api/mcp — Devuelve 405 (sin SSE en modo sin estado)
  • DELETE /_emdash/api/mcp — Devuelve 405 (sin sesión que cerrar)

Las respuestas siguen el formato JSON-RPC 2.0. Los errores usan códigos de error JSON-RPC estándar, con códigos específicos de MCP para fallos de scope y permisos.

Herramientas

El servidor expone herramientas en ocho dominios: contenido, esquema, multimedia, búsqueda, taxonomías, menús, revisiones y configuración. Cada herramienta devuelve resultados como contenido de texto JSON, o un mensaje de error con isError: true en caso de fallo.

Herramientas de contenido

content_list

Lista elementos de contenido en una colección con filtrado y paginación opcionales.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección (ej. posts, pages)
statusstringNoFiltro: draft, published o scheduled
limitintegerNoMáx. elementos a devolver (1-100, defecto 50)
cursorstringNoCursor de paginación de una respuesta anterior
orderBystringNoCampo para ordenar (ej. created_at, updated_at)
orderstringNoDirección de orden: asc o desc (defecto desc)
localestringNoFiltrar por locale (ej. en, fr). Solo relevante con i18n.

Scope: content:read | Solo lectura:

content_get

Obtiene un elemento de contenido único por ID o slug. Devuelve todos los valores de campo, metadatos y un token _rev para concurrencia optimista.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
idstringID del elemento (ULID) o slug
localestringNoLocale para búsqueda por slug. Los IDs son globalmente únicos.

Scope: content:read | Solo lectura:

content_create

Crea un nuevo elemento de contenido. El objeto data debe contener valores de campo que coincidan con el esquema de la colección — usa schema_get_collection para verificar qué campos están disponibles. Los elementos se crean como draft por defecto.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
dataobjectValores de campo como pares clave-valor
slugstringNoSlug URL (auto-generado del título si se omite)
statusstringNoEstado inicial: draft o published (defecto draft)
localestringNoLocale para este contenido (defecto: predeterminado del sitio)
translationOfstringNoID del elemento del que este es una traducción

Scope: content:write

content_update

Actualiza un elemento de contenido existente. Solo incluye los campos que quieres cambiar — los campos no especificados quedan sin cambios.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
idstringID del elemento o slug
dataobjectNoValores de campo a actualizar
slugstringNoNuevo slug URL
statusstringNoNuevo estado: draft o published
_revstringNoToken de revisión de content_get para detección de conflictos

Scope: content:write

content_delete

Elimina suavemente un elemento de contenido moviéndolo a la papelera. Usa content_restore para deshacer o content_permanent_delete para eliminarlo permanentemente.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
idstringID del elemento o slug

Scope: content:write | Destructivo:

content_restore

Restaura un elemento de contenido eliminado suavemente desde la papelera.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
idstringID del elemento o slug

Scope: content:write

content_permanent_delete

Elimina permanente e irreversiblemente un elemento de la papelera. El elemento debe estar en la papelera primero.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
idstringID del elemento o slug

Scope: content:write | Destructivo:

content_publish

Publica un elemento de contenido, haciéndolo visible en el sitio. Crea una revisión publicada del borrador actual. Ediciones posteriores crean un nuevo borrador sin afectar la versión en vivo hasta que se re-publique.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
idstringID del elemento o slug

Scope: content:write

content_unpublish

Revierte un elemento publicado a estado borrador. Ya no será visible en el sitio en vivo pero su contenido se preserva.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
idstringID del elemento o slug

Scope: content:write

content_schedule

Programa un elemento de contenido para publicación futura. Se publicará automáticamente en la fecha/hora especificada.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
idstringID del elemento o slug
scheduledAtstringFecha/hora ISO 8601 (ej. 2026-06-01T09:00:00Z)

Scope: content:write

content_unschedule

Cancela una publicación programada previamente. El elemento mantiene su estado actual; solo se limpia la marca de tiempo scheduledAt. Idempotente — llamar sobre un elemento no programado es una no-op.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
idstringID del elemento o slug

Scope: content:write

content_compare

Compara la versión publicada (en vivo) de un elemento de contenido con su borrador actual. Devuelve ambas versiones y un indicador de si hay cambios.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
idstringID del elemento o slug

Scope: content:read | Solo lectura:

content_discard_draft

Descarta el borrador actual y revierte a la última versión publicada. Solo funciona en elementos que han sido publicados al menos una vez.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
idstringID del elemento o slug

Scope: content:write | Destructivo:

content_list_trashed

Lista elementos de contenido eliminados suavemente en la papelera de una colección.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
limitintegerNoMáx. elementos (1-100, defecto 50)
cursorstringNoCursor de paginación

Scope: content:read | Solo lectura:

content_duplicate

Crea una copia de un elemento de contenido existente. El duplicado se crea como borrador con “(Copia)” añadido al título y un slug auto-generado.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
idstringID o slug del elemento a duplicar

Scope: content:write

content_translations

Obtiene todas las variantes de locale de un elemento de contenido. Devuelve el grupo de traducción y un resumen de cada versión de locale. Solo relevante cuando i18n está habilitado.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
idstringID del elemento o slug

Scope: content:read | Solo lectura:

Herramientas de esquema

schema_list_collections

Lista todas las colecciones de contenido definidas en el CMS. Devuelve slug, etiqueta, características soportadas y marcas de tiempo.

Sin parámetros.

Scope: schema:read | Rol mínimo: Editor | Solo lectura:

schema_get_collection

Obtiene información detallada sobre una colección incluyendo todas las definiciones de campo. Los campos describen el modelo de datos: nombre, tipo, restricciones y reglas de validación. Usa esto para entender qué esperan content_create y content_update.

ParámetroTipoRequeridoDescripción
slugstringSlug de la colección (ej. posts)

Scope: schema:read | Rol mínimo: Editor | Solo lectura:

schema_create_collection

Crea una nueva colección de contenido. Esto crea una tabla de base de datos y definición de esquema. El slug debe ser alfanumérico en minúsculas con guiones bajos, comenzando con una letra.

ParámetroTipoRequeridoDescripción
slugstringIdentificador único (/^[a-z][a-z0-9_]*$/)
labelstringNombre para mostrar (plural, ej. “Artículos del Blog”)
labelSingularstringNoNombre singular
descriptionstringNoDescripción de esta colección
iconstringNoNombre de icono para la UI de admin
supportsstring[]NoCaracterísticas: drafts, revisions, preview, scheduling, search (defecto: ['drafts', 'revisions'])

Scope: schema:write | Rol mínimo: Admin

schema_delete_collection

Elimina una colección y su tabla de base de datos. Esto es irreversible y elimina todo el contenido de la colección.

ParámetroTipoRequeridoDescripción
slugstringSlug de la colección a eliminar
forcebooleanNoForzar eliminación incluso si la colección tiene contenido

Scope: schema:write | Rol mínimo: Admin | Destructivo:

schema_create_field

Añade un nuevo campo al esquema de una colección. Esto añade una columna a la tabla de base de datos.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
slugstringIdentificador del campo (/^[a-z][a-z0-9_]*$/)
labelstringNombre para mostrar
typestringTipo de datos (ver abajo)
requiredbooleanNoSi el campo es obligatorio
uniquebooleanNoSi los valores deben ser únicos
defaultValueanyNoValor por defecto para nuevos elementos
validationobjectNoRestricciones: min, max, minLength, maxLength, pattern, options
optionsobjectNoConfig del widget: collection (para referencias), rows (para textarea)
searchablebooleanNoIncluir en índice de búsqueda de texto completo
translatablebooleanNoSi este campo es traducible (defecto true)

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

Para tipos select y multiSelect, proporciona valores permitidos en validation.options.

Scope: schema:write | Rol mínimo: Admin

schema_delete_field

Elimina un campo de una colección. Esto elimina la columna y todos los datos de ese campo. Irreversible.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
fieldSlugstringSlug del campo a eliminar

Scope: schema:write | Rol mínimo: Admin | Destructivo:

Herramientas de multimedia

media_list

Lista archivos multimedia subidos con filtrado opcional por tipo MIME y paginación.

ParámetroTipoRequeridoDescripción
mimeTypestringNoFiltrar por prefijo de tipo MIME (ej. image/, application/pdf)
limitintegerNoMáx. elementos (1-100, defecto 50)
cursorstringNoCursor de paginación

Scope: media:read | Solo lectura:

media_upload

Sube un archivo multimedia desde datos codificados en base64 o una URL externa y lo registra en la biblioteca de medios. Devuelve el elemento multimedia con id, storageKey y url — listo para referenciar desde campos de contenido (ej. featured_image) vía content_create / content_update.

Las subidas se deduplican por hash de contenido: re-subir bytes idénticos devuelve el elemento existente con deduplicated: true. Las subidas de imágenes se enriquecen automáticamente con dimensiones, un placeholder blurhash y el color dominante.

ParámetroTipoRequeridoDescripción
filenamestringNombre de archivo incluyendo extensión (ej. cover.png)
base64stringUno de base64 / urlContenido del archivo codificado en base64
urlstringUno de base64 / urlURL http(s) pública para descargar el archivo
contentTypestringCon base64Tipo MIME (ej. image/png). Con url se usa el header Content-Type de la respuesta.
altstringNoTexto alternativo para accesibilidad

Scope: media:write | Rol mínimo: Contributor

media_create

Registra un archivo multimedia que ya ha sido subido al almacenamiento. El llamante es responsable de colocar el archivo en storageKey. Esta herramienta persiste el registro de metadatos para que el archivo sea descubrible vía media_list / media_get y pueda ser referenciado por contenido.

ParámetroTipoRequeridoDescripción
filenamestringNombre de archivo original (ej. logo.png)
mimeTypestringTipo MIME (ej. image/png)
storageKeystringRuta/clave de almacenamiento donde se subió el archivo
sizeintegerNoTamaño del archivo en bytes
widthintegerNoAncho de imagen en píxeles
heightintegerNoAlto de imagen en píxeles
contentHashstringNoHash del contenido del archivo (para deduplicación)
blurhashstringNoBlurhash para placeholders de imagen
dominantColorstringNoColor hexadecimal del color dominante de la imagen

Scope: media:write | Rol mínimo: Author

media_get

Obtiene detalles de un archivo multimedia individual por ID. Devuelve metadatos incluyendo nombre de archivo, tipo MIME, tamaño, dimensiones, texto alternativo y URL.

ParámetroTipoRequeridoDescripción
idstringID del elemento multimedia

Scope: media:read | Solo lectura:

media_update

Actualiza metadatos de un archivo multimedia subido. El archivo en sí no puede ser cambiado.

ParámetroTipoRequeridoDescripción
idstringID del elemento multimedia
altstringNoTexto alternativo para accesibilidad
captionstringNoTexto de leyenda
widthintegerNoAncho de imagen en píxeles
heightintegerNoAlto de imagen en píxeles

Scope: media:write

media_delete

Elimina permanentemente un archivo multimedia. Elimina el registro de base de datos y el archivo del almacenamiento. El contenido que referencia este medio tendrá referencias rotas.

ParámetroTipoRequeridoDescripción
idstringID del elemento multimedia

Scope: media:write | Destructivo:

media_usage_repair

Repara índices de uso de medios en contenido para una colección o todas las colecciones. La reparación se ejecuta sincrónicamente y puede ser lenta o costosa en sitios grandes; prefiere el alcance de colección cuando sea posible.

ParámetroTipoRequeridoDescripción
scope"collection" | "all"Si reparar una colección o todas
collectionstringPara alcance de colecciónSlug de la colección; omitir cuando scope es all

El resultado tiene un status estructurado de complete, partial, failed o stale, más conteos agregados y por colección. Los cuatro estados son resultados exitosos de herramienta MCP, por lo que los llamantes deben inspeccionar status en lugar de confiar en isError. Errores de autenticación, validación o reparación inesperados devuelven isError: true.

Scope: admin | Rol mínimo: Admin

Herramienta de búsqueda

Búsqueda de texto completo a través de colecciones de contenido. Las colecciones deben tener search en su lista supports y los campos deben estar marcados como searchable.

ParámetroTipoRequeridoDescripción
querystringTexto de búsqueda
collectionsstring[]NoLimitar búsqueda a slugs de colección específicos
localestringNoFiltrar resultados por locale
limitintegerNoMáx. resultados (1-50, defecto 20)

Scope: content:read | Solo lectura:

Herramientas de taxonomía

taxonomy_list

Lista todas las definiciones de taxonomía (ej. categorías, etiquetas). Devuelve nombre, etiqueta, si es jerárquica y colecciones asociadas.

Sin parámetros.

Scope: content:read | Solo lectura:

taxonomy_list_terms

Lista términos en una taxonomía con paginación.

ParámetroTipoRequeridoDescripción
taxonomystringNombre de taxonomía (ej. categories, tags)
limitintegerNoMáx. elementos (1-100, defecto 50)
cursorstringNoCursor de paginación

Scope: content:read | Solo lectura:

taxonomy_create_term

Crea un nuevo término en una taxonomía. Para taxonomías jerárquicas, especifica un parentId para crear un término hijo. La cadena de ancestros del padre no debe exceder 100 niveles.

ParámetroTipoRequeridoDescripción
taxonomystringNombre de taxonomía
slugstringIdentificador seguro para URL
labelstringNombre para mostrar
parentIdstringNoID del término padre (para taxonomías jerárquicas)
descriptionstringNoDescripción del término

Scope: taxonomies:manage | Rol mínimo: Editor

taxonomy_update_term

Actualiza un término existente en una taxonomía. Cualquier campo puede omitirse para dejarlo sin cambios. Renombrar un slug no debe colisionar con otro término en la misma taxonomía. Establece parentId a null para desvincularse de un padre. El nuevo padre debe existir, pertenecer a la misma taxonomía y no introducir un ciclo.

ParámetroTipoRequeridoDescripción
taxonomystringNombre de taxonomía
termSlugstringSlug actual del término a actualizar
slugstringNoNuevo slug (debe ser único en la taxonomía)
labelstringNoNuevo nombre para mostrar
parentIdstring | nullNoNuevo ID del término padre; null para desvincular
descriptionstringNoNueva descripción

Scope: taxonomies:manage | Rol mínimo: Editor

taxonomy_delete_term

Elimina permanentemente un término de una taxonomía. Todo contenido etiquetado con el término pierde la asociación. No puede eliminar un término que tiene hijos — elimina los hijos primero.

ParámetroTipoRequeridoDescripción
taxonomystringNombre de taxonomía
termSlugstringSlug del término a eliminar

Scope: taxonomies:manage | Rol mínimo: Editor | Destructivo:

Herramientas de menú

Lista menús de navegación. Los menús son por locale: pasa locale para devolver solo las filas de un locale, u omítelo para listar todas las variantes de locale.

ParámetroTipoRequeridoDescripción
localestringNoFiltrar por locale (omitir para todas las variantes)

Scope: content:read | Solo lectura:

Obtiene un menú por nombre incluyendo todos sus elementos en orden. Los elementos tienen etiqueta, URL, tipo y padre opcional para anidamiento. Cuando el mismo nombre de menú existe en múltiples locales, pasa locale para resolver la traducción deseada.

ParámetroTipoRequeridoDescripción
namestringNombre del menú (ej. main, footer)
localestringNoLocale para resolver el menú

Scope: content:read | Solo lectura:

Crea un nuevo menú de navegación. El name es el identificador estable usado por las plantillas del sitio; label es el nombre legible mostrado en el admin. Los menús son por locale, así que pasa locale cuando el mismo nombre de menú existe en múltiples traducciones. Añade elementos después con menu_set_items. Si se establece translationOf, también debe establecerse locale.

ParámetroTipoRequeridoDescripción
namestringIdentificador estable (/^[a-z][a-z0-9_]*$/)
labelstringNombre para mostrar en el admin
localestringNoLocale para este menú (ej. fr-fr)
translationOfstringNoID de menú existente del que crear esta variante de locale

Scope: menus:manage | Rol mínimo: Editor

Actualiza la etiqueta de un menú. El name (identificador estable) no puede cambiarse. En instalaciones multi-locale, pasa locale para que se actualice la traducción correcta.

ParámetroTipoRequeridoDescripción
namestringNombre del menú a actualizar
labelstringNueva etiqueta para mostrar
localestringNoLocale del menú a actualizar

Scope: menus:manage | Rol mínimo: Editor

Elimina un menú y todos sus elementos. No puede deshacerse. En instalaciones multi-locale, pasa locale para que solo se elimine la traducción deseada.

ParámetroTipoRequeridoDescripción
namestringNombre del menú a eliminar
localestringNoLocale del menú a eliminar

Scope: menus:manage | Rol mínimo: Editor | Destructivo:

Reemplaza la lista completa de elementos de un menú en una llamada. Atómico: los elementos existentes se eliminan y la nueva lista se inserta en el orden proporcionado. Usa esto en lugar de operaciones individuales de añadir/eliminar para que el orden y los enlaces padre resultantes sean inequívocos. En instalaciones multi-locale, pasa locale para que solo se reescriba la traducción deseada.

Los elementos se posicionan por índice de array. La anidación se expresa vía parentIndex — un elemento con parentIndex: 0 está anidado bajo el elemento en el índice 0. El padre debe aparecer antes en la lista. Elementos sin parentIndex son de nivel superior.

ParámetroTipoRequeridoDescripción
namestringNombre del menú a actualizar
localestringNoLocale del menú a reescribir
itemsMenuItem[]Lista ordenada de elementos de menú (ver abajo)

Cada MenuItem tiene:

CampoTipoRequeridoDescripción
labelstringTexto de visualización del elemento
typestringUno de custom, page, post, taxonomy, collection
customUrlstringNoURL para elementos type: "custom" (ignorado en otros casos)
referenceCollectionstringNoSlug de colección destino para referencias de contenido
referenceIdstringNoID de contenido / término destino para referencias
titleAttrstringNoAtributo HTML title
targetstringNoAtributo HTML target (ej. _blank)
cssClassesstringNoClases CSS separadas por espacios
parentIndexintegerNoÍndice de array del elemento padre. Omitir para elementos de nivel superior.

Scope: menus:manage | Rol mínimo: Editor

Herramientas de revisiones

revision_list

Lista el historial de revisiones de un elemento de contenido, más reciente primero. Requiere que la colección soporte revisions.

ParámetroTipoRequeridoDescripción
collectionstringSlug de la colección
idstringID del elemento o slug
limitintegerNoMáx. revisiones (1-50, defecto 20)

Scope: content:read | Solo lectura:

revision_restore

Restaura un elemento de contenido a una revisión anterior. Reemplaza el borrador actual con los datos de la revisión especificada. No se publica automáticamente — usa content_publish después si es necesario.

ParámetroTipoRequeridoDescripción
revisionIdstringID de la revisión a restaurar

Scope: content:write

Herramientas de configuración

Configuraciones del sitio — título, eslogan, logo, favicon, URL canónica, tamaño de página predeterminado, formato de fecha y hora, handles sociales y valores SEO predeterminados.

settings_get

Obtiene todas las configuraciones del sitio. Las referencias de medios (logo, favicon, seo.defaultOgImage) incluyen URLs resueltas junto con el mediaId subyacente. Los valores no establecidos se omiten de la respuesta.

Sin parámetros.

Scope: settings:read | Rol mínimo: Editor | Solo lectura:

settings_update

Actualiza una o más configuraciones del sitio. Actualización parcial: solo los campos proporcionados se cambian; los campos omitidos se dejan como están. Devuelve el objeto de configuraciones completo después de la actualización.

Para establecer una referencia de medios (logo, favicon, seo.defaultOgImage), pasa un objeto con mediaId (y alt opcional). El elemento multimedia debe existir previamente — usa media_create primero.

ParámetroTipoRequeridoDescripción
titlestringNoTítulo del sitio
taglinestringNoDescripción corta mostrada junto al título
logoMediaRefNoReferencia de medios del logo ({ mediaId, alt? })
faviconMediaRefNoReferencia de medios del favicon
urlstringNoURL canónica del sitio (http o https). String vacío la limpia.
postsPerPageintegerNoTamaño de página predeterminado para listados de contenido (1-100)
dateFormatstringNoString de formato de fecha
timezonestringNoIdentificador de zona horaria IANA
socialobjectNoHandles sociales — twitter, github, facebook, instagram, linkedin, youtube
seoobjectNoValores SEO predeterminados (ver abajo)

El objeto seo acepta:

CampoTipoDescripción
titleSeparatorstringSeparador entre título de página y título del sitio (ej. " | " para una barra vertical)
defaultOgImageMediaRefImagen Open Graph predeterminada cuando el contenido no tiene ninguna
robotsTxtstringCuerpo personalizado de robots.txt. Omitir para usar el predeterminado de EmDash.
googleVerificationstringToken de verificación de Google Search Console
bingVerificationstringToken de verificación de Bing Webmaster Tools

Scope: settings:manage | Rol mínimo: Admin

Descubrimiento OAuth

La mayoría de clientes MCP manejan esto por ti; esta sección es para construir un cliente MCP directamente contra EmDash. Los clientes que soportan OAuth 2.1 descubren cómo autenticarse desde dos documentos de metadatos que el servidor publica:

Metadatos del recurso protegido

Solicita los metadatos del recurso protegido en el siguiente endpoint:

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

El servidor responde con el identificador del recurso, su servidor de autorización y scopes soportados:

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

Metadatos del servidor de autorización

Solicita los metadatos del servidor de autorización en el siguiente endpoint:

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

El servidor responde con los endpoints, scopes y tipos de concesión que soporta:

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

Cuando una solicitud no autenticada llega al endpoint MCP, el servidor devuelve:

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

Esto desencadena el flujo de descubrimiento estándar del cliente MCP.

Manejo de errores

Los errores de herramientas se devuelven como contenido de texto con isError: true. El mensaje tiene un prefijo [CODE] estable, y el mismo código se repite en _meta.code:

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

Los errores de scope y permisos usan el mismo formato de error de herramienta:

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

Los errores a nivel de transporte (mala configuración del servidor, excepciones no manejadas) devuelven código de error JSON-RPC -32603 (Error interno) sin filtrar detalles de implementación.