An MCP (Model Context Protocol) server that enables Claude Code to send and receive messages via Telegram. This allows you to interact with Claude Code remotely through your Telegram app.
- Send text messages from Claude Code to Telegram
- Receive messages from Telegram in Claude Code
- Send photos/screenshots to Telegram
- Proxy support for regions where Telegram is blocked
- NEW: Remote permission approval via hooks - Approve/deny sensitive operations from your phone
- NEW: Lock file mechanism - Prevents multiple instance conflicts
- NEW: Hammerspoon injection (macOS) - More reliable terminal injection via CGEvent API
- NEW: Auto webhook cleanup - Ensures message receiving works even if a webhook was previously set
- Node.js 18.0.0 or higher
- Claude Code installed
- A Telegram account
- Open Telegram and search for @BotFather
- Send
/newbotcommand - Follow the prompts to name your bot
- Save the bot token - it looks like:
1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
- Open Telegram and search for @userinfobot
- Send any message to this bot
- Save the
Idvalue from the response - it looks like:123456789
Important: Before Claude Code can receive your messages, you must start a conversation with your bot:
- Search for your bot by its username in Telegram
- Click "Start" or send any message to it
Add the MCP server to your Claude Code configuration.
Option A: Using Claude Code settings command
claude /settingsThen add the MCP server configuration.
Option B: Edit configuration file directly
The configuration file is located at:
- Windows:
%USERPROFILE%\.claude.json - macOS/Linux:
~/.claude.json
If you can access Telegram directly:
{
"mcpServers": {
"telegram": {
"command": "npx",
"args": ["-y", "mcp-telegram-claudecode"],
"env": {
"TELEGRAM_BOT_TOKEN": "1234567890:ABCdefGHIjklMNOpqrsTUVwxyz",
"TELEGRAM_CHAT_ID": "123456789"
}
}
}
}If you need a proxy to access Telegram:
{
"mcpServers": {
"telegram": {
"command": "npx",
"args": ["-y", "mcp-telegram-claudecode"],
"env": {
"TELEGRAM_BOT_TOKEN": "1234567890:ABCdefGHIjklMNOpqrsTUVwxyz",
"TELEGRAM_CHAT_ID": "123456789",
"HTTP_PROXY": "http://127.0.0.1:7890"
}
}
}
}Common proxy ports:
- Clash:
http://127.0.0.1:7890 - V2Ray:
http://127.0.0.1:10808 - Shadowsocks:
http://127.0.0.1:1080
Replace with your actual proxy address and port.
| Variable | Required | Description |
|---|---|---|
TELEGRAM_BOT_TOKEN |
Yes | Bot token from @BotFather |
TELEGRAM_CHAT_ID |
Yes | Your chat ID from @userinfobot |
HTTP_PROXY |
No | HTTP proxy URL (e.g., http://127.0.0.1:7890) |
HTTPS_PROXY |
No | HTTPS proxy URL (alternative to HTTP_PROXY) |
Once configured, Claude Code will have access to these tools:
Send a text message to your Telegram.
Parameters:
- message (required): The text message to send
Retrieve recent messages from Telegram.
Parameters:
- limit (optional): Maximum number of messages to retrieve (default: 10)
Quick check if there are new messages.
No parameters required
Send an image file to Telegram.
Parameters:
- photo_path (required): Absolute path to the image file
- caption (optional): Caption for the photo
After configuration, you can ask Claude Code to:
- "Send me a message on Telegram saying the task is complete"
- "Check if I sent any new messages on Telegram"
- "Send a screenshot of the current code to my Telegram"
Make sure you've added the bot token to your .claude.json configuration.
- Make sure you started a conversation with your bot first
- Check that your
TELEGRAM_CHAT_IDis correct - If using a proxy, verify the proxy is working
- Check stderr logs for "Webhook cleared" message - if a webhook was previously set,
getUpdatessilently returns empty results (v1.6.0 fixes this automatically)
If you're in a region where Telegram is blocked:
- Make sure your proxy software is running
- Add the
HTTP_PROXYenvironment variable to your configuration - Verify the proxy port is correct
- Check that the bot token is correct (no extra spaces)
- Make sure you've started a conversation with your bot
- Try sending a message to your bot first, then check for messages
Instead of using --dangerously-skip-permissions, you can use Claude Code hooks to approve sensitive operations remotely via Telegram.
┌─────────────┐ PreToolUse Hook ┌─────────────────┐ Telegram API ┌──────────┐
│ Claude Code │ ──────────────────────► │ Hook Script │ ◄─────────────────► │ Telegram │
│ (sensitive │ │ (asks approval) │ │ (you) │
│ operation) │ ◄────────────────────── │ │ │ │
└─────────────┘ approve/deny └─────────────────┘ └──────────┘
- Claude Code attempts a sensitive operation (Edit, Write, Bash)
- PreToolUse hook sends details to your Telegram
- You reply Y to approve or N to deny
- Hook returns the decision to Claude Code
- Copy the hooks to your system (included in
hooks/directory) - Configure Claude Code hooks via
/hookscommand or edit settings:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash|Edit|Write",
"hooks": [
"node /path/to/telegram-claude-mcp/hooks/pretool-approval.js"
]
}
]
}
}- Set environment variables (same as MCP server config)
See hooks/README.md for detailed setup instructions.
| Approve | Deny |
|---|---|
| Y, yes, 1, approve | N, no, 0, deny |
| 是, 好, 可以 | 否, 不, 拒绝 |
This MCP server acts as a bridge between Claude Code and Telegram:
┌─────────────┐ MCP Protocol ┌─────────────────┐ Telegram API ┌──────────┐
│ Claude Code │ ◄──────────────────► │ MCP Server │ ◄─────────────────► │ Telegram │
│ │ │ (this project) │ │ │
└─────────────┘ └─────────────────┘ └──────────┘
When the MCP server starts, it automatically begins polling for new Telegram messages. When a message is received, it attempts to inject the text into the active terminal window using:
- Clipboard: Message is copied to system clipboard
- SendKeys (Windows): PowerShell script simulates Ctrl+V and Enter keystrokes
- Window Activation: Attempts to find and activate terminal windows (Windows Terminal, cmd, PowerShell, VS Code)
This is an experimental feature - it enables "remote control" of Claude Code via Telegram, but has reliability limitations.
| Tool | Description |
|---|---|
telegram_send_message |
Send text to Telegram |
telegram_get_messages |
Retrieve recent messages |
telegram_check_new |
Quick check for new messages |
telegram_send_photo |
Send images to Telegram |
telegram_start_polling |
Manually start auto-polling |
telegram_stop_polling |
Stop auto-polling |
Problem: If you run multiple Claude Code windows, each will start its own MCP server instance.
Solution: Lock file mechanism now prevents multiple instances from polling simultaneously. Only the first instance will poll; others will skip polling automatically.
Problem: When SendKeys injection fails, you wouldn't know about it.
Solution: Failed injections now send a notification to Telegram, so you know when to check manually.
Problem: Cannot approve sensitive operations remotely.
Solution: Use the included PreToolUse hooks for remote approval via Telegram. See Remote Permission Approval section.
The terminal injection feature uses WriteConsoleInput API for no-focus injection:
How it works:
- Uses Windows Console API to write directly to the console input buffer
- Does not require window focus
- Does not use clipboard
- Works when other applications are active
Limitation - Single Terminal Only:
- Works correctly when only one terminal window is open
- If multiple terminals are open, messages may go to the wrong terminal
- This is due to Windows Terminal's ConPTY architecture
When it may fail:
- Multiple terminal windows open simultaneously
- Remote desktop or virtual machine environments
- Screen is locked
Workaround: Use hooks instead of SendKeys for more reliable operation, or ensure only one terminal is open.
| Platform | MCP Tools | Auto-Injection | Hooks |
|---|---|---|---|
| Windows | ✅ Full | ✅ SendKeys | ✅ Full |
| macOS | ✅ Full | ✅ Hammerspoon / |
✅ Full |
| Linux | ✅ Full | ❌ Not implemented | ✅ Full |
macOS Auto-Injection: Requires Hammerspoon with the CLI tool enabled:
- Install Hammerspoon:
brew install --cask hammerspoon - Open Hammerspoon preferences
- Enable "Enable CLI tool (hs)" in the preferences
- The
hscommand should now be available in your terminal
If Hammerspoon is not installed, falls back to AppleScript (clipboard + paste), which is less reliable and requires window focus.
Recommendation: Use hooks for cross-platform remote control, or Hammerspoon on macOS for auto-injection.
- ✅ Fixed message receiving: auto-delete webhook on startup (getUpdates returns empty if webhook is set)
- ✅ Added
getMediagnostic on startup to validate bot token - ✅ Added axios timeouts to polling/check requests to prevent hanging
- ✅ Added Hammerspoon injection for macOS (more reliable than AppleScript)
- ✅ AppleScript fallback when Hammerspoon is not installed
- ✅ Added video and document sending support
- ✅ Improved terminal injection security
- ✅ Added lock file mechanism to prevent multiple instance conflicts
- ✅ Added injection failure notifications via Telegram
- ✅ Added PreToolUse hook for remote permission approval
- ✅ Added PostToolUse hook for error notifications
- ✅ Improved terminal injection with WriteConsoleInput API (no focus required)
- ✅ Improved exit cleanup (SIGINT/SIGTERM handling)
⚠️ Known limitation: Single terminal mode only (multiple terminals may cause injection to wrong window)
- Added photo sending support
- Added proxy support
- Added auto-polling and terminal injection
- Added telegram_check_new tool
- Initial release
MIT License - see LICENSE file for details.
EthanSky