You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Once amp run is in place, developers can kick off agents and monitor them via SSH + tmux. However, launching runs and sending follow-up instructions still requires opening a terminal. A Slack-based control plane would let any team member manage agent runs entirely from their phone without leaving Slack — and without each person needing to set up their own bot.
Solution
A two-component system:
Relay — a lightweight always-on process running on a shared Tailscale node (a Raspberry Pi, cheap VPS, or any machine that stays on). It holds the single Slack app connection via Socket Mode, receives all events, looks up the sender's Slack user ID in a config mapping, and dispatches commands to the correct developer's machine over SSH via Tailscale.
Local agent — a small process on each developer's machine that accepts dispatched commands from the relay (over SSH), shells out to amp run, and sends completion results back through the relay to Slack.
Slack ←→ relay (always-on Tailscale node)
↓ SSH over Tailscale
developer's machine → amp run → tmux session
One Slack app is installed once by a team admin. Each team member registers their Tailscale IP in a shared config. No per-user app setup, no per-user bot tokens.
As a developer, I want to start an agent run from Slack by sending a message like /amp run 0-auth-base prompt.md so that I can kick off work from my phone without opening a terminal.
As a developer, I want the bot to confirm the run was started (branch, tmux session name, log path) so that I know the command was received.
As a developer, I want to receive a Slack DM when a run completes or fails so that I don't need a separate notification app.
As a developer, I want the completion message to include the branch, status, and a summary of the last N lines of agent output so that I have enough context to decide whether to review.
As a developer, I want to send a follow-up prompt to a running agent by messaging the bot mid-run so that I can course-correct without SSHing in.
As a developer, I want follow-up prompts to be injected into the running tmux session via tmux send-keys so that the agent receives them without interruption.
As a developer, I want commands from multiple team members to be handled concurrently so that one long-running agent run does not block my teammates.
As a developer, I want to run amp slackbot start on the relay node to launch the relay in the background so that it survives terminal closes.
As a developer, I want to run amp slackbot stop to shut the relay down cleanly.
As a developer, I want amp slackbot status to show whether the relay is running, which users are registered, and when it last received a message.
As a team admin, I want to configure the Slack app credentials and the user_id → tailscale_ip mapping in a single YAML file on the relay node so that team setup is a one-time operation.
As a new team member, I want to add a single line to the relay config (my Slack user ID and Tailscale IP) so that I can start using the bot without any app setup of my own.
As a developer, I want the relay to reply with a clear error if my Tailscale IP is unreachable so that I know my machine is offline rather than wondering why nothing happened.
Connects to Slack via Socket Mode (one stable outbound WebSocket, no inbound port needed)
Receives all workspace events
Parses commands from DMs
Looks up event.user in the users mapping to find the target Tailscale IP
SSHes to that IP and runs amp run <args> (non-blocking — amp run spawns a detached tmux session and returns)
Replies to Slack immediately with confirmation, then sends a follow-up message when the run completes (delivered via the relay's bot token)
Each SSH dispatch spawns a goroutine, so simultaneous commands from multiple team members are handled concurrently.
Relay config (on the relay node, not committed)
slack:
bot_token: xoxb-...app_token: xapp-...users:
U012AB3CD: # Slack user IDtailscale_ip: 100.x.x.xssh_user: aliceU034EF5GH:
tailscale_ip: 100.x.x.xssh_user: bob
Credentials are read from this file or from env vars (AMP_SLACK_BOT_TOKEN, AMP_SLACK_APP_TOKEN).
SSH dispatch
The relay SSHes to <ssh_user>@<tailscale_ip> and runs amp run <args>. SSH keys must be pre-authorised between the relay node and each developer's machine (standard Tailscale + SSH setup). The relay does not need sudo or special permissions — it only needs to be able to invoke amp on the target machine.
Follow-up prompt injection
When a developer sends a follow-up message to the bot referencing an active run, the relay SSHes to their machine and runs tmux send-keys -t <session> "<prompt>" Enter. The active session name is retrieved from RunStore (written by amp run at start time, readable over SSH).
Concurrency
Each incoming Slack event is handled in its own goroutine. amp run on the target machine spawns a detached tmux session and returns immediately, so the SSH call is short-lived. There is no sequential queue.
Daemon management
amp slackbot start forks the relay process and writes a PID file to a configurable path (default: ~/.amp/slackbot.pid on the relay node). amp slackbot stop sends SIGTERM to that PID.
Out of Scope
Per-user Slack app credentials (one app for the whole team)
Web dashboard
Slack slash command registration (DM-based commands are sufficient and carry implicit user context)
Relay high-availability / clustering
Audit logging of commands
Further Notes
The relay node does not need to be powerful — it is stateless and handles only short-lived SSH dispatches. A Raspberry Pi on the home network or a $5 VPS is sufficient. The Tailscale network handles addressing and encryption, so no additional VPN or firewall configuration is needed beyond what the team already has.
Claude Code runs locally on each developer's machine under their own account. The relay only dispatches the command — it never handles credentials or model access.
Problem Statement
Once
amp runis in place, developers can kick off agents and monitor them via SSH + tmux. However, launching runs and sending follow-up instructions still requires opening a terminal. A Slack-based control plane would let any team member manage agent runs entirely from their phone without leaving Slack — and without each person needing to set up their own bot.Solution
A two-component system:
Relay — a lightweight always-on process running on a shared Tailscale node (a Raspberry Pi, cheap VPS, or any machine that stays on). It holds the single Slack app connection via Socket Mode, receives all events, looks up the sender's Slack user ID in a config mapping, and dispatches commands to the correct developer's machine over SSH via Tailscale.
Local agent — a small process on each developer's machine that accepts dispatched commands from the relay (over SSH), shells out to
amp run, and sends completion results back through the relay to Slack.One Slack app is installed once by a team admin. Each team member registers their Tailscale IP in a shared config. No per-user app setup, no per-user bot tokens.
Depends on: #1 (
amp run)User Stories
/amp run 0-auth-base prompt.mdso that I can kick off work from my phone without opening a terminal.tmux send-keysso that the agent receives them without interruption.amp slackbot starton the relay node to launch the relay in the background so that it survives terminal closes.amp slackbot stopto shut the relay down cleanly.amp slackbot statusto show whether the relay is running, which users are registered, and when it last received a message.user_id → tailscale_ipmapping in a single YAML file on the relay node so that team setup is a one-time operation.amp runhas access to my env vars.Implementation Decisions
Relay architecture
The relay is a single
amp slackbotprocess. It:event.userin theusersmapping to find the target Tailscale IPamp run <args>(non-blocking —amp runspawns a detached tmux session and returns)Each SSH dispatch spawns a goroutine, so simultaneous commands from multiple team members are handled concurrently.
Relay config (on the relay node, not committed)
Credentials are read from this file or from env vars (
AMP_SLACK_BOT_TOKEN,AMP_SLACK_APP_TOKEN).SSH dispatch
The relay SSHes to
<ssh_user>@<tailscale_ip>and runsamp run <args>. SSH keys must be pre-authorised between the relay node and each developer's machine (standard Tailscale + SSH setup). The relay does not need sudo or special permissions — it only needs to be able to invokeampon the target machine.Follow-up prompt injection
When a developer sends a follow-up message to the bot referencing an active run, the relay SSHes to their machine and runs
tmux send-keys -t <session> "<prompt>" Enter. The active session name is retrieved from RunStore (written byamp runat start time, readable over SSH).Concurrency
Each incoming Slack event is handled in its own goroutine.
amp runon the target machine spawns a detached tmux session and returns immediately, so the SSH call is short-lived. There is no sequential queue.Daemon management
amp slackbot startforks the relay process and writes a PID file to a configurable path (default:~/.amp/slackbot.pidon the relay node).amp slackbot stopsends SIGTERM to that PID.Out of Scope
Further Notes
The relay node does not need to be powerful — it is stateless and handles only short-lived SSH dispatches. A Raspberry Pi on the home network or a $5 VPS is sufficient. The Tailscale network handles addressing and encryption, so no additional VPN or firewall configuration is needed beyond what the team already has.
Claude Code runs locally on each developer's machine under their own account. The relay only dispatches the command — it never handles credentials or model access.