Claude
Skills
Sign in
Back

ops-inbox

Included with Lifetime
$97 forever

Full inbox management across all channels — WhatsApp (wacli), Email (Gmail MCP), Slack (MCP), Telegram (user-auth MCP), Discord (webhook + REST read), Notion (MCP — comments, mentions, assigned tasks). Scans FULL inbox (not just unread), identifies messages needing replies, archives handled conversations.

AI Agents

What this skill does


# OPS ► INBOX ZERO

## Runtime Context

Before executing, load available context:

1. **Preferences**: Read `${CLAUDE_PLUGIN_DATA_DIR:-$HOME/.claude/plugins/data/ops-ops-marketplace}/preferences.json`
   - `default_channels` — which channels to scan by default
   - `secrets_manager` / `doppler` — how to resolve channel credentials if not in env

2. **Daemon health**: Read `${CLAUDE_PLUGIN_DATA_DIR}/daemon-health.json`
   - Check `wacli-sync` status — if not running or auth needed, skip WhatsApp and surface the issue
   - Also check `~/.wacli/.health` for live auth status before any wacli command

3. **Ops memories**: Check `${CLAUDE_PLUGIN_DATA_DIR}/memories/` before drafting any reply:
   - `contact_*.md` — load profile for the contact you're about to reply to
   - `preferences.md` — apply user's communication style and language preferences
   - `topics_active.md` — check for active threads or deadlines related to this contact
   - `donts.md` — never violate these restrictions in drafts

## CLI/API Reference

### wacli (WhatsApp)

**Health file** — check `~/.wacli/.health` BEFORE any wacli command:
- `status=connected` → proceed normally
- `status=needs_auth` → prompt user: "Run `wacli auth` in terminal, scan QR"
- `status=needs_reauth` → prompt user: "WhatsApp session expired. Run `wacli auth` to re-pair"
- File missing → fall back to `wacli doctor --json`

| Command | Usage | Output |
|---------|-------|--------|
| `wacli doctor --json` | Check auth/connected/lock/FTS | `{data: {authenticated, connected, lock_held, fts_enabled}}` |
| `wacli chats list --json` | All chats | `{data: [{JID, Name, Kind, LastMessageTS}]}` |
| `wacli messages list --chat "<JID>" --limit N --json` | Messages for chat | `{data: {messages: [{FromMe, Text, Timestamp, SenderName, ChatName}]}}` |
| `wacli messages search --query "<text>" --json` | FTS search | Same as above |
| `wacli contacts --search "<name>" --json` | Contact lookup | Contact objects |
| `wacli send --to "<JID>" --message "<msg>"` | Send text | Success/error |
| `wacli history backfill --chat="<JID>" --count=50 --requests=2 --wait=30s --idle-exit=5s --json` | Fetch older messages | Backfill result |

### gog CLI (Gmail/Calendar)

| Command | Usage | Output |
|---------|-------|--------|
| `gog gmail search "in:inbox" --max 50 -j --results-only --no-input` | Full inbox scan | JSON array of threads |
| `gog gmail thread get <threadId> -j` | Get full thread with all messages | Full message JSON |
| `gog gmail get <messageId> -j` | Get single message | Message JSON |
| `gog gmail archive <messageId> ... --no-input --force` | Archive messages (remove from inbox) | Archive result |
| `gog gmail archive --query "<gmail-query>" --max N --force` | Archive by query | Archive result |
| `gog gmail send --to "<email>" --subject "<subj>" --body "<body>"` | Send email | Send result |
| `gog gmail send --reply-to-message-id <msgId> --reply-all --body "text"` | Reply all | Send result |
| `gog gmail mark-read <messageId> ... --no-input` | Mark as read | Result |
| `gog gmail labels list -j` | List all labels | Labels JSON |

---


## Agent Teams support

If `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` is set, use **Agent Teams** when processing "all channels" mode. This enables:
- Channel agents run in parallel but can share context (e.g., WhatsApp agent finds a message referencing an email thread → email agent can prioritize it)
- You can steer agents: "skip WhatsApp for now, focus on email first"
- Agents report completion per-channel so you can process replies as they come in

