Hi, I'm Lena. I'll be honest — every time someone asks me "how do I plug my agent into Telegram?", my first reply is always the same question: is your CLI actually stable yet? This piece is written for builders who plan to run a real Hermes Agent gateway setup, not a generic bot tutorial. We'll focus on Telegram and Slack, with other platforms touched on where it matters.
What the Hermes gateway actually does
One agent across CLI and messaging platforms
Let's get the concept straight first. Hermes has two entry points: the terminal UI you launch with hermes, and the background process you launch with hermes gateway. The gateway is essentially a unified adapter layer — it connects to all your configured messaging platforms simultaneously and routes every message into the same AIAgent instance. In other words, the agent you talk to from Telegram and the one you talk to from Slack are the same agent, sharing the same session store, memory, skills, and cron schedule.
According to the official Hermes messaging gateway documentation, a single gateway process can run Telegram, Slack, Discord, WhatsApp, Signal, Email, Matrix, Mattermost and a dozen others at the same time. Each platform adapter receives messages, routes them through a per-chat session store, and hands them to the agent. This is why I always say: the gateway is a fan-out layer, not a separate brain.
Why gateway should not be your first setup step
Here's where most people trip. They get excited, install Hermes, and immediately try to wire up a Telegram bot — and then spend three hours debugging why messages "go in but nothing comes out." Look, I've been there. The gateway depends on three things being correct upstream: model config, tool config, and authorization config. If any of them is broken in CLI, the gateway will inherit that breakage and make it ten times harder to diagnose, because now you're staring at a Telegram chat instead of a verbose terminal log.
So my rule of thumb, and I say this every single time: CLI first, gateway second. Get a clean conversation working in hermes locally before you even open BotFather.
Prepare a stable base before platform setup
Verify local chat, tools, and model config first
Before touching any platform token, run through this checklist on the box that will host the gateway (ideally a small VPS — your laptop is the wrong place because the gateway needs to stay running 24/7):
hermes model— confirm your provider and model are reachable. If you're on a local model, make sure context length is at least 64K.hermes tools— enable only what you actually need. Every tool widens the blast radius later.hermes— open a real conversation. Ask it to run a shell command, do a web search, write a file. Watch the output. Anything weird here will be ten times weirder over Telegram.hermes doctor— let the built-in diagnostics catch path, permission, and dependency issues.
Only when all four are clean do I move on. The Hermes maintainers themselves emphasize this on the project's GitHub repository, where the documented flow goes setup wizard → CLI → gateway, in that order. Honestly, skipping this is the single most common reason people give up on Hermes.
Set up Telegram and Slack step by step
Tokens, permissions, pairing, and target routing
Now to the platforms. I'm going to walk these in parallel because the concepts are similar — you create an app, you get tokens, you set scopes/allowlists, you point Hermes at it — but the mechanics are quite different, and assuming they're the same is how people end up with silent gateways.
Telegram
Telegram is the faster of the two to bring up. The whole flow lives inside Telegram itself:
- Open a chat with
@BotFather. Per the official Telegram bots documentation, this is the only sanctioned way to register a bot and get a token. - Send
/newbot, pick a display name and a username ending inbot, and BotFather hands you a token shaped like123456789:ABCdef…. - Find your numeric user ID by messaging
@userinfobot. Don't confuse this with your@username— Hermes authorizes by numeric ID. - Drop both into
~/.hermes/.env:
TELEGRAM_BOT_TOKEN=123456789:ABCdef...
TELEGRAM_ALLOWED_USERS=123456789
- Run
hermes gateway start, then DM the bot. You should get a reply within seconds.
A detail that bites people: if you want to add teammates later, you have two options — extend TELEGRAM_ALLOWED_USERS with their numeric IDs, or use DM pairing, where unknown users get a one-time code that you approve with hermes pairing approve telegram XKGH5N7P. The pairing flow is documented in the Hermes Telegram setup guide and is honestly the better default for shared assistants — you don't have to chase down user IDs in advance.
Slack
Slack is more involved. Skip a step and the bot will be online but completely silent in channels.
- Go to
api.slack.com/appsand create a new app from scratch (not from a manifest, the first time — you'll learn faster). Classic Slack apps were fully deprecated in March 2025, so you must use the modern Bolt-based flow. - Under OAuth & Permissions → Bot Token Scopes, add at minimum:
app_mentions:read,chat:write,im:history,im:read,im:write,channels:history,groups:history,mpim:history. The two*:historyscopes are the most commonly missed — without them your bot will work in DMs but silently ignore everything in channels. - Under Socket Mode, toggle it on. This is the path Hermes uses, and it's the right choice for almost every self-hosted setup — your gateway doesn't need a public HTTP endpoint, it dials out over WebSocket. The mechanics and rationale are spelled out in the official Slack Socket Mode docs.
- Under Basic Information → App-Level Tokens, generate a token with
connections:write. This is thexapp-…token. The bot token from step 2 is thexoxb-…token. You need both. - Install the app to your workspace, then put both tokens plus a
SLACK_ALLOWED_USERSallowlist into~/.hermes/.env. /invite @YourBotinto the channel where you want it active. It will not see messages in channels it has not been invited to.
How to verify inbound and outbound messaging works
Don't just send "hi" and call it done. I run the same three-step verification on every platform:
- Inbound: send a plain message in a DM. The bot should reply.
- Outbound: ask the agent to run a multi-step task ("search the web for X and summarize"). Watch for streaming/typing indicators — if those don't appear, the adapter is connected but progress events aren't wired up.
- Targeted delivery: set
SLACK_HOME_CHANNEL(or run/sethomein Telegram) and trigger a cron job. If the cron fires in the wrong place, yourhomeconfig is wrong, not the schedule.
If all three pass on both platforms, you're genuinely done. If only the first passes, you have a partial setup that will fail in real use.
Platform-specific failure modes
This is where I spend most of my support time, so pay attention.
Auth failures, missing adapters, wrong scopes, silent delivery issues
Telegram failure modes are usually about the token or the allowlist. A revoked or mistyped token gives you a clean 401 — easy. A correct token with no TELEGRAM_ALLOWED_USERS set is sneakier: the gateway denies all users by default as a safety measure, so the bot looks dead but is actually doing exactly what it was told. If you're behind a firewall, set HTTPS_PROXY or the Telegram-specific proxy variable; the gateway falls back gracefully but you have to give it a path out.
Slack failure modes cluster around scopes. The pattern I see weekly: bot replies in DMs, ignores channels. That is almost always a missing channels:history or groups:history scope, plus the bot not being invited to the channel. Both have to be fixed; one alone is not enough. Other classic traps:
- Forgot the
xapp-app-level token → Socket Mode won't connect at all. - Added scopes after install but didn't reinstall the app → the new scopes aren't actually granted. Reinstall is mandatory.
- Used a classic app from before March 2025 → it just won't work. Recreate from scratch.
A cross-platform failure mode worth flagging: the gateway service itself dying. On macOS, hermes gateway install registers a launched plist. On Linux, you'll typically wrap it in a systemd unit. If the underlying service isn**'t supervised, your "24/7 assistant" is actually a 4-hour assistant** that dies the next time the box reboots.
Operational guardrails for shared assistants
Who can talk to the agent, approval boundaries, blast radius
Here's the part nobody wants to think about until it's too late. The moment you put an agent on Telegram or Slack, anyone with access to that chat surface can issue commands to a process running on your server. That deserves real respect.
A few rules I never break:
- Always set an explicit allowlist.
TELEGRAM_ALLOWED_USERSandSLACK_ALLOWED_USERSare not optional — without them, the safe default is denial, and you should leave it that way until you've made a deliberate choice.GATEWAY_ALLOW_ALL_USERS=trueis a foot-gun and I've never once had a legitimate use for it. - Run the agent in an isolated terminal backend. Hermes supports a Docker terminal backend that drops capabilities and disables privilege escalation. For any agent that's reachable from the outside world, this is the only setting I use. The CLI on my dev box can have raw shell; the gateway-backed agent should not.
- Treat tokens as production secrets. Bot tokens, app tokens, and allowlist files should live in
~/.hermes/.envwith mode600and nowhere else. The OWASP Secrets Management Cheat Sheet goes deep on rotation, centralized storage, and least-privilege access — if you're running this for a team, those practices stop being optional. - Keep approval prompts on destructive actions. When the agent wants to do something dangerous, it should ask in-chat and wait for
yes. Don't disable that to "make it smoother" — that prompt has saved me fromrm -rfmore than once. - Constrain the blast radius**.** Cron jobs deliver to
SLACK_HOME_CHANNELor the/sethomeTelegram channel. Don't point those at a public team channel "for visibility" — point them at a private channel only the operators are in, and forward summaries manually.
If you're running this for more than yourself, write the answers to these questions down before you go live: Who can talk to the agent? What can it do without asking? Where do its outputs land? Who rotates the tokens? If you can't answer all four in one sentence each, you're not ready to share it.
FAQ
Do I need both xoxb and xapp tokens for Slack?
Yes. The bot token (xoxb-…) is used for posting messages and Web API calls. The app-level token (xapp-…, with connections:write) is what opens the WebSocket for Socket Mode. Missing either and the connection fails differently — but token missing means no replies; app token missing means no inbound events at all.
Can one Hermes gateway serve multiple Slack workspaces?
Yes — Hermes maps each team_id to its own WebClient and bot user ID, so one gateway process can authenticate independently into each workspace. This is documented behavior, not a workaround.
My Telegram bot replies in DMs but ignores group messages. Why?
By default, Telegram bots have privacy mode enabled, which means they only see messages that explicitly mention them or reply to them. disable privacy mode in BotFather (/setprivacy → disable) if you want the bot to see all group messages. Alternatively, just @mention the bot.
Should I run the gateway on my laptop?
No, please don't. The whole point of Hermes is that it's not tied to your laptop — it should run on a $5 VPS or similar always-on machine. Otherwise, the bot dies every time you close the lid, and people stop trusting it.
Is gateway setup the same as setting up cron and profiles?
No, but they compound. Once the gateway is solid, cron jobs deliver naturally to your configured platforms, and personality profiles propagate across all surfaces. Get the gateway right and the rest of the agent ecosystem mostly just works. Get it wrong and every other feature inherits the breakage.
That's the honest version. Build the foundation in CLI, layer Telegram or Slack on top, lock down who can reach it, and don't skip the boring verification steps — they're the cheapest insurance you'll buy this quarter.




