vellum-ai

outlook

Manage Outlook email — drafting, sending, organizing, rules, vacation replies, and inbox analysis

vellum-ai 1.449 216 Actualitzat fa 1 mes

Recursos

2
GitHub

Instal·la

npx skillscat add vellum-ai/vellum-assistant/outlook

Instal·la des del registre de SkillsCat.

SKILL.md

This skill provides Outlook-specific operations beyond the shared messaging skill. For cross-platform messaging (send, read, search, reply), use the messaging skill. Outlook operations depend on the messaging skill's provider infrastructure - load messaging first if Outlook is not yet connected.

Script Reference

All operations use CLI scripts that return JSON:

  • Success: { "ok": true, "data": ... }
  • Failure: { "ok": false, "error": "..." }
Script Operation Description
outlook-email.ts draft Create email drafts in the Drafts folder (including reply drafts)
outlook-email.ts send-draft Send an existing draft (requires explicit user confirmation)
outlook-email.ts forward Create forward drafts, preserving attachments
outlook-email.ts trash Move messages to Deleted Items
outlook-manage.ts categories Manage message categories (add, remove, list available)
outlook-manage.ts follow-up Track messages with Outlook's native flag system
outlook-manage.ts attachments List and download email attachments
outlook-manage.ts rules Create, list, and delete server-side inbox message rules
outlook-manage.ts vacation Get, enable, or disable auto-reply (out-of-office) settings
outlook-manage.ts unsubscribe Unsubscribe from mailing lists (requires explicit user confirmation)
outlook-scan.ts sender-digest Scan inbox and group messages by sender for declutter workflows
outlook-scan.ts outreach-scan Identify cold outreach senders (no List-Unsubscribe header)

Email Operations

# Draft an email (--to is optional; omit it to create a draft with no recipient)
bun run scripts/outlook-email.ts draft --to "user@example.com" --subject "Hello" --body "Message body"
bun run scripts/outlook-email.ts draft --subject "Hello" --body "Message body"

# Send an existing draft (REQUIRES user confirmation before execution)
bun run scripts/outlook-email.ts send-draft --draft-id "AAMk..."

# Forward a message
bun run scripts/outlook-email.ts forward --message-id "AAMk..." --to "recipient@example.com" --comment "FYI"

# Trash a message
bun run scripts/outlook-email.ts trash --message-id "AAMk..."

Management Operations

# Categories - add categories to a message
bun run scripts/outlook-manage.ts categories --action add --message-id "AAMk..." --categories "Blue Category,Important"

# Follow-up - flag a message for follow-up
bun run scripts/outlook-manage.ts follow-up --action track --message-id "AAMk..."

# Attachments - list attachments on a message
bun run scripts/outlook-manage.ts attachments --action list --message-id "AAMk..."

# Rules - create a server-side inbox rule
bun run scripts/outlook-manage.ts rules --action create --name "Archive newsletters" --conditions '{"senderContains":["newsletter"]}' --actions '{"moveToFolder":"Archive"}'

# Vacation - enable auto-reply
bun run scripts/outlook-manage.ts vacation --action enable --internal-message "I'm out of office" --external-message "I'm currently away"

# Unsubscribe from a mailing list (REQUIRES user confirmation before execution)
bun run scripts/outlook-manage.ts unsubscribe --message-id "AAMk..."

Scan Operations

# Sender digest - scan inbox grouped by sender
bun run scripts/outlook-scan.ts sender-digest [--query "..."] [--time-range "90d"] [--account "..."]

# Outreach scan - identify cold outreach senders
bun run scripts/outlook-scan.ts outreach-scan [--time-range "90d"] [--account "..."]

Scan scripts store message IDs in the daemon's in-memory cache (via assistant cache) and return a lightweight summary with a cache_key. This keeps thousands of message IDs out of the conversation context. To retrieve cached message IDs for a specific sender:

assistant cache get <cache_key> --json
# Returns: { "ok": true, "data": { "sender@example.com": ["msgId1", "msgId2", ...], ... } }

Email Routing Priority

When the user mentions "email" - sending, reading, checking, decluttering, drafting, or anything else - always default to the user's own email (Outlook) unless they explicitly ask about the assistant's own email address (e.g., "set up your email", "send from your address", "check your inbox"). The vast majority of email requests are about the user's Outlook, not the assistant's @vellum.me address.

