← Back to Skills Marketplace
eppieapp

Eppie Email CLI

by Eppie · GitHub ↗ · v0.2.0 · MIT-0
cross-platform ✓ Security Clean
103
Downloads
1
Stars
0
Active Installs
1
Versions
Install in OpenClaw
/install eppie-email-cli
Description
Control the eppie-console CLI mail client to inspect accounts, folders, read/send messages, sync folders, and manage vaults with JSON output and automation s...
README (SKILL.md)

Eppie CLI agent skill\r

\r Use this skill when an autonomous or semi-autonomous agent must operate eppie-console directly.\r \r eppie-console is a console mail client that can work with:\r

  • Gmail,\r
  • Outlook,\r
  • Proton Mail,\r
  • regular IMAP/SMTP email services,\r
  • decentralized peer-to-peer Eppie mail.\r \r

Purpose\r

\r Use eppie-console in a predictable, automation-friendly way to:\r

  • inspect accounts,\r
  • inspect folders,\r
  • read messages,\r
  • send messages,\r
  • sync folders,\r
  • initialize, unlock, and reset the local vault when needed by the task.\r \r This skill focuses on deterministic command execution, structured output handling, and explicit standard-input contracts.\r \r For end-to-end validation, coverage, and reproducible test scenarios, use eppie-cli-agent-test-plan.md.\r \r

How to use this file\r

\r Treat sections marked Normative as the required contract for agent execution.\r Treat sections marked Reference as supporting material, examples, or quick navigation aids.\r \r Normative sections in this file:\r

  • Normative defaults for agents\r
  • Normative rules\r
  • Normative command patterns for agents\r
  • Normative stdin contracts\r
  • Normative execution policy for autonomous agents\r
  • Normative error handling\r \r Reference sections in this file:\r
  • Reference: preferred installation\r
  • Reference: required inputs\r
  • Reference: launch modes\r
  • Reference: decision guide\r
  • Reference: end-to-end agent scenarios\r
  • Reference: command-specific notes and examples\r
  • Reference: recommended agent workflow\r
  • Reference: known limitations\r
  • Reference: contributing\r \r

Normative defaults for agents\r

\r When the task requires executing eppie-console, use these defaults unless the task explicitly requires otherwise:\r \r

  1. use --non-interactive=true\r
  2. use --output=json for agent automation unless text output is explicitly required\r
  3. use --unlock-password-stdin=true for stateful commands that need an existing vault\r
  4. use --assume-yes=true for destructive automation\r
  5. provide stdin exactly in the required order\r
  6. use one consistent working directory per vault\r \r Canonical command patterns and exact stdin contracts are defined later in this file. Use those sections as the single source of truth for agent execution.\r \r

Use this skill when\r

\r

  • the task requires executing eppie-console\r
  • the agent must inspect accounts, folders, messages, or contacts\r
  • the agent must send a message\r
  • the agent must synchronize a folder\r
  • the agent must initialize or reset the local vault\r
  • the agent must work with machine-readable CLI output\r \r

Do not use this skill when\r

\r

  • the task does not require calling eppie-console\r
  • the task is only to explain behavior conceptually without running commands\r
  • the task is primarily about test coverage or validation workflows; use eppie-cli-agent-test-plan.md\r
  • an interactive REPL session is not explicitly required but would be the only execution path\r
  • the required executable or working directory is unavailable\r \r

Reference: preferred installation\r

\r Prefer the executable published in GitHub Releases.\r You can also build from source.\r \r Latest release page:\r

Linux\r

macOS\r

Windows\r

Reference: required inputs\r

\r

Common inputs\r

  • path to eppie-console\r
  • working directory\r
  • whether the task requires stateful access to an existing vault\r
  • whether structured JSON output is required\r \r

Vault access inputs\r

  • vault password\r
  • whether the vault must be initialized first\r \r

Reading inputs\r

  • account identifier for -a; for agent workflows, use the account address string returned by list-accounts in data[].address\r
  • folder name when folder-specific access is needed\r
  • message id\r
  • message pk\r
  • page size and total limit for paged commands\r \r

Sending inputs\r

  • sender address\r
  • receiver address\r
  • subject\r
  • message body\r \r

Account creation inputs\r

  • account type\r
  • vault password\r
  • structured JSON payload when required\r
  • provider-specific secrets only through standard input when supported\r \r

