Zur Dokumentation springen
CLI

Für KI-Agenten

`openemail` aus Claude Code, Codex oder einem CI-Job steuern: unbeaufsichtigte Anmeldung, Hilfe als Daten, Probeläufe, fehlende Scopes und Bestätigungscodes.

Die eingebaute Anleitung

openemail agents gibt eine kurze Anleitung in Markdown für einen KI-Agenten wie Claude Code oder Codex oder für ein Skript in CI aus: wie man sich ohne einen Menschen anmeldet, die Ausgabe liest, Befehle findet, Dinge sicher ändert und durch Listen blättert, was zu tun ist, wenn ein Bestätigungscode oder ein Scope fehlt, und fünf Rezepte zum Kopieren. openemail agent ist derselbe Befehl.

Terminal
openemail agentsopenemail agents --json | jq -r '.recipes[].commands[]'

Mit --json ist die Anleitung ein Dokument mit schemaVersion, title, intro, sections aus { id, title, points }, exitCodes und recipes aus { id, title, commands }. Statt diese Regeln in jeden Prompt zu kopieren, sagen Sie dem Agenten einmal, in der Anweisungsdatei, die Ihr Projekt ihm ohnehin gibt, dass er openemail agents ausführen soll, bevor er die CLI nutzt.

Anmelden ohne einen Menschen

  • Nutzen Sie einen API-Schlüssel. Setzen Sie OPENEMAIL_API_KEY oder übergeben Sie --api-key an einen einzelnen Befehl. Erstellen Sie ihn unter Einstellungen → API-Schlüssel (openemail open api-keys) mit nur den Scopes, die der Agent braucht. Ein Schlüssel öffnet nie einen Browser und braucht nie einen Bestätigungscode.
  • Oder verwenden Sie eine Browser-Anmeldung weiter, die ein Mensch einmal auf diesem Rechner mit openemail login vorgenommen hat, und wählen Sie sie mit --profile <name>. Die CLI erneuert ihre Tokens selbst.
  • Ohne Terminal fragt nichts nach. Unter --json, --no-input oder CI, oder ohne angeschlossenes Terminal, bricht ein Wert, nach dem die CLI gefragt hätte, mit Exit-Code 2 ab und nennt das Flag, das zu übergeben ist.
  • Eine Browser-Anmeldung braucht einen Menschen, der sie freigibt, daher bricht ein unbeaufsichtigtes openemail login mit Exit-Code 2 und dem Code unattended ab, bevor es irgendetwas registriert, und verweist auf openemail login --with-token.
  • openemail whoami --json zeigt den Workspace, die Art der Anmeldung und ihre scopes.

Die Ausgabe lesen

Übergeben Sie --json an jeden Befehl. stdout enthält dann genau ein JSON-Dokument, oder ein Objekt pro Zeile mit --ndjson, und der Fortschritt bleibt auf stderr. Ein Fehler gibt eine {"error":{...}}-Zeile auf stderr aus: Verzweigen Sie nach dem Exit-Code und nach dessen code, zeigen Sie next einem Menschen, und parsen Sie nie message, dessen Wortlaut sich ändern kann. Die Seite „Skripte“ führt jedes Feld und jeden Exit-Code auf.

Befehle als Daten

--help --json gibt die Hilfe als ein JSON-Dokument aus, gebaut aus derselben Befehlsregistrierung, mit der die CLI parst, sodass sie immer zur installierten Version passt. Es funktioniert auf der obersten Ebene, bei einer Gruppe oder einem Befehl, und openemail help <command> --json gibt dasselbe aus.

Terminal
openemail send --help --jsonopenemail domains delete --help --json | jq '.commands[0] | {scopes, destructive}'openemail help domains --json | jq -r '.commands[0].subcommands[].command'openemail --help --json | jq -r '.commands[].command'

Das Dokument

schemaVersionnumber
Ändert sich, wenn ein Feld seine Bedeutung ändert
cli, versionstring
Immer `openemail`, und die Version, die es ausgegeben hat
pathstring[]
Der abgefragte Befehl, leer für die oberste Ebene
commandsobject[]
Für die oberste Ebene jeder Befehl der ersten Ebene, sonst der abgefragte, jeweils mit seinen Unterbefehlen
globalFlagsobject[]
Die Flags, die jeder Befehl annimmt, in derselben Form wie die Flags eines Befehls
subcommandAliasesobject
Jeder gemeinsame Alias wie `ls` oder `rm` und die Verben, für die er steht
exitCodesobject[]
Jeder Exit-Code als `{ code, name, meaning }`

Ein Befehl

