gregbuehler

mcp-slack

Community gregbuehler
Updated

user oriented slack mcp

mcp-slack

An MCP server for reading Slack through your own browser session, forworkspaces where installing a Slack app isn't an option. Ten tools: sixprimitives, three multi-call operations, one write that is off by default.

It authenticates as you, not as a bot. Everything you can see, it can read;anything it posts is indistinguishable from a message you typed. Browser-sessionauth is not an officially supported Slack integration path, so check yourworkspace's policies first.

The tools take explicit ranges and neutral defaults — no assumed reportingcadence, channel naming scheme, or truncation limit — so workflows can be builton top rather than baked in.

Install

Copy the d cookie from your browser (developer tools → Application → Cookies →https://app.slack.com) into ~/.slack-tokens.yml:

slack:
  - name: myworkspace.slack.com
    token: xoxd-your-cookie-value-here
    xoxc: null # auto-populated on first run

The short-lived xoxc API token is derived automatically and written back, solater runs skip that step. Both values are session credentials — chmod 600 thefile, and expect to recopy the cookie whenever your browser session ends.

Then install the server and register it:

uv tool install --editable .
{
  "mcpServers": {
    "slack": {
      "command": "/Users/you/.local/bin/mcp-slack",
      "args": [],
      "lifecycle": "lazy"
    }
  }
}

To skip installing, point at the repo-root shim instead — it carries a PEP 723header, so uv resolves dependencies on the fly:"command": "uv", "args": ["run", "/path/to/mcp-slack/server.py"].

Tools

Tool Purpose
slack_search Native Slack search syntax (from:@user, in:#channel, after:, has:link)
slack_channel_history Messages from one channel over a time window
slack_thread Every reply in a thread
slack_dm_history DM history with one person
slack_user Resolve a username or user ID to a profile
slack_list_channels Channel discovery by glob and member count (expensive)

Three tools stitch many calls into one result. They exist because theirdeduplication isn't reproducible from outside: a message found by search, bychannel history, and by thread expansion is the same message, and only theserver sees all three passes.

Tool Purpose
slack_user_activity Everything one person said or received in a range, with optional surrounding context and thread expansion, grouped by channel
slack_channels_history History for many channels at once, by list or glob, with replies nested under their parents
slack_profiles Batch profiles with custom fields resolved to labels

Time ranges accept YYYY-MM-DD, an epoch, or a relative offset like -7d.

slack_post_message posts as you, and refuses unlessSLACK_MCP_ALLOW_WRITE=1 is set in the server's environment:

"env": { "SLACK_MCP_ALLOW_WRITE": "1" }

Behavior worth knowing

  • A channel with no messages can't be resolved by name. Names resolve viasearch.messages, because conversations.list is throttled to the point ofuselessness on Enterprise Grid — measured at 11m48s of consecutive 429backoffs without reaching the target channel. Pass a channel ID (C…) forempty or archived channels, and prefer a channel name overslack_list_channels, which still enumerates and may return rate_limited.

  • Glob discovery only sees channels you've joined. It usesusers.conversations for the same throttling reason.

  • Failures come back as data, not exceptions: {"error": "not_found", ...}.Codes are not_found, rate_limited, auth_failed, and write_disabled.An expired cookie shows up as auth_failed.

  • Rate-limit waits are bounded. A cumulative sleep budget (45s, reset eachtool call) means a call returns rate_limited rather than hanging. Librarycallers who don't mind waiting can raise it: SlackClient(ws, wait_budget=600).

  • Messages are projected, not passed through. Raw Slack records run toseveral KB each; tools return ts, time, user, user_name, text, andpermalink, plus thread fields when meaningful. Mentions and links arerewritten to readable text, and permalinks are built locally, so citing amessage costs no extra call.

  • Lookups are cached, message content is not. One JSON file per workspace,with a timestamp per entry:

    Cached TTL
    DM channel ID never assigned once per pair of users
    user name → ID 30d only a handle change invalidates it
    user ID → name 7d display names change occasionally
    channel name → ID 7d renames are rare but real
    team profile schema 30d effectively static
    channel member counts 24h drifts slowly, only gates a filter
    failed lookups 1h stops a typo being re-searched in a loop

    A negative is only recorded after a search completes and matches nothing, soa rate limit or transport error is never cached as "does not exist".

Library use

The multi-call operations are plain functions in slack_mcp/aggregate.py(user_activity, channels_history, profiles) taking an explicitSlackClient. Import them directly rather than speaking MCP to a subprocess.

License

MIT

MCP Server · Populars

MCP Server · New

    Bevel-Software

    hexis

    Git-backed skills, tools & context for AI agents

    Community Bevel-Software
    jonashertner

    OpenCaseLaw

    Open Swiss legal corpus + MCP server: 1M+ court decisions (1875–today), 21k laws, 10M-edge citation graph, 42 MCP tools. CC0 data, MIT code. Live at mcp.opencaselaw.ch

    Community jonashertner
    SystemCraftsman

    Strimzi Kafka CLI

    Command Line Interface for the Strimzi Kafka Operator

    Community SystemCraftsman
    DROOdotFOO

    Raxol

    Write one app, render it to a terminal, a browser, or as agent tools. The terminal for your Gundam.

    Community DROOdotFOO
    morluto

    REA: Reverse Engineer Anything

    Reverse engineer anything with agents, from app behavior down to native binaries.

    Community morluto