Reference: launch modes\r

\r

Interactive mode\r

Use only when a REPL session is explicitly needed.\r \r Example:\r

  • eppie-console\r \r Typical sequence:\r
  • open\r
  • vault password\r
  • list-accounts\r
  • exit\r \r open is useful in interactive mode to open the local vault inside the current process.\r \r

Non-interactive mode\r

Prefer this mode for agents.\r \r Use:\r

  • eppie-console --non-interactive=true \x3Ccommand> [command options]\r \r To avoid passing the same startup flags on every call, you can put them in appsettings.json next to eppie-console, for example:\r
  • { "non-interactive": true, "output": "json", "unlock-password-stdin": true }\r \r eppie-console also reads configuration from environment variables.\r \r When the default .NET host configuration pipeline is used, environment variables override appsettings.json. Command-line arguments override both.\r \r For structured machine-readable output, also use:\r
  • --output=json\r \r JSON responses use a normalized envelope:\r
  • type: result, status, warning, or error\r
  • code: stable machine-readable outcome code\r
  • data: payload for result and status responses\r
  • meta: optional metadata for result responses; usually null, but paged read commands can return objects such as {"header":"All messages:","returned":5,"hasMore":true}\r
  • message: human-readable warning/error text\r \r In --non-interactive=true --output=json mode, structured responses are emitted on stdout without a preceding stack trace on stderr for handled command failures such as unhandledException.\r \r In non-interactive mode, do not use open as part of the agent workflow. It does not establish reusable state for later process launches. For stateful non-interactive commands, use --unlock-password-stdin=true instead.\r \r For all agent examples in this file, \x3Caccount> means the account address returned by list-accounts in data[].address. Prefer that address string for -a instead of the numeric id, unless a command explicitly documents another identifier format.\r \r Common success-output examples:\r
  • --non-interactive=true --output=json list-accounts (with accounts):\r
    • {"type":"result","code":"accounts","data":[{"id":1,"address":"\x3Caddress>","accountType":"Dec"}],"meta":null}\r
  • --non-interactive=true --assume-yes=true --output=json reset:\r
    • {"type":"status","code":"reset","data":null}\r
  • --non-interactive=true --unlock-password-stdin=true --output=json send ...:\r
    • {"type":"status","code":"messageSent","data":{"subject":"\x3Csubject>","to":"\x3Creceiver>","from":"\x3Csender>"}}\r
  • --non-interactive=true --unlock-password-stdin=true --output=json sync-folder ...:\r
    • {"type":"status","code":"folderSynced","data":{"account":"\x3Caccount>","folder":"Inbox"}}\r
  • --non-interactive=true --unlock-password-stdin=true --output=json show-all-messages ...:\r
    • {"type":"result","code":"messages","data":[{"id":1,"pk":1,"to":["\x3Creceiver>"],"from":["\x3Csender>"],"folder":"Inbox","subject":"\x3Csubject>"}],"meta":{"header":"All messages:","returned":1,"hasMore":false}}\r \r Additional command-specific JSON result shapes are documented later in Reference: command-specific notes and examples.\r \r Common text success-output examples:\r
  • open:\r
    • The application was opened successfully.\r
  • reset:\r
    • The application has just been reset.\r
  • add-account -t dec:\r
    • Account \x3Cgenerated-address> added (Dec).\r
  • send:\r
    • Message sent from \x3Csender> to \x3Creceiver>. Subject: \x3Csubject>\r
  • sync-folder -f Inbox:\r
    • Folder 'Inbox' for account \x3Caccount> synchronized.\r \r

Normative rules\r

\r

  • Treat Normative command patterns for agents and Normative stdin contracts as normative for agent workflows.\r
  • Put global launch options before -- and put the startup command after --.\r
  • Do not assume open creates a reusable session for future process launches.\r
  • Synchronize the relevant folder before reading when the task requires newly arrived messages.\r
  • Do not guess provider-specific folder names; call list-folders first.\r
  • Use -l / --limit when predictable payload size matters.\r
  • Do not pass account secrets in command-line arguments when structured standard input is supported.\r \r eppie-console open only opens the vault inside the current process.\r It does not create a reusable session for future process launches.\r \r

Normative command patterns for agents\r

