Build a 24/7 Claude Code Agent With Telegram Control
Why This Stack Exists Now
For most of 2025, if you wanted a Claude-powered agent you could DM from your phone while it worked on a server somewhere, you were either hacking together OpenClaw, writing your own Telegram bridge, or wiring up a Bun script that polled for messages. The pieces that existed were all fine. None of them were first-party.
That changed in two big jumps. Claude Code shipped Channels (research preview, v2.1.80+) with an official Telegram plugin, turning a two-way chat bridge into a supported one-line install. Then on April 14, 2026, Anthropic shipped Routines — saved Claude Code configurations that execute on Anthropic-managed cloud infrastructure, triggered by a schedule, an API call, or a GitHub event. Your VPS no longer has to be online for scheduled work to fire. A few months before that, Zapier quietly opened the Zapier SDK beta, which is the piece that lets your agent act on Slack, Gmail, Google Sheets, HubSpot, Linear, and 9,000+ other apps through a single install — no per-app OAuth flows to wrestle with.
Industry context: every one of those pieces is first-party, actively maintained, and either free or included with the subscription you already have. This tutorial stitches them into a single durable setup.
What you'll have when this is done:
A Claude Code session running 24/7 on a VPS, controllable from Telegram on your phone
Skills (reusable slash commands) you can create in one sentence
Persistent memory across sessions via
CLAUDE.mdScheduled
/looptasks and one-time natural-language remindersAccess to 9,000+ apps through the Zapier SDK
Cloud-hosted Routines that fire on schedule, webhook, or GitHub event — even with the VPS off
Automatic restart on reboot
Total setup time: roughly 60–90 minutes, most of which is waiting on the Linode provisioner and the Zapier login redirect. Ongoing cost: $20/month Claude Pro (or Max), $12–$36/month for the VPS, everything else free.
Prerequisites
Confirm each of these before you start. Missing any one of them turns a 10-minute step into an hour of debugging.
Subscription and Accounts:
Claude Pro ($20/mo) or Max plan. The free plan does not include Claude Code. API-key authentication will NOT work for Channels — channels require a
claude.ailogin.A Linode account (or any VPS provider — DigitalOcean, Hetzner, Vultr, AWS EC2 all work identically on Debian/Ubuntu).
A Telegram account on your phone.
A Zapier account with at least one or two apps already connected at
zapier.com/app/assets/connections.A local terminal (macOS/Linux native, Windows via PowerShell or WSL).
Plan context: Routines are available on Pro, Max, Team, and Enterprise plans with Claude Code on the web enabled. They count against your daily Claude Code session cap. Check usage at claude.ai/settings/usage.
Step 1: Provision the VPS on Linode
Log into cloud.linode.com and click Create → Linode. Pick the region closest to you — Dallas (us-central) is the low-latency choice from DFW. Image: Debian 12, because it's stable, lightweight, and every command in this tutorial has been tested on it.
Plan Sizing Guidance:
Dedicated 4GB (~$36/mo) — the comfortable choice once Bun, Node 22, Claude Code, and a Zapier SDK project are all in memory.
Shared Linode 2GB (~$12/mo) — fine for a personal agent. This is the realistic sweet spot.
Nanode 1GB (~$5/mo) — technically works, but the memory headroom is tight once all four runtimes are live.
Set a long random root password, store it in a password manager, and create a firewall that only allows inbound SSH (port 22) from your IP. Leave everything else blocked. Click Create Linode. It'll show RUNNING in 1–2 minutes. Copy the SSH access command from the dashboard — it'll look like ssh [email protected].
Step 2: SSH In and Harden the Box
Paste the SSH command into your local terminal, type yes to the host-key prompt, and paste your root password.
Inside the box, update and install the essentials:
bash
# Update the system
apt update && apt upgrade -y
# Install tooling we'll need
apt install -y curl wget git unzip tmux ca-certificates build-essential
# Create a non-root user (recommended for production; optional for a personal agent)
adduser agent
usermod -aG sudo agent
# To switch: su - agentFor simplicity the rest of this tutorial runs as root. A production deployment should use the non-root user.
Step 3: Install Claude Code (Native, No Node Required)
The native installer is now the recommended method. No Node.js dependency, automatic background updates, works on every platform:
bash
curl -fsSL https://claude.ai/install.sh | bashIf the claude binary isn't on your PATH after the install:
bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrcVerify the version:
bash
claude --version⚠️ Channels require v2.1.80 or later. If you see anything older, run claude install from inside a Claude Code session to update.
Step 4: Authenticate With Your Subscription
Start Claude Code for the first time:
bash
claudeIt asks how you want to authenticate. Choose Claude with subscription (NOT API key — channels won't work with API auth).
It prints a long login URL. Since you're on a headless VPS, you can't open a browser there. Copy the URL, paste it into your local browser, authorize with your Claude account, and it gives you an auth code. Paste the code into the VPS terminal. You'll see Login successful.
Exit with /quit or Ctrl+C twice.
Real setup note: "I spent twenty minutes thinking the SSH session had broken because I kept trying to paste the login URL back into the VPS. It wants you to open it locally." — Every first-time user, approximately.
Step 5: Keep Claude Alive With tmux
Claude Code only listens for Telegram messages while its session is running in the foreground. If you close SSH, the session dies. tmux keeps it alive on the server.
bash
tmux new -s agentYou're now inside a tmux session named agent. Processes started in here survive SSH disconnects.
Essential tmux shortcuts:
Action | Keys |
|---|---|
Detach, leave running |
|
Reattach later |
|
List sessions |
|
Kill session |
|
Don't start Claude Code yet. Bun has to be installed first.
Step 6: Install Bun
The Telegram, Discord, and iMessage channel plugins are Bun scripts. Without Bun, the plugin silently fails to connect and the hours of confusion begin.
bash
# unzip is needed by the Bun installer
apt install -y unzip
# Install Bun
curl -fsSL https://bun.sh/install | bash
# Make bun available right now
export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$PATH"
# And persist across sessions
echo 'export BUN_INSTALL="$HOME/.bun"' >> ~/.bashrc
echo 'export PATH="$BUN_INSTALL/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
# Verify
bun --versionYou should see a 1.2.x or newer version string.
Step 7: Create the Telegram Bot With BotFather
On your phone, open Telegram and search for @BotFather — the official account with the blue verification checkmark.
Send
/newbot.It asks for a display name — anything human-readable, e.g.,
Personal Agent.It asks for a username — must be globally unique and end in
bot. Example:parash_personal_agent_bot.BotFather replies with an HTTP API token that looks like:
7412345678:AAHfiqksKZ8eXAMPleeXamPLetokeNVALUECopy the entire string, including the number before the colon. Treat it like a password — anyone with this token can DM your bot. If it leaks, rotate immediately via BotFather with /revoke and /token.
Step 8: Install and Configure the Channels Plugin
Back in the VPS tmux session, start Claude Code:
bash
cd ~
claudeRun these commands inside Claude Code, one at a time:
/plugin install telegram@claude-plugins-officialIf it responds "plugin not found," the marketplace is missing. Add it and retry:
/plugin marketplace add anthropics/claude-plugins-official
/plugin install telegram@claude-plugins-officialReload plugins so /telegram:* commands appear:
/reload-pluginsConfigure the bot token (paste yours):
/telegram:configure 7412345678:AAHfiqksKZ8eXAMPleeXamPLetokeNVALUEThis writes the token to ~/.claude/channels/telegram/.env. Lock the permissions:
bash
chmod 600 ~/.claude/channels/telegram/.envExit Claude Code (/quit or Ctrl+C twice), then restart with the channels flag — this is the step that actually turns the Telegram bot on:
bash
claude --channels plugin:telegram@claude-plugins-officialOpen Telegram on your phone, find your bot (search its username), and send it any message, e.g. hi. It replies with a 6-character pairing code.
Paste the pairing code back into Claude Code on the VPS:
/telegram:access pair ABC123You'll see paired ✅. Send another message from Telegram and you'll see it land in the VPS terminal instantly, with Claude's reply arriving in Telegram.
⚠️ Feature flag note: Channels is rolling out gradually. If you updated to v2.1.80+ and nothing happens after pairing, your account may not yet have the server-side flag enabled. Try updating Claude Code and restarting. If it still doesn't work, you're waiting on rollout.
Step 9: Lock Down the Bot (Sender Allowlist)
By default, anyone who stumbles on your bot's username can DM it. Switch to allowlist mode — only paired senders reach the agent, everyone else gets silently dropped:
/telegram:access policy allowlistWhile you're tightening security, set the permission mode so Claude doesn't stall on every tool-use prompt. Telegram can't easily forward permission dialogs, so the agent will hang waiting for input that never arrives. Two choices:
/permissionsPick auto-accept edits — the middle ground. Or, if you trust the agent fully on this isolated box, launch with permissions bypassed:
bash
claude --channels plugin:telegram@claude-plugins-official --dangerously-skip-permissions⚠️ --dangerously-skip-permissions means Claude will execute any shell command it decides to. On a locked-down personal VPS with no sensitive data or credentials, that's usually fine. Never use it on a shared machine, a production system, or anywhere near a key you care about.
Step 10: Personality and Memory
Claude Code has two memory systems you get for free:
1. CLAUDE.md — Instructions you write. Loads automatically in every session.
2. Auto memory — Notes Claude writes to itself as you work, stored under ~/.claude/projects/<project>/memory/MEMORY.md.
Seeding behavior from Telegram is the easiest path. Just tell Claude what to remember:
Remember: I work in Central Time. When I ask about meetings or availability, use America/Chicago. Default to concise bullet replies — I'm usually on my phone.Claude writes that to its memory file on its own.
Creating a user-wide CLAUDE.md that applies across every project and session:
bash
mkdir -p ~/.claude
cat > ~/.claude/CLAUDE.md <<'EOF'
# Personal preferences
## Context about me
- Timezone: America/Chicago (Central)
- Location: DFW area — use this for location-dependent answers unless told otherwise
- Most tasks are research, writing, or ops rather than raw coding
## Response style
- Default to short, scannable replies suitable for a phone screen
- Use bullets over paragraphs when listing 3+ items
- When you complete a task, confirm in one line (what you did + where the result is)
- Ask one clarifying question at most before acting; don't bury me
## Work rules
- When drafting documents, start with a 2-sentence TL;DR
- When summarizing long threads, always end with "Next actions:"
- Never invent stats or sources — say "I don't know" or search the web
EOFTo inspect what's loaded in a live session: type /memory inside Claude Code.
Step 11: Build Your First Skill
Skills are folders under ~/.claude/skills/ (user-wide) or .claude/skills/ (project-scoped). Each folder contains a SKILL.md file with YAML frontmatter. Once created, the skill becomes a slash command (e.g., /hn) and can also trigger automatically when the description matches what you're asking.
Option A: Have Claude build the skill for you.
Tell Claude in Telegram:
Build me a skill called /hn that fetches the top 10 stories from Hacker News using the official Firebase API (no key needed) and returns them as a numbered list with title and link. Keep output compact enough to read on a phone.Claude creates the folder, writes SKILL.md, and the command is available immediately.
Option B: Create it manually.
bash
mkdir -p ~/.claude/skills/hn
cat > ~/.claude/skills/hn/SKILL.md <<'EOF'
---
name: hn
description: Fetch the current top stories from Hacker News and show them as a compact numbered list with titles, points, and links. Use when the user asks for HN top stories, Hacker News headlines, or "what's on HN right now".
---
# Hacker News top stories
When invoked:
1. Fetch the list of top story IDs:
`https://hacker-news.firebaseio.com/v0/topstories.json`
2. Take the first 10 IDs.
3. For each ID, fetch its metadata:
`https://hacker-news.firebaseio.com/v0/item/<ID>.json`
4. Format as a numbered list. Each line: title, points, HN discussion URL `https://news.ycombinator.com/item?id=<ID>`.
5. Keep each line under ~80 characters. Truncate long titles with "…" if needed.
EOFTest from Telegram:
/hnWhere skills live:
Location | Scope |
|---|---|
| You, across every project |
| This project only |
Other skills worth building — each one is a ~20-line SKILL.md:
/domain <name>— WHOIS and DNS lookups viadns.googleJSON API/crypto <symbol>— price lookup via CoinGecko's free endpoint/ip— current IP plus geolocation viaipapi.co/sprint-estimate <story>— structured estimation prompt against a user story/url-short <url>— create a shortened link via a connected Zapier tool
Step 12: Scheduled Tasks — /loop and Reminders
Recurring loops — runs a prompt on a cadence inside your session:
/loop 15m fetch my site status with `curl -sI https://example.com | head -n 1` and only message me if it is NOT a 200 OK responseSyntax:
/loop 30s ...— rounds up to 1 minute (cron granularity)/loop 5m ...— every 5 minutes/loop 1h ...— every hour/loop 1d ...— daily/loop every 2 hours ...— natural language parses cleanly
Useful patterns:
/loop 30m summarize any new messages in my Slack #product channel (via the Zapier connector) and DM me only if something needs attention/loop 1h check if any new GitHub issues on my repo mention "security" or "CVE" and alert meOne-time reminders — no /loop prefix, just plain English:
remind me in 20 minutes to stand up and stretchremind me at 2pm to join the sprint reviewManaging tasks:
what scheduled tasks do I have?
cancel the uptime check
cancel all loops⚠️ Real limits you will hit:
Recurring
/looptasks auto-expire after 7 days per the current docs. Community reports mention a 3-day window in earlier builds; behavior is still in flux during research preview. Either way, don't treat/loopas permanent infrastructure.Tasks only fire while Claude Code is running and idle. If tmux dies, they stop. If Claude is mid-response, the task fires once when idle — not once per missed interval.
Starting a fresh session clears session-scoped tasks. Use
claude --continueorclaude --resumeto restore.Max 50 scheduled tasks per session.
For anything that must survive restarts or VPS reboots, use cloud Routines (Step 14).
Step 13: Connect 9,000+ Apps With the Zapier SDK
This is the "hands" of your agent. Slack, Gmail, Google Sheets, HubSpot, Airtable, Jira, Notion, Linear — all through one install, no per-app API keys to juggle. The SDK is in open beta, free, and reuses your existing Zapier connections.
13a. Install Node 20+.
The Zapier SDK needs Node 20 or newer. Debian 12 ships with Node 18, so install Node 22 from NodeSource:
bash
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt install -y nodejs
node -v # should report v22.x
npm -v13b. Create a project directory:
bash
mkdir -p ~/zapier-agent
cd ~/zapier-agent
npm init -y13c. Run the official Zapier setup prompt inside Claude Code.
Reattach tmux and start Claude Code in the new directory with Telegram enabled:
bash
tmux attach -t agent
cd ~/zapier-agent
claude --channels plugin:telegram@claude-plugins-official --dangerously-skip-permissionsPaste the following prompt into Claude Code (or into Telegram — it'll forward in). This is the official setup prompt from docs.zapier.com/sdk — it walks through every install step and offers a live test:
Set up the Zapier SDK for me. Work through these steps one at a time, running each command and telling me what happened before moving on:
1. Check what folder I'm in and whether a package.json already exists.
- If there's a package.json, use this project as-is.
- If not, run: npm init -y
2. Check Node.js is version 20+: node -v
- If Node is missing, tell me to install it and stop.
- If older than 20, tell me to upgrade and stop.
3. Install the SDK: npm install @zapier/zapier-sdk
4. Install dev dependencies: npm install -D @zapier/zapier-sdk-cli @types/node typescript
5. Log in to Zapier: npx zapier-sdk login
- This opens a browser. On a headless VPS it prints a URL — I'll open it in my local browser.
6. List my connected apps: npx zapier-sdk list-connections --owner me --json 2>/dev/null | head -n 1000
- Show only the first 10 results as a markdown table with columns: ID, App Key, Expired.
- Tell me total connection count.
- If the list is empty, tell me to connect at least one app at https://zapier.com/app/assets/connections and come back.
Once all steps are done, tell me I'm ready.13d. Browser-login on a headless VPS.
npx zapier-sdk login tries to open a browser. On a headless box it prints a URL instead. Copy it, open in your local browser, authorize, and the VPS CLI picks up the credentials via callback.
If that hangs, generate a token at zapier.com/app/settings/api-keys and export it:
bash
export ZAPIER_SDK_TOKEN="your-token-here"
echo 'export ZAPIER_SDK_TOKEN="your-token-here"' >> ~/.bashrc13e. Example commands from Telegram:
Find any Gmail messages from the last 24 hours labeled "priority" and give me a 1-line summary of each, with sender and subject.Create a new Google Sheet titled "Sprint 12 — Story Backlog" in my Drive, add these columns to row 1: Title, Priority, Estimate, Owner, Notes.Claude writes and runs the Zapier SDK calls on the fly using your existing connections — no OAuth flows to configure, no per-app keys to store.
Step 14: Cloud-Hosted Routines (Run Even When VPS Is Off)
Routines run on Anthropic-managed infrastructure, not your VPS. They're the "cron jobs that still fire when your machine is asleep" piece. Unlike /loop, they survive restarts, reboots, and even your VPS losing power — because they aren't running on your box.
Routines went live on April 14, 2026 as a research preview. Available on Pro, Max, Team, and Enterprise plans.
Create a Routine From the Web
Go to
claude.ai/code/routinesClick New routine
Fill in:
Name:
Monday AM priority briefPrompt:
Pull my unread Gmail from the last 72 hours flagged important or from domains I've marked as priority. Also pull any Slack DMs I haven't responded to. Produce a one-page brief with: (1) top 5 items needing action, (2) rough time-to-resolve for each, (3) anything I can safely ignore. Post to my Slack #morning-brief.Model: Claude Opus 4.7
Trigger: Schedule → Weekly → Monday at 7:30 AM local time
Connectors: Gmail, Slack, plus anything else the prompt references
Click Create, then Run now once to smoke-test.
Create a Routine From the CLI
Inside Claude Code on your VPS (or via Telegram):
/schedule weekly Monday at 7:30am, pull priority Gmail + unread Slack DMs and post a brief to #morning-briefClaude walks you through connector selection and saves the routine to your cloud account. Note: the CLI creates schedule-only routines — to add API or GitHub triggers, edit the routine on the web.
Three Trigger Types (A Single Routine Can Combine All Three)
Trigger | What it does |
|---|---|
Schedule | Runs on a cron cadence — hourly, daily, weekly, or a specific future time |
API | POST to a per-routine URL with a bearer token — trigger from any webhook, CI, or monitoring tool |
GitHub | Fires on PR opened/merged, release published, and other repo events |
API Trigger — The Real Power
After adding an API trigger on the web, Anthropic gives you a URL and a bearer token. The token is shown exactly once — copy it before you close the modal. Fire it from anywhere:
bash
curl -X POST https://api.anthropic.com/v1/claude_code/routines/trig_01ABCDEFGHJKL/fire \
-H "Authorization: Bearer sk-ant-oat01-xxxxx" \
-H "anthropic-beta: experimental-cc-routine-2026-04-01" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{"text": "UptimeRobot alert: example.com returned 502 at 14:03 UTC"}'The text field passes run-specific context — an alert body, a deploy hash, a stack trace, whatever. Up to 65,536 characters. Not parsed, so JSON payloads arrive as a literal string.
Response includes a claude_code_session_id and claude_code_session_url where you can watch execution in real time.
⚠️ The anthropic-beta: experimental-cc-routine-2026-04-01 header is required — requests without it get a 400. Request shapes, rate limits, and token semantics may change during the preview.
More Routine Ideas Worth Building
Friday backlog grooming — scan every Jira/Linear ticket untouched for 14 days and summarize which to close, reassign, or escalate.
Daily SEO regression check — hit your key pages via a connector, alert on performance regressions.
Deploy watcher via API trigger — your CI fires the routine after every prod deploy; the routine pulls recent errors from Sentry and posts a go/no-go verdict in the release channel.
Docs drift detector — weekly schedule scans merged PRs and opens docs-repo PRs for changed APIs.
Step 15: Survive a VPS Reboot (Optional but Recommended)
tmux sessions don't survive a reboot. Two options to auto-restart.
Option A — Quick @reboot cron:
bash
crontab -eAdd this line (adjust paths as needed):
@reboot /usr/bin/tmux new-session -d -s agent 'cd /root && /root/.local/bin/claude --channels plugin:telegram@claude-plugins-official --dangerously-skip-permissions'On every reboot, a detached tmux session agent spins up with the Telegram bot active.
Option B — Proper systemd service (recommended):
bash
cat > /etc/systemd/system/claude-agent.service <<'EOF'
[Unit]
Description=Claude Code agent with Telegram channel
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/root
Environment="PATH=/root/.local/bin:/root/.bun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
ExecStart=/usr/bin/tmux new-session -d -s agent '/root/.local/bin/claude --channels plugin:telegram@claude-plugins-official --dangerously-skip-permissions'
ExecStop=/usr/bin/tmux kill-session -t agent
RemainAfterExit=yes
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable claude-agent
systemctl start claude-agent
systemctl status claude-agentReattach to see what Claude is doing at any point:
bash
tmux attach -t agentDetach with Ctrl+B then D.
Troubleshooting
❌ Telegram silent after restart. The bot only replies when Claude Code is running with --channels. Messages sent during downtime are dropped, not queued. If restarts happen often, use the systemd service above.
❌ claude: command not found after install.
bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc❌ Plugin not found.
/plugin marketplace update claude-plugins-officialThen retry /plugin install telegram@claude-plugins-official.
❌ Bun missing when the Telegram plugin launches.
bash
source ~/.bashrc
which bun # should print /root/.bun/bin/bunIf still empty, re-run the Bun installer.
❌ Zapier SDK login hangs on a headless server. npx zapier-sdk login prints a URL — open it in your local browser, not on the VPS. The CLI picks up the callback.
❌ Channels paired but no replies arrive. Likely the server-side feature flag (tengu_harbor) isn't enabled for your account yet. Update Claude Code, restart, and if it still doesn't work, wait. Rollout is gradual.
❌ /loop task vanished after a day. Session-scoped /loop tasks expire (currently 7 days per the docs; behavior has fluctuated during preview). For anything permanent, use Routines.
Security Reminders
--dangerously-skip-permissionslets Claude run any shell command. Keep the VPS isolated from anything sensitive.Keep Telegram locked to your user with
/telegram:access policy allowlist.Rotate the BotFather token immediately if it leaks: BotFather →
/revoke→/token.Treat Zapier SDK credentials like any API key. Use env vars, never commit them.
The Routines bearer token is shown once and cannot be retrieved. Store it in a secrets manager or password vault before closing the modal.
Cost Breakdown
Claude subscription: $20 (Pro) or $100+ (Max) per month, flat.
Linode VPS: $12–$36/month depending on plan.
Zapier SDK: free during open beta (confirmed as of late April 2026).
Telegram: free.
Routines: count against your Claude subscription's daily session cap. Usage at
claude.ai/settings/usage.
Realistic monthly total for a personal agent: $32–$56.
Quick Reference Cheat Sheet
Start the agent:
bash
tmux attach -t agent
# or from scratch:
tmux new -s agent
claude --channels plugin:telegram@claude-plugins-official --dangerously-skip-permissionsDetach without killing: Ctrl+B then D
Essential slash commands and Telegram prompts:
Command | What it does |
|---|---|
| View/edit loaded memory files |
| List installed plugins |
| Reload plugin definitions |
| Recurring task every 5 minutes |
| One-time reminder |
| List tasks |
| Cancel a task |
| Create a cloud Routine interactively |
| List routines |
| Change tool permission mode |
| Exit Claude Code |
Key file locations:
~/.claude/CLAUDE.md # user-wide instructions
~/.claude/skills/<name>/SKILL.md # user-wide skills
~/.claude/channels/telegram/.env # telegram token
~/.claude/projects/<proj>/memory/ # auto memory
~/zapier-agent/ # zapier SDK projectWhat You Have Now
✅ 24/7 Claude Code on a VPS — with auto-restart if the box reboots
✅ Telegram control — DM your agent from anywhere with a phone
✅ Skills ecosystem — grow it with one-sentence prompts
✅ Persistent memory — CLAUDE.md plus auto-written session memory
✅ Scheduled loops and reminders — session-scoped, fine for the short term
✅ 9,000+ apps via the Zapier SDK — one install, no per-app OAuth
✅ Cloud Routines — schedule, API, and GitHub triggers that run with the VPS off
✅ Security hardened — allowlist, rotated token, locked env file
DM your bot from your phone with "hey" to confirm it's alive. Then start asking it to actually do work — that's the whole point of having built this.