AI Dev Tools

Control Your Server From Telegram Using Claude AI

Build a Telegram bot that bridges directly to Claude and your server. Send a message from your phone, get your site deployed, logs tailed, and services restarted — without ever opening a terminal.

12 min readApril 2025

SSH from a phone works, but it has friction. You need to open a terminal app, navigate to a saved host, type commands in a tiny keyboard. For emergencies it's fine. For daily server management, it gets old fast.

A better setup: a Telegram bot that talks to Claude, which talks to your server. You send a plain-English message from anywhere. Claude understands what you want, translates it to shell commands, and the bot executes and reports back. Your phone becomes a natural-language server management interface.

Telegram on mobile
Telegram's bot API + Claude's language understanding = a conversational server management interface that fits in your pocket.

How the Architecture Works

The system has three layers:

  1. Telegram bot — your input interface. You send messages to it from any device.
  2. Claude API — the intelligence layer. Receives your message, decides what command to run, formats the output into plain English.
  3. Server agent (Node.js or Python) — runs on your VPS, receives instructions from Claude via a webhook or polling loop, executes commands, and sends results back.

The agent running on your server is the piece that actually executes shell commands. Claude never directly touches your server — it reasons about what should happen and passes instructions to the agent. This design means you can add permission gates, audit logs, and rollback logic at the agent layer.

Server infrastructure diagram
The agent runs on your VPS. Claude and Telegram are both external — your server only receives signed requests from a process you control.

Step-by-Step Build

Step 1

Create the Telegram bot

Message @BotFather on Telegram. Use /newbot, name it, get the API token. Save it — you'll use it as TELEGRAM_BOT_TOKEN in your environment.

Step 2

Get your Claude API key

Create an account at console.anthropic.com. Generate an API key. Store it as ANTHROPIC_API_KEY. We'll use claude-opus-4-6 for maximum reasoning ability.

Step 3

Deploy the agent script to your server

The agent is a small Python or Node.js process that polls Telegram for messages, sends them to Claude with a system prompt describing your server, and executes the resulting commands.

Step 4

Lock it down to your Telegram user ID

Get your user ID from @userinfobot. Hard-code it as an allowed sender. The bot should refuse all messages from other user IDs with no response — silence is better than an error that confirms the bot exists.

Step 5

Run it as a systemd service

Create a systemd unit file so the agent starts on boot and restarts on crash. This is your always-on server management interface.

The Core Python Script

Here's a minimal working implementation. Drop this on your server and run it:

#!/usr/bin/env python3
# server_agent.py — Claude + Telegram server bridge
import os, subprocess, requests, anthropic

TELEGRAM_TOKEN = os.environ["TELEGRAM_BOT_TOKEN"]
ANTHROPIC_KEY = os.environ["ANTHROPIC_API_KEY"]
ALLOWED_USER = int(os.environ["ALLOWED_USER_ID"])

client = anthropic.Anthropic(api_key=ANTHROPIC_KEY)

SYSTEM_PROMPT = """You are a server management agent for an Ubuntu 22.04 VPS.
When the user describes what they need, respond with ONLY the shell command(s) to run.
Use one command per line. Add a comment above each command explaining what it does.
Never include explanation prose — just the commands."""

def get_updates(offset=None):
    params = {"timeout": 30}
    if offset: params["offset"] = offset
    r = requests.get(f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/getUpdates", params=params)
    return r.json().get("result", [])

def send_message(chat_id, text):
    requests.post(f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage",
        json={"chat_id": chat_id, "text": text, "parse_mode": "Markdown"})

def ask_claude(user_message):
    msg = client.messages.create(
        model="claude-opus-4-6",
        max_tokens=1024,
        system=SYSTEM_PROMPT,
        messages=[{"role": "user", "content": user_message}]
    )
    return msg.content[0].text

def run_commands(commands_text):
    output = []
    for line in commands_text.strip().split("\n"):
        if line.startswith("#") or not line.strip(): continue
        result = subprocess.run(line, shell=True, capture_output=True, text=True, timeout=60)
        output.append(f"$ {line}")
        if result.stdout: output.append(result.stdout.strip())
        if result.stderr: output.append(f"STDERR: {result.stderr.strip()}")
    return "\n".join(output)

offset = None
print("Agent running...")
while True:
    updates = get_updates(offset)
    for u in updates:
        offset = u["update_id"] + 1
        msg = u.get("message", {})
        if msg.get("from", {}).get("id") != ALLOWED_USER: continue
        chat_id = msg["chat"]["id"]
        text = msg.get("text", "")
        if not text: continue
        send_message(chat_id, "⏳ Working on it...")
        commands = ask_claude(text)
        result = run_commands(commands)
        send_message(chat_id, f"```\n{result}\n```")

Example Conversations With Your Bot

Once the agent is running, this is what using it feels like:

You: restart nginx and check its status
Bot:

$ sudo systemctl restart nginx
$ sudo systemctl status nginx
● nginx.service - A high performance web server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
   Active: active (running) since Fri 2025-04-11 14:32:07 UTC

You: show me the last 20 lines of the nginx error log
Bot: Returns the last 20 error log lines directly in Telegram.

You: pull the latest code for the getcodestaff site and restart pm2
Bot: Runs git pull and pm2 restart, reports back with output.

Security note: The ALLOWED_USER check is critical. Without it, anyone who finds your bot username can run arbitrary commands on your server. Also consider wrapping dangerous commands (rm, dd, chmod -R) in a confirmation prompt before executing.

Systemd Service Setup

Make the agent start automatically and restart on crashes:

# /etc/systemd/system/server-agent.service
[Unit]
Description=Claude Telegram Server Agent
After=network.target

[Service]
User=root
WorkingDirectory=/opt/server-agent
ExecStart=/usr/bin/python3 /opt/server-agent/server_agent.py
Restart=always
RestartSec=10
EnvironmentFile=/opt/server-agent/.env

[Install]
WantedBy=multi-user.target

# Then enable it:
systemctl daemon-reload
systemctl enable server-agent
systemctl start server-agent
Developer on phone managing servers
Once deployed, the agent runs 24/7. Message it from anywhere — Telegram works on any phone, no special apps needed.

Extending the Bot

The base script is just the beginning. Some extensions worth building:

Want a Production-Grade AI Server Agent?

We build custom AI agents that monitor infrastructure, auto-remediate issues, and report status — so you're never flying blind on your server.

Talk to the Team
Devin Mallonee

Devin Mallonee

Founder & AI Agent Architect · CodeStaff

Devin builds AI-powered infrastructure and automation systems. He founded CodeStaff to deploy AI agents that replace manual DevOps work — including the kind of emergency server fix that ruins a Saturday night.