\r Use this section as the single source of truth for agent command lines. Unless text output is explicitly required, all agent examples below use --output=json.\r \r | Task | Canonical command |\r | --- | --- |\r | Initialize a vault | --non-interactive=true --output=json -- init |\r | List accounts | --non-interactive=true --unlock-password-stdin=true --output=json -- list-accounts |\r | List folders | --non-interactive=true --unlock-password-stdin=true --output=json -- list-folders -a \x3Caccount> |\r | Show all messages | --non-interactive=true --unlock-password-stdin=true --output=json -- show-all-messages -s 10 -l 10 |\r | Show one message | --non-interactive=true --unlock-password-stdin=true --output=json -- show-message -a \x3Caccount> -f \x3Cfolder> -i \x3Cid> -k \x3Cpk> |\r | Delete one message | --non-interactive=true --unlock-password-stdin=true --output=json -- delete-message -a \x3Caccount> -f \x3Cfolder> -i \x3Cid> -k \x3Cpk> |\r | List contacts | --non-interactive=true --unlock-password-stdin=true --output=json -- list-contacts -s 10 -l 10 |\r | Show contact messages | --non-interactive=true --unlock-password-stdin=true --output=json -- show-contact-messages -c \x3Ccontact> -s 10 -l 10 |\r | Show folder messages | --non-interactive=true --unlock-password-stdin=true --output=json -- show-folder-messages -a \x3Caccount> -f \x3Cfolder> -s 10 -l 10 |\r | Sync a folder | --non-interactive=true --unlock-password-stdin=true --output=json -- sync-folder -a \x3Caccount> -f \x3Cfolder> |\r | Send a message | --non-interactive=true --unlock-password-stdin=true --output=json -- send -s \x3Csender> -r \x3Creceiver> -t "\x3Csubject>" |\r | Reset local data | --non-interactive=true --assume-yes=true --output=json -- reset |\r | Add a DEC account | --non-interactive=true --unlock-password-stdin=true --output=json -- add-account -t dec |\r | Add a regular IMAP/SMTP account | --non-interactive=true --unlock-password-stdin=true --output=json -- add-account -t email --input-json-stdin |\r | Add a Proton Mail account | --non-interactive=true --unlock-password-stdin=true --output=json -- add-account -t proton --input-json-stdin |\r \r

Normative stdin contracts\r

\r Provide stdin exactly in the documented order. Unless a command explicitly reads until end-of-stream, stop after the documented input has been written.\r \r | Command | Exact stdin contract | EOF required |\r | --- | --- | --- |\r | --non-interactive=true --output=json -- init | line 1: new vault password | no |\r | --non-interactive=true --unlock-password-stdin=true --output=json -- list-accounts | line 1: vault password | no |\r | --non-interactive=true --unlock-password-stdin=true --output=json -- list-folders -a \x3Caccount> | line 1: vault password | no |\r | --non-interactive=true --unlock-password-stdin=true --output=json -- show-all-messages -s \x3Cpage-size> -l \x3Climit> | line 1: vault password | no |\r | --non-interactive=true --unlock-password-stdin=true --output=json -- show-message -a \x3Caccount> -f \x3Cfolder> -i \x3Cid> -k \x3Cpk> | line 1: vault password | no |\r | --non-interactive=true --unlock-password-stdin=true --output=json -- delete-message -a \x3Caccount> -f \x3Cfolder> -i \x3Cid> -k \x3Cpk> | line 1: vault password | no |\r | --non-interactive=true --unlock-password-stdin=true --output=json -- list-contacts -s \x3Cpage-size> -l \x3Climit> | line 1: vault password | no |\r | --non-interactive=true --unlock-password-stdin=true --output=json -- show-contact-messages -c \x3Ccontact> -s \x3Cpage-size> -l \x3Climit> | line 1: vault password | no |\r | --non-interactive=true --unlock-password-stdin=true --output=json -- show-folder-messages -a \x3Caccount> -f \x3Cfolder> -s \x3Cpage-size> -l \x3Climit> | line 1: vault password | no |\r | --non-interactive=true --unlock-password-stdin=true --output=json -- sync-folder -a \x3Caccount> -f \x3Cfolder> | line 1: vault password | no |\r | --non-interactive=true --unlock-password-stdin=true --output=json -- send -s \x3Csender> -r \x3Creceiver> -t "\x3Csubject>" | line 1: vault password; line 2 and later: message body; then close stdin | yes |\r | --non-interactive=true --assume-yes=true --output=json -- reset | no stdin | no |\r | --non-interactive=true --unlock-password-stdin=true --output=json -- add-account -t dec | line 1: vault password | no |\r | --non-interactive=true --unlock-password-stdin=true --output=json -- add-account -t email --input-json-stdin | line 1: vault password; remaining bytes: one JSON object | yes |\r | --non-interactive=true --unlock-password-stdin=true --output=json -- add-account -t proton --input-json-stdin | line 1: vault password; remaining bytes: one JSON object | yes |\r \r

