A lightweight CLI client for Mastodon, written in Go.
- Simple Authentication: OAuth flow with automatic browser launch and localhost callback
- Post Status: Post text directly, use your
$EDITOR, or pipe from stdin - Reply to Posts: Reply to specific posts or your last posted status
- Delete Posts: Delete posts with confirmation (or
--forceto skip) - Content Warnings: Add spoiler text to your posts
- Visibility Control: Choose post visibility (public, unlisted, private, direct)
- Dry Run: Preview what would be posted without actually posting
- Secure Storage: SQLite-based storage in platform-appropriate directories
make buildmake installThis will build a release binary and install it to ~/.local/bin/tusk.
Authenticate with your Mastodon instance:
tusk authYou'll be prompted for your instance domain (e.g., mastodon.social), and your browser will open for authorization.
Post a simple status (the post command is the default, so you can omit it):
tusk "Hello, Mastodon!"
# or
tusk post "Hello, Mastodon!"Compose in your editor:
tusk -ePipe from stdin:
echo "Hello from the command line" | tusk
cat status.txt | tuskReply to a specific status:
tusk -r STATUS_ID "This is a reply"Reply to your last posted status:
tusk -R "Adding to my previous thought..."Interactive TUI to select which post to reply to:
tusk --reply-tui "This is my reply"In reply-tui mode:
- Use arrow keys or
j/kto navigate - Press
enterorspaceto select the post to reply to - Press
sto sync latest posts from Mastodon - Press
qto quit without selecting
Attach an image to your post:
tusk -i /path/to/image.jpg --alt "Description of image" "Check out this photo!"Features:
- HEIC Support: HEIC/HEIF images are automatically converted to JPG
- EXIF Stripping: All EXIF metadata is automatically removed for privacy
- Alt Text: You'll be prompted with a warning if you forget alt text (recommended for accessibility)
- Supported formats: JPG, PNG, HEIC/HEIF
Post without alt text (not recommended):
tusk -i photo.jpg "My photo"
# You'll get a warning and can choose to proceed or cancelPost with custom visibility:
tusk -v unlisted "This won't show in public timeline"
tusk -v private "Only followers can see this"Add a content warning:
tusk -w "politics" "Here's my take on..."Specify the language of your post (using ISO 639 language codes):
tusk -l es "¡Hola mundo!"
tusk -l ja "こんにちは"
tusk -l fr "Bonjour le monde!"Combine options:
tusk -v unlisted -w "food" "I made the best sandwich today!"
tusk -l de -v unlisted "Ein Post auf Deutsch"Edit a specific status by ID:
tusk edit STATUS_ID "Updated text"Edit your most recent post:
tusk edit --latest "Updated text"Interactive TUI selection mode:
tusk edit --tui "Updated text"Edit with $EDITOR:
tusk edit STATUS_ID -e
tusk edit --latest -ePipe content to edit:
echo "Updated content" | tusk edit STATUS_IDEdit with all posting flags:
tusk edit STATUS_ID -v unlisted -w "updated cw" --lang es "Texto actualizado"
tusk edit --latest -i new_image.jpg --alt "New image description" "Updated with new image"In edit TUI mode:
- Use arrow keys or
j/kto navigate - Press
enterorspaceto select the post to edit - Press
sto sync latest posts from Mastodon - Press
qto quit
Delete a specific status by ID (with confirmation):
tusk delete STATUS_IDDelete your most recent post:
tusk delete --latestForce delete without confirmation:
tusk delete STATUS_ID -f
tusk delete --latest -fInteractive TUI selection mode:
tusk delete --tuiIn delete TUI mode:
- Use arrow keys or
j/kto navigate - Press
spaceto toggle selection - Press
sto sync latest posts from Mastodon - Press
dto delete selected posts (with confirmation) - Press
qto quit
Tusk maintains a stack of your posted statuses. When you delete a post, it's removed from the stack, and -R and delete --latest will then operate on the next most recent post.
View your latest post:
tusk latestThis shows the post that -R (reply to last) and delete --latest would operate on.
Sync your recent posts from Mastodon to local history:
tusk syncSync a specific number of posts (default is 50, max 100):
tusk sync -n 100Clear the post history stack:
tusk clearSkip confirmation:
tusk clear -fPreview what would be posted:
tusk --dry-run "Test post"
tusk -R --dry-run -v unlisted "Reply test"Revoke your access token and clear local data:
tusk logoutTusk stores configuration and tokens in platform-appropriate locations:
- macOS:
~/.local/share/tusk/tusk.db - Linux:
$XDG_DATA_HOME/tusk/tusk.dbor~/.local/share/tusk/tusk.db - Windows:
%APPDATA%\tusk\tusk.db
go test ./...Debug build:
make buildRelease build (optimized):
make releasetusk/
├── main.go # Entry point
├── cmd/ # Command implementations
│ ├── root.go
│ ├── auth.go
│ ├── post.go
│ └── logout.go
├── internal/
│ ├── config/ # SQLite storage
│ ├── mastodon/ # Mastodon API client
│ ├── oauth/ # OAuth flow handler
│ └── output/ # Pretty terminal output
└── Makefile
- Add media attachment support
- Add OS keychain integration for secure token storage
- Add multiple account support
- Add timeline viewing commands
- Add bookmarks/favorites
- Add search functionality
MIT