ai claude code vps ssh ed25519 tmux telegram bot bun runtime agentic os devops remote development

Architecting Persistent Agentic Workflows: Deploying Claude Code on Remote VPS with tmux and Telegram Integration

5 min read

Architecting Persistent Agentic Workflows: Deploying Claude Code on Remote VPS with tmux and Telegram Integration

For many developers, running agentic CLI tools like Claude Code locally is the default approach. However, local execution introduces a fundamental bottleneck: the lifecycle of the AI agent is tethered to the lifecycle of your local machine's session. If your laptop enters sleep mode or the SSH connection drops, the agentic process terminates.

To move from simple task-based prompting to a true Agentic Operating System, we must decouple the execution environment from the client interface. This guide details the technical implementation of an "always-on" infrastructure using a Virtual Private Server (VPS), Secure Shell (SSH) with ED25519 key pairs, tmux for session persistence, and Telegram as a remote dispatch interface.

The Architecture of Persistence

The goal is to create a provider-agnostic, tool-agnostic underlying file structure. By hosting Claude Code on a VPS, we establish a centralized "brain" that maintains its own context, file system, and scheduled cron jobs. This setup allows for:

  1. 24/LT Workflows: Agents continue executing long-running tasks (e.g., complex refactors or repo indexing) regardless of client connectivity.
  2. Context Injection via Git: By cloning specific repositories (like an "Agentic OS" structure) directly onto the server, we provide Claude Code with a persistent, evolving context that is accessible from any device.
  3. Multi-Client Access: Multiple developers or devices can interface with the same file system and agent state simultaneously.

Phase 1: Establishing Secure Remote Access (SSH & ED25519)

Security in a remote execution environment relies on asymmetric cryptography rather than passwords. We utilize the ED25519 algorithm, which offers high security with small key sizes and excellent performance.

First, generate an ED25519 key pair on your local machine:

ssh-keygen -t ed25519 -C "your_email@example.com"

This generates a private key (which must remain on your local client) and a public key (.pub). The public key is what we will authorize on the VPS to allow passwordless, encrypted authentication.

Phase 2: Provisioning the Infrastructure

While you can manually manage a bare-metal or cloud instance via Hetzner, using a managed service like Elestio simplifies the orchestration of backups and monitoring. When provisioning an Ubuntu-based instance through Elestio, ensure you inject your public ED25519 key during the setup phase under the "SSH Keys" configuration.

Once the VPS is live, identify its IPv4 address. This will serve as our remote host identifier.

Phase 3: Configuring the Remote Development Environment

To interact with the server's file system as if it were local, we use the VS Code Remote-SSH extension.

  1. Local SSH Configuration: Edit your local ~/.ssh/config file to define a shorthand host:

s Host myvps HostName [YOUR_VPS_IP] User root IdentityFile ~/.ssh/id_ed25519

2. **Security Hardening (Non-Root User):** Running Claude Code as `root` is a security anti-pattern. We must create a dedicated service user:
```bash
adduser simon
usermod -aG sudo simon
# Copy authorized_keys from root to the new user
mkdir -p /home/simon/.ssh
cp /root/.ssh/authorized_keys /home/simon/.ssh/
chown -R simon:simon /home/simon/.ssh
chmod 700 /home/simon/.ssh
chmod 600 /home/simon/.ssh/authorized_keys
  1. Update SSH Config: Update your local ~/.ssh/config to point to the new user (User simon).

Phase 4: Implementing Claude Code and Runtime Dependencies

With the environment prepared, we need to install the necessary runtimes. Modern agentic plugins often rely on Bun, a fast JavaScript runtime, for high-performance execution of plugin logic.

  1. Install Bun and Unzip:
    curl -fsSL https://bun.sh/install | bash
    sudo apt update && sudo/apt install unzip -y
    
  2. Claude Code Installation: Install the Claude Code CLI (ensure you are targeting version 2.1.8 or higher for optimal plugin support). After installation, ensure the local bin directory is added to your $PATH.
  3. Context Injection via Git: Clone your agentic repository into the server:
    git clone https://[TOKEN]@github.com/username/agentic-os.git
    

Phase 5: The "Dispatch and Walk Away" Workflow (tmux + Telegram)

The final layer is the mobile interface. We want to dispatch tasks via Telegram and be able to disconnect without killing the process. This requires two components: tmux for session persistence and a Telegram Bot API integration.

1. Session Persistence with tmux

Standard SSH sessions terminate when the connection breaks. tmux (Terminal Multiplexer) creates a persistent window environment on the server.

# Start a new named session
tmux new -s agentic_os

Any command run inside this tmux session will continue to execute even if you close your laptop or lose cellular signal.

2. Telegram Bot Integration

Using the @claude-code-channels-plugin-telegram, we can bridge the Claude Code CLI with the Telegram Bot API.

  1. Bot Creation: Use @BotFather on Telegram to create a new bot and retrieve your API Token.
  2. Plugin Configuration: Install the plugin within the Claude Code environment:
    claude plugins install @claude-code-channels-plugin-telegram
    
  3. Authentication: Configure the bot token in the Claude session:
    claude telegram configure
    
  4. The Runtime Loop: To ensure the Telegram listener stays alive, run the command within a tmux window using the --channels flag:
    claude --channels @claude-code-channels-plugin-telegram
    

Conclusion: The Resulting Workflow

By implementing this stack, you have moved from a local CLI tool to a distributed agentic system. You can now send a complex coding instruction via Telegram while on your mobile device; the command is received by the VPS, processed within a persistent tmux session using Claude Code 2.1.8, and the results are pushed back to your chat—all without your primary workstation ever being powered on.