MCP Server-Referenz

Auf dieser Seite

EmDash enthält einen integrierten Model Context Protocol (MCP) Server unter /_emdash/api/mcp, der Content-Management-Operationen als Tools für KI-Assistenten bereitstellt.

Diese Seite behandelt die Protokolldetails: Authentifizierung, Transport, Toolspezifikationen, OAuth-Discovery und Fehlerbehandlung.

Authentifizierung

Der MCP-Server unterstützt drei Authentifizierungsmethoden:

MethodeFunktionsweise
OAuth 2.1 Authorization Code + PKCEStandard-Flow für MCP-Clients. Benutzer genehmigt Scopes im Browser.
Personal Access Token (PAT)Langlebige ec_pat_* Tokens, die im Admin-Panel erstellt werden.
Device FlowCLI-artiger Flow, bei dem Sie einen Code im Browser genehmigen. Wird von emdash login verwendet.

Session-Cookies (aus der Admin-UI) funktionieren ebenfalls, sind aber für externe MCP-Clients nicht praktikabel.

Scopes

Tokens sind auf Scopes beschränkt, um zu begrenzen, welche Operationen ein Client ausführen kann. Scopes werden während der OAuth-Autorisierung angefordert und bei jedem Tool-Aufruf erzwungen.

ScopeGewährt Zugriff auf
content:readListen, Abrufen, Vergleichen und Durchsuchen von Inhalten. Listen von Taxonomien, Taxonomie-Begriffen und Menüs.
content:writeErstellen, Aktualisieren, Löschen, Veröffentlichen, Zurückziehen, Planen, Entplanen, Duplizieren und Wiederherstellen von Inhalten. Gewährt implizit taxonomies:manage und menus:manage für Abwärtskompatibilität mit Tokens, die vor Existenz dieser Scopes ausgestellt wurden.
media:readListen und Abrufen von Medien-Elementen.
media:writeRegistrieren (Erstellen), Aktualisieren und Löschen von Medien-Metadaten.
schema:readListen von Collections und Abrufen von Collection-Schemas.
schema:writeErstellen und Löschen von Collections und Feldern.
taxonomies:manageErstellen, Aktualisieren und Löschen von Taxonomie-Begriffen.
menus:manageErstellen, Aktualisieren und Löschen von Navigationsmenüs und deren Elementen.
settings:readLesen von seitenweiten Einstellungen.
settings:manageAktualisieren von seitenweiten Einstellungen.
adminVollzugriff auf alle Operationen.

Der admin Scope gewährt Zugriff auf alles. Session-basierte Authentifizierung (ohne Token) hat ebenfalls vollen Zugriff basierend auf der Benutzerrolle.

content:write gewährt implizit taxonomies:manage und menus:manage, sodass Personal Access Tokens, die vor der Aufteilung dieser Scopes ausgestellt wurden, weiterhin ohne Neuausstellung funktionieren. Neue Tokens sollten die granularen Scopes anfordern.

Rollenanforderungen

Zusätzlich zu Scopes erfordern einige Tools eine minimale RBAC-Rolle. Beide müssen erfüllt sein — ein Token mit dem richtigen Scope schlägt dennoch fehl, wenn die Rolle des aufrufenden Benutzers zu niedrig ist.

OperationMinimale Rolle
Content lesenSubscriber (10) für veröffentlichte Elemente; Contributor (20) für Entwürfe, Geplantes, Papierkorb und Revisionen
Content erstellenContributor (20)
Eigenen Content bearbeiten / eigenen Content löschenAuthor (30)
Content veröffentlichenAuthor (30) für eigene Elemente; Editor (40) für fremde Elemente
Schema lesenEditor (40)
Schema schreibenAdmin (50)
Taxonomien verwaltenEditor (40)
Menüs verwaltenEditor (40)
Einstellungen lesenEditor (40)
Einstellungen verwaltenAdmin (50)
Medien hochladen (media_create)Author (30)

Siehe die Authentifizierungsanleitung für Rollendefinitionen.

Transport