Command summary\r

\r | Command group | Needs existing vault | Use --unlock-password-stdin=true | Prefer --output=json | Notes |\r | --- | --- | --- | --- | --- |\r | init | no | no | yes for agent workflows | writes a new local vault password from stdin |\r | reset | no | no | yes | destructive; also use --assume-yes=true |\r | list-accounts, list-folders | yes | yes | yes | inspect vault content |\r | show-all-messages, show-message, show-folder-messages, show-contact-messages | yes | yes | yes | use -l when payload size matters |\r | sync-folder | yes | yes | yes | call before reading when fresh messages are required |\r | send | yes | yes | yes | password first in stdin, then body until EOF |\r | add-account -t dec | yes | yes | yes | simple vault-backed account creation |\r | add-account -t email, add-account -t proton | yes | yes | yes | use --input-json-stdin; do not pass secrets in arguments |\r \r

Avoid these mistakes\r

\r

  • Do not use open in a non-interactive workflow.\r
  • Do not guess provider-specific folder names; call list-folders first.\r
  • Do not rely only on process exit code when JSON output is available.\r
  • Do not omit -l when an agent needs a predictable maximum payload size.\r
  • Do not pass secrets in command-line arguments when structured standard input is supported.\r \r

Normative execution policy for autonomous agents\r

\r

Output handling\r

  • Follow the Normative defaults for agents defaults unless the task explicitly requires otherwise.\r
  • Parse type, code, data, meta, and message from the normalized envelope.\r
  • Do not rely only on process exit code when structured output is available.\r
  • Treat warning and error responses as non-success outcomes even when the process exits cleanly.\r \r

Standard input handling\r

  • Follow Normative stdin contracts exactly.\r
  • For send, close stdin after the last body line.\r
  • For commands using --input-json-stdin, pass the password first when required, then the JSON payload.\r
  • Do not prepend labels, prompts, or extra blank lines to the documented stdin contract.\r \r

Working directory handling\r

  • Use one consistent working directory for related commands that operate on the same local vault.\r
  • Use an isolated working directory when the run is disposable or destructive.\r \r

Account identifier handling\r

  • For agent workflows, pass the account address from list-accounts data[].address to -a.\r
  • Do not assume the numeric id is accepted interchangeably by all commands.\r
  • Re-read the current address from list-accounts when a workflow depends on a newly created account.\r \r

Pagination handling\r

  • Use both -s / --page-size and -l / --limit in agent workflows when payload size must be predictable.\r
  • Treat -s as page size only. Treat -l as the total maximum number of records returned by the command.\r
  • If -l is omitted, paged read commands return up to 20 records by default.\r
  • Use meta.returned to confirm how many records were actually returned.\r
  • Use meta.hasMore to decide whether another read with a higher -l or a narrower filter is needed.\r
  • Do not assume provider folders or message volume are small enough to omit -l.\r \r

Reference: decision guide\r

\r Use Normative command patterns for agents for the exact command line. This guide is only for choosing the next command.\r \r

  • inspect available accounts → list-accounts\r
  • inspect available folders for an account → list-folders\r
  • inspect recent messages across folders → sync the relevant folders when new messages are required, then use show-all-messages\r
  • inspect messages in a specific folder → list-folders, then sync-folder, then show-folder-messages when new messages are required\r
  • inspect one message → show-message\r
  • delete one message → delete-message\r
  • inspect contacts → list-contacts\r
  • inspect messages for one contact → show-contact-messages\r
  • send a message → send\r
  • sync one folder → list-folders, then sync-folder\r
  • initialize a vault → init\r
  • reset local data → reset\r \r

Reference: end-to-end agent scenarios\r

\r This section is informative. Use Normative command patterns for agents for the exact command line and Normative stdin contracts for the exact stdin shape.\r \r

