WP Manifestindependent plugin directory
manifest / developer / missive-cli

Missive CLI

WP-CLI commands for syncing and managing Missive inbox conversations

by Austin Ginder · github.com/austinginder/missive-cli

2stars
7release downloads
0forks

Install

The author publishes release zips, so WP-CLI can install straight from GitHub:

wp plugin install https://github.com/austinginder/missive-cli/releases/download/v1.3.0/missive-cli.zip

Readme

Missive CLI

WP-CLI commands for syncing and managing Missive inbox conversations. Syncs your Missive inbox to a local SQLite database, giving you fast offline search, conversation reading, email drafting, and bulk operations from the command line.

Designed to work alongside AI coding assistants like Claude Code, which can read the local database directly and run CLI commands to search, triage, draft replies, and close conversations without touching the Missive API for every read.

Requirements

Installation

  1. Install and activate:
wp plugin install https://github.com/austinginder/missive-cli/releases/latest/download/missive-cli.zip --activate
  1. Add your API key to wp-config.php:
define( 'MISSIVE_API_KEY', 'your-api-key' );
define( 'MISSIVE_TEAM_ID', 'optional-team-id' );    // enables team inbox sync
define( 'MISSIVE_API_NAME', 'Your Name' );           // display name for close actions
  1. Run your initial sync:
# Sync the last week (default)
wp missive sync

# Or backfill your full history
wp missive sync --timeframe=10y

The database is stored at ../private/missive.db relative to your WordPress root.

Commands

sync

Sync conversations from Missive to the local database.

wp missive sync                        # Last 7 days (default)
wp missive sync --timeframe=1d         # Last 24 hours
wp missive sync --timeframe=7d         # Last 7 days
wp missive sync --timeframe=7d --full  # Include closed conversations
wp missive sync --all-open             # All open conversations regardless of age
wp missive sync --force                # Re-sync, including message bodies
wp missive sync --force-bodies         # Re-download bodies even when one is stored
wp missive sync --conversation=abc123  # Sync a single thread (partial ID OK)

For daily use, wp missive sync --timeframe=7d keeps the database current. The sync is incremental and only fetches message bodies for conversations with new activity.

To backfill one incomplete thread, reach for --conversation=<id> rather than --force on the whole inbox. It is deterministic and does not depend on the pagination cutoff.

list

List synced conversations from the local database.

wp missive list
wp missive list --status=open
wp missive list --subject="Site Removal" --status=open
wp missive list --preview                # Show message preview snippets
wp missive list --unclassified
wp missive list --format=ids             # Output IDs only (for piping)
wp missive list --limit=100

search

Search conversations by keyword in subjects, message bodies, or sender names.

wp missive search "504 Gateway"
wp missive search "kinsta" --field=body
wp missive search "launchkits" --field=from
wp missive search "Site Removal" --status=open
wp missive search "Monitor:" --status=open --before=2026-02-14
wp missive search "Monitor:" --after=2026-03-01 --format=count
wp missive search "Injection" --format=ids

Use search for keyword lookups. The list command only supports --subject= filtering.

The --format=ids output is designed for piping into other commands:

wp missive close $(wp missive search "storage limit" --status=open --format=ids | tr '\n' ' ')

Search by sender with --field=from:

wp missive close $(wp missive search "Hover" --field=from --status=open --limit=200 --format=ids | tr '\n' ' ')

show

Display a conversation with its messages. Uses the local database, no API call needed.

wp missive show abc123                  # Partial ID matching
wp missive show abc123 --pretty         # TUI-style boxed format with colors
wp missive show abc123 --full           # Full message bodies (no truncation)
wp missive show abc123 --links          # Extract URLs from message bodies
wp missive show abc123 --format=json    # JSON output

Prefer wp missive show over hitting the API directly. For comments (not stored locally), use wp missive comments.

draft

Create an email draft or send immediately.

# New email
wp missive draft \
  --to="Name <email@example.com>" \
  --from="Your Name <you@example.com>" \
  --subject="Subject line" \
  --body="<p>HTML body content</p>"

# Reply to a conversation
wp missive draft \
  --to="Name <email@example.com>" \
  --from="Your Name <you@example.com>" \
  --subject="Re: Original subject" \
  --conversation=abc123 \
  --body="Thanks for reaching out."

