AI / Automation

2026-05-28 Hermes Agent Telegram setup on a leased Mac mini M4 (HK / JP / KR / SG / US)

You can run Hermes Agent as a Telegram bot on the same Mac mini M4 host that already builds iOS apps over SSH. The gateway process (hermes gateway) holds your BotFather token, enforces an allowed-user allowlist, and forwards chat messages into Hermes's tool loop—so you can approve CI fixes or ask architecture questions from a phone without keeping a laptop awake.

Disclosure: MacXCode operates leased Apple Silicon cloud Macs in HK, JP, KR, SG, and the US. Hermes Agent is a third-party MIT project; Telegram and model API usage are governed by those providers. This guide is operational documentation, not an endorsement of any vendor subscription.

For serverless Modal/Daytona terminal backends and near-idle compute, see our Hermes serverless Modal/Daytona hibernate guide.

Hermes Agent Telegram gateway setup on Mac mini M4 leased cloud Mac

Why Telegram on a builder Mac

Telegram fits headless leases because the gateway uses outbound long polling by default: your Mac initiates HTTPS to Telegram's API, so you do not need to expose inbound ports on a shared builder (contrast with webhook mode on public HTTPS endpoints).

Typical reasons teams wire Hermes to Telegram on a lease host:

  • On-call triage when GitHub Actions or xcodebuild fails overnight—reply from mobile while the agent reads logs on NVMe.
  • Separation of concerns—keep OpenClaw for repo automation and Hermes for personal/ops chat, but only if you accept two gateway processes (RAM and token isolation).
  • Migration path from OpenClaw messaging—Hermes documents hermes claw migrate in upstream README; see our Hermes vs OpenClaw vs OpenHuman matrix before running both gateways on one 16 GB host.

Apple Mac mini specifications list 16–24 GB unified memory. Budget ~1–2 GB for hermes gateway plus your model provider's working set before stacking Xcode parallel testing.

How the Telegram gateway fits together

Hermes separates CLI chat (hermes TUI) from messaging (hermes gateway). For Telegram, configuration lands in ~/.hermes/.env (or wizard output), logs under ~/.hermes/logs/gateway.log, and optional launchd service on macOS.

ComponentPath / commandRole
Installcurl -fsSL …/install.sh | bashPython 3.11 + hermes CLI
Model/authhermes setupProvider API keys (BYO or Nous Portal)
Telegram confighermes gateway setupBot token + TELEGRAM_ALLOWED_USERS
Foreground testhermes gatewayLong-polling bot until Ctrl+C
Servicehermes gateway installhermes gateway startlaunchd on macOS, survives logout
Healthhermes doctor, hermes gateway statusConfig + process checks

Data flow (polling mode):

  1. You message the bot in Telegram.
  2. Gateway receives update via Telegram Bot API (outbound poll).
  3. Hermes agent loop runs tools on configured terminal backend (local, Docker, or SSH to same host).
  4. Reply text (and optional MEDIA:/path attachments) returns through the gateway to Telegram.

Security defaults that matter: upstream uses numeric user IDs in TELEGRAM_ALLOWED_USERS, not @usernames. Anyone with your bot token can impersonate the bot—treat tokens like API keys and revoke via BotFather /revoke on leak.

Official reference: Hermes Telegram docs (BotFather, privacy mode, webhooks).

BotFather and access control

Create the bot

  1. Open @BotFather/newbot.
  2. Set display name (e.g. Builder Hermes) and username ending in bot.
  3. Copy the token format 123456789:ABCdefGHIjklMNOpqrs… — store in a password manager, not git.

Allowlist your user ID

Message @userinfobot for your numeric ID (e.g. 123456789). Hermes rejects strangers when TELEGRAM_ALLOWED_USERS is set.

Optional hardening on shared leases:

  • Single-user allowlist only—no wildcard "team" IDs until you understand tool scope.
  • Separate bot per environment (staging vs production lease) so a leaked staging token cannot touch production workspaces.
  • Disable group access until DM behavior is verified.

Configure Hermes for Telegram

Interactive (recommended)

hermes setup # model provider first, if fresh install hermes gateway setup # pick Telegram → paste token → allowed user IDs

Manual ~/.hermes/.env

TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrSTUvwxYZ TELEGRAM_ALLOWED_USERS=123456789 # Optional team: TELEGRAM_ALLOWED_USERS=111111111,222222222

Verify files are mode 600 and excluded from dotfile sync you do not trust.

Foreground smoke test:

hermes gateway

Send hello in Telegram; expect a reply within seconds. Stop with Ctrl+C before installing launchd.

