- Published on
Controlling Claude Code running on my Mac from Slack on my phone
Claude Code just added a research preview feature called Channels — a way to push external events into a running session. I built a Slack bridge on top of it. Now I can message Claude from my phone while it works on a project on my laptop.
Claude Code sessions are stateful. The agent has context, file access, a running tool environment but the session is tied to a terminal window which means you have to be sitting in front of it to interact with it.
A common occurence for me is to set Claude to work in Claude Code on my Mac and walk away from the computer and when I do that I lose touch with that open process. This solution offers a way to continue interacting with Claude in that session on my Mac via Slack on my phone.
The setup: Claude Code is running a session on my laptop. As long as that session is open and the computer is awake and connected to the network I can pick up my phone, send a message to the right Slack channel, and Claude will act on it and reply. No app switching, no VPN, no remote desktop. Just Slack.
From Slack on my phone, mid-afternoon:
Which projects are best to work on next? Like which issues?
Claude ran bd ready, checked priorities, and replied in the thread within a few seconds. I didn't open the terminal.
How it works
You could already do something like this with Open Claw — using a Slack bot that talks to Claude through MCP. But that requires standing up a separate service. Channels looks like it is Anthropic addressing a part of the Open Claw feature set in Claude Code itself: a research preview MCP capability that lets external processes push events directly into a running session. Claude picks them up between turns, it finishes whatever it's doing then reads the message. The asynchronous nature is the point.
The Slack side uses Socket Mode, which opens a persistent WebSocket to Slack rather than waiting for Slack to push to you. No public URL, no ngrok session to babysit. Your machine dials out on startup and keeps the connection alive. It's the same model the official Telegram and Discord plugins use, and it's the right call for a tool running on a dev laptop.
One server file. One Slack bot. Each project gets its own channel configured by env vars in .mcp.json. Claude Code spawns the server at startup and the whole thing is running.
The thing that actually matters
The initial version worked one way: messages arrived, Claude did the work, nothing went back to Slack. The reply tool was listed correctly, but Claude wasn't calling it.
The fix was in the instructions field — the string the MCP server passes to Claude Code, which goes directly into the system prompt. The original wording told Claude to call reply "when appropriate." The working version is more direct:
CRITICAL: The user cannot see the terminal at all. The ONLY way they receive your response is if you call the reply tool. You MUST call reply after every single Slack message — no exceptions.
This is worth internalizing for any MCP tool that expects reliable behavior: the instructions field is your system prompt. Write it like a constraint, not a suggestion. Claude will follow vague guidance vaguely.
One security decision worth naming
An ungated channel is a prompt injection vector. Anyone who can reach the Slack channel can put arbitrary text in front of Claude.
The server gates on Slack user ID, not channel ID. That distinction matters in group channels, where gating on membership would let anyone in the channel inject messages. User ID is the right unit.
Where this lands for me
For now I'm treating this as a playground. For real work where I need reliable file system access and a more complete feature set, I'm still on OpenClaw. But I can see where Channels is going, and if Anthropic keeps building in this direction, it could become the default way to stay connected to a running session. I'm watching it.