Control Claude Code CLI remotely via Telegram. No API key needed.
I'm not really a programmer — more of a power user who relies on Claude Code daily. When OpenClaw got cut off, I needed a way to keep using Claude Code from my phone.
My solution was pretty basic: a Python script that connects Telegram to a Claude Code session running in tmux. It types your message into the terminal (send-keys) and reads back what's on screen (capture-pane). That's it.
No API key needed. No extra cost. If you're already paying for Claude Code, this just lets you use it remotely.
It works for what I need, so I figured I'd share it in case others are looking for something similar.
Unlike tools that call Claude's API directly (which means extra costs), LiteClaw operates your existing Claude Code CLI session through tmux. You're already paying for Claude Max — this just lets you use it from your phone.
- Single Python file (~900 lines), not a framework
- No API keys to Anthropic needed
- No containers, no Docker
- Your subscription covers everything
- Remote access — Control Claude Code from anywhere via Telegram
- AI summarization — Responses cleaned up by an LLM before delivery (toggleable)
- Busy detection — Knows when Claude is working, queues your message automatically
- Progress updates — Periodic status messages while Claude works on long tasks
- File transfer — Send files to the server and download results back to Telegram
- Multi-target — Switch between tmux sessions and windows on the fly
- Photo upload — Send photos for Claude's vision tasks
git clone https://github.com/breaktheready/liteclaw.git
cd liteclaw
bash setup.shThe setup script creates the virtual environment, installs dependencies, and copies .env.example to .env.
git clone https://github.com/breaktheready/liteclaw.git
cd liteclaw
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .envEdit .env and set the required values:
BOT_TOKEN=your_bot_token_here
CHAT_ID=your_numeric_chat_id_here
TMUX_TARGET=claude:1tmux new-session -s claude 'claude --dangerously-skip-permissions'source .venv/bin/activate
python3 liteclaw.pySend /start to your Telegram bot to confirm it is working.
All settings are controlled via .env. Copy .env.example and edit as needed.
| Variable | Default | Description |
|---|---|---|
BOT_TOKEN |
(required) | Telegram bot token from @BotFather |
CHAT_ID |
(required) | Your numeric Telegram user ID |
TMUX_TARGET |
claude:1 |
Target tmux session and window (SESSION:WINDOW.PANE) |
SUMMARIZER_URL |
http://localhost:8080/v1 |
OpenAI-compatible API endpoint for summarization |
SUMMARIZER_MODEL |
claude-haiku-4-5 |
Model to use for response cleanup |
SCROLLBACK_LINES |
500 |
Number of tmux history lines to capture per poll |
INTERMEDIATE_INTERVAL |
10 |
Seconds between progress updates while Claude works |
STAGING_DIR |
~/liteclaw-files |
Directory where uploaded files are saved on the server |
EXTRA_PROMPT_PATTERNS |
(empty) | Comma-separated regex patterns for custom prompt detection |
| Command | Description |
|---|---|
| Any text | Relay text directly to Claude Code and return the response |
/start or /help |
Show available commands and current configuration |
/status |
Display the last 30 lines of Claude's current tmux pane |
/target SESSION:WIN.PANE |
Switch to a different tmux target (e.g. /target work:0) |
/cancel |
Send Ctrl+C to interrupt Claude's current task |
/escape |
Send the Escape key (useful for exiting Claude modal dialogs) |
/raw |
Toggle between summarized and raw output |
/model MODEL_NAME |
Change the summarizer model (e.g. /model claude-sonnet-4-6) |
/sessions |
List all active tmux sessions |
/get FILEPATH |
Download a file from the server to Telegram |
| Send a document | Upload a file to STAGING_DIR and relay its path (and contents for small files) to Claude |
| Send a photo | Upload a photo to STAGING_DIR and relay the path to Claude for vision tasks |
Any text message — LiteClaw checks if Claude is idle, injects your message into the tmux pane, polls for a response, optionally runs it through the summarizer, and sends it back. Long responses are split into 4000-character chunks automatically.
/status — Shows raw pane content without filtering. Useful for checking what Claude is doing mid-task or diagnosing prompt detection issues.
/target — Switches the active tmux target without restarting the bot. Accepts any valid tmux target format: session, session:window, or session:window.pane.
/cancel — Sends a SIGINT (Ctrl+C) to the active pane. Use this to abort a long-running Claude task before sending a new message.
/escape — Sends the Escape key sequence. Useful for closing Claude's permission dialogs or exiting selection mode.
/raw — Toggles raw mode. When enabled, responses are sent unfiltered (terminal noise and all). When disabled (default), the summarizer removes noise and formats the response for readability.
/model — Changes the summarizer model at runtime. Takes effect immediately for the next response.
/sessions — Runs tmux list-sessions and sends the output. Helps when you need to find the right session name for /target.
/get — Downloads a file from the server. Relative paths are resolved from the tmux pane's working directory. Absolute paths work as-is. Maximum 50 MB.
Send any file as a Telegram document attachment (up to 50 MB), or send a photo directly from your camera or gallery.
LiteClaw will:
- Save the file to
STAGING_DIRon the server - If the file is a small text file (under ~50 KB), embed its contents in the message to Claude
- Otherwise, relay the file path so Claude can read it directly
- Send Claude's response back to Telegram
Add a caption to your file to pass instructions alongside it. For example:
Caption: "Summarize the key findings in this report"
For photos, the caption is relayed as the prompt for Claude's vision capabilities.
/get results.txt
/get ~/projects/output.json
/get /tmp/analysis_20260405.csv
The file is fetched and sent back as a Telegram document. Relative paths resolve from the tmux pane's current working directory.
You (Telegram) --> LiteClaw --> tmux send-keys --> Claude Code CLI
|
You (Telegram) <-- Summarizer <-- capture-pane <-- Response
- Your message arrives at the Telegram bot
- LiteClaw checks if Claude is idle (prompt visible) or busy
- If idle, the message is injected into the tmux pane via
send-keys - LiteClaw polls
capture-paneevery 1.5 seconds - When the pane content stabilizes and a prompt reappears, the response is ready
- The response is optionally passed through the summarizer to remove terminal noise
- The clean response is split into chunks and sent back to Telegram
LiteClaw does not call Claude's API directly. It controls Claude Code through tmux using your existing Claude Code subscription. Summarization is handled by a local OpenAI-compatible proxy (optional). If the summarizer is unavailable, LiteClaw falls back to raw output automatically.
LiteClaw has a 3-tier summarizer that works out of the box — no extra setup needed.
Tier 1: API Proxy (fastest, 2-3s) — If you have an OpenAI-compatible API endpoint, set SUMMARIZER_URL. Options:
- claude-max-api-proxy — Use your Claude Max subscription
- LiteLLM — Proxy to any LLM provider
- Any OpenAI-compatible endpoint
Tier 2: Claude Code Agent (automatic fallback, 10-20s) — If no API proxy is available, LiteClaw automatically creates a hidden Claude Code session to summarize responses. Since you already have Claude Code installed, this works without any extra setup. Set SUMMARIZER_AGENT_MODEL to choose a specific model, or leave empty for default.
Tier 3: Raw Output — If both tiers fail, responses are sent unfiltered. You can also force this with /raw.
At startup, LiteClaw probes the API endpoint. If it's unreachable, Tier 2 is pre-warmed automatically.
- Open Telegram and search for
@BotFather - Send
/newbot - Choose a display name for your bot (e.g. "My Claude Bot")
- Choose a username ending in
bot(e.g.my_claude_bot) - BotFather will return a token like
123456789:ABCdef... - Copy the token to
.envasBOT_TOKEN
- Open Telegram and search for
@userinfobot - Send any message
- It will reply with your numeric user ID — copy it to
.envasCHAT_ID
Bot token — Stored only in .env, which is gitignored by default. Never hardcode your token in source code or share it publicly. Anyone with your bot token can send messages as your bot.
Authentication — Only messages from the Telegram user ID configured as CHAT_ID are processed. All other users are silently ignored. This is a single-user tool by design.
tmux access — LiteClaw has direct, unsandboxed access to your tmux session. It can inject arbitrary keystrokes. Secure your server with appropriate access controls — LiteClaw itself does not add any authentication beyond the Telegram chat ID check.
--dangerously-skip-permissions — This flag disables Claude Code's permission prompts, auto-approving all file writes, shell commands, and other actions. Only use this in trusted environments where you understand the implications.
Network — LiteClaw connects only to the Telegram API (for receiving and sending messages) and optionally to your local summarizer endpoint. No user data is sent to external servers beyond Telegram's own infrastructure.
"tmux session not found"
The tmux session in TMUX_TARGET does not exist. Start Claude Code first:
tmux new-session -s claude 'claude --dangerously-skip-permissions'Then update TMUX_TARGET in .env to match your session name.
"Still processing / Use /cancel to abort"
Claude is busy. LiteClaw queues your message but warns you. Send /cancel to interrupt the current task, then retry.
No response from Claude
Run /status to see Claude's current pane content. If you do not see the ❯ prompt, Claude may be waiting for input or stuck. If you use a custom shell prompt, add its pattern to EXTRA_PROMPT_PATTERNS in .env.
Garbled or incomplete output
Claude may have still been rendering when LiteClaw captured the response. Try /raw to see unfiltered output. If the issue is consistent, increase SCROLLBACK_LINES in .env.
"Conflict: terminated by other getUpdates request" Another process is already polling the same bot token. Find and stop it:
ps aux | grep liteclaw.py
pkill -f liteclaw.pyThen restart LiteClaw.
Summarizer requests timeout
The summarizer proxy is slow or unreachable. Switch to raw mode with /raw, or verify the proxy is running and SUMMARIZER_URL is correct.
Run LiteClaw inside its own tmux session so it survives terminal disconnects:
tmux new-session -d -s liteclaw -c /path/to/liteclaw \
'.venv/bin/python3 liteclaw.py'Monitor it with:
tmux attach -t liteclawFor automatic startup and restart on failure, create a systemd unit file:
[Unit]
Description=LiteClaw Telegram-Claude Bridge
After=network.target
[Service]
Type=simple
User=youruser
WorkingDirectory=/path/to/liteclaw
ExecStart=/path/to/liteclaw/.venv/bin/python3 liteclaw.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetInstall and enable:
sudo cp liteclaw.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now liteclawLiteClaw is a personal project shared as-is for the community.
- Use at your own risk. The author is not responsible for any damage, data loss, or security issues arising from use of this software.
- This tool controls Claude Code via tmux. Ensure your server and tmux sessions are properly secured.
- Bot token and chat ID security is your responsibility. Never share your
.envfile. - This project is not affiliated with, endorsed by, or sponsored by Anthropic.
MIT