You have too much email. You already knew that. What you might not know is that OpenClaw can act as a 24×7 sorting hat that surfaces only what matters and quietly takes care of the rest.
Below is a practical, from-scratch tutorial on building an OpenClaw email triage system prioritizing important messages – urgent (ping me right now), important (include in my daily briefing), routine (auto-handle) and junk (archive forever).

Why OpenClaw for email triage?

Traditional filters are brittle: one Regex miss and the CFO’s message lands in spam. OpenClaw combines LLM reasoning, tool integrations and persistent memory to make the rules less hard-coded and more adaptive. Thanks to Composio, you get Gmail, Outlook, Fastmail and IMAP out of the box. Everything below works on OpenClaw v0.47.2 (Node 22+) locally or on ClawCloud; I’ll show both paths.

Prerequisites and fast setup

Local install (dev box or server):

# Node 22 is mandatory for the worker threads rewrite brew install node@22 # or asdf install nodejs 22.5.0 npm install -g openclaw@0.47.2 openclaw daemon start # boots gateway on http://localhost:3033

ClawCloud (hosted, less yak-shaving):

  1. Sign in → New Agent → Name it mail-triage.
  2. Choose the Gmail or IMAP integration.
  3. Click Deploy. 60 s later you have a public gateway URL.

The rest of the guide is identical; just swap localhost for your ClawCloud URL when you hit APIs.

Connect the email inbox

Using the Gmail adapter

OpenClaw uses OAuth2 under the hood. In the gateway UI go to Integrations → Gmail → Connect, grant scopes gmail.readonly and gmail.modify. Behind the curtain Claw stores the token in its encrypted secrets store (~/.claw/secrets.json locally, KMS on Cloud).

IMAP fallback

If your company forbids Gmail OAuth, use plain IMAP:

{ "type": "imap", "host": "imap.acme.com", "port": 993, "secure": true, "auth": { "user": "me@acme.com", "pass": "CHANGE_ME" } }

Add the JSON above in Settings → Tool Config → Email IMAP.

Designing the four-tier priority model

Borrowing from airline boarding but for email:

  • Tier 0 – Urgent: incidents, production alerts, messages from the CEO. Notify immediately via Slack/Signal.
  • Tier 1 – Important: stuff you want in your daily briefing at 8 AM.
  • Tier 2 – Routine: receipts, GitHub notifications, newsletters. Auto-archive after action.
  • Tier 3 – Junk: marketing blasts, no-reply anything. Archive + mark read.

We encode this with a priority classifier skill in OpenClaw.

Implementing the priority classifier

1. Create a new skill

# file: skills/emailPriority.js module.exports = async function classifyEmail({ subject, sender, snippet, body }, ctx) { const vipSenders = ctx.memory.get("vipSenders") || []; const urgentKeywords = [ /production down/i, /security breach/i, /payment failed/i, ]; if (vipSenders.includes(sender)) return "urgent"; if (urgentKeywords.some(rx => rx.test(subject) || rx.test(body))) return "urgent"; if (/invoice|receipt|statement/i.test(subject)) return "routine"; if (/unsubscribe|promo|sale/i.test(body)) return "junk"; return "important"; // default fall-through };

The logic mixes:

  • A memory-based vipSenders list (mutable without redeploy).
  • Regexes for hard triggers (fast, deterministic).
  • Fallback to LLM when ambiguous (see next step).

2. Let the LLM break ties

# file: skills/emailPriorityLLM.js const { openai } = require("openclaw/toolkit"); module.exports = async (email) => { const prompt = `Classify the email into one of: urgent, important, routine, junk.\nSubject: ${email.subject}\nBody: ${email.snippet}`; const res = await openai.chat({ model: "gpt-4o", prompt }); return res.choices[0].message.content.trim().toLowerCase(); };

Wire both skills in agent.json:

{ "skills": [ "./skills/emailPriority.js", { "when": "confidence < 0.7", "use": "./skills/emailPriorityLLM.js" } ] }

Training OpenClaw on your rules

Populate VIP list

POST /memory/vipSenders \ -H "Authorization: Bearer $CLAWS" \ -d '["ceo@acme.com", "pagerduty@alerts.io"]'

The list lives in vector storage; edits are O(1), no container restart needed.

Keyword triggers via UI