Der Server verwendet den Streamable HTTP-Transport im stateless mode. Jede Anfrage ist unabhängig — es gibt keine Sessions oder langlebige Verbindungen.

  • POST /_emdash/api/mcp — JSON-RPC Tool-Aufrufe senden
  • GET /_emdash/api/mcp — Gibt 405 zurück (kein SSE im stateless mode)
  • DELETE /_emdash/api/mcp — Gibt 405 zurück (keine Session zum Schließen)

Antworten folgen dem JSON-RPC 2.0 Format. Fehler verwenden Standard-JSON-RPC-Fehlercodes, mit MCP-spezifischen Codes für Scope- und Berechtigungsfehler.

Tools

Der Server stellt 45 Tools über acht Domänen bereit: Content, Schema, Media, Search, Taxonomies, Menus, Revisions und Settings. Jedes Tool gibt Ergebnisse als JSON-Text-Inhalt zurück, oder eine Fehlermeldung mit isError: true bei Fehler.

Content Tools

content_list

Listen von Content-Elementen in einer Collection mit optionaler Filterung und Paginierung.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug (z.B. posts, pages)
statusstringNeinFilter: draft, published oder scheduled
limitintegerNeinMax. Anzahl zurückzugebender Elemente (1-100, Standard 50)
cursorstringNeinPaginierungs-Cursor aus vorheriger Antwort
orderBystringNeinSortierfeld (z.B. created_at, updated_at)
orderstringNeinSortierrichtung: asc oder desc (Standard desc)
localestringNeinNach Locale filtern (z.B. en, fr). Nur relevant mit i18n.

Scope: content:read | Read-only: Ja

content_get

Ein einzelnes Content-Element nach ID oder Slug abrufen. Gibt alle Feldwerte, Metadaten und ein _rev Token für optimistische Nebenläufigkeit zurück.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
idstringJaContent-Element-ID (ULID) oder Slug
localestringNeinLocale für Slug-Suche. IDs sind global eindeutig.

Scope: content:read | Read-only: Ja

content_create

Ein neues Content-Element erstellen. Das data Objekt sollte Feldwerte enthalten, die dem Schema der Collection entsprechen — verwenden Sie schema_get_collection, um zu prüfen, welche Felder verfügbar sind. Elemente werden standardmäßig als draft erstellt.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
dataobjectJaFeldwerte als Schlüssel-Wert-Paare
slugstringNeinURL-Slug (automatisch aus Titel generiert, wenn weggelassen)
statusstringNeinAnfangsstatus: draft oder published (Standard draft)
localestringNeinLocale für diesen Content (Standard: Site-Standard)
translationOfstringNeinID des Elements, dessen Übersetzung dies ist

Scope: content:write

content_update

Ein bestehendes Content-Element aktualisieren. Schließen Sie nur Felder ein, die Sie ändern möchten — nicht angegebene Felder bleiben unverändert.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
idstringJaContent-Element-ID oder Slug
dataobjectNeinZu aktualisierende Feldwerte
slugstringNeinNeuer URL-Slug
statusstringNeinNeuer Status: draft oder published
_revstringNeinRevisions-Token von content_get zur Konflikterkennung

Scope: content:write

content_delete

Ein Content-Element durch Verschieben in den Papierkorb soft-löschen. Verwenden Sie content_restore zum Rückgängigmachen oder content_permanent_delete zum endgültigen Entfernen.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
idstringJaContent-Element-ID oder Slug

Scope: content:write | Destructive: Ja

content_restore

Ein soft-gelöschtes Content-Element aus dem Papierkorb wiederherstellen.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
idstringJaContent-Element-ID oder Slug

Scope: content:write

content_permanent_delete

Ein im Papierkorb befindliches Content-Element dauerhaft und unwiderruflich löschen. Das Element muss zuerst im Papierkorb sein.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
idstringJaContent-Element-ID oder Slug

Scope: content:write | Destructive: Ja

content_publish

Ein Content-Element veröffentlichen und auf der Website live schalten. Erstellt eine veröffentlichte Revision aus dem aktuellen Entwurf. Weitere Bearbeitungen erstellen einen neuen Entwurf ohne die Live-Version zu beeinflussen, bis erneut veröffentlicht wird.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
idstringJaContent-Element-ID oder Slug

Scope: content:write

content_unpublish