Eight-step headless rollout on Mac mini M4

  1. Install Hermes on the lease user account (not root): official install.sh from NousResearch/hermes-agent.
  2. Run hermes setup — configure model provider; confirm hermes doctor is clean.
  3. Create BotFather token and numeric user ID (sections above).
  4. Run hermes gateway setup — select Telegram; confirm ~/.hermes/.env contains token + allowlist.
  5. Foreground testhermes gateway, message bot, trigger a harmless tool (e.g. pwd via agent); Ctrl+C stop.
  6. Install servicehermes gateway install then hermes gateway start (macOS launchd).
  7. Persist env for daemons — ensure API keys in ~/.hermes/.env load for launchd (same user as install); compare with OpenClaw launchd PATH notes if tools fail only in background.
  8. Monitorhermes gateway status, tail -f ~/.hermes/logs/gateway.log, and Telegram /new to reset poisoned sessions after config changes.

Quotable operational rule: One gateway process can serve multiple platforms (Telegram, Discord, Slack, etc.)—you do not need separate daemons per chat app.

launchd and SSH-only leases

On macOS leases, hermes gateway install registers a user launchd job—analogous to OpenClaw's openclaw onboard --install-daemon pattern documented on this blog.

hermes gateway install hermes gateway start hermes gateway status tail -f ~/.hermes/logs/gateway.log

After SSH disconnect, the gateway should stay up under the same Unix user that ran install. If the job stops, check:

  • launchctl list | grep -i hermes
  • log file for TELEGRAM_BOT_TOKEN / auth errors
  • whether a lease policy kills long-running user agents at logout (rare on dedicated M4; common on shared shells)

Docker backend note: if terminal.backend: docker, files sent via MEDIA:/path must exist on the host path the gateway reads—not only inside the container. Mount host-visible volumes per upstream telegram.md.

Group chats (optional)

Telegram privacy mode defaults ON—bots in groups only see /commands, replies to the bot, or admin-visible traffic. For broader group context, disable privacy in BotFather (Bot Settings → Group Privacy → Turn off) and remove/re-add the bot to each group so Telegram refreshes state—or promote the bot to group admin.

For "observe but don't reply until @mention" behavior, upstream documents TELEGRAM_OBSERVE_UNMENTIONED_GROUP_MESSAGES and allowlisted chat IDs—use only after reading the telegram.md group section.

Troubleshooting

Symptom: bot never replies (polling silent)

CheckCommand / fix
Gateway running?hermes gateway status; restart hermes gateway start
Token valid?Re-paste from BotFather; /revoke old token if leaked
User not allowlisted?Add your numeric ID to TELEGRAM_ALLOWED_USERS, restart gateway
Model/auth failure?hermes doctor; test hermes CLI locally first
Logsgrep -i error ~/.hermes/logs/gateway.log | tail -20

Symptom: 401 Unauthorized or Conflict: terminated by other getUpdates

  • 401: wrong or revoked TELEGRAM_BOT_TOKEN.
  • Conflict: two processes polling the same bot—stop duplicate hermes gateway foreground sessions or a second host using the same token.

hermes gateway stop pkill -f "hermes gateway" 2>/dev/null || true hermes gateway start

Symptom: works in foreground, fails under launchd

  • launchd runs with a minimal environment—confirm ~/.hermes/.env is readable and provider keys are present.
  • Compare echo $PATH in SSH vs launchctl print gui/$(id -u) environment (macOS); align tool paths like Node if plugins shell out.

Symptom: group sees nothing except /commands

  • BotFather privacy mode still ON—disable or make bot admin; re-add bot to group.

FAQ

Does Hermes Telegram replace OpenClaw Telegram bindings?+
They are different gateways. You can migrate settings with hermes claw migrate, but running both bots on one host duplicates RAM and risks conflicting automation. Pick one messaging owner per lease.
Do I need a public URL for Telegram?+
No for default long polling. Webhook mode needs HTTPS ingress (Fly.io, Railway, etc.)—usually not required on SSH-only Mac mini leases.
Can I use Telegram on a 16 GB M4 with Xcode CI?+
Yes if you serialize heavy jobs. Measure memory_pressure during archive + gateway peak; pause gateway during large xcodebuild matrices if needed.
Is the bot token enough to secure the system?+
No. The token controls the bot identity. Tool execution still follows Hermes tool permissions and terminal backend scope—lock workspaces and avoid running gateway as root on multi-tenant hosts.
Where is official Telegram documentation?+

Headless M4 for Hermes Telegram gateway

SSH-first Apple Silicon in HK, JP, KR, SG, and US—enough unified memory for a 24/7 Telegram gateway beside Xcode lanes when you need always-on ops chat.