Перейти к документации
CLI

Для ИИ-агентов

Управляйте `openemail` из Claude Code, Codex или задания CI: вход без участия человека, справка как данные, пробные запуски, недостающие scope и коды подтверждения.

Встроенное руководство

openemail agents выводит короткое руководство в Markdown для ИИ-агента вроде Claude Code или Codex или для скрипта в CI: как войти без человека, читать вывод, находить команды, безопасно что-то менять и листать списки, что делать, когда не хватает кода подтверждения или scope, и пять готовых рецептов. openemail agent это та же команда.

Терминал
openemail agentsopenemail agents --json | jq -r '.recipes[].commands[]'

С --json руководство становится одним документом с schemaVersion, title, intro, sections из { id, title, points }, exitCodes и recipes из { id, title, commands }. Вместо того чтобы вставлять эти правила в каждый промпт, один раз скажите агенту в файле инструкций, который ваш проект ему уже даёт, запускать openemail agents перед работой с CLI.

Вход без участия человека

  • Используйте API-ключ. Задайте OPENEMAIL_API_KEY или передайте --api-key одной команде. Создайте его в разделе «Настройки → API-ключи» (openemail open api-keys) только с теми scope, которые нужны агенту. Ключ никогда не открывает браузер и никогда не требует кода подтверждения.
  • Или используйте повторно вход через браузер, который человек один раз выполнил на этой машине через openemail login, и выберите его через --profile <name>. CLI сама обновляет свои токены.
  • Без терминала ничего не спрашивается. Под --json, --no-input или CI, либо без подключённого терминала, значение, которое CLI спросила бы, приводит к остановке с кодом выхода 2, и называется флаг, который нужно передать.
  • Вход через браузер должен одобрить человек, поэтому openemail login без участия человека останавливается с кодом выхода 2 и кодом unattended, прежде чем что-либо зарегистрировать, и указывает на openemail login --with-token.
  • openemail whoami --json показывает рабочее пространство, вид входа и его scopes.

Чтение вывода

Передавайте --json каждой команде. Тогда stdout содержит ровно один JSON-документ или один объект на строку с --ndjson, а ход работы остаётся в stderr. Сбой выводит одну строку {"error":{...}} в stderr: ветвитесь по коду выхода и по её code, показывайте next человеку и никогда не разбирайте message, формулировка которого может измениться. Страница «Скрипты» перечисляет каждое поле и каждый код выхода.

Команды как данные

--help --json выводит справку одним JSON-документом, построенным из того же реестра команд, по которому CLI разбирает аргументы, поэтому он всегда соответствует установленной версии. Это работает на корне, на группе или на команде, а openemail help <command> --json выводит то же самое.

Терминал
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'

Документ

schemaVersionnumber
Меняется, когда поле меняет смысл
cli, versionstring
Всегда `openemail`, и версия, которая его вывела
pathstring[]
Запрошенная команда, пустой для корня
commandsobject[]
Для корня каждая команда верхнего уровня, иначе запрошенная, каждая со своими подкомандами
globalFlagsobject[]
Флаги, которые принимает каждая команда, в том же виде, что и флаги команды
subcommandAliasesobject
Каждый общий псевдоним, например `ls` или `rm`, и глаголы, которые он заменяет
exitCodesobject[]
Каждый код выхода в виде `{ code, name, meaning }`

Команда

namestring
Последнее слово команды
commandstring
Вся команда, например `openemail domains delete`
path, aliasesstring[]
Слова после `openemail`, которые ведут к ней, и её другие имена
summary, descriptionstring
Что она делает, одной строкой и полностью
usagestring[]
Как её вызвать
categorystring | null
Её раздел в `openemail --help` для команды верхнего уровня, иначе `null`
group, runnable, hiddenboolean
Есть ли у неё подкоманды, запускается ли она сама по себе и не скрывает ли её справка
authstring
Вход, который ей нужен: `required`, `browser` только для входа через браузер, `optional` или `none`
scopesstring[]
Scope API, которые нужны каждому её запуску
destructiveboolean
Спрашивает ли она сначала подтверждение, на которое отвечает `--yes`
argumentsobject[]
`name`, `description`, `required` и `variadic` каждого аргумента
flagsobject[]
`name`, `short`, `kind`, `required`, `repeatable`, `choices`, `placeholder`, `description` и `hidden` каждого флага
notes, examplesobject[]
Дополнительные блоки справки в виде `{ title, lines }` и примеры в виде `{ command, note }`
resourceobject | null
Для команды ресурса метод SDK и вызов REST за ней, иначе `null`
subcommandsobject[]
Команды внутри группы, в том же виде

Ресурс

namespacestring
Пространство имён SDK, например `domains`
sdkMethodstring
Метод SDK, например `openemail.domains.delete`
sdkMethodAllstring | null
Для списка метод `listAll`, который обходит `--all --json`
httpMethod, httpPathstring
Вызов REST, например `DELETE` и `/domains/{id}`
scopesstring[]
Scope, которые нужны методу
authstring
`apiKey`, либо `none` и `inboxToken` для метода, который не отправляет API-ключ
returnsobject
`{ shape, type }`: форма ответа, например `object` или `page`, и его тип в SDK
paginatesboolean
Возвращает ли он одну страницу списка