Ein veröffentlichtes Element auf Entwurfsstatus zurücksetzen. Es wird auf der Live-Website nicht mehr sichtbar sein, aber sein Inhalt bleibt erhalten.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
idstringJaContent-Element-ID oder Slug

Scope: content:write

content_schedule

Ein Content-Element für zukünftige Veröffentlichung planen. Es wird automatisch zum angegebenen Datum/Uhrzeit veröffentlicht.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
idstringJaContent-Element-ID oder Slug
scheduledAtstringJaISO 8601 Datum/Zeit (z.B. 2026-06-01T09:00:00Z)

Scope: content:write

content_unschedule

Eine zuvor geplante Veröffentlichung abbrechen. Das Element behält seinen aktuellen Status; nur der scheduledAt Zeitstempel wird gelöscht. Idempotent — Aufruf auf einem nicht geplanten Element ist ein No-op.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
idstringJaContent-Element-ID oder Slug

Scope: content:write

content_compare

Die veröffentlichte (Live-)Version eines Content-Elements mit seinem aktuellen Entwurf vergleichen. Gibt beide Versionen und ein Flag zurück, das anzeigt, ob es Änderungen gibt.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
idstringJaContent-Element-ID oder Slug

Scope: content:read | Read-only: Ja

content_discard_draft

Den aktuellen Entwurf verwerfen und zur letzten veröffentlichten Version zurückkehren. Funktioniert nur bei Elementen, die mindestens einmal veröffentlicht wurden.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
idstringJaContent-Element-ID oder Slug

Scope: content:write | Destructive: Ja

content_list_trashed

Soft-gelöschte Content-Elemente im Papierkorb einer Collection auflisten.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
limitintegerNeinMax. Elemente (1-100, Standard 50)
cursorstringNeinPaginierungs-Cursor

Scope: content:read | Read-only: Ja

content_duplicate

Eine Kopie eines bestehenden Content-Elements erstellen. Das Duplikat wird als Entwurf mit “(Copy)” an den Titel angehängt und einem automatisch generierten Slug erstellt.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
idstringJaZu duplizierende Content-Element-ID oder Slug

Scope: content:write

content_translations

Alle Locale-Varianten eines Content-Elements abrufen. Gibt die Übersetzungsgruppe und eine Zusammenfassung jeder Locale-Version zurück. Nur relevant, wenn i18n aktiviert ist.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
idstringJaContent-Element-ID oder Slug

Scope: content:read | Read-only: Ja

Schema Tools

schema_list_collections

Alle im CMS definierten Content-Collections auflisten. Gibt Slug, Label, unterstützte Funktionen und Zeitstempel zurück.

Keine Parameter.

Scope: schema:read | Minimale Rolle: Editor | Read-only: Ja

schema_get_collection

Detaillierte Informationen über eine Collection einschließlich aller Felddefinitionen abrufen. Felder beschreiben das Datenmodell: Name, Typ, Einschränkungen und Validierungsregeln. Verwenden Sie dies, um zu verstehen, was content_create und content_update erwarten.

ParameterTypErforderlichBeschreibung
slugstringJaCollection-Slug (z.B. posts)

Scope: schema:read | Minimale Rolle: Editor | Read-only: Ja

schema_create_collection

Eine neue Content-Collection erstellen. Dies erstellt eine Datenbanktabelle und Schema-Definition. Der Slug muss kleingeschrieben, alphanumerisch mit Unterstrichen sein und mit einem Buchstaben beginnen.

ParameterTypErforderlichBeschreibung
slugstringJaEindeutiger Bezeichner (/^[a-z][a-z0-9_]*$/)
labelstringJaAnzeigename (Plural, z.B. “Blog Posts”)
labelSingularstringNeinSingular-Anzeigename
descriptionstringNeinBeschreibung dieser Collection
iconstringNeinIcon-Name für die Admin-UI
supportsstring[]NeinFunktionen: drafts, revisions, preview, scheduling, search (Standard: ['drafts', 'revisions'])

Scope: schema:write | Minimale Rolle: Admin

schema_delete_collection

Eine Collection und ihre Datenbanktabelle löschen. Dies ist unwiderruflich und löscht alle Inhalte in der Collection.

ParameterTypErforderlichBeschreibung
slugstringJaZu löschender Collection-Slug
forcebooleanNeinLöschung erzwingen, auch wenn die Collection Inhalt hat

