English | 한국어(./README.ko.md)
Get Telegram or Discord notifications when Claude Code needs your input.
Inspired by call-me, DM-Plz lets Claude send you messages via Telegram or Discord when it completes tasks, needs decisions, or wants to report progress. Perfect for long-running tasks where you don't want to watch Claude work.
-
Multiple platforms - Choose between Telegram or Discord
-
Simple notifications - Get updates without phone calls
-
Ask questions - Claude can ask you questions and wait for your response
-
Permission reject reason - When you reject a permission request, you can optionally enter a reason; the reason is treated as the next instruction so Claude can adjust and retry
-
No complex setup - Just a bot token and channel/chat ID
-
Free - Both Telegram and Discord Bot APIs are completely free
-
Async friendly - Reply at your own pace, no real-time pressure
Choose your preferred platform:
- Open Telegram and message @BotFather
- Send
/newbotand follow the prompts - Give your bot a name (e.g., "Claude Code Bot")
- Give your bot a username (e.g., "my_claude_code_bot")
- Copy the bot token you receive (looks like
123456789:ABCdefGHIjklMNOpqrsTUVwxyz)
- Message @userinfobot on Telegram
- Copy your Chat ID (a number like
123456789)
Add these to ~/.claude/settings.json:
{
"env": {
"DMPLZ_PROVIDER": "telegram",
"DMPLZ_TELEGRAM_BOT_TOKEN": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz",
"DMPLZ_TELEGRAM_CHAT_ID": "123456789"
}
}- Go to Discord Developer Portal
- Click "New Application" and give it a name
- Go to "Bot" section and click "Add Bot"
- Under "Token", click "Copy" to get your bot token
- Enable "MESSAGE CONTENT INTENT" under Privileged Gateway Intents
- Go to "OAuth2" > "URL Generator"
- Select scopes:
bot - Select permissions:
Send Messages,Read Messages,Read Message History - Copy the generated URL and open it in your browser
- Select your server and authorize the bot
- Enable Developer Mode in Discord (Settings > Advanced > Developer Mode)
- Right-click the channel where you want notifications
- Click "Copy ID" to get your Channel ID
- (Optional) If you want permission requests in DMs, also copy your User ID (right-click your profile)
Add these to ~/.claude/settings.json:
{
"env": {
"DMPLZ_PROVIDER": "discord",
"DMPLZ_DISCORD_BOT_TOKEN": "your_discord_bot_token_here",
"DMPLZ_DISCORD_CHANNEL_ID": "123456789012345678",
"DMPLZ_DISCORD_DM_USER_ID": "123456789012345678",
"DMPLZ_PERMISSION_CHAT_ID": "123456789012345678"
}
}# Install from local directory
/plugin marketplace add /path/to/dm-plz
/plugin install dm-plz@dm-plzOr if published to GitHub:
/plugin marketplace add https://github.com/j-token/dm-plz-claude.git
/plugin install dm-plz@dm-plzRestart Claude Code. Done!
| Variable | Required | Description |
|---|---|---|
DMPLZ_PROVIDER |
No (default: telegram) |
Platform to use: telegram or discord |
DMPLZ_TELEGRAM_BOT_TOKEN |
Yes (for Telegram) | Bot token from @BotFather |
DMPLZ_TELEGRAM_CHAT_ID |
Yes (for Telegram) | Your personal chat ID from @userinfobot |
DMPLZ_DISCORD_BOT_TOKEN |
Yes (for Discord) | Bot token from Discord Developer Portal |
DMPLZ_DISCORD_CHANNEL_ID |
Yes (for Discord) | Channel ID (enable Developer Mode to copy) |
DMPLZ_DISCORD_DM_USER_ID |
No (Discord) | User ID for sending permission requests via DM |
DMPLZ_PERMISSION_CHAT_ID |
No | Override chat/channel ID for permission requests |
DMPLZ_QUESTION_TIMEOUT_MS |
No (default: 10800000) |
Timeout for waiting for responses (3 hours) |
DMPLZ_REJECT_REASON_TIMEOUT_MS |
No (default: 600000) |
Timeout for entering a rejection reason (10 min) |
Permission requests use DMPLZ_PERMISSION_CHAT_ID first if set, otherwise DMPLZ_DISCORD_DM_USER_ID (Discord only), and finally the default chat/channel.
Claude Code DM-Plz MCP Server (local)
?? ??
?? "Task completed!" ??
?? ??
Plugin ?�?�?�?�?�?�stdio?�?�?�?�?�?�?�?�?�?�?�??MCP Server
??
??HTTPS
??
Telegram Bot API / Discord API
??
??
Your Telegram / Discord app
The MCP server runs locally and uses the bot API with polling (no webhooks needed).
Send a simple notification message.
await send_message({
message: "Build completed successfully! ??,
parse_mode: "Markdown" // optional
});Ask a question and wait for the user's reply.
const response = await ask_question({
question: "I found 3 bugs. Should I fix them now or create issues?",
parse_mode: "Markdown", // optional
});
// User's response is returned as textSend a notification with a title and detailed message.
await send_notification({
title: "Deployment Complete",
message:
"Successfully deployed to production\n??15 files changed\n??0 errors\n??2 warnings",
parse_mode: "Markdown", // optional
});Claude: *finishes implementing authentication*
Claude: Uses send_message("Authentication system implemented! Added JWT tokens, login/logout, and password hashing.")
You: *receive notification on Telegram/Discord*
Claude: *finds multiple approaches to solve a problem*
Claude: Uses ask_question("I can implement caching with Redis or in-memory. Which do you prefer?")
You: *reply on Telegram/Discord* "In-memory for now"
Claude: *continues with your choice*
Claude: *running tests*
Claude: Uses send_notification(title: "Tests Running", message: "Running 250 tests... this may take a few minutes")
You: *can go do something else*
Claude: *finishes tests*
Claude: Uses send_notification(title: "Tests Complete", message: "All 250 tests passed ??)
The plugin includes a Stop hook that automatically prompts Claude to evaluate if it should notify you when it stops working. This means Claude will often proactively message you without being explicitly told to.
You can customize this behavior by editing .claude-plugin/plugin.json.
If you are using other plugins that also have Stop hooks (like oh-my-claude-sisyphus), they may conflict with DM-Plz's Stop hook. Only one Stop hook response will be used by Claude Code.
To disable other Stop hooks in your project, add this to your project's .claude/settings.json:
{
"hooks": {
"Stop": []
}
}This ensures only DM-Plz's Stop hook runs when Claude stops working.
Due to a Claude Code bug (#10412), Stop hooks installed via plugins cannot use the continueInstruction feature. To enable the "continue via DM" functionality, you need to install the Stop hook directly.
Option 1: Using npm script (Recommended)
cd /path/to/dm-plz/server
bun run install-stop-hookThis will add the Stop hook to your ~/.claude/settings.json.
Option 2: Manual installation
Add this to your ~/.claude/settings.json:
{
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "bun run \"/path/to/dm-plz/server/src/stop-hook.ts\"",
"timeout": 300000
}
]
}
]
}
}Replace /path/to/dm-plz with the actual path where DM-Plz is installed.
After installation, restart Claude Code for the changes to take effect.
Both Markdown and HTML formatting are supported:
**bold** *italic* `code`
[link](https://example.com)
<b>bold</b> <i>italic</i> <code>code</code>
<a href="https://example.com">link</a>
Note: Discord uses Markdown natively. HTML mode will be converted to Markdown for Discord.
$0.00 - Both Telegram and Discord Bot APIs are completely free!
| Feature | Telegram | Discord |
|---|---|---|
| Setup complexity | Very low | Low |
| Personal DMs | Yes | Yes (via channel) |
| Markdown support | Yes | Yes (native) |
| Rate limits | Very generous | Moderate |
| Polling speed | 10s intervals | 2s intervals |
| Best for | Personal notifications | Team/server notifications |
- Check all environment variables are set in
~/.claude/settings.json - Restart Claude Code after installing the plugin
- Try explicitly: "Send me a message when you're done."
- Verify bot token is correct
- Make sure you've started a chat with your bot (send
/start) - Check the chat ID is your personal chat ID (not a group)
- Check MCP server logs with
claude --debug
- Verify bot token and channel ID are correct
- Make sure the bot has been invited to your server
- Check bot has permissions: Send Messages, Read Messages, Read Message History
- Verify MESSAGE CONTENT INTENT is enabled in Discord Developer Portal
- Check MCP server logs with
claude --debug
- Increase
DMPLZ_QUESTION_TIMEOUT_MSif you need more time to respond - Make sure you're replying in the correct chat/channel
- Verify token format is correct
- Check your internet connection
- For Discord: Check bot hasn't been removed from server
- For Telegram: Check bot hasn't been deleted by @BotFather
cd server
bun install
bun run devBefore using the plugin with Claude Code, you can test your configuration:
Telegram:
cd server
export DMPLZ_PROVIDER=telegram
export DMPLZ_TELEGRAM_BOT_TOKEN="your_token"
export DMPLZ_TELEGRAM_CHAT_ID="your_chat_id"
bun run testDiscord:
cd server
export DMPLZ_PROVIDER=discord
export DMPLZ_DISCORD_BOT_TOKEN="your_token"
export DMPLZ_DISCORD_CHANNEL_ID="your_channel_id"
bun run testThe test script will:
- Verify your environment variables are set correctly
- Test the connection to Telegram/Discord
- Send a test message to confirm everything works
To test the server manually:
Telegram:
export DMPLZ_PROVIDER=telegram
export DMPLZ_TELEGRAM_BOT_TOKEN="your_token"
export DMPLZ_TELEGRAM_CHAT_ID="your_chat_id"
bun run src/index.tsDiscord:
export DMPLZ_PROVIDER=discord
export DMPLZ_DISCORD_BOT_TOKEN="your_token"
export DMPLZ_DISCORD_CHANNEL_ID="your_channel_id"
bun run src/index.tsdm-plz/
?��??� .claude-plugin/
?? ?��??� plugin.json # Plugin configuration
?? ?��??� marketplace.json # Marketplace metadata
?��??� server/
?? ?��??� src/
?? ?? ?��??� index.ts # MCP server main
?? ?? ?��??� types.ts # Type definitions
?? ?? ?��??� providers/
?? ?? ?��??� index.ts # Provider factory
?? ?? ?��??� telegram.ts # Telegram implementation
?? ?? ?��??� discord.ts # Discord implementation
?? ?��??� package.json
?��??� .env.example
?��??� .gitignore
?��??� README.md
?��??� SETUP.md
Contributions are welcome! Please open an issue or PR.
MIT
- Inspired by call-me by @ZeframLou
- Referenced implementations: