What it gives Plexward
- Channel reads. The comms monitor sweeps named channels on a cron and folds what it finds into the entity's brain, so a Monday brief knows what was said in the operations channel on Friday.
- Drafted posts. Weekly updates and status posts are drafted in the entity's voice and staged for review. Nothing is posted without a human.
- Thread context. A session working on an issue can read the thread where it was discussed instead of asking you to paste it.
- Search across a workspace when you need to find where a decision was made.
Layer
Either, and pick deliberately:
brain(recommended when entities have separate workspaces): a local Slack MCP server process per brain, holding that workspace's bot token. Real isolation. Two entities cannot see each other's Slack.account: the claude.ai Slack connector, one workspace for your whole machine, visible from every brain. Fine for a single-workspace operator.
An entity can even run two brain-layer Slack servers when it has both an internal workspace and a client or partner workspace. Name them distinctly (acme-slack and acme-ops-slack) so the routing doc can tell them apart.
Declare it as:
{ "name": "acme-slack", "layer": "local MCP", "svc": "Channels · Threads", "account": "Acme workspace" }
Prerequisites
- Admin rights, or a friendly admin, in the Slack workspace: installing an app is not something a member can do.
- A Slack app with a bot token, scoped to what you actually need.
- The Slack MCP server binary, installed locally.
- A decision on write access before you install, not after.
Setup steps
1. Create the Slack app in the workspace. Give it a bot user. Request the read scopes you need (channels:history, channels:read, groups:history for private channels the bot is in, users:read) and, only if you want drafted posts to be postable, chat:write.
2. Install it and invite the bot to each channel it should see. Slack does not grant a bot history in a channel it was never invited to, and there is no error that says so: the channel simply returns nothing.
3. Store the token outside the repo.
cat > ~/.config/secrets/acme-slack.env <<'ENV'
SLACK_MCP_XOXB_TOKEN=xoxb-<token>
ENV
chmod 600 ~/.config/secrets/acme-slack.env
4. Write the server block into the brain's gitignored .mcp.json:
{
"mcpServers": {
"acme-slack": {
"command": "/absolute/path/to/slack-mcp-server",
"args": ["-t", "stdio"],
"env": {
"SLACK_MCP_XOXB_TOKEN": "${SLACK_MCP_XOXB_TOKEN}",
"SLACK_MCP_ADD_MESSAGE_TOOL": "false"
}
}
}
}
SLACK_MCP_ADD_MESSAGE_TOOL is the send switch. Leave it off unless the entity has a reason to post directly, and prefer routing outbound through the approval gate instead. A connector that can only read cannot embarrass you.
5. Declare it in catalog/declarations.json, one entry per server if the entity has two.
6. Record the channel names the entity cares about in the brain, so sweeps do not have to guess:
<!-- ~/brains/acme-brain/integrations/integration-patterns.md -->
## Slack
- Workspace: Acme
- Swept channels: #ops, #launch
- Post target for weekly updates: #ops (drafted, never auto-posted)
Per-entity routing
## Owned Integrations
| MCP Tool | Service | Account / Workspace | Notes |
|---|---|---|---|
| acme-slack | Channels, Threads | Acme workspace | Local server, read-only token. |
## NOT This Company
- Any other entity's Slack server.
- claude.ai Slack, if you also have the account-layer connector attached: it
reaches a different workspace.
If you are on the account layer with several workspaces in one Slack account, you have the same problem ClickUp and Notion have: isolation is a doctrine. Pin the channel ids the entity owns and require every call to name one.
Verify
cd ~/brains/acme-brain && claude mcp list | grep '^acme-slack'
bin/mc-connectors --company acme --dry-run | grep -i slack
Expected: ✔ Connected and an active row. Then read the last five messages in a channel you know has recent traffic. An empty result from a busy channel means the bot is not in it.
Common failures
- The bot is not in the channel. The most common failure, and it presents as an empty history rather than an error. Invite the bot explicitly, including in every private channel.
not_in_channelandmissing_scopelook alike from a distance. Both give you nothing. Check the app's granted scopes in the Slack admin before re-installing anything.- Token type confusion. A bot token (
xoxb-) and a user token (xoxp-) grant different things. The server expects a bot token; a user token may work for reads and then fail oddly elsewhere. - Re-installing the app rotates the token. Everything breaks at once and the probe correctly says
disconnected. Update the env file and restart the session. - Rate limits on a wide sweep. Reading a month of history across ten channels will hit them. Sweep a narrow window on a schedule instead of a wide one on demand.
- Two servers, one name. If an entity runs two Slack servers and both are called
slack, the probe cannot tell them apart and the routing doc is meaningless. Distinct names, always.
What Plexward does with it once connected
The comms monitor sweeps the declared channels on a cron and writes what it found into the entity's brain and into the comms feed the briefings read. The daily brief surfaces anything that looks like it needs you.
Weekly update skills read the week's channel traffic plus the entity's meeting notes and draft a post in your voice, staged for review. Where an entity has a regular internal sync, the same skill drafts both the written recap and the chat post from one source, so they cannot drift apart.
Outbound, when enabled, goes through the same human gate as everything else: drafted, shown to you, sent only on approval.