namestring
Das letzte Wort des Befehls
commandstring
Der ganze Befehl, zum Beispiel `openemail domains delete`
path, aliasesstring[]
Die Wörter nach `openemail`, die zu ihm führen, und seine anderen Namen
summary, descriptionstring
Was er tut, in einer Zeile und ausführlich
usagestring[]
Wie er aufgerufen wird
categorystring | null
Sein Abschnitt in `openemail --help` bei einem Befehl der ersten Ebene, sonst `null`
group, runnable, hiddenboolean
Ob er Unterbefehle hat, ob er für sich allein läuft und ob die Hilfe ihn auslässt
authstring
Die Anmeldung, die er braucht: `required`, `browser` nur für eine Browser-Anmeldung, `optional` oder `none`
scopesstring[]
Die API-Scopes, die jeder seiner Aufrufe braucht
destructiveboolean
Ob er zuerst um Bestätigung bittet, die `--yes` erteilt
argumentsobject[]
`name`, `description`, `required` und `variadic` jedes Arguments
flagsobject[]
`name`, `short`, `kind`, `required`, `repeatable`, `choices`, `placeholder`, `description` und `hidden` jedes Flags
notes, examplesobject[]
Die zusätzlichen Hilfeblöcke als `{ title, lines }` und die Beispiele als `{ command, note }`
resourceobject | null
Bei einem Ressourcenbefehl die SDK-Methode und der REST-Aufruf dahinter, sonst `null`
subcommandsobject[]
Die Befehle unter einer Gruppe, in derselben Form

Eine Ressource

namespacestring
Der SDK-Namespace, zum Beispiel `domains`
sdkMethodstring
Die SDK-Methode, zum Beispiel `openemail.domains.delete`
sdkMethodAllstring | null
Bei einer Liste die `listAll`-Methode, die `--all --json` durchläuft
httpMethod, httpPathstring
Der REST-Aufruf, zum Beispiel `DELETE` und `/domains/{id}`
scopesstring[]
Die Scopes, die die Methode braucht
authstring
`apiKey`, oder `none` und `inboxToken` für eine Methode, die keinen API-Schlüssel sendet
returnsobject
`{ shape, type }`: die Form der Antwort, zum Beispiel `object` oder `page`, und ihr SDK-Typ
paginatesboolean
Ob sie eine Seite einer Liste zurückgibt

Der ganze Baum ist etwa ein Megabyte groß, fast alles davon die 198 Ressourcenbefehle, fragen Sie also nach dem Befehl, den Sie brauchen, oder filtern Sie den Baum mit jq. Der Text behält seine Backticks und enthält keine Farbcodes, und versteckte Befehle wie security sind enthalten, mit hidden auf true.

Probeläufe

--dry-run funktioniert bei jedem Befehl außer mcp serve. Lesezugriffe laufen wie gewohnt, dann wird die erste Anfrage, die etwas ändern würde, ausgegeben statt gesendet, und der Befehl endet mit Exit-Code 0, ohne sonst etwas zu tun. Bestätigungen werden übersprungen, da nichts gesendet wird, sodass ein Agent sehen kann, was ein destruktiver Befehl tun würde, ohne --yes zu übergeben.

Terminal
openemail domains delete <domain-id> --dry-runopenemail send --from [email protected] --to [email protected] --subject "Hi" --text "Hello" --dry-run --json
stdout
{  "dryRun": true,  "request": {    "method": "POST",    "url": "https://api.openemail.uk/emails",    "headers": {      "accept": "application/json",      "authorization": "Bearer [redacted]",      "content-type": "application/json",      "idempotency-key": "58e6fb61-ad2e-401e-b141-7a0546c7c749",      "user-agent": "openemail-cli/0.0.1 openemail-sdk/0.0.5"    },    "body": {      "from": "[email protected]",      "to": [        "[email protected]"      ],      "subject": "Hi",      "text": "Hello"    },    "raw": null  }}
  • Eine Änderung ist jede Anfrage außer GET und HEAD, ein MCP-Tool-Aufruf sowie die An- und Abmeldeanfragen von login und logout. Die Token-Erneuerung und docs ask laufen trotzdem.
  • Der Plan zeigt die Methode, die vollständige URL, die Header mit dem Wert von Authorization gekürzt auf Bearer [redacted] und den JSON-Body, in dem geheime Felder wie ein Resend-Schlüssel geschwärzt sind. Ein Upload zeigt nur seine Größe und seinen Inhaltstyp.
  • Eine Änderung, die auf diesem Rechner bleibt, wie profile use, login --with-token oder das Vergessen eines gespeicherten API-Schlüssels, gibt {"dryRun":true,"local":{"action","profile"}} aus und speichert nichts.
  • Ein Befehl, der vor seiner ersten Änderung ausgibt, was er gelesen hat, zeigt das zuerst: read gibt den Thread aus, dann die Anfrage, die ihn als gelesen markieren würde. Übergeben Sie --no-mark-read, um die zweite wegzulassen.
  • mcp serve lehnt --dry-run mit Exit-Code 2 ab, weil sein Client entscheidet, was gesendet wird. Prüfen Sie stattdessen einen einzelnen Tool-Aufruf mit openemail mcp call <tool> --dry-run vorab.

