Claude Code talks to Slack over MCP, but out of the box you only get 1 workspace. Here’s how to run 2 or more at once.
The trick: every workspace beyond the first runs as its own token-based stdio MCP server. stdio servers don’t collide (more on why later), so they all load in every session.
Grab your Slack tokens
For each extra workspace, you need 2 values from a logged-in Slack web tab:
xoxc: fromlocalStorage, keylocalConfig_v2.xoxd: thedcookie. It’s httpOnly, so read it from a request’s Cookie header in devtools, notdocument.cookie.
Sanity-check them before wiring anything:
curl -s "https://<workspace>.slack.com/api/auth.test" \
-H "Cookie: d=<xoxd>" \
--data-urlencode "token=<xoxc>"
{"ok":true} means you’re good.
Wire up the stdio server
I use korotovsky’s slack-mcp-server. It auths with those browser tokens, no Slack app or admin approval needed.
Drop the tokens in a gitignored .env, and have the MCP command source it so secrets stay out of ~/.claude.json:
claude mcp add --scope user slack-global -- \
sh -c 'set -a; . /path/to/.env; set +a; exec npx -y slack-mcp-server@latest --transport stdio'
Repeat with a different name per workspace. 1 instance handles 1 workspace.
If you also run the official Slack plugin, disable it so the claude.ai connector stops clashing (next section), then restart once:
claude plugin disable slack@claude-plugins-official
Now every session loads all of them.
Why a fresh session only kept one
Here’s the trap, in case you’re staring at a workspace that vanished after a restart.
The claude.ai connector and the official plugin both use the same URL, https://mcp.slack.com/mcp. Claude Code de-duplicates MCP servers by URL at startup, so it hides one:
claude.ai Slack · ◯ hidden — same URL as your server 'plugin:slack:slack'
It’s not an auth problem, both are authed fine. It’s the shared URL. stdio servers have no URL to collide on, which is the whole reason the token route fixes it.
Gotchas that cost me time
xoxdmust stay URL-encoded. The%2B/%2Fin the cookie aren’t decorative. Decode it and you getinvalid_auth, and you’ll swear the token is wrong.- Session tokens rotate. When your browser session expires, re-grab them. An
xoxpapp token is the set-and-forget upgrade. - No file or image upload. It posts text only.
The surprise: it posts as you
This is the part that made me sit up.
It uses your user token, so when it posts, it posts as you. No APP badge, no “sent via” footer, nothing. Indistinguishable from you typing it yourself.
The official plugin posts through a registered app, so Slack tags it. This doesn’t. Powerful, and honestly a little unsettling.
So I keep my posting scoped to an allowlist. A misfire lands as me, silently, with no “oops, a bot did that” tell.
2 workspaces, both surviving restarts, one of them posting as me. Worth the afternoon.