AI एजेंटों के लिए
Claude Code, Codex या किसी CI जॉब से `openemail` चलाएँ: बिना किसी व्यक्ति के साइन-इन, डेटा के रूप में मदद, ड्राई रन, छूटे हुए स्कोप और सत्यापन कोड।
बिल्ट-इन गाइड
openemail agents Claude Code या Codex जैसे AI एजेंट, या CI की किसी स्क्रिप्ट के लिए Markdown में एक छोटी गाइड प्रिंट करता है: बिना किसी व्यक्ति के साइन इन कैसे करें, आउटपुट कैसे पढ़ें, कमांड कैसे खोजें, चीज़ें सुरक्षित रूप से कैसे बदलें और सूचियों के पेज कैसे पलटें, सत्यापन कोड या स्कोप न होने पर क्या करें, और कॉपी करने लायक पाँच नुस्खे। openemail agent वही कमांड है।
openemail agentsopenemail agents --json | jq -r '.recipes[].commands[]'--json के साथ गाइड एक दस्तावेज़ होती है जिसमें schemaVersion, title, intro, { id, title, points } वाले sections, exitCodes और { id, title, commands } वाले recipes होते हैं। ये नियम हर प्रॉम्प्ट में चिपकाने के बजाय, जो निर्देश फ़ाइल आपका प्रोजेक्ट एजेंट को पहले से देता है उसमें एक बार बता दें कि 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 पर रहती है। विफलता stderr पर एक {"error":{...}} लाइन प्रिंट करती है: एग्ज़िट कोड और उसके 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`, या API कुंजी न भेजने वाले मेथड के लिए `none` और `inboxToken`
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{ "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एग्ज़िट कोड2के साथ--dry-runको ठुकरा देता है, क्योंकि क्या भेजना है यह उसका क्लाइंट तय करता है। इसकी जगहopenemail mcp call <tool> --dry-runसे किसी एक टूल कॉल का पूर्वावलोकन करें।
छूटे हुए स्कोप
हर कमांड जानती है कि उसे हमेशा किन API स्कोप की ज़रूरत है, और उसकी मदद उनकी सूची देती है। जब किसी सहेजे गए साइन-इन में उनमें से कोई नहीं होता, तो कमांड API से एक बार मौजूदा सूची पूछती है, इसलिए साइन-इन के बाद वेबसाइट पर दी गई पहुँच तुरंत गिनी जाती है। अगर स्कोप फिर भी नहीं है, तो वह कुछ पूछने या कोई अनुरोध भेजने से पहले एग्ज़िट कोड 4 और कोड insufficient_scope के साथ रुकती है:
{"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 --jsonverify --status --json एजेंट को बताता है कि प्रोफ़ाइल सत्यापित है या नहीं, elevated में, और कब तक, elevatedUntil में। सत्यापन के बिना बदलाव एग्ज़िट कोड 4 और कोड step_up_required के साथ रुकता है, और कुछ नहीं बदलता:
{"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 बोलने वाला एजेंट इसकी जगह OpenEmail MCP सर्वर इस्तेमाल कर सकता है। openemail mcp config --client claude-code, या codex, cursor और उसकी सूची के दूसरे क्लाइंट, सेटअप प्रिंट करते हैं, और openemail mcp serve एक लोकल ब्रिज है जो इसी CLI का ब्राउज़र साइन-इन दोबारा इस्तेमाल करता है। API कुंजियाँ MCP सर्वर तक नहीं पहुँच सकतीं। विवरण "AI और MCP" पेज पर है।
नुस्खे
openemail inbox --unread --limit 20 --jsonopenemail inbox --unread --json | jq -r '.items[].id'openemail read CAHk7pQ2x9LmZ4 --no-mark-read --jsonopenemail send --from [email protected] --to [email protected] --subject "Weekly report" --body-file report.md --idempotency-key weekly-report-39 --jsonopenemail domains create --domain example.com --dry-run --jsonopenemail domains create --domain example.com --jsonopenemail whoami --json | jq '.scopes'