How to Run Claude Code on a VPS: 24/7 Always-On AI Workflows
Running Claude Code on a VPS keeps your AI workflows alive when your laptop sleeps. Learn how to set up SSH, install Claude, and connect via Telegram.
Why Your Laptop Keeps Getting in the Way
If you’ve been running Claude Code locally, you’ve probably hit the same wall: close your laptop, kill the session. Step away from your desk, lose your context. Start a long-running task at midnight, wake up to nothing.
Running Claude Code on a VPS solves that. A virtual private server stays on around the clock, holds your sessions in place, and keeps your AI workflows running whether you’re asleep, offline, or working from a different device. This guide walks through the full setup — from spinning up a server to connecting remotely via Telegram.
This isn’t theoretical. Developers are already using always-on Claude Code setups for things like automated code reviews, background refactoring pipelines, documentation generators, and multi-step agents that work while they’re doing something else.
What You Actually Need Before Starting
Before touching a server, get a few things sorted.
On the Anthropic side:
- An active Anthropic account with API access
- Your Claude API key (from console.anthropic.com)
- Enough API credits for sustained use — long-running agents can burn through tokens fast
On the infrastructure side:
- A VPS from any major provider (DigitalOcean, Vultr, Linode, Hetzner, AWS EC2)
- A basic understanding of SSH and the Linux command line
- An SSH key pair (you probably already have one)
Recommended specs for a solo developer setup:
- 2 vCPUs, 2–4 GB RAM
- Ubuntu 22.04 LTS
- 40 GB SSD storage minimum
- A static IP address (most VPS plans include this)
Hetzner and Vultr are cost-effective options if you’re running this lean. A $6–12/month VPS is enough for most single-user Claude Code workflows.
Set Up Your VPS and Secure SSH Access
Provision the Server
Spin up a fresh Ubuntu 22.04 instance with your provider of choice. During setup, add your SSH public key directly — most providers let you do this at creation time. If not, you’ll need to log in with a password first and add the key manually.
Once the instance is running, connect:
ssh root@YOUR_SERVER_IP
Create a Non-Root User
Running everything as root is a bad habit. Create a regular user with sudo privileges:
adduser claude-user
usermod -aG sudo claude-user
Copy your SSH key to the new user:
rsync --archive --chown=claude-user:claude-user ~/.ssh /home/claude-user
Log out and reconnect as the new user to confirm it works before proceeding.
Harden SSH Access
Open the SSH config:
sudo nano /etc/ssh/sshd_config
Make these changes:
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
Restart SSH:
sudo systemctl restart sshd
This disables password logins entirely. Anyone trying to brute-force your server will hit a dead end.
Configure the Firewall
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status
Add additional ports later as needed (like 8080 if you’re running a web interface).
Install Node.js and Claude Code
Claude Code runs on Node.js. Install it via the NodeSource repository to get a recent stable version:
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
Verify the installation:
node --version
npm --version
Now install Claude Code globally:
npm install -g @anthropic-ai/claude-code
Confirm it’s available:
claude --version
Set Your API Key
Don’t hardcode your API key into scripts. Use an environment variable instead:
echo 'export ANTHROPIC_API_KEY="your-key-here"' >> ~/.bashrc
source ~/.bashrc
For a more secure approach, use a .env file in your project directory and load it with dotenv, or store sensitive values in a secrets manager. The key point: never commit your API key to a repository.
Keep Sessions Alive with tmux
This is where the “always-on” part actually happens. Without a persistent session manager, any work Claude Code does will stop the moment your SSH connection drops. tmux creates terminal sessions that keep running independently of your SSH connection.
Install tmux
sudo apt-get install tmux
Basic tmux Workflow
Start a named session:
tmux new-session -s claude-main
Inside that session, start Claude Code and kick off whatever you’re working on. When you need to disconnect, detach from the session without killing it:
Ctrl+B, then D
The session keeps running. SSH back in later and reattach:
tmux attach -t claude-main
Useful tmux Commands
| Command | What it does |
|---|---|
tmux new -s name | Start a named session |
tmux ls | List all sessions |
tmux attach -t name | Reattach to a session |
Ctrl+B, D | Detach (leave session running) |
Ctrl+B, C | Create a new window |
Ctrl+B, [0-9] | Switch windows |
tmux kill-session -t name | End a session |
You can run multiple Claude Code instances in separate tmux windows — one for a code review pipeline, one for a docs agent, one for interactive use. Each one is isolated and persistent.
Run Claude Code Autonomously
Headless Mode for Automated Tasks
Remy doesn't write the code. It manages the agents who do.
Remy runs the project. The specialists do the work. You work with the PM, not the implementers.
Claude Code supports a non-interactive mode that’s useful for scripted workflows. You can pass prompts directly from the command line:
claude --print "Review the code in /home/claude-user/project/src and summarize any issues"
This outputs the result to stdout, which you can pipe, log, or trigger from a cron job.
Schedule Tasks with Cron
For recurring jobs, cron is the simplest option. Edit your crontab:
crontab -e
Example — run a code audit every morning at 7am:
0 7 * * * /usr/local/bin/claude --print "Check /home/claude-user/project for any obvious bugs and log findings to /home/claude-user/logs/audit.txt" >> /home/claude-user/logs/cron.log 2>&1
Make sure the cron environment has access to your ANTHROPIC_API_KEY. The easiest way is to add it directly to the crontab file at the top:
ANTHROPIC_API_KEY=your-key-here
Long-Running Agent Loops
For more complex setups — like an agent that watches a directory for changes and automatically refactors code — you’ll want a small wrapper script in a tmux session:
#!/bin/bash
while true; do
if [ -f /home/claude-user/queue/pending.txt ]; then
claude --print "$(cat /home/claude-user/queue/pending.txt)" >> /home/claude-user/logs/output.log
rm /home/claude-user/queue/pending.txt
fi
sleep 30
done
This is a minimal polling loop. Drop a prompt into pending.txt, and the agent picks it up within 30 seconds.
Connect Remotely via Telegram
Having Claude Code running on a VPS is useful. Being able to send it tasks from your phone and get responses back is much better. Telegram bots make this surprisingly simple.
Create a Telegram Bot
- Open Telegram and search for
@BotFather - Send
/newbotand follow the prompts - Copy the bot token BotFather gives you
Build a Minimal Bridge Script
Install the node-telegram-bot-api package:
npm install node-telegram-bot-api
Create a file called bot.js:
const TelegramBot = require('node-telegram-bot-api');
const { exec } = require('child_process');
const token = process.env.TELEGRAM_BOT_TOKEN;
const allowedUserId = process.env.TELEGRAM_USER_ID; // your personal Telegram user ID
const bot = new TelegramBot(token, { polling: true });
bot.on('message', (msg) => {
if (msg.from.id.toString() !== allowedUserId) {
bot.sendMessage(msg.chat.id, 'Unauthorized.');
return;
}
const prompt = msg.text;
bot.sendMessage(msg.chat.id, `Running: ${prompt}`);
exec(`claude --print "${prompt.replace(/"/g, '\\"')}"`, { env: process.env }, (error, stdout, stderr) => {
if (error) {
bot.sendMessage(msg.chat.id, `Error: ${stderr}`);
return;
}
bot.sendMessage(msg.chat.id, stdout || 'Done.');
});
});
Add your credentials to .bashrc or a .env file:
export TELEGRAM_BOT_TOKEN="your-bot-token"
export TELEGRAM_USER_ID="your-numeric-telegram-id"
Run the bot inside a tmux session:
tmux new -s telegram-bot
node bot.js
Detach. Now send a message to your bot from Telegram, and Claude Code handles it.
This is a minimal implementation. For production use, add rate limiting, better error handling, and consider response chunking for long outputs (Telegram has a 4096-character message limit).
Alternative: VS Code Remote SSH
If you prefer a full IDE experience, VS Code’s Remote SSH extension lets you connect directly to your VPS and work as if you were running locally. Claude Code’s editor integrations work the same way — you’re just pointing at a remote filesystem.
Security Considerations
Running an AI agent with shell access on a remote server requires some thought about what it can and can’t do.
Other agents ship a demo. Remy ships an app.
Real backend. Real database. Real auth. Real plumbing. Remy has it all.
Scope what Claude can touch. Don’t run Claude Code as a user with broad system permissions. Create a dedicated user with access only to the directories it needs.
Audit the prompt inputs. If your Telegram bot or any other interface accepts external input, sanitize it. The basic bot script above only accepts messages from your own Telegram ID — keep that gate in place.
Rotate your API key periodically. If your VPS is ever compromised, a rotated key limits the damage. Set a reminder.
Log everything. Pipe Claude Code output to log files. If something goes wrong with an automated agent, logs are your only way to understand what happened.
Use environment variables, not config files with hardcoded secrets. This is standard practice, but worth repeating. Even a private repo can be a leak vector.
Monitor API usage. Check your Anthropic console regularly. Unexpected usage spikes might indicate a runaway loop or a compromised key.
Where MindStudio Fits Into This Setup
Running Claude Code on a VPS is powerful for developers comfortable with the command line. But if you want to give your always-on Claude workflows real capabilities — sending emails, searching the web, generating images, updating spreadsheets, calling external APIs — you’d normally have to build all of that yourself.
That’s where the MindStudio Agent Skills Plugin comes in. It’s an npm SDK (@mindstudio-ai/agent) that gives any AI agent — including Claude Code running on your VPS — access to over 120 typed capabilities as simple method calls.
Instead of writing custom integrations for Google Sheets, Slack, or image generation, you just call:
await agent.sendEmail({ to: '...', subject: '...', body: '...' });
await agent.searchGoogle({ query: '...' });
await agent.generateImage({ prompt: '...' });
await agent.runWorkflow({ workflowId: '...' });
The SDK handles rate limiting, retries, and auth. Your Claude Code agent focuses on reasoning and decision-making, not plumbing.
This is especially useful when your VPS agent needs to do something after it finishes a task — notify you via email, log results to a connected tool, or trigger another downstream workflow. One install, and those capabilities are available without building anything from scratch.
You can try MindStudio free at mindstudio.ai.
Troubleshooting Common Issues
Claude Code exits unexpectedly
Check if the process was killed due to memory limits. Run free -m to see available memory. If your VPS is under-provisioned, upgrade or add swap space:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
API key not found in cron jobs
Cron runs in a minimal environment and doesn’t inherit your shell variables. Add the key directly to the crontab file at the top (see the cron section above), or use a wrapper script that sources your environment before running Claude.
Telegram bot stops responding after a few hours
The polling connection can drop. Add a process manager like PM2 to automatically restart the bot:
npm install -g pm2
pm2 start bot.js --name telegram-bot
pm2 startup
pm2 save
Session history not persisting between tmux reattaches
tmux preserves the terminal session but not Claude Code’s internal conversation history by default. If you need persistent context across reconnections, use Claude Code’s --continue flag or manage conversation state in your wrapper script.
Frequently Asked Questions
Can Claude Code run unattended on a server?
Yes. Claude Code supports a --print flag that runs non-interactively, outputs the result, and exits. Combined with tmux for persistent sessions and cron for scheduling, you can run Claude Code entirely without human input. The key is structuring your prompts to be self-contained and specific enough that the agent doesn’t need to ask clarifying questions mid-task.
How much does it cost to run Claude Code on a VPS continuously?
VPS costs are separate from API costs. A basic VPS runs $6–12/month on providers like Hetzner or Vultr. API costs depend entirely on usage — Anthropic charges per token. A light scheduled workflow might cost a few dollars a month in API usage; a continuous high-frequency agent could be significantly more. Monitor your usage in the Anthropic console and set spending limits to avoid surprises.
What’s the difference between running Claude Code locally vs. on a VPS?
Local: tied to your machine’s uptime, your network connection, and your active session. Closes when you close the terminal or sleep your laptop.
VPS: always on, always connected, accessible from anywhere. Sessions persist indefinitely in tmux. Tasks can run on a schedule without you being present. The tradeoff is a small monthly cost and some initial setup time.
Is it safe to give Claude Code access to my codebase on a server?
With proper access controls, yes. The practical steps are: run Claude as a non-root user with scoped filesystem access, use read-only permissions where write access isn’t needed, and audit logs regularly. Claude Code itself doesn’t exfiltrate data — the risk is prompt injection or poorly scoped permissions letting the agent modify things it shouldn’t.
Can I use Claude Code on a VPS with GitHub or GitLab?
Yes. Set up SSH keys for your Git host on the VPS, clone your repo, and Claude Code can read, analyze, and even commit changes to your codebase. This is a common pattern for automated code review pipelines: new pull requests trigger a webhook, a script passes the diff to Claude Code, and the result gets posted as a comment.
What happens if my VPS reboots?
tmux sessions don’t survive reboots by default. You have two options: use tmux-resurrect to restore sessions after a reboot, or use a process manager like PM2 or systemd to automatically restart your agent scripts on boot. For production-grade setups, systemd service files are the most reliable approach.
Key Takeaways
- Running Claude Code on a VPS removes the dependency on your local machine — workflows run 24/7 regardless of what you’re doing.
- tmux is essential for persistent sessions. Install it, learn the basic commands, and use named sessions to organize multiple agents.
- Telegram provides a low-friction remote interface that works from any device without any additional infrastructure.
- Security defaults matter: disable root SSH login, use key authentication only, scope filesystem permissions, and treat your API key like a password.
- The MindStudio Agent Skills Plugin extends what your VPS-hosted Claude Code can do — adding email, search, image generation, and workflow triggers without custom integration work.
If you’re ready to build more capable AI workflows without managing all the infrastructure yourself, MindStudio is worth exploring — especially for connecting your agents to the tools and data sources they need to actually get work done.