Initialize a new vault, add an account, then verify it\r

\r Use this flow when the working directory does not yet contain the required local vault.\r \r

  1. initialize the vault with init\r
  2. add the required account with add-account\r
  3. verify the created account with list-accounts\r
  4. use the returned data[].address as \x3Caccount> in later commands\r \r Typical sequences:\r
  • DEC account: initadd-account -t declist-accounts\r
  • regular IMAP/SMTP account: initadd-account -t emaillist-accounts\r
  • Proton Mail account: initadd-account -t protonlist-accounts\r \r Agent notes:\r
  • keep one consistent working directory across the whole sequence so all commands operate on the same local vault\r
  • for add-account -t email and add-account -t proton, provide the structured payload through standard input after the vault password as documented in Normative stdin contracts\r
  • after account creation, re-read the current address from list-accounts instead of assuming another identifier format\r \r

Read the latest message from a specific folder\r

\r Use this flow when the task requires a concrete folder such as inbox or sent mail and the messages may have changed since the last sync.\r \r

  1. inspect accounts with list-accounts\r
  2. inspect folders for the chosen account with list-folders\r
  3. choose the correct folder name from data[].fullName or data[].roles\r
  4. synchronize that folder with sync-folder\r
  5. read a bounded message list with show-folder-messages\r
  6. open one returned message with show-message using its id and pk\r \r Typical sequence:\r
  • list-accountslist-folderssync-foldershow-folder-messagesshow-message\r \r Agent notes:\r
  • do not guess the folder name; use the fullName returned by list-folders\r
  • use -s and -l on show-folder-messages when predictable payload size matters\r
  • when meta.hasMore is true, treat the result as partial and increase -l only if the task requires a larger set\r \r

Send a message from an existing account\r

\r Use this flow when the local vault already contains the sender account and the task is to deliver one message deterministically.\r \r

  1. inspect accounts with list-accounts\r
  2. choose the sender address from data[].address\r
  3. call send with the sender, receiver, and subject\r
  4. pass the vault password on the first stdin line\r
  5. pass the message body starting from line 2, then close stdin\r \r Typical sequence:\r
  • list-accountssend\r \r Agent notes:\r
  • if the sender is unknown or the workflow depends on a newly created account, refresh the account list before sending\r
  • in --non-interactive=true mode, send reads the body until end-of-stream, so the agent should close stdin after the last body line\r
  • prefer --output=json and verify the messageSent status response instead of relying only on the process exit code\r \r

Reference: command-specific notes and examples\r

\r The canonical command lines are defined in Normative command patterns for agents, and the exact inputs are defined in Normative stdin contracts. This section keeps only command-specific notes, result shapes, and examples that are easy to reference during agent execution.\r \r

Init local vault\r

Notes:\r

  • writes a new local vault password from stdin\r \r

Show all messages\r

Notes:\r

  • -s / --page-size controls only the page size\r
  • -l / --limit caps the total number of returned records and should be used by agents to keep payload size predictable\r
  • if -l is omitted, paged read commands return up to 20 records by default\r
  • message items use the same address shape as show-message: to and from are arrays\r
  • paged result metadata can include returned and hasMore\r
  • agents should check meta.hasMore before assuming the returned list is complete\r \r

List folders\r

Expected result shape:\r

  • {"type":"result","code":"folders","data":[{"fullName":"Inbox","unreadCount":0,"totalCount":0,"roles":["inbox"]}],"meta":{"account":"\x3Caccount>"}}\r \r Notes:\r
  • \x3Caccount> should be the account address from list-accounts data[].address\r
  • use this command before show-folder-messages or sync-folder instead of guessing provider-specific folder names\r
  • Proton may expose names such as All Sent; rely on the returned fullName\r
  • use roles when you need a machine-readable way to find folders such as inbox or sent mail\r \r

Delete one message\r

Notes:\r

  • when called for a message outside Trash, the command moves the message to Trash\r
  • when called for a message already in Trash, the command deletes it permanently\r \r

Show contact messages\r

Notes:\r

  • paged result metadata can include returned and hasMore\r \r

Show folder messages\r

Notes:\r

  • paged result metadata can include returned and hasMore\r \r

Sync folder\r

Expected result shape:\r

  • {"type":"status","code":"folderSynced","data":{"account":"\x3Caccount>","folder":"Inbox"}}\r \r