Scope: schema:write | Minimale Rolle: Admin | Destructive: Ja

schema_create_field

Ein neues Feld zum Schema einer Collection hinzufügen. Dies fügt eine Spalte zur Datenbanktabelle hinzu.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
slugstringJaFeld-Bezeichner (/^[a-z][a-z0-9_]*$/)
labelstringJaAnzeigename
typestringJaDatentyp (siehe unten)
requiredbooleanNeinOb das Feld erforderlich ist
uniquebooleanNeinOb Werte eindeutig sein müssen
defaultValueanyNeinStandardwert für neue Elemente
validationobjectNeinEinschränkungen: min, max, minLength, maxLength, pattern, options
optionsobjectNeinWidget-Konfiguration: collection (für Referenzen), rows (für textarea)
searchablebooleanNeinIn Volltextsuchindex aufnehmen
translatablebooleanNeinOb dieses Feld übersetzbar ist (Standard true)

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

Für select und multiSelect Typen geben Sie erlaubte Werte in validation.options an.

Scope: schema:write | Minimale Rolle: Admin

schema_delete_field

Ein Feld aus einer Collection entfernen. Dies löscht die Spalte und alle Daten in diesem Feld. Unwiderruflich.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
fieldSlugstringJaZu entfernender Feld-Slug

Scope: schema:write | Minimale Rolle: Admin | Destructive: Ja

Media Tools

media_list

Hochgeladene Mediendateien mit optionaler MIME-Typ-Filterung und Paginierung auflisten.

ParameterTypErforderlichBeschreibung
mimeTypestringNeinNach MIME-Typ-Präfix filtern (z.B. image/, application/pdf)
limitintegerNeinMax. Elemente (1-100, Standard 50)
cursorstringNeinPaginierungs-Cursor

Scope: media:read | Read-only: Ja

media_create

Eine Mediendatei registrieren, die bereits in den Speicher hochgeladen wurde. Der Aufrufer ist dafür verantwortlich, die Datei bei storageKey zu platzieren (typischerweise mittels signierter Upload-URL aus der Admin-UI oder einer separaten API). Dieses Tool persistiert den Metadaten-Datensatz, sodass die Datei über media_list / media_get auffindbar ist und von Content referenziert werden kann.

ParameterTypErforderlichBeschreibung
filenamestringJaOriginal-Dateiname (z.B. logo.png)
mimeTypestringJaMIME-Typ (z.B. image/png)
storageKeystringJaSpeicherpfad/-schlüssel, zu dem die Datei hochgeladen wurde
sizeintegerNeinDateigröße in Bytes
widthintegerNeinBildbreite in Pixeln
heightintegerNeinBildhöhe in Pixeln
contentHashstringNeinHash des Dateiinhalts (zur Deduplizierung)
blurhashstringNeinBlurhash für Bild-Platzhalter
dominantColorstringNeinHex-Farbstring für die dominante Farbe des Bildes

Scope: media:write | Minimale Rolle: Author

media_get

Details einer einzelnen Mediendatei nach ID abrufen. Gibt Metadaten einschließlich Dateiname, MIME-Typ, Größe, Abmessungen, Alt-Text und URL zurück.

ParameterTypErforderlichBeschreibung
idstringJaMedien-Element-ID

Scope: media:read | Read-only: Ja

media_update

Metadaten einer hochgeladenen Mediendatei aktualisieren. Die Datei selbst kann nicht geändert werden.

ParameterTypErforderlichBeschreibung
idstringJaMedien-Element-ID
altstringNeinAlt-Text für Barrierefreiheit
captionstringNeinBildunterschrift
widthintegerNeinBildbreite in Pixeln
heightintegerNeinBildhöhe in Pixeln

Scope: media:write

media_delete

Eine Mediendatei dauerhaft löschen. Entfernt den Datenbank-Datensatz und die Datei aus dem Speicher. Content, der diese Medien referenziert, hat fehlerhafte Referenzen.

ParameterTypErforderlichBeschreibung
idstringJaMedien-Element-ID

Scope: media:write | Destructive: Ja

Search Tool