**Team setup** (only when flag is enabled, "all channels" mode):
```
TeamCreate("inbox-channels")
Agent(team_name="inbox-channels", name="whatsapp-scanner", ...)
Agent(team_name="inbox-channels", name="email-scanner", ...)
Agent(team_name="inbox-channels", name="slack-scanner", ...)
Agent(team_name="inbox-channels", name="telegram-scanner", ...)
Agent(team_name="inbox-channels", name="notion-scanner", ...)
```

Each agent scans its channel and reports back classified results. You then process NEEDS_REPLY items across all channels in priority order.

If the flag is NOT set, process channels sequentially or use fire-and-forget subagents.

## Pre-gathered data

```!
${CLAUDE_PLUGIN_ROOT}/../../bin/ops-unread 2>/dev/null || echo '{}'
```

## Environment variables

All channel credentials come from env vars or CLI auth — no hardcoded secrets.

| Variable            | Default     | Purpose                                              |
| ------------------- | ----------- | ---------------------------------------------------- |
| `GMAIL_ACCOUNT`     | auto-detect | Gmail account for `gog` CLI                          |
| `SLACK_MCP_ENABLED` | `false`     | Set `true` when Slack MCP server is configured       |
| `TELEGRAM_ENABLED`  | `false`     | Set `true` when Telegram user-auth MCP is configured |
| `NOTION_MCP_ENABLED`| `false`     | Set `true` when Notion MCP integration is configured |
| `WACLI_STORE`       | `~/.wacli`  | wacli store directory                                |

## Core principle: FULL INBOX SCAN

Do NOT just check unread. Scan the FULL recent inbox for each channel and classify every conversation:

## Core principle: FULL CONTEXT — NEVER ASSUME

**CRITICAL SAFETY RULE — NEVER SEND WITHOUT UNDERSTANDING:**
Before drafting or sending ANY reply on ANY channel, you MUST have read the FULL conversation history (20+ messages) and PROVEN you understand it by summarizing:
1. What the conversation is about
2. What each party said (distinguish user messages from contact messages)
3. What the contact is actually asking/saying in their last message
4. What a sensible reply would address

**Failure mode this prevents:** An agent reads only the last message "je kan het toch uit Klaviyo halen?" and replies "Welke data heb je nodig?" — completely wrong because the contact was telling the user to pull data themselves (they have 2FA), not asking for data. Without the full thread, the reply was nonsensical and confused the contact.

**Hard rule: if you cannot summarize the conversation arc in 2 sentences, you have not read enough messages. Go back and read more.**

The user does NOT remember every thread. For EVERY message you present, you MUST build full context BEFORE showing it. Never show just a subject line and ask "what do you want to do?" — the user needs to understand what it's about first.

**For every NEEDS REPLY item, gather this context automatically:**

1. **Full thread body** — read the ENTIRE thread (`gog gmail thread get` / `wacli messages list --limit 20`), not just the last message. Summarize the full conversation arc.
2. **Contact profile** — search across channels to build a card:
   - `gog gmail search "from:<contact_email>" --max 10` — recent email history
   - `wacli contacts --search "<name>" --json` — WhatsApp presence
   - `wacli messages search --query "<name>" --json --limit 5` — recent WhatsApp mentions
   - If Linear configured: search for issues assigned to or mentioning this contact
   - Present: who they are, role/company, last N interactions, relationship context
3. **Topic context** — identify the subject matter and search for related threads:
   - `gog gmail search "subject:<keywords>" --max 5` — related email threads
   - `wacli messages search --query "<topic keywords>" --json --limit 5` — related WA messages
   - Summarize: what this topic is about, any deadlines, any pending decisions
4. **ops-memories** (if available) — check `~/.claude/plugins/data/ops-ops-marketplace/memories/` for any stored context about this contact or topic

**When presenting a NEEDS REPLY item:**
```
━━━ [Contact Name] — [Subject] ━━━
 Who: [role, company, relationship — from contact search]
 History: [last 3 interactions across channels]
 Thread: [2-3 sentence summary of full conversation arc]
 Last msg: [full body of their last message]
 Context: [related threads/decisions/deadlines found]
 
 Draft reply: "[contextually aware draft b

Related in AI Agents