A unified command-line interface for interacting with Discord as a bot. Supports TUI mode (default), interactive mode, and REST API-style commands.
Used to test bots from a terminal, needs a BOT token. This is not a self-bot and is not trying to be.

pip install -r requirements.txtThe client automatically loads your Discord token in this priority order:
-
CLI Argument (
--token/-t)python discord_cli.py user --token YOUR_TOKEN
- Highest priority - overrides everything
-
.envfile next to script (discord_cli.py/.env)# Create .env in same directory as discord_cli.py echo "DISCORD_TOKEN=your_token_here" > .env
-
Parent config directory (
../config/.env)# Create .env in parent/config/.env mkdir -p ../config echo "DISCORD_TOKEN=your_token_here" > ../config/.env
-
System environment variables
DISCORD_TOKEN(checked first)DISCORD_BOT_TOKEN(fallback)TOKEN(fallback)
# Windows PowerShell $env:DISCORD_TOKEN="your_token_here" # Windows CMD set DISCORD_TOKEN=your_token_here # Linux/Mac export DISCORD_TOKEN="your_token_here"
-
Interactive prompt (lowest priority)
- Only used if no token is found in any of the above sources
- Prompts user to enter token securely
Recommended: Create a .env file next to discord_cli.py:
# .env (in same directory as discord_cli.py)
DISCORD_TOKEN=your_discord_token_hereNote: CLI argument --token always takes highest priority and overrides all .env files and environment variables.
Run without any arguments to enter TUI (Text User Interface) mode:
python discord_cli.pyTUI mode provides a visual, interactive interface with four panels:
- Guilds Panel: List of all servers you're in
- Channels Panel: List of text channels in the selected guild
- Messages Panel: Message history from the selected channel
- Users Panel: List of members in the current guild with status indicators
- ← (Left Arrow): Switch to previous panel (users → messages → channels → guilds)
- → (Right Arrow): Switch to next panel (guilds → channels → messages → users)
- ↑ (Up Arrow): Navigate up within the active panel
- In Guilds: Select previous guild (loads channels and messages)
- In Channels: Select previous channel (loads messages)
- In Messages: Scroll to older messages
- In Users: Select previous user
- ↓ (Down Arrow): Navigate down within the active panel
- In Guilds: Select next guild (loads channels and messages)
- In Channels: Select next channel (loads messages)
- In Messages: Scroll to newer messages
- In Users: Select next user
- Messages are displayed in the Messages panel
- Shows author name and message content (truncated to 60 characters)
- Scroll through message history with ↑/↓ arrows
- Messages panel shows scroll position indicator
i: Enter input mode to type a message- Type your message
- Enter: Send the message
- Esc: Cancel and exit input mode
- Backspace: Delete characters
- Messages are sent to the currently selected channel
- After sending, messages automatically refresh
r: Refresh messages in the current channel- Resets scroll position to show newest messages
- Enter (when Users panel is active): Open user information overlay
- Shows detailed user information:
- Username and display name
- User ID
- Online status (Online/Idle/Do Not Disturb/Offline)
- Bot status
- Account creation date
- Server join date
- Roles
- Avatar URL
- Esc: Close overlay
- Shows detailed user information:
When viewing a user's information overlay:
- DM Panel: Shows message history with that user
- Automatically refreshes every 3 seconds
- Displays last 50 messages
m: Enter DM input mode- Type your DM message
- Enter: Send the DM
- Esc: Cancel DM input
r: Manually refresh DM messages- Esc: Close overlay
The Users panel shows color-coded status indicators:
- 🟢 Green dot: Online
- 🟡 Yellow dot: Idle
- 🔴 Red dot: Do Not Disturb
- ⚪ Gray circle: Offline
h: Show help (displays in status bar)q: Quit the application
The footer shows:
- Current status messages
- Available keyboard shortcuts
- Input mode indicator when typing
Run with --interactive or -i flag:
python discord_cli.py --interactiveInteractive mode provides a command-line interface where you can run multiple commands with a persistent connection. Connect once, run many commands.
All commands support the --output / -o option (default: json):
json- Pretty-printed JSON with indentation (default)raw- Compact JSON without indentationpretty- Formatted output using rich terminal formatting
user [--output json|raw|pretty]Example:
discord> user
discord> user --output prettyguilds [--id GUILD_ID] [--output json|raw|pretty]Examples:
discord> guilds
discord> guilds --id 123456789012345678
discord> guilds --output prettychannels [--guild-id GUILD_ID] [--id CHANNEL_ID] [--output json|raw|pretty]Examples:
discord> channels
discord> channels --guild-id 123456789012345678
discord> channels --id 987654321098765432
discord> channels --guild-id 123456789012345678 --output prettydms [--id CHANNEL_ID] [--output json|raw|pretty]Examples:
discord> dms
discord> dms --id 123456789012345678
discord> dms --output prettymessages --channel-id CHANNEL_ID [--limit N] [--before MESSAGE_ID] [--after MESSAGE_ID] [--around MESSAGE_ID] [--output json|raw|pretty]Parameters:
--channel-id(required): Channel ID to get messages from--limit/-l: Number of messages to retrieve (max 100, default: 50)--before: Get messages before this message ID--after: Get messages after this message ID--around: Get messages around this message ID
Examples:
discord> messages --channel-id 123456789012345678
discord> messages --channel-id 123456789012345678 --limit 100
discord> messages --channel-id 123456789012345678 --before 987654321098765432
discord> messages --channel-id 123456789012345678 --after 987654321098765432 --limit 25post --channel-id CHANNEL_ID [--content TEXT] [--embed-title TITLE] [--embed-description DESC] [--embed-color COLOR] [--reply-to MESSAGE_ID] [--output json|raw|pretty]Parameters:
--channel-id(required): Channel ID to send message to--content/-c: Message text content--embed-title: Embed title--embed-description: Embed description--embed-color: Embed color (hex format:#FF0000or0xFF0000)--reply-to: Message ID to reply to
Note: At least one of --content, --embed-title, or --embed-description is required.
Examples:
discord> post --channel-id 123456789012345678 --content "Hello, Discord!"
discord> post --channel-id 123456789012345678 --embed-title "Title" --embed-description "Description" --embed-color "#FF0000"
discord> post --channel-id 123456789012345678 --content "This is a reply" --reply-to 987654321098765432help
?Shows available commands and usage.
exit
quit
qExits interactive mode.
- Use quotes for arguments with spaces:
post --channel-id 123 --content "Hello world" - Commands are case-insensitive
- You can chain multiple commands in one session
Run specific commands directly from the command line. Each command runs independently and exits after completion.
All commands support --token to override the .env configuration and --output for format selection.
python discord_cli.py user [--token TOKEN] [--output json|raw|pretty]Examples:
python discord_cli.py user
python discord_cli.py user --output raw
python discord_cli.py user --output pretty
python discord_cli.py user --token YOUR_TOKENpython discord_cli.py guilds [--token TOKEN] [--id GUILD_ID] [--output json|raw|pretty]Examples:
# Get all guilds
python discord_cli.py guilds
# Get specific guild by ID
python discord_cli.py guilds --id 123456789012345678
# With custom output format
python discord_cli.py guilds --output prettypython discord_cli.py channels [--token TOKEN] [--guild-id GUILD_ID] [--id CHANNEL_ID] [--output json|raw|pretty]Examples:
# Get all channels from all guilds
python discord_cli.py channels
# Get channels from specific guild
python discord_cli.py channels --guild-id 123456789012345678
# Get specific channel by ID
python discord_cli.py channels --id 123456789012345678
# Combined options
python discord_cli.py channels --guild-id 123456789012345678 --output prettypython discord_cli.py dms [--token TOKEN] [--id CHANNEL_ID] [--output json|raw|pretty]Examples:
# Get all DM channels
python discord_cli.py dms
# Get specific DM channel by ID
python discord_cli.py dms --id 123456789012345678
# With output format
python discord_cli.py dms --output prettypython discord_cli.py messages --channel-id CHANNEL_ID [--token TOKEN] [--limit N] [--before MESSAGE_ID] [--after MESSAGE_ID] [--around MESSAGE_ID] [--output json|raw|pretty]Parameters:
--channel-id(required): Channel ID to get messages from--limit/-l: Number of messages to retrieve (max 100, default: 50)--before: Get messages before this message ID--after: Get messages after this message ID--around: Get messages around this message ID
Examples:
# Get messages from a channel
python discord_cli.py messages --channel-id 123456789012345678 --limit 50
# Get messages with query parameters
python discord_cli.py messages --channel-id 123456789012345678 --before 987654321098765432
python discord_cli.py messages --channel-id 123456789012345678 --after 987654321098765432
python discord_cli.py messages --channel-id 123456789012345678 --around 987654321098765432
# With custom limit
python discord_cli.py messages --channel-id 123456789012345678 --limit 100python discord_cli.py post --channel-id CHANNEL_ID [--token TOKEN] [--content TEXT] [--embed-title TITLE] [--embed-description DESC] [--embed-color COLOR] [--reply-to MESSAGE_ID] [--output json|raw|pretty]Parameters:
--channel-id(required): Channel ID to send message to--content/-c: Message text content--embed-title: Embed title--embed-description: Embed description--embed-color: Embed color (hex format:#FF0000or0xFF0000)--reply-to: Message ID to reply to
Note: At least one of --content, --embed-title, or --embed-description is required.
Examples:
# Simple text message
python discord_cli.py post --channel-id 123456789012345678 --content "Hello, Discord!"
# Message with embed
python discord_cli.py post --channel-id 123456789012345678 \
--embed-title "Title" \
--embed-description "Description" \
--embed-color "#FF0000"
# Reply to a message
python discord_cli.py post --channel-id 123456789012345678 \
--content "This is a reply" \
--reply-to 987654321098765432
# Combined content and embed
python discord_cli.py post --channel-id 123456789012345678 \
--content "Check this out!" \
--embed-title "Embed Title" \
--embed-description "Embed description"All commands support the --output / -o option (default: json):
json- Pretty-printed JSON with indentation (default)raw- Compact JSON without indentation (single line, no spaces)pretty- Formatted output using rich terminal formatting
Examples:
# Default JSON output
python discord_cli.py user
# Raw JSON (compact, single line)
python discord_cli.py user --output raw
# Pretty formatted output
python discord_cli.py user --output prettyDiscord does NOT support username/password authentication through their API. Discord only supports token-based authentication. This is by design for security and API stability reasons.
Token Types:
- Bot Tokens: Official way to authenticate bot accounts (recommended for production)
- User Tokens: Tokens from user accounts (violates Discord's ToS - see warning below)
Why not username/password?
- Discord's API doesn't provide a username/password login endpoint
- The
discord.pylibrary only supports token authentication - Even if implemented, it would require reverse engineering Discord's login flow, which is:
- Against Discord's Terms of Service
- Unreliable (Discord can change their auth flow anytime)
- A security risk (storing passwords)
- Not officially supported
Solution: Get your token once and store it in a file (we support automatic file detection). The token acts as a long-lived session key.
For Bot Accounts (✅ recommended):
- Go to https://discord.com/developers/applications
- Create a new application
- Go to the "Bot" section
- Create a bot and copy the token
- This is the official, supported way to interact with Discord programmatically
Security Warning: Never share your Discord token! It gives full access to your account.
- ✅ Visual interface with four panels (Guilds, Channels, Messages, Users)
- ✅ Navigate with arrow keys
- ✅ View messages in real-time
- ✅ Send messages to channels
- ✅ View user information with detailed overlay
- ✅ Send and receive direct messages in overlay
- ✅ Automatic DM updates (every 3 seconds)
- ✅ User status indicators (online/idle/dnd/offline)
- ✅ Scroll through message history
- ✅ Refresh messages manually
- ✅ Command-line interface for multiple commands
- ✅ Persistent connection (connect once, run many commands)
- ✅ Get user information
- ✅ List guilds and channels
- ✅ List direct messages
- ✅ Get messages with query parameters
- ✅ Post messages with embeds and replies
- ✅ Multiple output formats
- ✅ Run specific commands and exit
- ✅ Get user information
- ✅ List guilds and channels
- ✅ List direct messages
- ✅ Get messages with query parameters
- ✅ Post messages with embeds and replies
- ✅ Multiple output formats
- ✅ Token override support
- ✅ Multiple output formats (json, raw, pretty)
- ✅ .env configuration support
- ✅ Multiple token loading methods
- ✅ Cross-platform support (Windows, Linux, Mac)