From xmtp-cli
Use when working with XMTP messaging - sending messages, managing conversations, groups, consent, and identity operations via the xmtp CLI tool
How this skill is triggered — by the user, by Claude, or both
Slash command
/xmtp-cli:xmtp-cliThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The XMTP CLI (`xmtp`) is a command-line tool for interacting with the XMTP decentralized messaging protocol. It enables:
The XMTP CLI (xmtp) is a command-line tool for interacting with the XMTP decentralized messaging protocol. It enables:
Before using most commands, initialize the CLI with wallet and encryption keys:
# generate keys and save to default path (~/.xmtp/.env)
xmtp init
# output keys to console instead of writing to a file
xmtp init --stdout
# generate keys for production env and save to custom path
xmtp init --env production --output ./my-project/.env
# overwrite existing config file
xmtp init --force
This creates a .env file with:
XMTP_WALLET_KEY - Your wallet private key (identity)XMTP_DB_ENCRYPTION_KEY - Database encryption key (local data protection)XMTP_ENV - Network environment (local, dev, production)--env-file <path>.env in the current working directory~/.xmtp/.env (global default)| Variable | Description | Required |
|---|---|---|
XMTP_WALLET_KEY | Ethereum private key (hex, with or without 0x prefix) | Yes* |
XMTP_DB_ENCRYPTION_KEY | 32-byte encryption key (hex) | Yes* |
XMTP_ENV | Network: local, dev, or production | No (default: dev) |
XMTP_DB_PATH | Custom database file path | No (default: ~/.xmtp/xmtp-db) |
XMTP_GATEWAY_HOST | Custom gateway URL | No |
*Required for commands that need a client. If missing, the CLI will suggest running init to generate them.
All commands use kebab-case:
xmtp [TOPIC] [COMMAND] [ARGUMENTS] [FLAGS]
| Topic | Purpose |
|---|---|
| (root) | Standalone utility commands |
client | Identity and installation management |
conversations | Manage multiple conversations |
conversation | Single conversation operations |
preferences | Consent and preferences |
All commands support --json for machine-readable JSON output:
xmtp client info --json
Use --verbose to see detailed client initialization logs (env, db path, etc.). When combined with --json, verbose output goes to stderr so it doesn't interfere with JSON parsing:
xmtp client info --verbose
xmtp conversations list --json --verbose 2>/dev/null
# check if a single address can receive XMTP messages
xmtp can-message <address>
# check multiple addresses at once
xmtp can-message <address-1> <address-2>
# output result as JSON for scripting
xmtp can-message <address> --json
Shows client properties (address, inboxId, installationId, etc.) and client options (env, dbPath, etc.) in two sections. JSON output is nested as { properties, options }.
# display client properties in human-readable format
xmtp client info
# output as JSON (nested as { properties, options })
xmtp client info --json
# sign a message with the installation key, output signature as hex
xmtp client sign "Hello, World!"
# sign a message, output signature as base64 instead of hex
xmtp client sign "verify me" --base64
# verify a hex-encoded signature against the original message
xmtp client verify-signature "Hello, World!" --signature <hex-signature>
# verify a base64-encoded signature against the original message
xmtp client verify-signature "verify me" --signature <base64-signature> --base64
# create a DM conversation with a wallet address
xmtp conversations create-dm <address>
# send a text message to a conversation by its ID
xmtp conversation send-text <conversation-id> "Hello, world!"
# combined: create DM, extract the conversation ID via JSON, then send
DM_ID=$(xmtp conversations create-dm <address> --json | jq -r '.id')
xmtp conversation send-text "$DM_ID" "Hello!"
# queue message locally without publishing to the network
xmtp conversation send-text <conversation-id> "Quick message" --optimistic
# publish all queued optimistic messages for this conversation
xmtp conversation publish-messages <conversation-id>
# send a markdown-formatted message
xmtp conversation send-markdown <conversation-id> "**bold** and *italic*"
# send a plain text reply referencing another message by its ID
xmtp conversation send-reply <conversation-id> <message-id> "Replying to your message"
# send a markdown-formatted reply referencing another message
xmtp conversation send-reply <conversation-id> <message-id> "**Bold** reply" --markdown
# add a reaction to a message (action: add, content: emoji)
xmtp conversation send-reaction <conversation-id> <message-id> add "👍"
# remove a previously added reaction from a message
xmtp conversation send-reaction <conversation-id> <message-id> remove "👍"
# send a read receipt to mark conversation as read
xmtp conversation send-read-receipt <conversation-id>
# create a group with multiple members and a name
xmtp conversations create-group <address-1> <address-2> --name "My Team"
# create a group with full metadata and admin-only permissions
xmtp conversations create-group <address> \
--name "Project Team" \
--description "Discussion for our project" \
--image-url "https://example.com/team.png" \
--permissions admin-only
# list all conversations from local database
xmtp conversations list
# sync from network before listing to get latest data
xmtp conversations list --sync
# filter to only DMs (or use --type group for groups)
xmtp conversations list --type dm
# filter to only conversations with "allowed" consent state
xmtp conversations list --consent-state allowed
# filter by multiple consent states (repeatable flag)
xmtp conversations list --consent-state allowed --consent-state unknown
# sort by most recent activity and limit to 10 results
xmtp conversations list --order-by last-activity --limit 10
# filter by creation time (nanosecond timestamps)
xmtp conversations list --created-after 1700000000000000000
xmtp conversations list --created-before 1700000000000000000
# list messages in a conversation (default: descending order)
xmtp conversation messages <conversation-id>
# limit to the 10 most recent messages
xmtp conversation messages <conversation-id> --limit 10
# sync from network before reading to get latest messages
xmtp conversation messages <conversation-id> --sync
# sort in ascending order (oldest first)
xmtp conversation messages <conversation-id> --direction ascending
# include only specific content types (repeatable flag)
xmtp conversation messages <conversation-id> --content-type text --content-type markdown
# exclude specific content types (repeatable flag)
xmtp conversation messages <conversation-id> --exclude-content-type reaction
# filter by delivery status: unpublished, published, or failed
xmtp conversation messages <conversation-id> --delivery-status published
# filter by message kind: application (user messages) or membership-change
xmtp conversation messages <conversation-id> --kind application
# filter by sent timestamp range (nanoseconds)
xmtp conversation messages <conversation-id> --sent-after 1700000000000000000
xmtp conversation messages <conversation-id> --sent-before 1700000000000000000
# filter by local insertion timestamp range (nanoseconds)
xmtp conversation messages <conversation-id> --inserted-after 1700000000000000000
xmtp conversation messages <conversation-id> --inserted-before 1700000000000000000
# exclude messages from a specific sender (repeatable flag)
xmtp conversation messages <conversation-id> --exclude-sender <inbox-id>
# sort by local insertion time instead of sent time
xmtp conversation messages <conversation-id> --sort-by inserted-at
Content types: actions, attachment, custom, group-membership-change, group-updated, intent, leave-request, markdown, multi-remote-attachment, reaction, read-receipt, remote-attachment, reply, text, transaction-reference, wallet-send-calls
# look up a DM conversation by wallet address
xmtp conversations get-dm <address>
# look up a DM conversation by inbox ID
xmtp conversations get-dm <inbox-id>
# stream messages from all conversations indefinitely
xmtp conversations stream-all-messages
# stop streaming after 60 seconds
xmtp conversations stream-all-messages --timeout 60
# stop after receiving 10 messages
xmtp conversations stream-all-messages --count 10
# only stream messages from group conversations (or use --type dm)
xmtp conversations stream-all-messages --type group
# only stream from conversations with "allowed" consent
xmtp conversations stream-all-messages --consent-state allowed
# skip the initial sync before streaming starts
xmtp conversations stream-all-messages --disable-sync
# stream messages from a single conversation
xmtp conversation stream <conversation-id>
# stream new conversations as they are created
xmtp conversations stream
# only stream new DM conversations
xmtp conversations stream --type dm
# only stream new group conversations
xmtp conversations stream --type group
# stop after 60 seconds or 5 new conversations, whichever comes first
xmtp conversations stream --timeout 60 --count 5
# skip the initial sync before streaming starts
xmtp conversations stream --disable-sync
# list members of a conversation
xmtp conversation members <conversation-id>
# sync from network before listing to get latest membership
xmtp conversation members <conversation-id> --sync
# add members by their Ethereum addresses (space-separated)
xmtp conversation add-members <conversation-id> <address-1> <address-2>
# remove a member by their Ethereum address
xmtp conversation remove-members <conversation-id> <address>
# restrict adding members to admins only
xmtp conversation update-permission <conversation-id> --type add-member --policy admin
# restrict removing members to super-admins only
xmtp conversation update-permission <conversation-id> --type remove-member --policy super-admin
# restrict updating group name to admins (--metadata-field required for update-metadata type)
xmtp conversation update-permission <conversation-id> --type update-metadata --policy admin --metadata-field group-name
# restrict updating group description to admins
xmtp conversation update-permission <conversation-id> --type update-metadata --policy admin --metadata-field group-description
Permission types: add-member, remove-member, add-admin, remove-admin, update-metadata
Policies: allow, deny, admin, super-admin
Metadata fields: group-name, group-description, group-image-url, app-data
# get the consent state of a conversation
xmtp conversation consent-state <conversation-id>
# allow messages from this conversation
xmtp conversation update-consent <conversation-id> --state allowed
# block messages from this conversation
xmtp conversation update-consent <conversation-id> --state denied
# get consent state for an inbox ID
xmtp preferences get-consent --entity-type inbox_id --entity <inbox-id>
# get consent state for a conversation ID
xmtp preferences get-consent --entity-type conversation_id --entity <conversation-id>
# block an inbox ID (deny all messages from this sender)
xmtp preferences set-consent --entity-type inbox_id --entity <inbox-id> --state denied
# allow a conversation ID
xmtp preferences set-consent --entity-type conversation_id --entity <conversation-id> --state allowed
Entity types use snake_case: inbox_id, conversation_id
# request to be removed from a group conversation
xmtp conversation request-removal <conversation-id>
# sync conversation list from the network
xmtp conversations sync
# sync all conversations and their messages (more thorough, slower)
xmtp conversations sync-all
# sync only conversations with "allowed" consent state
xmtp conversations sync-all --consent-state allowed
# sync a single conversation from the network
xmtp conversation sync <conversation-id>
# sync user preferences (consent states, HMAC keys) from the network
xmtp preferences sync
# stream all preference changes (consent updates, HMAC key updates) indefinitely
xmtp preferences stream
# stop streaming after 60 seconds
xmtp preferences stream --timeout 60
# stop after receiving 5 preference update batches
xmtp preferences stream --count 5
# skip the initial preferences sync before streaming starts
xmtp preferences stream --disable-sync
# get your own inbox state from local database
xmtp preferences inbox-state
# fetch the latest inbox state from the network before displaying
xmtp preferences inbox-state --sync
# fetch inbox states from the network for specific inbox IDs (no local client needed)
xmtp inbox-states <inbox-id-1> <inbox-id-2>
# get cached inbox states from local database for specific inbox IDs
xmtp preferences inbox-states <inbox-id-1> <inbox-id-2>
# get HMAC keys for all conversations
xmtp conversations hmac-keys
These operations require --force to skip confirmation:
# add a new wallet to this inbox (--force skips confirmation prompt)
xmtp client add-account --new-wallet-key <wallet-key> --force
# remove a wallet from this inbox
xmtp client remove-account --identifier <address> --force
# change the recovery wallet address for this inbox
xmtp client change-recovery-identifier --identifier <address> --force
# verify the current inbox state after changes
xmtp preferences inbox-state
# check if a wallet address is authorized for an inbox (args: inbox-id, address)
xmtp address-authorized <inbox-id> <address>
# check if an installation is authorized for an inbox (args: inbox-id, installation-id)
xmtp installation-authorized <inbox-id> <installation-id>
# look up the inbox ID associated with a wallet address
xmtp client inbox-id --identifier <address>
# get detailed info about a conversation (type, metadata, members)
xmtp conversations get <conversation-id>
# get the permission policies for a group conversation
xmtp conversation permissions <conversation-id>
# get internal debug info for a conversation
xmtp conversation debug-info <conversation-id>
# fetch a specific message by its ID
xmtp conversations get-message <message-id>
# count messages in a conversation from local database
xmtp conversation count-messages <conversation-id>
# sync from network before counting to include latest messages
xmtp conversation count-messages <conversation-id> --sync
# count only application messages (exclude membership changes)
xmtp conversation count-messages <conversation-id> --kind application
# count only text and markdown messages
xmtp conversation count-messages <conversation-id> --content-type text --content-type markdown
# count messages sent after a timestamp (nanoseconds)
xmtp conversation count-messages <conversation-id> --sent-after 1700000000000000000
# promote a member to admin
xmtp conversation add-admin <conversation-id> <inbox-id>
# demote an admin to regular member
xmtp conversation remove-admin <conversation-id> <inbox-id>
# promote a member to super admin
xmtp conversation add-super-admin <conversation-id> <inbox-id>
# demote a super admin
xmtp conversation remove-super-admin <conversation-id> <inbox-id>
# list all admins in a group
xmtp conversation list-admins <conversation-id>
# list all super admins in a group
xmtp conversation list-super-admins <conversation-id>
# set the group name
xmtp conversation update-name <conversation-id> "New Name"
# set the group description
xmtp conversation update-description <conversation-id> "New description"
# set the group image URL
xmtp conversation update-image-url <conversation-id> "https://example.com/image.png"
# list all installations for this client's inbox
xmtp preferences inbox-state --json | jq '.installations'
# revoke specific installations from this client's inbox (--force skips confirmation)
xmtp client revoke-installations --installation-ids <installation-id> --force
# revoke all installations except the current one
xmtp client revoke-all-other-installations --force
# check key package status for specific installations
xmtp client key-package-status --installation-ids <installation-id>
# revoke installations from any inbox without local database (requires wallet key)
xmtp revoke-installations <inbox-id> -i <installation-id>
# revoke multiple installations (repeated -i flag)
xmtp revoke-installations <inbox-id> -i <id-1> -i <id-2>
# revoke multiple installations (comma-separated)
xmtp revoke-installations <inbox-id> -i <id-1>,<id-2>
Each device/app instance has a unique installation ID. This allows:
Unique identifier for each conversation (DM or group). Required for most conversation operations.
| State | Meaning |
|---|---|
allowed | Messages are welcome |
denied | Messages are blocked |
unknown | No decision made |
| Network | Use Case |
|---|---|
local | Local XMTP node |
dev | Development/testing (default) |
production | Production use |
xmtp init to generate keyscan-message to check firstconversations syncconversation permissions# 1. initialize with dev environment (first time only)
xmtp init --env dev
# 2. check if the recipient can receive XMTP messages
xmtp can-message <address>
# 3. create a DM conversation and extract the conversation ID
DM=$(xmtp conversations create-dm <address> --json)
DM_ID=$(echo "$DM" | jq -r '.id')
# 4. send a text message to the new DM
xmtp conversation send-text "$DM_ID" "Hello! This is my first message."
# 5. stream replies for up to 5 minutes
xmtp conversation stream "$DM_ID" --timeout 300
can-message before creating conversations--json flag when you need to extract data--sync flag when reading messages to ensure fresh data--timeout and --count flags for bounded operations--env flag explicitly when context requires specific networkadd-account, remove-account, revoke-installations, revoke-all-other-installations, and change-recovery-identifier prompt for confirmation unless --force is passedxmtp <command> --help for full flag documentationnpx claudepluginhub xmtp/claude-plugins --plugin xmtp-cliRuns Inkbox CLI commands for managing identities, email, SMS, phone, contacts, notes, vault, mailboxes, phone numbers, webhooks, and signup workflows.
Access, search, analyze, and send messages across Beeper's unified networks using MCP API, beeper-cli, or SQLite/DuckDB archives. Useful for chat automation and cross-network analysis.
Interacts with WhatsApp via CLI: send messages, list chats, read conversations, manage accounts. Authenticates as companion device using QR code or pairing code for AI agents.