Всё дерево занимает около мегабайта, почти целиком это 198 команд ресурсов, поэтому запрашивайте нужную команду или фильтруйте дерево через jq. Текст сохраняет обратные кавычки и не содержит кодов цвета, а скрытые команды вроде security включены с hidden, равным true.

Пробные запуски

--dry-run работает на всех командах, кроме mcp serve. Чтение выполняется как обычно, затем первый запрос, который что-то изменил бы, выводится вместо отправки, и команда завершается с кодом 0, больше ничего не делая. Подтверждения пропускаются, раз ничего не отправляется, так что агент может увидеть, что сделала бы разрушительная команда, не передавая --yes.

Терминал
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  }}
  • Изменение это любой запрос, кроме GET и HEAD, вызов инструмента MCP, а также запросы входа и выхода у login и logout. Обновление токенов и docs ask всё равно выполняются.
  • План показывает метод, полный URL, заголовки со значением Authorization, урезанным до Bearer [redacted], и JSON-тело, в котором секретные поля, например ключ Resend, скрыты. Загрузка файла показывает только его размер и тип содержимого.
  • Изменение, которое остаётся на этой машине, например profile use, login --with-token или удаление сохранённого API-ключа, выводит {"dryRun":true,"local":{"action","profile"}} и ничего не сохраняет.
  • Команда, которая выводит прочитанное перед первым изменением, показывает это первым: read выводит цепочку, а затем запрос, который отметил бы её прочитанной. Передайте --no-mark-read, чтобы убрать второе.
  • mcp serve отклоняет --dry-run с кодом выхода 2, потому что что отправлять, решает его клиент. Вместо этого просмотрите один вызов инструмента через openemail mcp call <tool> --dry-run.

Недостающие scope

Каждая команда знает scope API, которые ей нужны всегда, и её справка их перечисляет. Когда сохранённому входу не хватает одного из них, команда один раз запрашивает у API текущий список, поэтому доступ, выданный на сайте после входа, учитывается сразу. Если scope всё ещё не хватает, она останавливается с кодом выхода 4 и кодом insufficient_scope, прежде чем что-либо спросить или отправить запрос:

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}}
  • Для входа через браузер next советует дать приложению больше доступа в разделе «Аккаунт → Командная строка» (openemail open cli, затем «Изменить доступ») или запустить openemail login --force и выбрать больше доступа. Входу через браузер никогда не выдаются keys:write и keys:manage, поэтому для них он указывает на API-ключ.
  • Для API-ключа next советует взять ключ, у которого есть этот scope.
  • Ключ из --api-key или OPENEMAIL_API_KEY заранее не проверяется, решает API. Когда API отклоняет вызов из-за недостающего scope, ошибка несёт тот же next.

Коды подтверждения

API-ключу никогда не нужен код подтверждения. Входу через браузер он нужен перед чувствительным изменением, например добавлением вебхука, созданием правила, изменением участника или удалением домена, а агент не может его ввести. Поэтому до запуска агента человек либо запускает openemail verify в терминале с тем же профилем, либо выбирает для этого входа «Разрешить изменения на 60 минут» в разделе «Аккаунт → Командная строка». Любой из вариантов покрывает следующие 60 минут.

Терминал
openemail verifyopenemail verify --status --json

verify --status --json сообщает агенту, подтверждён ли профиль, в elevated, и до какого времени, в elevatedUntil. Без подтверждения изменение останавливается с кодом выхода 4 и кодом step_up_required, и ничего не меняется:

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

Через MCP

Агент, который говорит на MCP, может вместо этого использовать MCP-сервер OpenEmail. openemail mcp config --client claude-code, или codex, cursor и другие клиенты из его списка, выводит настройку, а openemail mcp serve это локальный мост, который использует вход через браузер этой CLI. API-ключи не могут достучаться до MCP-сервера. Подробности на странице «ИИ и MCP».

Рецепты

Непрочитанные цепочки в JSON
openemail inbox --unread --limit 20 --jsonopenemail inbox --unread --json | jq -r '.items[].id'
Прочитать цепочку, не отмечая её прочитанной
openemail read CAHk7pQ2x9LmZ4 --no-mark-read --json
Отправить из файла, безопасно при повторе
openemail send --from [email protected] --to [email protected] --subject "Weekly report" --body-file report.md --idempotency-key weekly-report-39 --json
Добавить домен после пробного запуска
openemail domains create --domain example.com --dry-run --jsonopenemail domains create --domain example.com --json
Проверить, что разрешено учётным данным
openemail whoami --json | jq '.scopes'

Ваши входящие,
на ваших условиях.

Почтовая инфраструктура для бизнеса, ИИ, агентов и личной почты. Создана для масштаба, приватности и контроля. Всё, что должно было быть в почте с первого дня.

OpenEmail

Почтовая инфраструктура для бизнеса, ИИ, агентов и личной почты. Создана для масштаба, приватности и контроля. Всё, что должно было быть в почте с первого дня.

© 2026 OpenEmail. Все права защищены.