Volltextsuche über Content-Collections. Collections müssen search in ihrer supports Liste haben und Felder müssen als searchable markiert sein.

ParameterTypErforderlichBeschreibung
querystringJaSuchanfrage-Text
collectionsstring[]NeinSuche auf bestimmte Collection-Slugs beschränken
localestringNeinErgebnisse nach Locale filtern
limitintegerNeinMax. Ergebnisse (1-50, Standard 20)

Scope: content:read | Read-only: Ja

Taxonomy Tools

taxonomy_list

Alle Taxonomie-Definitionen auflisten (z.B. Kategorien, Tags). Gibt Name, Label, ob hierarchisch und zugehörige Collections zurück.

Keine Parameter.

Scope: content:read | Read-only: Ja

taxonomy_list_terms

Begriffe in einer Taxonomie mit Paginierung auflisten.

ParameterTypErforderlichBeschreibung
taxonomystringJaTaxonomie-Name (z.B. categories, tags)
limitintegerNeinMax. Elemente (1-100, Standard 50)
cursorstringNeinPaginierungs-Cursor

Scope: content:read | Read-only: Ja

taxonomy_create_term

Einen neuen Begriff in einer Taxonomie erstellen. Für hierarchische Taxonomien geben Sie eine parentId an, um einen untergeordneten Begriff zu erstellen. Die Vorfahrenkette des Elternteils darf 100 Ebenen nicht überschreiten.

ParameterTypErforderlichBeschreibung
taxonomystringJaTaxonomie-Name
slugstringJaURL-sicherer Bezeichner
labelstringJaAnzeigename
parentIdstringNeinEltern-Begriff-ID (für hierarchische Taxonomien)
descriptionstringNeinBeschreibung des Begriffs

Scope: taxonomies:manage | Minimale Rolle: Editor

taxonomy_update_term

Einen bestehenden Begriff in einer Taxonomie aktualisieren. Jedes Feld kann weggelassen werden, um es unverändert zu lassen. Das Umbenennen eines Slugs darf nicht mit einem anderen Begriff in derselben Taxonomie kollidieren. Setzen Sie parentId auf null, um von einem Elternteil zu trennen. Das neue Elternteil muss existieren, zur selben Taxonomie gehören und darf keinen Zyklus einführen.

ParameterTypErforderlichBeschreibung
taxonomystringJaTaxonomie-Name
termSlugstringJaAktueller Slug des zu aktualisierenden Begriffs
slugstringNeinNeuer Slug (muss in der Taxonomie eindeutig sein)
labelstringNeinNeuer Anzeigename
parentIdstring | nullNeinNeue Eltern-Begriff-ID; null zum Trennen
descriptionstringNeinNeue Beschreibung

Scope: taxonomies:manage | Minimale Rolle: Editor

taxonomy_delete_term

Einen Begriff dauerhaft aus einer Taxonomie löschen. Jeglicher mit dem Begriff getaggte Content verliert die Zuordnung. Kann keinen Begriff löschen, der untergeordnete Elemente hat — löschen Sie zuerst die untergeordneten Elemente.

ParameterTypErforderlichBeschreibung
taxonomystringJaTaxonomie-Name
termSlugstringJaSlug des zu löschenden Begriffs

Scope: taxonomies:manage | Minimale Rolle: Editor | Destructive: Ja

Navigationsmenüs auflisten. Menüs sind pro Locale: übergeben Sie locale, um nur die Zeilen eines Locale zurückzugeben, oder lassen Sie es weg, um jede Locale-Variante aufzulisten.

ParameterTypErforderlichBeschreibung
localestringNeinNach Locale filtern (weglassen für alle Locale-Varianten)

Scope: content:read | Read-only: Ja

Ein Menü nach Namen einschließlich aller seiner Elemente in Reihenfolge abrufen. Elemente haben ein Label, URL, Typ und optionales Elternteil für Verschachtelung. Wenn derselbe Menüname in mehreren Locales existiert, übergeben Sie locale, um die beabsichtigte Übersetzung aufzulösen.

ParameterTypErforderlichBeschreibung
namestringJaMenüname (z.B. main, footer)
localestringNeinLocale zur Auflösung des Menüs

Scope: content:read | Read-only: Ja

