پرش به مستندات
CLI

برای عامل‌های هوش مصنوعی

`openemail` را از Claude Code، Codex یا یک کار CI به کار بگیرید: ورود بدون حضور کسی، راهنما به‌صورت داده، اجرای آزمایشی، دامنه‌های مجوزِ ناموجود و کدهای تأیید هویت.

راهنمای داخلی

openemail agents یک راهنمای کوتاه به‌صورت Markdown برای عاملی مانند Claude Code یا Codex، یا برای یک اسکریپت در CI، چاپ می‌کند: چگونه بدون یک انسان وارد شود، خروجی را بخواند، فرمان‌ها را پیدا کند، چیزها را با اطمینان تغییر دهد و صفحه‌به‌صفحه در فهرست‌ها پیش برود، وقتی کد تأیید هویت یا دامنهٔ مجوزی کم است چه کند، و پنج دستورالعمل آماده برای رونوشت. openemail agent همان فرمان است.

ترمینال
openemail agentsopenemail agents --json | jq -r '.recipes[].commands[]'

با --json راهنما یک سند است با schemaVersion، title، intro، sections از { id, title, points }، exitCodes و recipes از { id, title, commands }. به‌جای چسباندن این قاعده‌ها در هر پرامپت، یک بار در همان فایل دستورالعملی که پروژهٔ شما از قبل به عامل می‌دهد، به او بگویید پیش از به کار بردن CLI فرمان openemail agents را اجرا کند.

ورود بدون یک انسان

  • از یک کلید API استفاده کنید. OPENEMAIL_API_KEY را تنظیم کنید، یا --api-key را به یک فرمان بدهید. آن را در تنظیمات ← کلیدهای API (openemail open api-keys) فقط با دامنه‌های مجوزی که عامل نیاز دارد بسازید. کلید هرگز مرورگری باز نمی‌کند و هرگز به کد تأیید هویت نیاز ندارد.
  • یا ورود با مرورگری را که یک انسان یک بار روی همین دستگاه با 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[]
دامنه‌های مجوز 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[]
دامنه‌های مجوزی که متد لازم دارد
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 پیش‌نمایش کنید.

دامنه‌های مجوزِ ناموجود

هر فرمان دامنه‌های مجوز API را که همیشه لازم دارد می‌شناسد و راهنمایش آن‌ها را فهرست می‌کند. وقتی ورود ذخیره‌شده یکی از آن‌ها را ندارد، فرمان یک بار فهرست کنونی را از API می‌پرسد، پس دسترسی‌ای که پس از ورود در وب‌سایت داده شده بی‌درنگ به حساب می‌آید. اگر دامنهٔ مجوز هنوز نباشد، پیش از پرسیدن هر چیزی یا فرستادن درخواستی، با کد خروج 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 می‌گوید از کلیدی استفاده کنید که آن دامنهٔ مجوز را دارد.
  • کلیدی که از --api-key یا OPENEMAIL_API_KEY می‌آید از پیش بررسی نمی‌شود و API تصمیم می‌گیرد. وقتی API فراخوانی‌ای را به خاطر دامنهٔ مجوزِ ناموجود رد کند، خطا همان 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. همه حقوق محفوظ است.