web-slack-mcp
by sercant
README.md
# web-slack-mcp
An [MCP](https://modelcontextprotocol.io) server that reads Slack through
*your own logged-in web session*.
Built for the case where you're a **guest** in a workspace and can't install a
Slack app or mint API tokens — so instead of an app, it reuses the session of a
persistent Chromium profile that you log into once.
**Draft-only by design.** It reads channels, messages, and threads. There is no
send code path in this server — it never posts a message.
## How it works
- **Login** is manual and one-time: a visible Chromium window opens, you sign in
(SSO / magic link / whatever your workspace uses), and the session is saved to
a persistent profile so it survives restarts.
- **Credentials** — the workspace token from the web client's localStorage plus
the `d` session cookie — are extracted from that profile (headless when you're
already signed in), and the browser is closed straight away.
- **Every read** is a plain HTTP call to Slack's web API (`users.conversations`,
`conversations.history`, `conversations.replies`, `search.messages`, …)
authenticated with those credentials. No UI is driven.
- **Re-login** happens only when Slack rejects the session: the browser reopens,
fresh credentials are extracted, and the call is retried once.
- **Multiple agents** can use the server at once. Each MCP client runs its own
server process; they share the credentials cached in the profile directory,
and a file lock ensures only one of them opens the browser when a login is due.
- **Names** — including Slack Connect / external members that per-id lookups
won't return — are harvested in one `conversations.view` call per channel.
## Tools
| Tool | Description |
|------|-------------|
| `list_channels` | List channels, DMs, and group DMs you're a member of. |
| `read_messages` | Read recent messages in a channel/DM by name, partial name, or id (`channel`, `limit`). |
| `read_thread` | Read a thread by matching text in its parent message. |
| `search_messages` | Search messages workspace-wide with Slack search syntax. |
## Requirements
- Python **3.13+**
- [`uv`](https://docs.astral.sh/uv/) (provides `uvx`)
## Install & run
Run straight from GitHub with `uvx` — no clone needed:
```bash
uvx --from git+https://github.com/sercant/web-slack-mcp web-slack-mcp
```
On the first launch the server downloads the Chromium build Playwright drives
into Playwright's shared cache (`~/Library/Caches/ms-playwright` on macOS), so it
happens once and persists across runs.
### Register with Claude Code
```bash
claude mcp add web-slack -- \
uvx --from git+https://github.com/sercant/web-slack-mcp web-slack-mcp
```
Then reload Claude Code; the tools appear as `mcp__web-slack__*`. The first time
you call a read tool while signed out, the server opens a visible Chromium and
waits for you to sign in — no separate step. The session is saved and reused on
later runs, and by every other agent running the server.
### Other MCP clients
Any client that speaks stdio works — point it at the same command:
```json
{
"mcpServers": {
"web-slack": {
"command": "uvx",
"args": [
"--from", "git+https://github.com/sercant/web-slack-mcp",
"web-slack-mcp"
]
}
}
}
```
## Configuration
All optional, via environment variables:
| Variable | Default | Purpose |
|----------|---------|---------|
| `SLACK_URL` | `https://app.slack.com/client` | Slack web client URL. |
| `SLACK_PROFILE_DIR` | `~/.web-slack-mcp/profile` | Where the persistent browser profile and cached credentials live. Shared by every server process. |
| `SLACK_TEAM` | *(unset)* | Team id, name, or domain to use when the browser is signed into several workspaces. |
| `SLACK_HEADLESS` | `0` | `1` never opens a visible window and fails instead when sign-in is needed. |
| `SLACK_LOGIN_WAIT` | `180` | Seconds to wait for you to finish signing in before giving up. |
The profile directory holds your live Slack session and a `0600` credentials
file — treat it like a credential and keep it out of version control.
## Local development
```bash
git clone https://github.com/sercant/web-slack-mcp
cd web-slack-mcp
uv sync
uv run web-slack-mcp
uv run pytest
```
## License
MIT
TDQS
A4.3/5.0
Scored across 5 tools
Disambiguation5/5
Each tool has a clear, distinct purpose: authentication status, channel listing, login, message reading, and thread reading. No overlap in functionality.
Naming Consistency5/5
All tools follow a consistent verb_noun naming pattern (check_login, list_channels, read_messages, read_thread), with 'login' being a natural exception as a standalone verb.
Tool Count4/5
Five tools is a reasonable count for a focused Slack read-only client. It covers the essential operations without being excessive, though a send tool might be expected.
Completeness3/5
The tool set covers authentication, channel enumeration, and message reading, but lacks write operations like sending messages or creating channels, which limits completeness for general Slack use.
Maintenance
ActivityMaintained
ResponsivenessNo issues