EmDash stellt einen integrierten Model Context Protocol-Server (MCP) unter /_emdash/api/mcp bereit. MCP-Clients nutzen ihn, um Inhalte, Bylines, Schemas, Medien, Taxonomien, Menüs, Revisionen und Einstellungen zu lesen und zu verwalten sowie die gesamte Site zu exportieren oder zu importieren.
Authentifizierung
Der MCP-Endpunkt erfordert ein Bearer-Token. EmDash unterstützt diese Token-Flows:
| Methode | Verwendung |
|---|---|
| OAuth 2.1 Authorization Code with Proof Key for Code Exchange (PKCE) | Interaktive MCP-Clients. Der Benutzer genehmigt die angeforderten Scopes im Browser. |
| Personal access token | Langfristiger Zugriff für einen Client oder Automatisierung. Tokens haben das Präfix ec_pat_ und werden im Admin erstellt. |
| OAuth 2.0 Device Authorization Grant | Befehlszeilen-Clients, die den Benutzer bitten, einen Code im Browser zu genehmigen. emdash login nutzt diesen Flow. |
Sitzungs-Cookies authentifizieren den MCP-Endpunkt nicht.
Scopes
OAuth- und Personal-Access-Tokens begrenzen, welche Tools ein Client aufrufen kann. Die Rolle des Benutzers wird separat geprüft; ein Scope gewährt niemals eine Berechtigung, die der Benutzer nicht hat.
| Scope | Zugriff |
|---|---|
content:read | Inhalte, Bylines, Taxonomien, Terms, Menüs und Revisionen lesen und durchsuchen. Entwurfsähnliche Inhalte erfordern zusätzlich die Berechtigung content:read_drafts des Benutzers. |
content:write | Inhalte, Bylines und Revisionen erstellen und ändern. Gewährt außerdem taxonomies:manage und menus:manage zur Kompatibilität mit bestehenden Tokens. |
media:read | Medien-Einträge lesen. |
media:write | Medien hochladen, registrieren, aktualisieren und löschen. |
schema:read | Collections und Felder lesen. |
schema:write | Collections und Felder erstellen, aktualisieren und löschen. |
taxonomies:manage | Taxonomie-Definitionen und Terms erstellen, aktualisieren und löschen. |
menus:manage | Menüs und Menüeinträge erstellen, aktualisieren und löschen. |
settings:read | Site-Einstellungen lesen. |
settings:manage | Site-Einstellungen aktualisieren. |
mcp:tools | Von jedem aktivierten Plugin bereitgestellte MCP-Tools aufrufen. |
mcp:tools:<pluginId> | Von einem aktivierten Plugin bereitgestellte MCP-Tools aufrufen. |
transfer:export | Die gesamte Site als Site-Paket exportieren und herunterladen. |
transfer:analyze | Ein Site-Paket hochladen und für den Import analysieren. |
transfer:execute | Einen Site-Import starten, fortsetzen, abbrechen und aufgeben. |
admin | Jedes Core-Tool aufrufen, einschließlich der Site-Transfer-Tools. Plugin-Tools erfordern weiterhin mcp:tools oder den plugin-spezifischen Scope. |
Der Scope admin umfasst transfer:export, transfer:analyze und transfer:execute. Jeder Transfer-Scope gewährt nur die eigenen Aktionen und erfordert die Administrator-Rolle. Damit ein Client, etwa ein Agent, ein Site-Paket analysieren kann, ohne zu exportieren oder zu importieren, gewähren Sie transfer:analyze statt admin.
Auf der Consent-Seite für den Authorization Code kann der Benutzer angeforderte Scopes entfernen. EmDash schneidet die Anfrage außerdem mit den registrierten Scopes des Clients und der Rolle des Benutzers und lehnt eine leere Gewährung ab.
Rollenanforderungen
Die folgende Tabelle zeigt die Mindestrolle für die jeweilige umfassende Fähigkeit. Eigentumsprüfungen können eine höhere Rolle verlangen, wenn ein Benutzer auf Inhalte eines anderen Benutzers zugreift.
| Fähigkeit | Mindestrolle |
|---|---|
| Veröffentlichte Inhalte, Medien, Taxonomien, Terms und Menüs lesen | Subscriber |
| Entwürfe, geplante Inhalte, Papierkorb, Vergleiche und Revisionen lesen | Contributor |
| Inhalte erstellen oder Medien hochladen | Contributor |
| Eigene Inhalte bearbeiten oder veröffentlichen und Medien registrieren | Author |
| Bylines, Taxonomien, Menüs oder Inhalte aller Benutzer verwalten | Editor |
| Schemas oder Einstellungen lesen | Editor |
| Schemas oder Einstellungen ändern, Inhalte dauerhaft löschen oder Medien-Nutzung reparieren | Admin |
| Die gesamte Site exportieren oder importieren | Admin |
Die vollständigen Rollendefinitionen finden Sie unter Benutzerrollen.
Transport
Der Server nutzt stateless Streamable HTTP. Jede Anfrage ist unabhängig; der Server hält keine MCP-Sitzung und keine Server-Sent-Events-Verbindung.
| Methode | Endpunkt | Verhalten |
|---|---|---|
POST | /_emdash/api/mcp | Akzeptiert JSON-RPC-Initialisierung, Tool-Auflistung und Tool-Aufrufe. |
GET | /_emdash/api/mcp | Gibt 405 Method Not Allowed zurück. |
DELETE | /_emdash/api/mcp | Gibt 405 Method Not Allowed zurück. |
Antworten verwenden JSON-RPC 2.0. Rufen Sie tools/list auf, um die aktuellen Eingabe-Schemas und MCP-Annotationen zu erhalten, bevor Sie eine Tool-Anfrage aufbauen.
Tool-Übersicht
Die folgende Übersicht entspricht den statischen Tools, die tools/list zurückgibt. Der registrierte Titel ist enthalten, weil Clients ihn statt des Tool-Namens anzeigen können.
Content-Tools
| Tool | Registered title | Required scope |
|---|---|---|
content_list | List Content | content:read |
content_get | Get Content | content:read |
content_create | Create Content | content:write |
content_update | Update Content | content:write |
content_delete | Delete Content (Trash) | content:write |
content_restore | Restore Content | content:write |
content_permanent_delete | Permanently Delete Content | content:write |
content_publish | Publish Content | content:write |
content_unpublish | Unpublish Content | content:write |
content_schedule | Schedule Content | content:write |
content_unschedule | Cancel Scheduled Publication | content:write |
content_compare | Compare Live vs Draft | content:read |
content_discard_draft | Discard Draft | content:write |
content_list_trashed | List Trashed Content | content:read |
content_duplicate | Duplicate Content | content:write |
content_translations | Get Content Translations | content:read |
Byline-Tools
| Tool | Registered title | Required scope |
|---|---|---|
byline_list | List Bylines | content:read |
byline_get | Get Byline | content:read |
byline_create | Create Byline | content:write |
byline_update | Update Byline | content:write |
byline_delete | Delete Byline | content:write |
byline_translations | List Byline Translations | content:read |
Schema-Tools
| Tool | Registered title | Required scope |
|---|---|---|
schema_list_collections | List Collections | schema:read |
schema_get_collection | Get Collection Schema | schema:read |
schema_list_block_types | List Block Types | schema:read |
schema_get_block_type | Get Block Type | schema:read |
schema_create_block_type | Create Block Type | schema:write |
schema_update_block_type | Update Block Type | schema:write |
schema_activate_block_type_version | Activate Block Type Version | schema:write |
schema_create_collection | Create Collection | schema:write |
schema_delete_collection | Delete Collection | schema:write |
schema_update_collection | Update Collection | schema:write |
schema_create_field | Add Field to Collection | schema:write |
schema_delete_field | Remove Field from Collection | schema:write |
schema_update_field | Update Field | schema:write |
Medien-Tools
| Tool | Registered title | Required scope |
|---|---|---|
media_list | List Media | media:read |
media_create | Confirm Signed Media Upload | media:write |
media_upload | Upload Media | media:write |
media_get | Get Media Item | media:read |
media_update | Update Media Metadata | media:write |
media_delete | Delete Media | media:write |
media_usage_repair | Repair Media Usage Index | admin |
Such-Tool
| Tool | Registered title | Required scope |
|---|---|---|
search | Search Content | content:read |
Taxonomie-Tools
| Tool | Registered title | Required scope |
|---|---|---|
taxonomy_list | List Taxonomies | content:read |
taxonomy_get | Get Taxonomy Definition | content:read |
taxonomy_create | Create Taxonomy Definition | taxonomies:manage |
taxonomy_update | Update Taxonomy Definition | taxonomies:manage |
taxonomy_delete | Delete Taxonomy Definition | taxonomies:manage |
taxonomy_list_terms | List Taxonomy Terms | content:read |
taxonomy_create_term | Create Taxonomy Term | taxonomies:manage |
taxonomy_update_term | Update Taxonomy Term | taxonomies:manage |
taxonomy_delete_term | Delete Taxonomy Term | taxonomies:manage |
taxonomy_term_translations | List Term Translations | content:read |
Menü-Tools
| Tool | Registered title | Required scope |
|---|---|---|
menu_list | List Menus | content:read |
menu_get | Get Menu with Items | content:read |
menu_translations | List Menu Translations | content:read |
menu_create | Create Menu | menus:manage |
menu_update | Update Menu | menus:manage |
menu_delete | Delete Menu | menus:manage |
menu_set_items | Set Menu Items | menus:manage |
Revisions-Tools
| Tool | Registered title | Required scope |
|---|---|---|
revision_list | List Revisions | content:read |
revision_restore | Restore Revision | content:write |
Einstellungs-Tools
| Tool | Registered title | Required scope |
|---|---|---|
settings_get | Get Site Settings | settings:read |
settings_update | Update Site Settings | settings:manage |
Site-Transfer-Tools
transfer:* bedeutet eines von transfer:export, transfer:analyze oder transfer:execute. Der Scope admin erfüllt jede Anforderung in dieser Tabelle.
| Tool | Registered title | Required scope |
|---|---|---|
site_transfer_capabilities | Get Site Transfer Capabilities | transfer:* |
site_export_start | Start Site Export | transfer:export |
site_export_status | Get Site Export Status | transfer:export |
site_import_analyze | Analyze Site Import | transfer:analyze |
site_import_start | Start Site Import | transfer:execute |
site_import_status | Get Site Import Status | transfer:* |
site_import_resume | Resume Site Import | transfer:execute |
site_import_receipt | Get Site Import Receipt | transfer:* |
site_export_start und site_import_start akzeptieren auch ein Token ohne den Scope, wenn ein Admin die Anfrage genehmigt. Für den Vorgang, den eine genehmigte Anfrage startet, akzeptieren site_export_status, site_import_status, site_import_resume und site_import_receipt dasselbe Token ohne den Scope.
Tool-Schemas nutzen
tools/list liefert für jedes Tool Beschreibung, JSON-Eingabe-Schema und Annotationen. Lesen Sie diese Metadaten, bevor Sie einen Aufruf aufbauen, damit Ihr Client die Felder, erlaubten Werte und Limits der installierten EmDash-Version nutzt.
Beispiel: Ein Client, der einen Artikel aktualisiert, ruft zuerst content_get auf und behält den zurückgegebenen _rev. Anschließend kann er diese JSON-RPC-Anfrage senden:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "content_update",
"arguments": {
"collection": "articles",
"id": "01JARTICLE0000000000000000",
"data": { "title": "Updated title" },
"_rev": "opaque-revision-token"
}
}
}
Das Ergebnis wird als JSON-Text im ersten Inhaltsblock zurückgegeben. Ein Tool mit Ausgabe-Schema kann denselben Wert auch in structuredContent zurückgeben.
Inhaltslebenszyklus und Bylines
Die Referenz zum Inhaltslebenszyklus definiert Zustand, Revision, Berechtigungen, Konflikte und Hook-Verhalten, die MCP, REST, CLI und Admin-Panel gemeinsam nutzen.
content_get liefert einen undurchsichtigen _rev-Wert. Übergeben Sie ihn an content_update, content_publish, content_unpublish, content_schedule oder content_discard_draft. Ein veralteter Wert führt zu einem Konflikt; lesen Sie den Eintrag erneut, bevor Sie es noch einmal versuchen.
content_update ist eine partielle Aktualisierung: weggelassene Felder behalten ihre aktuellen Werte. Die Aktualisierung eines veröffentlichten Eintrags legt einen Entwurf an, während die Live-Version unverändert bleibt. Nutzen Sie content_compare, um Live- und Entwurfswerte zu prüfen, rufen Sie dann content_publish auf, um den Entwurf live zu schalten, oder content_discard_draft, um ihn zu entfernen. content_delete verschiebt einen Eintrag in den Papierkorb; nur content_permanent_delete entfernt einen Eintrag im Papierkorb dauerhaft.
Bylines sind wiederverwendbare Autoren- oder Mitwirkendenangaben. byline_create kann einen Gast-Eintrag anlegen oder eine Byline mit einem CMS-Benutzer verknüpfen. Übergeben Sie die zurückgegebene Byline-ID in der Eingabe bylines, die content_create und content_update akzeptieren. Das Löschen einer Byline entfernt diese Angabe aus Inhalten und löscht sie als primäre Byline.
MCP-Schreibvorgänge nehmen nicht am Entry-Edit-Lock des Admins teil. Die _rev-Prüfung schützt die Operationen, die sie akzeptieren, aber andere Schreib-Tools können einen Eintrag ändern, während ein Redakteur ihn geöffnet hat.
Übersetzungen
Tools für Inhalts-, Byline-, Taxonomie-Term- und Menü-Übersetzungen liefern jede Locale-Variante in der jeweiligen Übersetzungsgruppe. Nutzen Sie die Eingabe translationOf des Erstellungstools, wenn das Schema sie vorsieht; tools/list ist maßgeblich für die erforderlichen Felder.
content_translations akzeptiert Collection und Inhalts-ID oder Slug. Die Byline-, Taxonomie-Term- und Menü-Übersetzungs-Tools akzeptieren entweder die ID eines Datensatzes oder die gemeinsame Übersetzungsgruppen-ID. Ein Benutzer ohne Entwurfszugriff sieht nur veröffentlichte Inhaltsübersetzungen.
Schemas, Medien, Taxonomien und Menüs
Schema-Tools ändern die Datenbankstruktur. Rufen Sie schema_get_collection auf, bevor Sie Inhalte erstellen oder Felder ändern; es liefert verfügbare Feldnamen, Typen, Constraints und Validierungsregeln. Das Löschen von Collections und Feldern entfernt gespeicherte Inhalte oder Feldwerte und kann nicht rückgängig gemacht werden.
Nutzen Sie media_upload, um base64-kodierte Bytes zu senden. Uploads unterliegen den konfigurierten Größen- und MIME-Typ-Limits; identische Bytes können einen bestehenden Medieneintrag mit deduplicated: true zurückgeben.
media_create bestätigt einen ausstehenden Upload, der über POST /_emdash/api/media/upload-url erstellt wurde. Laden Sie die Datei mit der zurückgegebenen signierten URL hoch, rufen Sie dann media_create vom selben Benutzerkonto mit dem zurückgegebenen storageKey auf. Das Tool prüft, dass die gespeicherte Datei existiert und der Größe entspricht, die beim Anfordern der Upload-URL angegeben wurde, bevor sie in der Medienbibliothek verfügbar wird.
Taxonomie-Definitionen beschreiben die Klassifikation und die Collections, auf die sie zutrifft; Terms sind die einzelnen Werte, die Inhalten zugewiesen werden. Hierarchische Terms können parentId nutzen, aber ein Parent muss zur selben Taxonomie gehören und darf keinen Zyklus erzeugen. Das Erstellen oder Aktualisieren eines Terms mit parentId in einer nicht hierarchischen Taxonomie liefert VALIDATION_ERROR. Ein Term mit Kindern muss diese entfernt oder verschoben haben, bevor er gelöscht werden kann.
menu_set_items ersetzt die vollständige Eintragsliste eines Menüs in einer atomaren Operation. Die Array-Reihenfolge wird zur Menü-Reihenfolge. Der parentIndex eines verschachtelten Eintrags verweist auf einen früheren Eintrag im selben Array; platzieren Sie daher jeden Parent vor seinen Kindern.
media_usage_repair kann eine Collection oder alle Collections verarbeiten und auf einer großen Site lange laufen. Die Status complete, partial, failed und stale sind erfolgreiche Tool-Antworten. Prüfen Sie den zurückgegebenen Status und die Zähler, statt sich auf isError zu verlassen; Authentifizierungs-, Validierungs- und unerwartete Ausführungsfehler setzen isError: true.
Site-Transfer
Die site_*-Tools exportieren eine gesamte Site als Site-Paket und importieren ein Paket in eine leere Site. Sie starten und steuern Vorgänge und liefern begrenzte Zusammenfassungen. Sie transportieren niemals Paket-Bytes, Medien, Datensatzinhalte, E-Mail-Adressen von Principals oder Download-URLs. Laden Sie einen Export herunter und laden Sie ein Paket für den Import mit der CLI oder der REST-API hoch, und verweisen Sie dann per ID auf den Vorgang.
Jedes Transfer-Tool erfordert die Admin-Rolle. Die Rolle wird vor dem Scope geprüft; ein Nicht-Admin erhält INSUFFICIENT_PERMISSIONS, und es wird keine Genehmigungsanfrage erstellt.
Export
site_export_start akzeptiert comments (Standard true) und liefert den neuen Vorgang. site_export_status führt bei jedem Aufruf einen begrenzten Export-Schritt aus und meldet den Vorgang und nextRequestInMs. Rufen Sie es nach dieser Verzögerung erneut auf, bis nextRequestInMs null ist. Übergeben Sie advance: false, um den Status zu lesen, ohne einen Schritt auszuführen. Ist der Export abgeschlossen, enthält das Ergebnis auch totals: Datensatzzähler nach Art, Medienanzahl und -bytes sowie Paketdateianzahl und -bytes.
Import
Laden Sie zuerst das Paket hoch. emdash site import <file> --analyze der CLI lädt hoch, analysiert und gibt die Vorgangs-ID aus.
site_import_analyze führt pro Aufruf einen begrenzten Analyse-Schritt aus. Wiederholen Sie, bis nextRequestInMs null ist; das Ergebnis enthält dann eine Plan-Zusammenfassung mit packageDigest, planDigest, executable, Zählern, Größen, Principals, Entscheidungen, Transformationen, Warnungen und Blockern. Jede Transformation wird als code, die Datensatz-kind, sofern vorhanden, und ein count aufgeführt, ohne die IDs oder Werte, auf die sie angewendet wird. Principals, Warnungen und Blocker listen höchstens 50 Einträge, mit der Gesamtzahl in total. Principals werden ohne E-Mail-Adressen mit den vorgeschlagenen und aktuell zugeordneten Ziel-Benutzer-IDs aufgeführt. Übergeben Sie decisions, um Principals Ziel-Benutzer-IDs (oder null) zuzuordnen und Titel und Tagline des Pakets oder Ziels zu wählen. Jede Änderung erzeugt einen neuen planDigest.
site_import_start nimmt die Vorgangs-ID sowie packageDigest und planDigest des neuesten Plans. Der Plan darf keine Blocker haben. Das Tool hat destructiveHint: true: Nach dem Start schreibt der Import in die Site und blockiert andere Schreibvorgänge, bis er abgeschlossen ist oder ein Administrator ihn aufgibt. Zeigen Sie dem Benutzer den Plan und holen Sie seine Bestätigung ein, bevor Sie es aufrufen.
site_import_resume führt einen begrenzten Import-Schritt aus und meldet den Vorgang und nextRequestInMs. Rufen Sie es auf, bis nextRequestInMs null ist; nach einer Unterbrechung ist Wiederholung sicher. site_import_status meldet den Vorgang und hochgeladene Dateizähler, ohne den Import voranzutreiben. site_import_receipt liefert den vollständigen Beleg inklusive receiptDigest, sobald der Import abgeschlossen ist.
Während ein Import läuft und nach Fehlschlag oder Abbruch bis zur Aufgabe schlagen alle anderen schreibenden Tools mit TRANSFER_IMPORT_IN_PROGRESS fehl. Das gilt auch für Plugin-Tools. Mit readOnlyHint: true annotierte Tools und die acht site_*-Tools funktionieren weiter, und initialize sowie tools/list werden nie blockiert. Während der Medien-Nutzungs-Aktivierung schlagen Schreib-Tools analog mit MEDIA_USAGE_ACTIVATION_IN_PROGRESS fehl.
Vorgangs-Zusammenfassungen enthalten id, kind, state, stage, progress, packageDigest, planDigest, error ({ code } oder null) und Zeitstempel. progress ist { done, total } Schritte, plus records, die ein Export bisher geschrieben hat, und bytesDone sowie bytesTotal, sobald bekannt. Die MCP-Tools können einen Import nicht abbrechen oder aufgeben; nutzen Sie die REST-API.
Genehmigungen
Ein Token mit admin oder dem benötigten Transfer-Scope fragt nie nach Genehmigung. Für ein Token ohne beides, etwa einen Agenten nur mit transfer:analyze, laufen site_export_start und site_import_start, wenn ein Administrator die Anfrage genehmigt:
- Der erste Aufruf ohne Scope erstellt eine ausstehende Genehmigungsanfrage und schlägt mit
TRANSFER_APPROVAL_REQUIREDfehl. Nachrichtentext und_meta.detailsenthaltenapprovalIdundexpiresAt. Erneuter Aufruf mit denselben Argumenten und ohneapprovalIdliefert dieselbe offene Anfrage. - Ein Administrator genehmigt unter Genehmigungsanfragen in Einstellungen → Transfer oder über den nur für die Sitzung gültigen Genehmigungs-Endpunkt der REST-API. API-Tokens können Anfragen nicht genehmigen.
- Der Client wiederholt den Aufruf mit denselben Argumenten und der
approvalId. Die Genehmigung wird verbraucht, wenn dieser Aufruf den Vorgang startet. Startet der Vorgang nicht, kann der Client mit derselbenapprovalIdwiederholen, bis sie abläuft.
Eine Anfrage ist an Benutzer, Token, Aktion und exakte Argumente gebunden: Export-Optionen oder Import-Vorgangs-ID und beide Digests. Eine ausstehende Anfrage läuft 15 Minuten nach Erstellung ab, eine genehmigte 15 Minuten nach Genehmigung. Ein Aufruf mit anderen Argumenten oder einem anderen Token oder mit abgelehnter, abgelaufener oder verbrauchter Genehmigung schlägt mit TRANSFER_APPROVAL_INVALID fehl.
site_import_start prüft Digests, Vorgangsstatus und Blocker des Plans, bevor eine Anfrage erstellt wird, sodass ein Administrator nur einen Import genehmigen muss, der ausführbar ist. Eine Genehmigung erfordert eine Token-ID; ein Aufrufer ohne Token-ID erhält INSUFFICIENT_SCOPE.
Nachdem ein genehmigter Aufruf einen Vorgang gestartet hat, können derselbe Benutzer und dasselbe Token site_export_status bzw. site_import_status, site_import_resume und site_import_receipt für diesen Vorgang ohne den Scope aufrufen.
Plugin-Tools
Ein Administrator muss die MCP-Oberfläche jedes Plugins aktivieren. Aktivierte Tools erscheinen in tools/list als <pluginId>__<localName> und erfordern für token-authentifizierte Aufrufe mcp:tools oder mcp:tools:<pluginId>. EmDash prüft außerdem die vom Plugin-Route deklarierte Berechtigung und protokolliert Plugin, Tool, Route und Akteur im Audit-Log.
Da Plugin-Tools installationsabhängig sind, sind sie nicht Teil der statischen Übersicht oben.
OAuth-Discovery
MCP-Clients entdecken den Authorization Server über die Protected-Resource-Metadaten:
GET /.well-known/oauth-protected-resource
Die Antwort identifiziert /_emdash/api/mcp als geschützte Ressource und verlinkt zum Authorization Server. Clients lesen dann dessen Metadaten unter:
GET /.well-known/oauth-authorization-server/_emdash
Dieses Dokument liefert die aktuellen Endpunkte für Authorization, Token, Registration und Device Authorization, unterstützte Scopes, Grant-Typen und die PKCE-Methode S256. Nutzen Sie die entdeckten Werte statt OAuth-Protokoll-Routen fest zu codieren.
Eine nicht authentifizierte MCP-Anfrage liefert 401 mit der Discovery-URL:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://example.com/.well-known/oauth-protected-resource"
Fehler
Ein Tool-Fehler hat isError: true. Der erste Textblock beginnt mit einem stabilen Code, und _meta.code wiederholt ihn für Clients, die strukturierte Metadaten lesen:
{
"content": [{ "type": "text", "text": "[NOT_FOUND] Collection 'articles' not found" }],
"isError": true,
"_meta": { "code": "NOT_FOUND" }
}
Authentifizierungsfehler nutzen Codes wie INSUFFICIENT_SCOPE und INSUFFICIENT_PERMISSIONS. Transportfehler nutzen den JSON-RPC-Internal-Error-Code -32603 und geben die zugrunde liegende Exception nicht preis.