The Problem
Claude Code is a phenomenal agentic coding tool, but the default installation assumes a desktop-first workflow. You open a terminal, you start Claude Code, you type prompts, you close the terminal when you're done.
What if you want the agent to run 24/7? What if you want to poke it from your phone at the airport? What if you want to fire off a long-running refactor, go to bed, and check results in the morning?
Three problems stand in the way:
- ●Persistence — Claude Code dies when you close the terminal. You need it running as a service.
- ●Remote access — SSH works, but typing prompts over SSH from a phone is miserable. Telegram DMs feel native.
- ●Permission prompts — Claude Code asks for confirmation on tool calls. Those prompts are fine at your desk, brutal when the agent is running unattended.
This is the architecture we use to solve all three.
What We Built
A Claude Code instance running 24/7 on a Linux VPS, accessible via a private Telegram bot, with a background watcher that auto-approves all permission prompts. The whole stack costs $7/month on a cheap VPS and takes about 30 minutes to set up from scratch.
The components:
- ●Claude Code CLI installed on the VPS as a non-root user
- ●systemd service keeping Claude Code alive across reboots
- ●Telegram Channels plugin (official Claude plugin) bridging Telegram to Claude Code
- ●Auto-permission watcher (a small bash script) approving permission prompts in the background
- ●tmux session holding the interactive Claude Code session the watcher attaches to
When we message our Telegram bot, the message flows into Claude Code. Claude works, calls tools, gets permission prompts that the watcher auto-approves, completes the task, and replies in the Telegram chat. We can be on the train, in bed, or out running errands.
Why Not Just SSH In?
SSH works, but the ergonomics are wrong for a phone-first workflow.
SSH from a phone requires:
- ●An SSH client app (Termius, Blink, or similar)
- ●A stable keyboard on mobile (painful)
- ●A tmux session you manually attach to
- ●Visual parsing of terminal output on a small screen
Telegram bot access gives you:
- ●Native iOS and Android keyboards with dictation
- ●Message history with formatting
- ●Push notifications when Claude replies
- ●Conversation context that reads naturally
- ●Inline keyboard buttons for confirmations (when needed)
For quick "what was that thing I did last week" queries or "fix the CI failure and push" requests, Telegram is dramatically better than SSH. For heavy debugging sessions, SSH still wins.
Why Telegram Specifically
The official Claude Channels plugin supports multiple messaging platforms: Telegram, Discord, Slack, iMessage, Signal. We chose Telegram because:
- ●Private by default — no public servers or channels to configure. A bot DM is end-to-end between you and the bot.
- ●Cross-platform — same Telegram client on iOS, Android, desktop, web. Context syncs.
- ●Bot API is battle-tested — Telegram's Bot API has been stable for years. Rate limits are generous.
- ●Allowlist control — you can restrict the bot to respond only to your user ID. No risk of strangers messaging the bot and triggering Claude on your infrastructure.
- ●Inline buttons — Telegram's inline keyboard buttons work as permission prompt UI when the watcher isn't enough.
If Telegram is blocked in your country or you're deep in the Discord ecosystem, the same architecture works on Discord. The Claude Channels plugin supports both.
The Architecture
At a high level:
- ●Your phone runs the Telegram app
- ●Telegram servers route messages to/from your private bot
- ●Your VPS runs Claude Code under a non-root user, wrapped in a systemd service
- ●The systemd service launches tmux + Claude Code + the Telegram Channels plugin
- ●A background watcher script monitors the tmux session for permission prompts and auto-approves them
- ●Claude's tools (Read, Write, Bash, Edit, etc.) all operate within the user's home directory and permitted paths
Every incoming Telegram message becomes a new Claude Code turn. Every Claude reply comes back as a Telegram message. Permission prompts get handled silently in the background.
The systemd Service Pattern
We run Claude Code under a non-root user (we'll call it claude-user) because Anthropic recommends against running Claude Code as root, and the VS Code extension explicitly refuses to. The service file looks like this:
[Unit]
Description=Claude Code Persistent Session
After=network.target
[Service]
Type=forking
User=claude-user
WorkingDirectory=/home/claude-user
ExecStart=/usr/bin/tmux new-session -d -s claude-session
ExecStartPost=/usr/bin/tmux send-keys -t claude-session "cd /home/claude-user && claude" Enter
ExecStop=/usr/bin/tmux kill-session -t claude-session
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.targetSave as /etc/systemd/system/claude-code.service, then:
sudo systemctl daemon-reload
sudo systemctl enable claude-code
sudo systemctl start claude-codeNow Claude Code runs inside a tmux session that persists across SSH disconnects and VPS reboots. You can attach to see what's happening:
sudo -u claude-user tmux attach -t claude-sessionPress Ctrl+B then D to detach without killing the session.
The Telegram Channels Plugin
Claude Code plugins install via a single slash command inside an active Claude session. Once attached to the tmux session:
/plugin install telegram@claude-plugins-officialThe plugin asks for three things:
- ●Bot token — create a bot with @BotFather on Telegram. Free, 30 seconds.
- ●Allowlist — a list of Telegram user IDs permitted to message the bot. Start with just yours.
- ●Mode — "allowlist" (only listed users) vs "public" (anyone can message). Always use allowlist.
Get the Weekly IT + AI Roundup
What changed this week in NinjaOne, ServiceNow, CrowdStrike, and AI. One email, every Monday.
No spam, unsubscribe anytime. Privacy Policy
The plugin stores config in ~/.claude/channels/telegram/.env. The bot token goes there, file-permissioned to the claude-user only.
Once configured, Telegram messages to your bot flow into Claude Code automatically. No webhooks, no reverse proxy, no public endpoints required. The plugin uses Telegram's long-polling API by default.
The Auto-Permission Watcher (The Secret Sauce)
This is the piece no one documents.
Claude Code prompts for permission whenever a tool call requires it (Bash commands, file writes, certain MCP operations). Those prompts are inline in the terminal as arrow-key-navigable menus. In an unattended session, they block indefinitely until someone presses a key.
The watcher script runs in the background, monitors the tmux session for pending permission prompts, and sends "approve" keystrokes. A minimal version:
#!/bin/bash
# Auto-approve Claude Code permission prompts in the claude-session tmux session.
while true; do
# Capture the tmux pane output
OUTPUT=$(tmux capture-pane -t claude-session -p 2>/dev/null)
# Check for permission prompt patterns
if echo "$OUTPUT" | grep -qE "(Allow|Permit|Yes).*\[(y/n|Y/n|yes/no)\]"; then
# Send 'y' to approve
tmux send-keys -t claude-session "y" Enter
elif echo "$OUTPUT" | grep -qE "Do you want to (proceed|continue)"; then
# Send Enter (default = yes in some prompts)
tmux send-keys -t claude-session "" Enter
fi
sleep 2
doneSave as /home/claude-user/channel-watcher.sh, chmod +x, then run it as a second systemd service or via a nohup background process.
Full disclosure: this is risky. You're handing the keys to any tool Claude wants to call. Claude Code has guardrails (destructive operations like rm -rf require explicit confirmation phrases), but the watcher disables the human-in-the-loop by design. Use allowlists aggressively and never expose the bot to untrusted users.
Real Gotchas
1. MCP permissions don't always persist across restarts
Even with wildcard approvals in .claude/settings.local.json, some MCP tool calls prompt again after a service restart. The watcher handles this, but the first time you see it the behavior is confusing.
2. Telegram bot tokens expire silently
OAuth tokens on the Claude side expire after ~18 months. Schedule a calendar reminder. When they expire, the bot goes silent (no error message). Regenerate via claude setup-token on the VPS.
3. The OS doesn't autostart systemd services by default
Run sudo systemctl enable claude-code explicitly. We've seen this missed and the service dies on first reboot.
4. tmux sessions don't survive VPS image restorations
If your VPS provider offers snapshots and you restore one, the tmux session inside is dead. You'll need to restart the systemd service manually after restore.
5. Message length limits
Telegram messages cap at ~4096 characters. Claude's longer responses get auto-split. The plugin handles this, but threaded conversations with long replies can feel fragmented.
Security Considerations
Running Claude Code with auto-permission approval is powerful. It's also a delegated-access pattern with real risks. We mitigate with:
- ●Allowlist mode only — only your own Telegram user ID can trigger the bot
- ●Non-root user — Claude Code runs as claude-user, not root, so worst-case damage is confined to the user's home directory
- ●No sudo access for claude-user — claude-user is not in the sudoers file
- ●Dedicated VPS — not your daily-driver server. If the agent does something destructive, the blast radius is contained.
- ●Regular audit of .claude/settings.local.json — verify no new unwanted MCP servers have been added
- ●Rotate the bot token every 6-12 months
- ●Monitor outbound traffic — alerts for unusual external API calls
Never run this setup with sudo privileges, never enable it on your personal workstation, and never add untrusted users to the allowlist.
Who This Is For
Developers who want to fire off coding tasks from their phone without opening a laptop.
Infrastructure engineers running Claude Code as an always-on automation agent responding to webhooks and alerts.
Content teams piping CMS events or analytics into Claude Code for async processing.
Anyone who's thought "I wish I could tell Claude to check on that deploy while I'm at lunch."
If you don't have a VPS, aren't comfortable with systemd, or don't want to manage Linux security, this setup isn't for you. Use Claude Code in its intended desktop form until you're ready for the operational overhead.
The Bigger Picture
Claude Code was designed for interactive use at a developer's workstation. We're using it as a 24/7 autonomous agent accessible from anywhere. That's a different operating mode from the intended one, and it carries different risks and rewards.
The reward: an AI agent that answers to your phone, works on your codebase, handles your webhooks, and never needs you to open your laptop.
The risk: auto-approval disables the human-in-the-loop. One bad prompt, one compromised allowlist, one misconfigured MCP server, and the agent does something you don't want.
We run this setup because the productivity gain is worth it to us. Your calculation may differ.
Get Started
Claude Code is free with an Anthropic API key or Claude Pro subscription. The Telegram Channels plugin is free and bundled with Claude plugins.
Want the full agent deployment playbook? Our Claude Code Pro Track covers Projects, Artifacts, System Prompts, Claude Code, and advanced reasoning techniques across 7 modules.
Running n8n, Claude Code, and other services on the same VPS? Our n8n Administration Pro Track covers the multi-service deployment pattern end-to-end.
Not sure which AI stack fits your workflow? Take the free quiz and get matched in 2 minutes.