| name | twist-cli |
| description | Twist messaging CLI. View and respond to inbox threads, channel threads, direct messages, mentions, and group conversations; search, react, archive, mute, and manage workspaces. Use when the user mentions Twist, asks about their inbox, mentions, threads, DMs, channels, or wants to read or send Twist messages. |
| license | MIT |
| metadata | {"author":"Doist","version":"2.36.3"} |
Twist CLI (tw)
Access Twist messaging via the tw CLI. Use when the user asks about their Twist workspaces, threads, messages, or wants to interact with Twist in any way.
Setup
tw auth login
tw auth login --read-only
tw auth token
tw auth status
tw auth status --json
tw auth logout
tw workspaces
tw workspace use <ref>
tw completion install
tw config view
tw config set <key> <value>
tw doctor
tw update
tw changelog
Stored auth uses the system credential manager when available. If secure storage is unavailable, tw warns and falls back to ~/.config/twist-cli/config.json. TWIST_API_TOKEN always takes priority over the stored token, and legacy plaintext config tokens are migrated automatically when secure storage is available.
In read-only mode (tw auth login --read-only), commands that modify Twist data (reply, archive, react, delete, etc.) are blocked by the CLI. Externally provided tokens (TWIST_API_TOKEN or tw auth token) are treated as unknown scope and assumed write-capable.
View by URL
tw view <url>
Routes automatically based on URL structure:
- Message URL →
tw msg view
- Conversation URL →
tw conversation view
- Thread+comment URL →
tw thread view (comment ID extracted from URL)
- Thread URL →
tw thread view
All target command flags pass through (e.g. --json, --raw, --full).
Inbox
tw inbox
tw inbox --unread
tw inbox --archive-filter all
tw inbox --archive-filter archived
tw inbox --channel <filter>
tw inbox --since <date>
tw inbox --limit <n>
Threads
tw thread <thread-ref>
tw thread view <thread-ref>
tw thread view <ref> --comment <id>
tw thread view <url-with-/c/id>
tw thread view <ref> --unread
tw thread view <ref> --context 3
tw thread view <ref> --limit 20
tw thread view <ref> --since <date>
tw thread view <ref> --raw
tw thread create <channel-ref> "Title" "content"
tw thread create <channel-ref> "Title" "content" --json
tw thread create <channel-ref> "Title" "content" --json --full
tw thread create <channel-ref> "Title" "content" --notify 123,456
tw thread create <channel-ref> "Title" "content" --unarchive
tw thread create <channel-ref> "Title" "content" --no-unarchive
tw thread create <channel-ref> "Title" "content" --dry-run
tw thread reply <ref> "content"
tw thread reply <ref> "content" --notify EVERYONE
tw thread reply <ref> "content" --notify 123,id:456
tw thread reply <ref> "content" --json
tw thread reply <ref> "content" --json --full
tw thread reply <ref> "content" --close
tw thread reply <ref> "content" --reopen
tw thread done <ref>
tw thread done <ref> --json
tw thread mute <ref>
tw thread mute <ref> --minutes 480
tw thread mute <ref> --json
tw thread mute <ref> --json --full
tw thread unmute <ref>
tw thread unmute <ref> --json
tw thread delete <ref>
tw thread delete <ref> --yes
tw thread delete <ref> --yes --json
tw thread rename <ref> "New title"
tw thread rename <ref> "New title" --json
tw thread rename <ref> "New title" --json --full
tw thread update <ref> "New body"
echo "New body" | tw thread update <ref>
tw thread update <ref> "New body" --dry-run
tw thread update <ref> "New body" --json
tw thread update <ref> "New body" --json --full
Default --notify for reply is EVERYONE_IN_THREAD, which may notify more people than intended. Before posting, confirm with the user whether specific people should be notified instead (via --notify <user-ids>). Options: EVERYONE, EVERYONE_IN_THREAD, or comma-separated ID refs.
--notify automatically resolves IDs: group IDs are routed to the groups API field, user IDs to recipients. No special syntax needed.
Thread Comments
tw comment <comment-ref>
tw comment view <comment-ref>
tw comment view <comment-ref> --raw
tw comment view <comment-ref> --json
tw comment view <comment-ref> --ndjson
tw comment view <comment-ref> --json --full
tw comment update <comment-ref> "new content"
tw comment update <comment-ref> "content" --json
tw comment update <comment-ref> "content" --json --full
tw comment delete <comment-ref>
tw comment delete <comment-ref> --json
Conversations (DMs/Groups)
tw conversation unread
tw conversation <conversation-ref>
tw conversation view <conversation-ref>
tw conversation with <user-ref>
tw conversation with <user-ref> --snippet
tw conversation with <user-ref> --include-groups
tw conversation reply <ref> "content"
tw conversation reply <ref> "content" --json
tw conversation reply <ref> "content" --json --full
tw conversation done <ref>
tw conversation done <ref> --json
tw conversation mute <ref>
tw conversation mute <ref> --minutes 480
tw conversation mute <ref> --json
tw conversation mute <ref> --json --full
tw conversation unmute <ref>
tw conversation unmute <ref> --json
Alias: tw convo works the same as tw conversation.
Conversation Messages
tw msg <message-ref>
tw msg view <message-ref>
tw msg update <ref> "content"
tw msg update <ref> "content" --json
tw msg update <ref> "content" --json --full
tw msg delete <ref>
tw msg delete <ref> --json
Alias: tw message works the same as tw msg.
Search
tw mentions
tw mentions --since 2026-04-01 --all
tw mentions --type threads --json
tw search "query"
tw search "query" --type threads
tw search "query" --author <ref>
tw search "query" --to <ref>
tw search "query" --title-only
tw search "query" --mention-me
tw search "query" --conversation <refs>
tw search "query" --since <date>
tw search "query" --until <date>
tw search "query" --channel <refs>
tw search "query" --limit <n>
tw search "query" --cursor <cur>
tw search "query" --all
Users, Channels & Groups
tw user
tw user --json
tw user --json --full
tw users
tw users --search <text>
tw channels
tw channels --state all
tw channels --scope discoverable
tw channels --scope public --state all --json
tw channel threads <channel-ref>
tw channel threads "general" --unread
tw channel threads <ref> --archive-filter all
tw channel threads <ref> --since 2026-01-01
tw channel threads <ref> --limit 20
tw channel threads <ref> --limit 20 --cursor <cursor-from-prev>
tw channel threads <ref> --json
tw groups
tw groups --search "frontend"
tw groups --json
tw groups --json --full
tw groups view <group-ref>
tw groups view <ref> --json
tw groups view <ref> --json --full
tw groups create "Name"
tw groups create "Name" --users alice@doist.com,bob@doist.com
tw groups create "Name" --json
tw groups rename <group-ref> "New name"
tw groups rename <ref> "Name" --json
tw groups delete <group-ref> --yes
tw groups delete <ref> --dry-run
tw groups add-user <group-ref> user1 user2
tw groups add-user <ref> a@d.com,b@d.com
tw groups add-user <ref> id:123 --json
tw groups remove-user <group-ref> user1 user2
tw groups remove-user <ref> id:123,id:456
If a channel is not found in tw channels, widen with broader listings such as tw channels --scope public, then tw channels --scope public --state all. Check tw channels --help for other available filters.
tw channel threads returns every thread in the channel; pagination filters (--limit, --cursor, --since, --until, --unread) are applied client-side after fetch. --archive-filter is applied server-side. Results are sorted newest-first by last activity. In --json / --ndjson, the response includes a nextCursor string (opaque) you can pass via --cursor to fetch the next page; NDJSON emits the cursor as a final { "_meta": true, "nextCursor": "..." } line.
Away Status
tw away
tw away set <type> [until]
tw away set vacation 2026-03-20
tw away set vacation 2026-03-20 --from 2026-03-15
tw away clear
Reactions
tw react thread <ref> 👍
tw react comment <ref> +1
tw react message <ref> heart
tw react thread <ref> 👍 --json
tw unreact thread <ref> 👍
tw unreact thread <ref> 👍 --json
Supported shortcodes: +1, -1, heart, tada, smile, laughing, thinking, fire, check, x, eyes, pray, clap, rocket, wave
Shell Completions
tw completion install
tw completion install bash
tw completion install zsh
tw completion install fish
tw completion uninstall
Diagnostics
tw doctor
tw doctor --offline
tw doctor --json
Configuration
tw config view
tw config view --json
tw config view --show-token
tw config set unarchive-new-threads true
tw config set unarchive-new-threads false
User preferences are stored under userSettings in the config file. Currently supported keys: unarchive-new-threads. The flag on tw thread create (--unarchive / --no-unarchive) overrides this default per-invocation.
Update
tw update
tw update --check
tw update --channel
tw update switch --stable
tw update switch --pre-release
Changelog
tw changelog
tw changelog -n 3
tw changelog --count 10
Global Options
--no-spinner
--progress-jsonl
--accessible
--non-interactive
--interactive
Output Formats
All list/view commands support:
--json
--ndjson
--full
Dry Run
Mutating commands accept --dry-run to preview the operation without making the change. Where a command performs pre-flight validation (e.g. fetching the target thread to check channel access or ownership), those checks still run in dry-run — only the mutating write is skipped. Commands that have no pre-flight validation parse the reference and print the preview without hitting the API. The preview is structured:
[dry-run] Would <action>:
<Key>: <resolved value>
...
Run without --dry-run to execute.
Reference System
Commands accept flexible references:
- Numeric IDs:
123 or id:123
- Twist URLs: Full
https://twist.com/... URLs (parsed automatically)
- Fuzzy names: For workspaces/users -
"My Workspace" or partial matches
Piping Content
Commands that accept content (thread create, thread reply, comment update, conversation reply, msg update) auto-detect piped stdin:
cat notes.md | tw thread reply <ref>
tw thread create <channel-ref> "Title" < body.md
echo "Quick reply" | tw conversation reply <ref>
If no content argument is provided and no stdin is piped, the CLI opens $EDITOR for interactive input. In non-TTY environments (e.g. when called by an agent or in a pipeline), the editor is automatically skipped and the command fails fast with an actionable error message. Use --non-interactive to force this behavior even in a TTY, or --interactive to override auto-detection.
Common Workflows
View by URL (auto-routes to the right command):
tw view https://twist.com/a/1585/ch/100/t/200
tw view https://twist.com/a/1585/ch/100/t/200/c/300
tw view https://twist.com/a/1585/msg/400
tw view https://twist.com/a/1585/msg/400/m/500 --json
Check inbox and respond:
tw inbox --unread --json
tw thread view <id> --unread
tw thread reply <id> "Thanks, I'll look into this."
tw thread done <id>
Search and review:
tw mentions --since 2026-04-01 --all --json
tw search "deployment" --type threads --json
tw thread view <thread-id>
Check DMs:
tw conversation unread --json
tw conversation view <conversation-id>
tw conversation with "Alice Example"
tw conversation reply <id> "Got it, thanks!"