Chat Gateways
Manage your agents from anywhere. Groove has native Telegram, Discord, and Slack gateways built into the daemon — push notifications for agent events and full command access from your phone.
Not MCP integrations
Gateways are first-class daemon components, not bolt-on MCP servers. They run inside the daemon process with direct access to the registry, process manager, and supervisor. Zero overhead, zero external processes.
Why Gateways?
The GUI is your command center for deep work. Gateways are your awareness layer — get notified when agents finish, crash, or need approval, and take quick actions without opening a browser.
- Agent completes at 2am? See it on your lock screen.
- Approval request while you're at lunch? Tap Approve right in the chat.
- Quick status check from your phone?
statusin Slack. - Build an entire project from a single message?
/plan build me a marketplace.
How It Works
Gateways are team-first. You talk to teams, not individual agents. When you send a message, Groove's team lead resolver finds the senior agent (QC, fullstack, or lead) and routes your message to them — like talking to a project manager who handles the rest.
For new projects, the /plan command spawns a planner agent that reads your codebase, designs a full team with scopes and models, and sends the plan back to your chat for approval. One tap to launch the whole team.
Setup
Telegram
- Open Telegram and message @BotFather
- Send
/newbotand name it GroovePilot (or whatever you prefer) - Choose a username ending in
bot— e.g.GroovePilot_bot - Copy the bot token BotFather gives you
- In Groove Settings > Gateways, click Set Token on the Telegram card
- Paste your bot token and save
- Open a chat with your new bot in Telegram and send
/status— the chat ID is captured automatically - Click Test in Settings to verify notifications work
Zero dependencies
The Telegram gateway uses raw fetch() against the Bot API with long-polling. No npm packages needed — it works out of the box.
Discord
- Go to the Discord Developer Portal
- Click New Application and name it GroovePilot
- Go to the Bot tab and click Reset Token — copy the bot token
- Go to OAuth2 > URL Generator:
- Under Scopes, check bot
- Under Bot Permissions, check:
| Permission | Purpose |
|---|---|
| Send Messages | Send notifications and command responses |
| Read Message History | Read commands from channels |
| Embed Links | Rich notification formatting |
| Use External Emojis | Status indicators |
- Copy the generated URL and open it in your browser
- Select your server and click Authorize
- Go back to the Bot tab, scroll to Privileged Gateway Intents
- Enable Message Content Intent — required for reading command text
- Click Save Changes
- In Groove Settings > Gateways, click Set Token on the Discord card
- Paste your bot token and save — send
/statusin a channel to capture it automatically
Optional dependency
Discord requires discord.js. Install it in the daemon package:
cd packages/daemon && npm i discord.jsSlack
Slack setup is the most involved because Socket Mode requires both a bot token and an app-level token. Follow every step carefully.
- Go to api.slack.com/apps and click Create New App > From scratch
- Name it GroovePilot and select your workspace
Enable Socket Mode
- In the left sidebar, go to Settings > Socket Mode
- Toggle Enable Socket Mode to on
- It will prompt you to create an App-Level Token — name it
groove, add theconnections:writescope - Click Generate — copy the
xapp-...token
Save this token immediately
You cannot view the App Token again after closing the dialog. If you lose it, you'll need to generate a new one.
Set Bot Token Scopes
- Go to Features > OAuth & Permissions
- Scroll to Bot Token Scopes and add all of these:
| Scope | Purpose |
|---|---|
chat:write | Send messages and notifications |
channels:read | List public channels for the channel picker |
channels:history | Receive messages in public channels |
groups:read | List private channels |
groups:history | Receive messages in private channels |
im:history | Receive direct messages to the bot |
app_mentions:read | Respond to @mentions in channels |
- Scroll up and click Install to Workspace, then click Allow
- Copy the Bot User OAuth Token (
xoxb-...)
Enable Event Subscriptions
- Go to Features > Event Subscriptions
- Toggle Enable Events to on
- Under Subscribe to bot events, add all three:
message.channels— messages in public channelsmessage.im— direct messages to the botapp_mention— @mentions of the bot
- Click Save Changes
Connect to Groove
- In Groove Settings > Gateways, click Set Token on the Slack card
- Paste the Bot Token (
xoxb-...) in the first field - Paste the App Token (
xapp-...) in the second field - Click Save — Groove will auto-connect
- Invite the bot to a channel:
/invite @GroovePilot - Select the channel from the dropdown, or @mention the bot to auto-capture
- Click Test to verify
Commands in Slack
Slack reserves the / prefix for its own slash commands, so Groove commands use plain text. Just type status, agents, help etc. You can also mention the bot: @GroovePilot status.
Reinstall after adding scopes
If you add scopes after the initial install, you must click Reinstall to Workspace. The bot token changes each time — update it in Groove Settings.
Only one connection at a time
If you see num_connections > 1 errors, another process has a socket open. Stop any other instances of Groove or Slack apps using the same token.
Commands
Gateways use a team-first interaction model. You address teams by name — Groove routes your message to the team lead.
Talk to Teams
| Telegram / Discord | Slack | Description |
|---|---|---|
/instruct <team> <msg> | instruct <team> <msg> | Send a message to the team lead |
/query <team> <question> | query <team> <question> | Ask about team status (journalist synthesis) |
/log <team> [lines] | log <team> [lines] | View recent team logs |
/plan <description> | plan <description> | Plan a new project → approve → build |
Intelligence
| Telegram / Discord | Slack | Description |
|---|---|---|
/brief | brief | Latest journalist project summary |
/tokens | tokens | Token usage, costs, and savings breakdown |
Fleet Management
| Telegram / Discord | Slack | Description |
|---|---|---|
/status | status | Daemon status + active agent summary |
/agents | agents | List all agents with status and metrics |
/teams | teams | List all teams |
/spawn <role> | spawn <role> | Manually spawn an agent |
/kill <name> | kill <name> | Kill an agent by name |
/rotate <name> | rotate <name> | Trigger context rotation |
/approve <id> | approve <id> | Approve a pending request or plan |
/reject <id> | reject <id> | Reject a pending request or plan |
/schedules | schedules | List scheduled agents |
/help | help | Show all commands |
Fuzzy matching
You don't need exact agent IDs. Commands accept team names, agent names, name prefixes, and roles. If there's ambiguity, Groove will ask you to clarify.
Plan → Approve → Build
The /plan command is the gateway to Groove's full orchestration power. Instead of spawning agents manually, describe what you want and let the planner figure out the team.
How it works
- You send:
/plan build me a marketplace with user accounts and payments - Planner spawns — reads your codebase, architecture, and project structure
- Plan delivered to chat — you see the recommended team: roles, scopes, models, prompts
- You approve or edit:
/approve <id>— launches the full team immediately/reject <id>— discards the plan/plan <edits>— spawns a new planner with your feedback
- Team launches — Phase 1 agents build in parallel with file scopes and knock protocol
- QC auto-spawns — when Phase 1 completes, a fullstack QC agent audits all changes, runs tests, and verifies the build
What the planner outputs
The planner creates a team spec with:
- Roles — frontend, backend, fullstack, etc.
- Scopes — file patterns each agent owns (prevents conflicts)
- Prompts — specific tasks for each agent
- Models — which AI model to use per agent
- Phases — Phase 1 runs in parallel, Phase 2 (QC) auto-spawns after
Team lead routing
When you /instruct an existing team, Groove finds the team lead using role priority:
- QC / quality agent
- Fullstack agent
- Lead / senior agent
- PM agent
- First running agent (fallback)
The lead receives your message and routes it internally — you never need to remember individual agent names.
Notifications
Gateways push notifications when important things happen. Choose a preset to control what you receive:
Presets
| Preset | Events |
|---|---|
| Critical (default) | Approval requests, scope conflicts, agent crashes |
| Lifecycle | Critical + all agent exits, rotations, scheduled spawns, QC activation |
| All | Everything except raw agent output and state sync |
Raw agent output (agent:output) and state updates (state) are never forwarded — they're too high-frequency. Use the journalist:cycle notification for periodic activity summaries.
Event Coalescing
When multiple events fire within 3 seconds, they're batched into a single message:
- "3 agents completed: frontend-1, backend-1, tests-1"
- "2 scope conflicts detected"
Approval requests are never batched — each gets its own message with action buttons.
Approval Buttons
When an approval request arrives, all three platforms show interactive buttons:
- Telegram — inline keyboard with Approve/Reject buttons below the message
- Discord — ActionRow with green Approve and red Reject buttons
- Slack — Block Kit action buttons with primary/danger styling
After tapping a button, the message updates to show the resolution. No need to type /approve <id> — just tap.
Permissions
User Allowlist
Each gateway has an allowedUsers list. If empty, anyone who can message the bot can send commands (fine for personal bots). Add user IDs to restrict access:
- Telegram — numeric user ID (get it from @userinfobot)
- Discord — user snowflake ID (enable Developer Mode, right-click user > Copy ID)
- Slack — member ID (click profile > three dots > Copy member ID)
Command Permissions
Each gateway can be set to Full Access or Read Only:
- Full Access — all commands including spawn, kill, instruct, plan
- Read Only — only status, agents, teams, query, log, brief, tokens, help
Set this in the Settings UI or via the API:
curl -X PATCH http://localhost:31415/api/gateways/tg-abc123 \
-H "Content-Type: application/json" \
-d '{"commandPermission": "read-only"}'Security
- No inbound ports — Telegram uses long-polling, Discord and Slack use outbound WebSocket connections. Your firewall stays unchanged.
- Encrypted tokens — Bot tokens stored in the CredentialStore with AES-256-GCM encryption, same as provider API keys.
- Audit trail — All gateway operations logged to the audit log (
gateway.create,gateway.connect,gateway.test, etc.). - Local daemon — Gateways call daemon methods directly in-process. No HTTP round-trips, no CORS, no authentication tokens.
Troubleshooting
Slack: Bot not responding to messages
- Check Event Subscriptions — go to Features > Event Subscriptions and verify all three events are listed:
message.channels,message.im,app_mention - Check Socket Mode — must be enabled under Settings > Socket Mode
- Reinstall the app — if you added scopes after install, click Reinstall to Workspace. Copy the new bot token into Groove.
- Check for duplicate connections — only one process can hold a socket connection. Stop other Groove instances.
- Private channels — the bot needs the
groups:readandgroups:historyscopes to see private channels
Slack: "invalid_auth" error
Your bot token has changed. This happens after reinstalling the app. Copy the new xoxb-... token from OAuth & Permissions and update it in Groove Settings.
Telegram: Bot not receiving messages
- Make sure you're sending messages directly to the bot (open a chat with it)
- In group chats, the bot only responds to
/commands— not plain text - Check that no other application is polling the same bot token (only one poller allowed)
Discord: Bot is online but ignoring commands
- Message Content Intent must be enabled in the Developer Portal > Bot > Privileged Gateway Intents
- Commands must start with
/in Discord - Make sure
discord.jsis installed:cd packages/daemon && npm i discord.js
General: Commands return "Unauthorized"
Your user ID is not in the gateway's allowlist. Either add your ID to the allowlist or clear the list to allow all users.
API
Gateways are fully manageable via the REST API. See the API Reference for all endpoints.
