Install
$ agentstack add skill-samir-g-agent-skills-inbox-monitor ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Inbox monitor
Config-driven IMAP inbox poller. One subcommand: update.
uv run "${CLAUDEPLUGINROOT}/skills/inbox-monitor/inbox_monitor.py" \ --config /path/to/config.json update
Default behaviour: fetch only emails received since the last successful run, using a server-side IMAP SINCE filter plus UID dedup. On the very first run (no prior lastSuccess), falls back to scanning the most recent scanLimit UIDs.
Override with --since N to fetch emails from the past N days:
update --since 1 # past day update --since 7 # past week
--since skips UID dedup (so previously-seen messages in the window are re-emitted) and does not write state, so it's safe to use as an ad-hoc query without disrupting the default since-last-run cursor.
Add --json for machine-readable output. --dry-run fetches and prints without writing state.
Config
{ "statePath": "~/.openclaw/workspace/state", "envFile": "~/.openclaw/secrets/assistant-email.env", "imapHost": "imap.gmail.com", "imapPort": 993, "mailbox": "INBOX", "scanLimit": 100, "feedKeywords": ["google alerts", "newsletter", "digest"] }
Keys:
statePath(required) — directory for the state JSON. Relative paths resolve against the config file's directory;~is expanded. The script writesinbox_monitor.jsoninside it.envFile/envFiles— path or list of paths toKEY=VALUEfiles providingASSISTANT_EMAIL_ADDRESSandASSISTANT_EMAIL_APP_PASSWORD. Falls back to the process env.--env-file PATH(repeatable) overrides; later wins.imapHost— IMAP server. Defaultimap.gmail.com. Resolved against a public-IP guard before connecting.imapPort— IMAP port. Default993.mailbox— mailbox to select. DefaultINBOX.scanLimit— most-recent N UIDs to scan per run. Default100.feedKeywords— case-insensitive substrings used to tag a message asfeed(matched againstsubject+from). Default covers common newsletter/digest patterns.
Print a worked example:
uv run inbox_monitor.py example-config
See assistant_email_setup.md for instructions on creating the env file.
State JSON
Written on every run to /inbox_monitor.json. Standard keys plus skill-specific counters:
system,lastRun,lastSuccess,previousSuccess,lastErrorstatus(Healthy/Attention),materialChange,notesnewMessageCount,feedMessageCount,otherMessageCountlastUid— highest IMAP UID seen so farlastArchiveDir— absolute path to the most recent per-run archive (see below); preserved across runs that fetched zero new messages
previousSuccess snapshots the prior lastSuccess on each successful run, so downstream consumers can ask "what landed since last run."
Archive
Each successful run that fetched ≥1 new message writes a per-run directory under the state folder:
/inboxmonitorruns// email-001.md email-002.md ...
Each email-NNN.md is YAML frontmatter (uid, from, subject, date, type) followed by the message body. Body extraction prefers text/plain; falls back to text/html (kept raw) if no plain part exists. Attachments are skipped.
Skipped when: there are no new messages, the run errored, --dry-run is set, or --since N was used (ad-hoc query).
Behaviour
- Uses IMAP
SEARCH SINCEto restrict the server-side scan to the relevant window (date-of-lastSuccessminus one day for timezone margin). UID dedup still runs on top of the result to be precise. - Dedupes by IMAP UID against
lastUid(the monotonic high-water mark). Re-running with no new mail is a no-op apart from thelastRuntimestamp. - SSRF guard rejects
imapHostvalues that resolve to private/loopback/link-local addresses. - Only
ASSISTANT_EMAIL_ADDRESS/ASSISTANT_EMAIL_APP_PASSWORDare read from env. IMAP host/port live in the config (single source of truth). - Exit
0on success,2on failure (config error, missing env, IMAP error). Errors land on stderr; in--jsonmode the state JSON is emitted to stderr on failure so stdout stays clean. - Progress spinner on stderr; suppressed when stderr is not a TTY or
--jsonis set. runner.shis a thin wrapper that runsupdateagainst the co-locatedconfig.json.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: samir-g
- Source: samir-g/agent-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.