Send message\r

Examples:\r

  • vault password\r
  • Hello from automation\r
  • Second body line\r
  • close stdin\r \r Notes:\r
  • in --non-interactive=true mode, send reads the message body until end-of-stream\r
  • JSON success shape: {"type":"status","code":"messageSent","data":{"subject":"\x3Csubject>","to":"\x3Creceiver>","from":"\x3Csender>"}}\r \r PowerShell example with the command line and exact stdin in one block:\r \r
@"\r
vault password\r
Hello from automation\r
Second body line\r
"@ | .\eppie-console --non-interactive=true --unlock-password-stdin=true --output=json -- send -s [email protected] -r [email protected] -t "Hello from automation"\r
```\r
\r
Linux / bash example with the command line and exact `stdin` in one block:\r
\r
```bash\r
cat \x3C\x3C'EOF_INPUT' | ./eppie-console --non-interactive=true --unlock-password-stdin=true --output=json -- send -s [email protected] -r [email protected] -t "Hello from automation"\r
vault password\r
Hello from automation\r
Second body line\r
EOF_INPUT\r
```\r
\r
Notes:\r
- on Linux and macOS, use `./eppie-console` after extracting the archive and making sure the file is executable.\r
\r
### Open local vault\r
Use `open` only in interactive mode when the agent is already inside a REPL session and must open the local vault in that same process.\r
\r
Notes:\r
- do not use `open` as part of the non-interactive agent workflow\r
\r
### Reset local data\r
Notes:\r
- `reset` is a destructive command and should be called with `--assume-yes=true` in automation or other non-interactive scripts.\r
\r
### Add DEC account\r
Expected result shape:\r
- `{"type":"result","code":"accountAdded","data":{"address":"\x3Cgenerated-address>","accountType":"Dec"},"meta":null}`\r
\r
### Add regular IMAP/SMTP account\r
Examples:\r
\r
JSON object:\r
\r
```json\r
{\r
  "email": "[email protected]",\r
  "accountPassword": "account password",\r
  "imapServer": "imap.example.com",\r
  "imapPort": 993,\r
  "smtpServer": "smtp.example.com",\r
  "smtpPort": 465\r
}\r
```\r
\r
`stdin` shape:\r
- first line: `vault password`\r
- remaining bytes:\r
\r
```json\r
{"email":"[email protected]","accountPassword":"account password","imapServer":"imap.example.com","imapPort":993,"smtpServer":"smtp.example.com","smtpPort":465}\r
```\r
\r
Notes:\r
- use this mode for regular IMAP/SMTP providers when browser-based OAuth is not needed\r
- do not pass account secrets in command-line arguments\r
- required structured properties are `email`, `accountPassword`, `imapServer`, `imapPort`, `smtpServer`, and `smtpPort`\r
- invalid structured input returns one of these machine-readable errors:\r
  - `structuredStandardInputInvalidJson`\r
  - `structuredStandardInputMissingProperty`\r
\r
### Add Proton Mail account\r
Examples:\r
\r
JSON object:\r
\r
```json\r
{\r
  "email": "[email protected]",\r
  "accountPassword": "account password",\r
  "mailboxPassword": "mailbox password",\r
  "twoFactorCode": "123456"\r
}\r
```\r
\r
`stdin` shape:\r
- first line: `vault password`\r
- remaining bytes:\r
\r
```json\r
{"email":"[email protected]","accountPassword":"account password","mailboxPassword":"mailbox password"}\r
```\r
\r
Notes:\r
- do not pass Proton secrets in command-line arguments\r
- `email` and `accountPassword` are required in structured input\r
- `mailboxPassword` is required only if the Proton flow asks for it\r
- `twoFactorCode` is required only if the Proton flow asks for it\r
- if the mailbox password is the same as the account password, repeat the same value in `mailboxPassword`\r
- invalid structured input returns one of these machine-readable errors:\r
  - `structuredStandardInputInvalidJson`\r
  - `structuredStandardInputMissingProperty`\r
\r
## Reference: recommended agent workflow\r
\r
1. Start from the defaults in `Normative defaults for agents`.\r
2. Choose the exact command line from `Normative command patterns for agents`.\r
3. Provide `stdin` in the exact shape defined in `Normative stdin contracts`.\r
4. Use the account address from `list-accounts` `data[].address` for `-a`.\r
5. Use an isolated working directory when the run is disposable or destructive.\r
6. For message reading:\r
   - start with `list-folders` if the next step requires a specific folder name,\r
   - synchronize the relevant folder before reading when you need newly arrived messages,\r
   - then use `show-all-messages` when you need recent messages across all folders,\r
   - then call `show-message` or `delete-message` with the returned `id` and `pk`.\r
7. In `--non-interactive=true` mode text output stops after the first page instead of prompting.\r
8. For common task chains, use `Reference: end-to-end agent scenarios` as a quick reference.\r
\r
## Reference: known limitations\r
\r
### Some commands still require explicit non-interactive inputs\r
`--non-interactive=true` suppresses interactive prompts, but it does not invent missing data.\r
\r
Commands that normally ask follow-up questions still need explicit arguments or `stdin` data.\r
The main examples are already covered above:\r
- `send` reads the message body until end-of-stream in `--non-interactive=true` mode\r
- `add-account -t email` and `add-account -t proton` should use `--input-json-stdin`\r
- destructive commands such as `reset` still need `--assume-yes=true`\r
- paged read commands still default to 20 records when `-l` is omitted\r
\r
## Normative error handling\r
\r
For agent automation, prefer deterministic handling over implicit retries.\r
\r
### Interpret the normalized envelope\r
\r
When `--output=json` is enabled, handle responses by `type` first:\r
\r
| `type` | Meaning | Agent action |\r
| --- | --- | --- |\r
| `result` | command returned data | parse `data` and `meta` |\r
| `status` | command completed successfully without a list-style result | read `data` when present |\r
| `warning` | handled problem or non-success condition | inspect `code`; do not assume success; stop unless the workflow explicitly defines a recovery step |\r
| `error` | handled failure | inspect `code`, `message`, and `data`; stop unless the input can be corrected deterministically |\r
\r
### Common machine-readable codes\r
\r
| `code` | Meaning | Typical agent response |\r
| --- | --- | --- |\r
| `invalidPassword` | vault password was rejected | stop; do not retry automatically with the same password |\r
| `structuredStandardInputInvalidJson` | structured payload is not valid JSON | fix serialization and retry once with corrected JSON |\r
| `structuredStandardInputMissingProperty` | required JSON property is missing or empty | provide the missing property and retry once |\r
| `unhandledException` | command failed and returned exception details | inspect `data.exceptionType` and command context; do not retry blindly |\r
\r
### Agent response rules\r
\r
- Parse `type` first, then `code`.\r
- Do not treat `warning` as success.\r
- Do not retry `invalidPassword` automatically.\r
- Retry only when the failure is deterministic and local to the request, such as malformed JSON or a missing structured property.\r
- When retrying after `structuredStandardInputInvalidJson` or `structuredStandardInputMissingProperty`, change only the invalid input and keep the command line unchanged.\r
- For `unhandledException`, record the command, the parsed `code`, and `data.exceptionType` when present.\r
- When a paged read returns `meta.hasMore: true`, treat that as an incomplete result set rather than an error.\r
\r
### Error-output examples\r
\r
Invalid password example:\r
- `{"type":"warning","code":"invalidPassword","message":"Warning: Invalid password.","data":null}`\r
\r
Unknown sender account example for `send`:\r
- `{"type":"error","code":"unhandledException","message":"An error has occurred: ...","data":{"exceptionType":"Tuvi.Core.Entities.AccountIsNotExistInDatabaseException"}}`\r
\r
Invalid Proton structured input example:\r
- `{"type":"error","code":"structuredStandardInputInvalidJson","message":"Error: The remaining standard input for the 'add-account' command is not valid JSON.","data":{"commandName":"add-account"}}`\r
\r
Missing Proton structured property example:\r
- `{"type":"error","code":"structuredStandardInputMissingProperty","message":"Error: The structured standard input for the 'add-account' command must contain a non-empty 'email' property.","data":{"commandName":"add-account","propertyName":"email"}}`\r
\r
## Reference: contributing\r
\r
Contributions are welcome.\r
\r
Please open issues for bugs, UX problems, and feature ideas.\r
Pull requests on GitHub are also welcome.\r
\r
Repository:\r
- https://github.com/Eppie-io/Eppie-CLI\r
Usage Guidance
This skill is a detailed automation contract for the eppie-console CLI and appears coherent. Before installing or enabling it: (1) ensure you have the eppie-console binary from a trusted source (verify GitHub release checksums) and place it where your agent expects; (2) do not provide vault passwords or provider secrets to untrusted agents — the skill expects vault passwords via stdin and supports destructive commands (reset) when --assume-yes is used; (3) if you enable autonomous agents with this skill, restrict their permissions and review any commands they will run to avoid accidental data loss or message sending; (4) consider updating the skill metadata to declare the required binary so automated eligibility checks can warn if eppie-console is missing.
Capability Analysis
Type: OpenClaw Skill Name: eppie-email-cli Version: 0.2.0 The skill bundle provides a comprehensive and well-structured interface for an AI agent to operate the `eppie-console` email CLI. It includes detailed 'Normative' instructions in `SKILL.md` (and its duplicate `eppie-cli-agent-skill.md`) for managing email accounts, reading/sending messages, and handling local vaults across services like Gmail and Proton Mail. The skill demonstrates good security practices by explicitly directing the agent to pass sensitive credentials via standard input (stdin) rather than command-line arguments and by utilizing non-interactive JSON output for deterministic processing. No evidence of malicious intent, unauthorized data exfiltration, or harmful prompt injection was found.
Capability Tags
requires-oauth-token
Capability Assessment
Purpose & Capability
The name/description match the instructions: the file documents how an agent should drive the eppie-console CLI to inspect accounts, read/send messages, sync folders, and manage a vault. The skill does not ask for unrelated permissions or credentials. Minor note: the registry metadata lists no required binaries even though the skill expects a path to the eppie-console executable at runtime; this is an omission in metadata rather than a functionality mismatch.
Instruction Scope
The SKILL.md stays focused on CLI usage and deterministic stdin/CLI patterns. It explicitly instructs agents to pass vault passwords and provider-specific secrets via stdin (which is standard for CLI automation) and recommends using --non-interactive/--output=json. It also recommends --assume-yes=true for destructive operations; while coherent for automation, that enables potentially destructive actions (reset, remove) if an agent runs without appropriate guardrails.
Install Mechanism
This is an instruction-only skill and contains only reference download URLs pointing to GitHub Releases (well-known release host). There is no install spec that would cause arbitrary code to be fetched/installed by the platform itself.
Credentials
The skill does not declare required environment variables or credentials (registry metadata lists none). The document does mention that eppie-console can read appsettings.json and environment variables and that vault passwords and provider secrets should be supplied via stdin. This is proportional to the CLI's purpose, but users/agents should be aware that environment variables or config files adjacent to the executable can affect behavior and must be managed by whoever runs the agent.
Persistence & Privilege
The skill does not request persistent privileges (always:false) and does not install background components. Autonomous invocation is allowed by default on the platform; combined with the ability to unlock/reset vaults, that means an agent with this skill could perform destructive actions if given roaming authority — the skill itself does not demand persistent elevated privileges.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install eppie-email-cli
  3. After installation, invoke the skill by name or use /eppie-email-cli
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v0.2.0
- Added SKILL.md with comprehensive guidelines for agent-driven use of eppie-console, including normative defaults and command patterns. - Clarified recommended launch modes (interactive vs non-interactive) and provided installation references for all platforms. - Detailed required inputs for common agent tasks: reading, sending, account creation, and vault management. - Defined when to use (and not use) this skill to focus on automation and machine-readable workflows. - Included examples of structured JSON outputs and error handling policies for reliable agent integration.
Metadata
Slug eppie-email-cli
Version 0.2.0
License MIT-0
All-time Installs 0
Active Installs 0
Total Versions 1
Frequently Asked Questions

What is Eppie Email CLI?

Control the eppie-console CLI mail client to inspect accounts, folders, read/send messages, sync folders, and manage vaults with JSON output and automation s... It is an AI Agent Skill for Claude Code / OpenClaw, with 103 downloads so far.

How do I install Eppie Email CLI?

Run "/install eppie-email-cli" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is Eppie Email CLI free?

Yes, Eppie Email CLI is completely free, licensed under MIT-0. You can download, install and use it at no cost.

Which platforms does Eppie Email CLI support?

Eppie Email CLI is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created Eppie Email CLI?

It is built and maintained by Eppie (@eppieapp); the current version is v0.2.0.

💬 Comments