Do not offer the assistant's own email as an option unless the user specifically asks. If Outlook is not connected, guide them through Outlook setup.

Connection Setup

Outlook

  1. Check connection health first. Run assistant oauth ping outlook. This checks whether the user's Outlook/Microsoft account is connected and the token is valid.
  2. If no connection is found or the ping fails: Load the vellum-oauth-integrations skill. The skill will evaluate whether managed or your-own mode is appropriate and guide the user accordingly.

Error Recovery

When an Outlook script fails with a token or authorization error:

  1. Try to reconnect silently. Run assistant oauth ping outlook. This often resolves expired tokens automatically.
  2. If reconnection fails, go straight to setup. Don't present options, ask which route the user prefers, or explain what went wrong technically. Just tell the user briefly (e.g., "Outlook needs to be reconnected - let me set that up") and immediately load the vellum-oauth-integrations skill. The user came to you to get something done, not to troubleshoot - make it seamless.
  3. Never try alternative approaches. Don't use curl, browser automation, or any workaround. If the scripts can't do it, the reconnection flow is the answer.
  4. Never expose error details. The user doesn't need to see error messages about tokens, OAuth, or API failures. Translate errors into plain language.

Safety: Send-Draft and Unsubscribe

Two operations are high-risk and require explicit user confirmation before execution:

  • send-draft: Always show the user what will be sent (recipients, subject, body summary) and wait for explicit confirmation ("yes", "send it", etc.) before running the send-draft script. Never auto-send.
  • unsubscribe: Always tell the user which mailing list will be unsubscribed from and wait for explicit confirmation before running the unsubscribe script. Unsubscribe actions cannot be undone.

If the user has not explicitly confirmed, do not execute these operations. A general instruction like "clean up my inbox" is not confirmation to unsubscribe - it means scan and present options.

Drafting vs Sending (Outlook)

Outlook uses a draft-first workflow, matching Gmail. Compose and reply land in the user's Outlook Drafts folder. Nothing is sent until they confirm.

  • Prefer messaging_send with platform: "outlook". That creates a real Outlook draft (not a local file). Recipients are optional: if the user has not named a To address, pass a non-email conversation_id (for example drafts) and still create the draft.
  • bun run scripts/outlook-email.ts draft does the same via Graph. --to is optional.
  • Do not inspect this skill's scripts before creating a draft. Call messaging_send or run the draft command immediately.
  • Do not tell the user a draft exists until the tool or script returns success with a draftId. If creation fails or is interrupted, say so and offer the email copy in chat (clipboard or an in-app notification if they ask).
  • The forward operation creates a forward draft, preserving attachments.

To actually send: use bun run scripts/outlook-email.ts send-draft with the draft ID after the user has reviewed it. Only run send-draft when the user explicitly says "send it" or equivalent.

Differences from Gmail

Outlook and Gmail have different organizational models. Keep these distinctions in mind:

Concept Gmail Outlook
Organization Labels (multiple per message) Folders (one per message) + Categories (multiple per message)
Categorization Labels serve dual purpose Categories are color-coded tags independent of folder location
Follow-up Label-based tracking Native flag system (flagged, complete, notFlagged)
Inbox rules Gmail filters Outlook inbox rules (server-side)
Archive Remove INBOX label Move to Archive folder

Categories

Categories are Outlook's tagging system for organizing messages. Unlike Gmail labels, categories are independent of folder structure - a message can be in any folder and have multiple categories. Categories are color-coded (Blue, Green, Orange, Purple, Red, Yellow, or custom names). Use categories to tag and organize messages without moving them between folders.

Follow-up Flags

Outlook uses a native flag system for follow-up tracking:

  • flagged - message is marked for follow-up
  • complete - follow-up is done
  • notFlagged - no follow-up tracking

This replaces Gmail's label-based follow-up approach. Use the Outlook flag system directly rather than creating custom folder-based workarounds.

Inbox Rules vs Gmail Filters

Outlook inbox rules run server-side and support conditions like sender, subject, body keywords, and importance level. Actions include moving to folders, categorizing, flagging, forwarding, and deleting. When a user asks to "filter" or "auto-sort" email, use the rules operation - do not try to replicate Gmail's label-based filtering with Outlook folders.