Navigate to Skills → EmailPriority → Parameters. There you can add or remove Regexes without touching the repo – the gateway rewrites the skill file under the hood.

Automating actions per tier

Routing graph

OpenClaw’s Router DSL is terse. Create routes/email.json:

{ "on": "email.received", "steps": [ { "run": "classifyEmail", "as": "prio" }, { "switch": "{{ prio }}", "cases": { "urgent": ["notifySlack", "forwardPhone"], "important": ["appendBriefing"], "routine": ["autoReply", "archive"], "junk": ["archive"] } } ] }

Each step is just another skill; two examples:

# skills/notifySlack.js const { slack } = require("openclaw/toolkit"); module.exports = async ({ subject, sender, link }) => { await slack.post("#alerts", `🚨 <${link}|${subject}> from ${sender}`); }; # skills/appendBriefing.js const fs = require("node:fs/promises"); module.exports = async (email) => { await fs.appendFile("/tmp/briefing.md", `* ${email.subject} – ${email.link}\n`); };

Auto-replies that don’t sound like a bot

# skills/autoReply.js const { gmail } = require("openclaw/toolkit"); module.exports = async ({ threadId, sender }) => { const draft = `Hi,\n\nThanks for the update – I\'ll review when I\'m back online.\n\nCheers,\n--\nSent via OpenClaw`; await gmail.reply(threadId, draft); };

You can A/B the draft via the UI; the skill hot-reloads.

Escalation paths and fail-safes

LLMs hallucinate; production incidents can’t. Add guardrails:

  • Confidence score threshold: Skills can return { label, confidence }. If <0.4 → send to important bucket instead of junk.
  • PagerDuty hook: For any urgent email with subject matching /SEV[1-2]/, call pagerduty.trigger().
  • Audit log: Pipe every decision to Postgres. This saved me when the model update in OpenAI gpt-4o-mini silently changed tone detection.

Testing: unit, integration, chaos

Unit test the classifier

# test/emailPriority.test.js const classify = require("../skills/emailPriority"); test("CEO sender -> urgent", async () => { const tier = await classify({ sender: "ceo@acme.com", subject: "hi", body: "ping" }, { memory: { get: () => ["ceo@acme.com"] } }); expect(tier).toBe("urgent"); });

Replay 1,000 historical emails

openclaw replay --source mbox://2023.mbox --route email.received

The --dry-run flag prints routing decisions without acting.

Chaos testing escalation

openclaw chaos email --inject "production down" --expect urgent

The agent aborts if the expect block fails.

Running in production

  • Scaling workers: openclaw daemon scale 4 adds three more Node workers on the same box; ClawCloud users resize in the web UI.
  • Rate limits: Gmail caps users.messages.send to 100/day by default. Move routine replies to scheduled batches (gmail.quota()) or use Outlook integration.
  • Monitoring: Ship ~/.claw/logs/*.log to Grafana Loki; set alert if urgent volume > N per hour.
  • Backups: openclaw export memory --to s3://claw-backup/mail-$(date +%F).json

Hardening: security & privacy

Email is PII. Minimal checklist:

  1. Rotate OAuth tokens weekly (openclaw oauth rotate --all).
  2. Set OPENCLAW_ENCRYPTION_KEY in environment; by default Claw falls back to a generated key on disk – bad for laptops.
  3. Disable browser control skill for this agent; no reason for an email bot to control Chrome.
  4. Use memory.scopes to restrict skills: classifier can read sender but not full body for junk tier.

What about multiple inboxes?

Add another Gmail integration and tag its events with the account ID. In the classifier prepend the account to the VIP lookup key (sales:vipSenders) so sales@ mail doesn’t inherit engineering alerts.

Cost snapshot

  • ClawCloud Pro: $19/month per agent
  • OpenAI gpt-4o calls: ≈$0.0005 / email (assuming 1K tokens round-trip)
  • Composio Gmail API: free tier 10k calls / month

My midsize startup sees 4,500 emails/day. Total monthly cost: ~$9 in LLM, $19 ClawCloud, negligible bandwidth. Cheaper than one hour of me pre-coffee.

Next step: ship it

Push the repo to GitHub, point your CI at openclaw test, and enable the router. Day one you’ll still check the junk folder; day three you’ll forget it exists. When the CEO emails on Saturday and your phone buzzes, you’ll know the system works.