Ein neues Navigationsmenü erstellen. Der name ist der stabile Bezeichner, der von Site-Templates verwendet wird; label ist der menschenlesbare Name, der im Admin angezeigt wird. Menüs sind pro Locale, übergeben Sie also locale, wenn derselbe Menüname in mehreren Übersetzungen existiert. Fügen Sie Elemente danach mit menu_set_items hinzu. Wenn translationOf gesetzt ist, muss auch locale gesetzt sein.

ParameterTypErforderlichBeschreibung
namestringJaStabiler Bezeichner (/^[a-z][a-z0-9_]*$/)
labelstringJaAnzeigename für den Admin
localestringNeinLocale für dieses Menü (z.B. fr-fr)
translationOfstringNeinBestehende Menü-ID, von der diese Locale-Variante erstellt wird

Scope: menus:manage | Minimale Rolle: Editor

Das Label eines Menüs aktualisieren. Der name (stabiler Bezeichner) kann nicht geändert werden. Bei Multi-Locale-Installationen übergeben Sie locale, damit die richtige Übersetzung aktualisiert wird.

ParameterTypErforderlichBeschreibung
namestringJaZu aktualisierender Menüname
labelstringJaNeues Anzeige-Label
localestringNeinLocale des zu aktualisierenden Menüs

Scope: menus:manage | Minimale Rolle: Editor

Ein Menü und alle seine Elemente löschen. Kann nicht rückgängig gemacht werden. Bei Multi-Locale-Installationen übergeben Sie locale, damit nur die beabsichtigte Übersetzung entfernt wird.

ParameterTypErforderlichBeschreibung
namestringJaZu löschender Menüname
localestringNeinLocale des zu löschenden Menüs

Scope: menus:manage | Minimale Rolle: Editor | Destructive: Ja

Die gesamte Elementliste eines Menüs in einem Aufruf ersetzen. Atomar: bestehende Elemente werden gelöscht und die neue Liste wird in der angegebenen Reihenfolge eingefügt. Verwenden Sie dies statt pro-Element-Add/Remove-Operationen, damit die resultierende Reihenfolge und Eltern-Links eindeutig sind. Bei Multi-Locale-Installationen übergeben Sie locale, damit nur die beabsichtigte Übersetzung neu geschrieben wird.

Elemente werden nach Array-Index positioniert. Verschachtelung wird über parentIndex ausgedrückt — ein Element mit parentIndex: 0 ist unter dem Element bei Index 0 verschachtelt. Das Elternteil muss früher in der Liste erscheinen. Elemente ohne parentIndex sind oberste Ebene.

ParameterTypErforderlichBeschreibung
namestringJaZu aktualisierender Menüname
localestringNeinLocale des neu zu schreibenden Menüs
itemsMenuItem[]JaGeordnete Liste von Menü-Elementen (siehe unten)

Jedes MenuItem hat:

FeldTypErforderlichBeschreibung
labelstringJaElement-Anzeigetext
typestringJaEiner von custom, page, post, taxonomy, collection
customUrlstringNeinURL für type: "custom" Elemente (sonst ignoriert)
referenceCollectionstringNeinZiel-Collection-Slug für Content-Referenzen
referenceIdstringNeinZiel-Content-/Begriff-ID für Referenzen
titleAttrstringNeinHTML title Attribut
targetstringNeinHTML target Attribut (z.B. _blank)
cssClassesstringNeinLeerzeichen-getrennte CSS-Klassen
parentIndexintegerNeinArray-Index des Eltern-Elements. Weglassen für oberste Ebene.

Scope: menus:manage | Minimale Rolle: Editor

Revision Tools

revision_list

Revisionsverlauf für ein Content-Element auflisten, neueste zuerst. Erfordert, dass die Collection revisions unterstützt.

ParameterTypErforderlichBeschreibung
collectionstringJaCollection-Slug
idstringJaContent-Element-ID oder Slug
limitintegerNeinMax. Revisionen (1-50, Standard 20)

Scope: content:read | Read-only: Ja

revision_restore

Ein Content-Element auf eine frühere Revision zurücksetzen. Ersetzt den aktuellen Entwurf durch die Daten der angegebenen Revision. Wird nicht automatisch veröffentlicht — verwenden Sie danach bei Bedarf content_publish.