Folders vs Labels

Gmail uses labels - a message can have multiple labels and removing the INBOX label archives it. Outlook uses folders - a message lives in exactly one folder at a time. Moving a message to Archive removes it from Inbox. To tag a message with multiple categories without moving it, use the categories operation. Do not create folder hierarchies to simulate Gmail's multi-label system.

Email Decluttering

When a user asks to declutter, clean up, or organize their email - start scanning immediately. Don't ask what kind of cleanup they want or request permission to read their inbox. Go straight to scanning - but once results are ready, always present them and let the user choose actions before archiving or unsubscribing.

CRITICAL: Never archive, unsubscribe, or take similar bulk actions unless the user has explicitly confirmed for that specific batch. Each batch of results requires its own explicit user confirmation. If the user says "keep going" or "keep decluttering," that means scan and present new results - NOT auto-archive. Previous batch approvals do not carry forward, but deselections DO carry forward: when the user deselects senders from a cleanup batch, record those as user preferences and exclude them from future cleanup batches.

Workflow

  1. Scan: Run bun run scripts/outlook-scan.ts sender-digest. The script returns a cache_key plus a lightweight sender summary (counts, unsubscribe availability, sample subjects). Message IDs are stored daemon-side — do NOT ask for them unless needed for archiving.
  2. Present: Show results to the user — senders, email counts, and whether unsubscribe is available for each. Pre-select all senders so users deselect what they want to keep.
  3. Wait for user action: Stop and wait. Do NOT proceed to archiving or unsubscribing until the user explicitly confirms which senders to clean up and which action to take ("Archive & Unsubscribe" or "Archive Only").
  4. Act on selection: After confirmation, use messaging_archive_by_sender with from:<email> queries to archive selected senders. For unsubscribe, run the unsubscribe script for senders with hasUnsubscribe: true. If you need specific message IDs (e.g., for targeted operations), retrieve them via assistant cache get <cache_key> --json.
  5. Accurate summary: Report exact counts: "Cleaned up [total_archived] emails from [sender_count] senders. Unsubscribed from [unsub_count]."
  6. Ongoing protection offer: After reporting results, offer inbox rules:
    • "Want me to set up inbox rules so future emails from these senders skip your inbox?"
    • If yes, run the rules script with --action create for each sender.
    • Then offer a recurring declutter schedule.

Edge Cases

  • Zero results: Tell the user "No newsletter emails found" and suggest broadening the query (e.g. extending the date range)
  • Unsubscribe failures: Report per-sender success/failure
  • Truncation handling: If truncated is true (message cap reached or time budget exceeded), the top senders are still captured. Present whatever results were collected - do not retry or continue. Tell the user: "Scanned [N] messages - here are your top senders."

Common Workflows

Declutter Inbox

  1. Run bun run scripts/outlook-scan.ts sender-digest to scan for newsletters and promotions
  2. Present results showing senders, message counts, and unsubscribe availability
  3. Wait for user to select senders and confirm an action
  4. Archive selected senders and unsubscribe where available (if user chose "Archive & Unsubscribe")
  5. Offer to create inbox rules for ongoing protection

Create a Mail Rule

  1. User says "auto-archive emails from newsletters@example.com"
  2. Run bun run scripts/outlook-manage.ts rules --action create --name "..." --conditions '...' --actions '...'
  3. Confirm the rule was created and explain what it does

Set Vacation Auto-Reply

  1. User says "set my out-of-office for next week"
  2. Run bun run scripts/outlook-manage.ts vacation --action enable --internal-message "..." --external-message "..."
  3. Confirm the auto-reply is active and when it expires

Manage Follow-ups

  1. User says "flag this email for follow-up" - run bun run scripts/outlook-manage.ts follow-up --action track --message-id "..."
  2. User says "what emails am I tracking?" - run bun run scripts/outlook-manage.ts follow-up --action list
  3. User says "mark that as done" - run bun run scripts/outlook-manage.ts follow-up --action complete --message-id "..."

Identify Cold Outreach

  1. Run bun run scripts/outlook-scan.ts outreach-scan to find senders without unsubscribe headers
  2. Present results for review - these are likely cold outreach or unsolicited emails
  3. User can choose to archive, create rules to block, or ignore