Fehlende Scopes

Jeder Befehl kennt die API-Scopes, die er immer braucht, und seine Hilfe führt sie auf. Fehlt einer gespeicherten Anmeldung einer davon, fragt der Befehl die API einmal nach der aktuellen Liste, sodass Zugriff, der nach der Anmeldung auf der Website erteilt wurde, sofort zählt. Fehlt der Scope dann immer noch, bricht er mit Exit-Code 4 und dem Code insufficient_scope ab, bevor er etwas fragt oder eine Anfrage sendet:

stderr
{"error":{"type":"cli_error","code":"insufficient_scope","message":"This sign-in does not have the emails:send permission, which openemail send needs.","hint":null,"next":"Give this app more access in Account settings, Connected apps (openemail open apps, then Edit access), or run openemail login --force and choose more access.","status":null,"requestId":null,"param":null,"docUrl":null,"exitCode":4}}
  • Bei einer Browser-Anmeldung sagt next, dass Sie der App unter Konto → Kommandozeile mehr Zugriff geben (openemail open cli, dann Zugriff bearbeiten) oder openemail login --force ausführen und mehr Zugriff wählen sollen. Eine Browser-Anmeldung erhält nie keys:write oder keys:manage, daher verweist sie dafür auf einen API-Schlüssel.
  • Bei einem API-Schlüssel sagt next, dass Sie einen Schlüssel mit diesem Scope verwenden sollen.
  • Ein Schlüssel aus --api-key oder OPENEMAIL_API_KEY wird nicht vorab geprüft, und die API entscheidet. Lehnt die API einen Aufruf wegen eines fehlenden Scopes ab, trägt der Fehler dasselbe next.

Bestätigungscodes

Ein API-Schlüssel braucht nie einen Bestätigungscode. Eine Browser-Anmeldung braucht einen vor einer heiklen Änderung, etwa beim Hinzufügen eines Webhooks, beim Anlegen einer Regel, beim Ändern eines Mitglieds oder beim Entfernen einer Domain, und ein Agent kann ihn nicht eingeben. Bevor der Agent läuft, führt daher ein Mensch entweder openemail verify in einem Terminal mit demselben Profil aus oder wählt Änderungen für 60 Minuten erlauben für diese Anmeldung unter Konto → Kommandozeile. Beides deckt die nächsten 60 Minuten ab.

Terminal
openemail verifyopenemail verify --status --json

verify --status --json sagt dem Agenten, ob das Profil bestätigt ist, in elevated, und bis wann, in elevatedUntil. Ohne Bestätigung bricht die Änderung mit Exit-Code 4 und dem Code step_up_required ab, und nichts wird geändert:

stderr
{"error":{"type":"cli_error","code":"step_up_required","message":"This action needs a verification code, and there is no interactive terminal to ask for one.","hint":null,"next":"Run openemail verify in an interactive terminal first, then run this again within 60 minutes. An API key never needs a code.","status":403,"requestId":"req_9Qm4tV","param":null,"docUrl":"https://openemail.uk/docs/api/errors#step_up_required","exitCode":4}}

Über MCP

Ein Agent, der MCP spricht, kann stattdessen den OpenEmail-MCP-Server nutzen. openemail mcp config --client claude-code, oder codex, cursor und die anderen Clients, die es auflistet, gibt die Einrichtung aus, und openemail mcp serve ist eine lokale Brücke, die die Browser-Anmeldung dieser CLI wiederverwendet. API-Schlüssel erreichen den MCP-Server nicht. Die Seite „KI und MCP“ hat die Einzelheiten.

Rezepte

Ungelesene Threads als JSON
openemail inbox --unread --limit 20 --jsonopenemail inbox --unread --json | jq -r '.items[].id'
Einen Thread lesen, ohne ihn als gelesen zu markieren
openemail read CAHk7pQ2x9LmZ4 --no-mark-read --json
Aus einer Datei senden, sicher wiederholbar
openemail send --from [email protected] --to [email protected] --subject "Weekly report" --body-file report.md --idempotency-key weekly-report-39 --json
Eine Domain nach einem Probelauf hinzufügen
openemail domains create --domain example.com --dry-run --jsonopenemail domains create --domain example.com --json
Prüfen, was die Zugangsdaten dürfen
openemail whoami --json | jq '.scopes'

Der Posteingang,
nach eigenen Regeln.

E-Mail-Infrastruktur für Unternehmen, KI, Agenten und persönliche E-Mail. Gebaut für Skalierung, Privatsphäre und Kontrolle. Alles, was E-Mail vom ersten Tag an hätte haben sollen.

OpenEmail

E-Mail-Infrastruktur für Unternehmen, KI, Agenten und persönliche E-Mail. Gebaut für Skalierung, Privatsphäre und Kontrolle. Alles, was E-Mail vom ersten Tag an hätte haben sollen.

© 2026 OpenEmail. Alle Rechte vorbehalten.