ParameterTypErforderlichBeschreibung
revisionIdstringJaWiederherzustellende Revisions-ID

Scope: content:write

Settings Tools

Seitenweite Einstellungen — Titel, Tagline, Logo, Favicon, kanonische URL, Standard-Seitengröße, Datums- und Zeitformatierung, Social-Handles und SEO-Standards.

settings_get

Alle seitenweiten Einstellungen abrufen. Medien-Referenzen (logo, favicon, seo.defaultOgImage) enthalten aufgelöste URLs neben der zugrunde liegenden mediaId. Nicht gesetzte Werte werden in der Antwort weggelassen.

Keine Parameter.

Scope: settings:read | Minimale Rolle: Editor | Read-only: Ja

settings_update

Eine oder mehrere seitenweite Einstellungen aktualisieren. Partielle Aktualisierung: nur die bereitgestellten Felder werden geändert; weggelassene Felder bleiben wie sie sind. Gibt das vollständige Settings-Objekt nach der Aktualisierung zurück.

Um eine Medien-Referenz (logo, favicon, seo.defaultOgImage) zu setzen, übergeben Sie ein Objekt mit mediaId (und optionalem alt). Das Medien-Element muss bereits existieren — verwenden Sie zuerst media_create.

ParameterTypErforderlichBeschreibung
titlestringNeinSite-Titel
taglinestringNeinKurze Beschreibung neben dem Titel
logoMediaRefNeinLogo-Medien-Referenz ({ mediaId, alt? })
faviconMediaRefNeinFavicon-Medien-Referenz
urlstringNeinKanonische Site-URL (http oder https). Leerer String löscht sie.
postsPerPageintegerNeinStandard-Seitengröße für Content-Auflistungen (1-100)
dateFormatstringNeinDatumsformat-Token-String
timezonestringNeinIANA-Zeitzone-Bezeichner
socialobjectNeinSocial-Handles — twitter, github, facebook, instagram, linkedin, youtube
seoobjectNeinSEO-Standards (siehe unten)

Das seo Objekt akzeptiert:

FeldTypBeschreibung
titleSeparatorstringTrennzeichen zwischen Seitentitel und Site-Titel (z.B. " | " für senkrechten Strich)
defaultOgImageMediaRefStandard-Open Graph-Bild, wenn Content keines hat
robotsTxtstringBenutzerdefinierter robots.txt Body. Weglassen für EmDash-Standard.
googleVerificationstringGoogle Search Console Verifizierungs-Token
bingVerificationstringBing Webmaster Tools Verifizierungs-Token

Scope: settings:manage | Minimale Rolle: Admin

OAuth Discovery

Die meisten MCP-Clients handhaben dies für Sie; dieser Abschnitt ist für den Bau eines MCP-Clients gegen EmDash direkt. Clients, die OAuth 2.1 unterstützen, erkennen, wie sie sich authentifizieren, aus zwei Metadaten-Dokumenten, die der Server veröffentlicht:

Protected Resource Metadata

Fordern Sie die Protected Resource Metadata an folgendem Endpunkt an:

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

Der Server antwortet mit der Ressourcen-Kennung, ihrem Authorization Server und unterstützten Scopes:

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

Authorization Server Metadata

Fordern Sie die Authorization Server Metadata an folgendem Endpunkt an:

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

Der Server antwortet mit den Endpunkten, Scopes und Grant-Typen, die er unterstützt:

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

Wenn eine nicht authentifizierte Anfrage den MCP-Endpunkt trifft, gibt der Server zurück:

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

Dies löst den Standard-MCP-Client-Discovery-Flow aus.

Fehlerbehandlung

Tool-Fehler werden als Text-Inhalt mit isError: true zurückgegeben. Die Nachricht ist mit einem stabilen [CODE] präfixiert, und derselbe Code wird in _meta.code wiederholt:

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

Scope- und Berechtigungsfehler verwenden dasselbe Tool-Fehler-Envelope:

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

Transport-Level-Fehler (Server-Fehlkonfiguration, unbehandelte Ausnahmen) geben JSON-RPC-Fehlercode -32603 (Internal error) zurück, ohne Implementierungsdetails preiszugeben.