# Body from file
wp missive draft \
  --to="Name <email@example.com>" \
  --subject="Report" \
  --body-file=./email.html

# Reply to everyone on the thread (To/Cc filled from the latest inbound message)
wp missive draft \
  --reply-all \
  --conversation=abc123 \
  --from="Your Name <you@example.com>" \
  --subject="Re: Original subject" \
  --body="Thanks all."

# With attachments
wp missive draft \
  --to="Name <email@example.com>" \
  --subject="Report" \
  --body-file=./email.html \
  --attach=./report.pdf,./data.csv

# Send immediately
wp missive draft \
  --to="Name <email@example.com>" \
  --subject="Urgent" \
  --body="Message" \
  --send
Option Required Description
--to Yes* Recipient (format: email or Name <email>). *Not required with --reply-all
--reply-all No Fill To/Cc from the latest inbound message (requires --conversation). Excludes your own addresses and de-dupes
--subject No** Email subject (**required for new conversations)
--body Yes† Email body (HTML or plain text)
--body-file Yes† Path to file containing body (†alternative to --body)
--attach No File(s) to attach, comma-separated paths. Max 25 files, ~7 MB of source files
--conversation No Conversation ID to reply to (supports partial ID)
--from No Sender email (must match a Missive alias)
--cc No CC recipients (comma-separated, merges with --reply-all)
--bcc No BCC recipients (comma-separated)
--send No Send immediately instead of creating draft

Tips for drafting:

  • HTML formatting: Use <br> for line breaks and <br><br> for paragraph spacing. Missive's editor collapses <p> tags into single line breaks.
  • Replies need a subject: The API does not auto-populate the subject on replies. Always include --subject="Re: Original subject".
  • Check reply-to: For automated notification emails, the "from" address is often a no-reply. Check the conversation's reply_to_fields to find the correct recipient.
  • Attachments: Missive accepts up to 25 files and a 10 MB total request. Files are base64 encoded, which inflates them by roughly a third, so the practical ceiling is about 7 MB of source files. Both limits are checked before the request is sent, so an oversized batch fails fast rather than after the upload.

close

Close one or more conversations in both Missive and the local database.

wp missive close abc123
wp missive close abc123 def456 ghi789   # Multiple IDs in one call
wp missive close abc123 --username="Bot Name"

# Pipe from search
wp missive search "Injection" --format=ids | xargs wp missive close

Pass multiple IDs to a single close call rather than chaining separate commands.

comments

Fetch comments from the Missive API for a conversation.

wp missive comments abc123
wp missive comments abc123 --all        # Paginate through all comments

drafts / delete-draft

Manage drafts on a conversation.

wp missive drafts abc123                # List drafts
wp missive delete-draft <draft-id>      # Delete a draft
wp missive delete-draft id1 id2 id3     # Delete multiple

export

Export open conversations as Markdown.

wp missive export
wp missive export --full                # Full message bodies
wp missive export --timeframe=1d        # Only recent activity

api

Query any Missive API endpoint directly. Supports GET, POST, PATCH, and DELETE.

wp missive api /users/me
wp missive api "/conversations?inbox=true&limit=10"
wp missive api /conversations/<id>/messages
wp missive api /shared_labels
wp missive api /posts --method=POST --data='{"posts":{"conversation":"<id>","close":true}}'

For complex JSON payloads, use --data-file= to pass a JSON file instead of inline --data.

See the API cookbook section below for real-world examples.

endpoints

Show the Missive API endpoint reference, grouped by resource.

wp missive endpoints
wp missive endpoints conversations
wp missive endpoints drafts
wp missive endpoints posts

stats

Show database statistics.

wp missive stats

Using with Claude Code

The local SQLite database is what makes this CLI powerful with Claude Code. Instead of hitting the Missive API for every read, Claude Code can query the database directly and use CLI commands to act on conversations.

Setup

Add a CLAUDE.md to your project with drafting instructions so Claude Code knows how to compose emails:

Use `wp missive draft` to create email drafts in Missive.

### Replying to a conversation

wp missive draft \
  --to="Name <email@example.com>" \
  --from="Your Name <you@example.com>" \
  --conversation=<partial-or-full-id> \
  --subject="Re: Original subject" \
  --body="Message body here"

Workflow: Email Triage

A typical triage session with Claude Code:

  1. Sync recent conversations:
wp missive sync --timeframe=7d
  1. Batch-close noise categories first. Search by subject or sender, review the matches, then close in bulk:
# Find and close storage alerts
wp missive search "storage limit exceeded" --status=open
wp missive close $(wp missive search "storage limit exceeded" --status=open --format=ids | tr '\n' ' ')

# Close by sender
wp missive close $(wp missive search "Hover" --field=from --status=open --limit=200 --format=ids | tr '\n' ' ')
  1. Work through actionable items. Read conversations locally, draft replies, close when done:
wp missive show abc123 --pretty
wp missive draft --to="client@example.com" --conversation=abc123 --subject="Re: Their question" --body="Your reply"
wp missive close abc123

Tips

  • Use --limit=200 when bulk closing by sender or category. The default limit of 50 will miss older conversations. Re-run until the count is 0.
  • Use wp missive show to read conversations locally. Only fall back to the API if a conversation is not synced yet.
  • Use wp missive comments <id> for internal comments (these are not stored in the local database).
  • Conversation IDs support partial matching everywhere. The first 8 characters usually suffice.

API Cookbook

The wp missive api command gives you direct access to the full Missive REST API. Here are practical examples for common tasks that go beyond the built-in commands.

Conversations

# List 10 most recent inbox conversations
wp missive api "/conversations?inbox=true&limit=10"

# List closed conversations
wp missive api "/conversations?closed=true&limit=10"

# List conversations in a team inbox
wp missive api "/conversations?team_inbox=<team-id>&limit=10"

# List conversations by shared label
wp missive api "/conversations?shared_label=<label-id>"

# Filter conversations by contact email
wp missive api "/conversations?inbox=true&email=user@example.com"

# Filter conversations by contact domain
wp missive api "/conversations?inbox=true&domain=example.com"

# Get a single conversation (full metadata)
wp missive api /conversations/<id>

# Get messages in a conversation
wp missive api /conversations/<id>/messages

# Get comments on a conversation
wp missive api /conversations/<id>/comments

# Get drafts in a conversation
wp missive api /conversations/<id>/drafts

# Merge two conversations
wp missive api /conversations/<source-id>/merge --method=POST \
  --data='{"target":"<destination-id>","subject":"Optional new subject"}'

Messages

# Get a single message with full body and headers
wp missive api /messages/<id>

# Get multiple messages in one call (comma-separated)
wp missive api /messages/<id1>,<id2>,<id3>

# Find messages by email Message-ID header
wp missive api "/messages?email_message_id=<message-id-header>"

Posts (Conversation Actions)

Posts are the primary way to manage conversation state through the API. Each post leaves a visible trace in the conversation.

# Close a conversation
wp missive api /posts --method=POST \
  --data='{"posts":{"conversation":"<id>","close":true,"username":"Bot","notification":{"title":"Closed","body":"Resolved"}}}'

# Reopen a conversation
wp missive api /posts --method=POST \
  --data='{"posts":{"conversation":"<id>","reopen":true,"text":"Reopening for follow-up","username":"Bot","notification":{"title":"Reopened","body":"Needs follow-up"}}}'

# Move to inbox (unarchive)
wp missive api /posts --method=POST \
  --data='{"posts":{"conversation":"<id>","add_to_inbox":true,"text":"Moved to inbox","username":"Bot","notification":{"title":"Inbox","body":"Moved"}}}'

# Add a shared label
wp missive api /posts --method=POST \
  --data='{"posts":{"conversation":"<id>","add_shared_labels":["<label-id>"],"text":"Labeled","username":"Bot","notification":{"title":"Labeled","body":"Added label"}}}'

# Assign a user
wp missive api /posts --method=POST \
  --data='{"posts":{"conversation":"<id>","add_assignees":["<user-id>"],"text":"Assigned","username":"Bot","notification":{"title":"Assigned","body":"User assigned"}}}'

# Delete a post
wp missive api /posts/<post-id> --method=DELETE

Drafts (Sending Email via API)

Read the full README on GitHub →

Releases

TagPublishedAssetDownloads
v1.3.0 Aug 5, 2026 missive-cli.zip 3
v1.2.0 Aug 5, 2026 missive-cli.zip 1
v1.1.0 Jun 22, 2026 missive-cli.zip 1
v1.0.0 Mar 28, 2026 missive-cli.zip 2