Skip to main content
Glama
mhmdsami

Slack Code Mode MCP

by mhmdsami

Slack Code Mode MCP

A Code Mode MCP server for Slack. It exposes two tools, search and execute, and runs agent-written JavaScript against the Slack Web API in a celld V8 isolate with no network access and no Slack token.

Why Code Mode

search returns TypeScript signatures from the Slack SDK, so the agent calls methods with the right arguments instead of guessing them. One execution can chain several calls, such as resolving a user, reading a thread, posting a reply, and editing a canvas, without sending intermediate results back through the model.

The guest isolate never receives the Slack token. Calls go through a service binding to the host, which holds the credential and enforces the allowlist. The isolate has globalOutbound: null, so fetch() throws.

Related MCP server: Code Mode MCP Server

Requirements

  • Node.js 20+

  • celld v0.6.2 on PATH (macOS arm64 and Linux; Windows is not supported)

  • A Slack internal app with PKCE enabled

Install

git clone https://github.com/mhmdsami/slack-codemode-mcp.git
cd slack-codemode-mcp
npm ci

Celld is a separate binary. Put it on PATH, or point the server at it with SLACK_CODE_CELLD_BIN.

celld --version

Configure the Slack app

  1. Create an internal app at https://api.slack.com/apps.

  2. Open OAuth & Permissions and enable PKCE. This is one-way and makes the app a public client, so no client secret is distributed.

  3. Add the redirect URL http://localhost:33417/callback.

  4. Add the user token scopes the server expects:

npm run scopes

A user token attributes messages to you and keeps canvases on your account. A bot token would post as an app and only see channels the bot joined. Because the app is a public client, colleagues need only the same Client ID.

Add the Client ID

cp .env.example .env
$EDITOR .env

.env holds one value, SLACK_CLIENT_ID. It is gitignored.

Authenticate

npm run auth

This opens Slack, completes the PKCE exchange, and stores the token in the macOS Keychain or ~/.config/slack-codemode/token on Linux.

npm run doctor

The checker calls one method per area and reports any missing scope.

Register the server

Pick your harness.

Claude Code

Claude Code needs --scope user to make the server global. Without it, the entry is tied to the current directory.

claude mcp add --scope user slack-codemode-mcp -- node "$PWD/mcp/server.mjs"

Codex

codex mcp add slack-codemode-mcp -- node "$PWD/mcp/server.mjs"

OpenCode

opencode mcp add slack-codemode-mcp --global -- node "$PWD/mcp/server.mjs"

Amp

amp mcp add slack-codemode-mcp -- node "$PWD/mcp/server.mjs"

Pi

pi mcp add slack-codemode-mcp -- node "$PWD/mcp/server.mjs"

Antigravity

agy mcp add slack-codemode-mcp node "$PWD/mcp/server.mjs"

Zed

Add this to ~/.config/zed/settings.json:

"context_servers": {
  "slack-codemode-mcp": {
    "command": "node",
    "args": ["/absolute/path/to/slack-codemode-mcp/mcp/server.mjs"]
  }
}

If a harness starts with a narrow PATH, set SLACK_CODE_CELLD_BIN to the celld binary.

Try it

Ask the agent to run this through the MCP:

return await app.whoami();

Tools

Tool

Purpose

search

Find an allowed method by name, or fetch a TypeScript type.

execute

Run JavaScript with app.*, slack.*, api.call, and console.

search covers allowlisted methods by default. Pass include_blocked: true to search the full index.

Actions

app.* covers lookups, DMs, posts, threads, message links, file uploads, and canvases. Actions paginate and cache in the host, not in the guest. Raw allowlisted methods remain available through slack.* and api.call.

See docs/actions.md for the full surface and examples.

Security model

MCP client
  execute(code)
    └─ host: allowlist, token, Slack HTTP
         └─ celld: globalOutbound null
              └─ fresh isolate: slack/app/api, no token, no fs
                   └─ service binding → trusted worker
                        └─ authenticated loopback bridge

The host holds the token and the allowlist. The isolate has no network, no filesystem, and no credential. Each execution gets a random id and bridge token. See docs/security.md for the threat model and docs/architecture.md for the request flow.

Development

npm run gate
npm run test
npm run format
npm run doctor
npm run generate

gate runs Biome and the unit tests, and is what CI runs. Lefthook runs Biome and tests on commit and the full gate on push:

npm install
npx lefthook install

CI runs the gate on Ubuntu and macOS (.github/workflows/ci.yml).

Docs

Licensed under the MIT License.

Available Tools

2 tools
executeExecute Slack API codeB

Run JavaScript inside a network-isolated celld V8 isolate. Prefer app.* for lookups, DMs, posts, threads, links, files, and canvases; slack exposes the allowlisted Web API. Return a value to get it back; console output is included.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYesJavaScript body. Use `return` for the value you want back.
timeout_msNoExecution limit in milliseconds (default 30000).

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden. It discloses key traits: network isolation, an allowlisted Web API, return-value semantics, and console output inclusion. However, it omits authentication requirements, error handling, and rate limits, so it is substantial but not complete.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the core action, then usage guidance, then return behavior. No fluff, and each sentence serves a purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a code-execution tool with no output schema and no annotations, the description covers the environment and API surface well. Yet it leaves out auth requirements and error/rate-limit behavior, which are important for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds only a small note about returning a value and console output, which is already partly in the schema's `code` description; it adds little beyond structured fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: run JavaScript in a network-isolated V8 isolate for Slack API code. It names the accessible namespaces (`app.*` and `slack`), making the tool's scope clear. However, it does not explicitly differentiate from the sibling `search` tool, so a 4 rather than 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives internal guidance on which namespace to use for different actions, but never states when to choose this tool over the `search` sibling or when not to use it. No conditions, prerequisites, or alternatives are mentioned for tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.4.0
    • First observedexecute
    • First observedsearch

TDQS

A3.8/5.0

Scored across 2 tools

Disambiguation5/5

search and execute target completely different actions: one discovers Slack API methods, the other runs JavaScript. There is no plausible overlap, so an agent can always pick the right tool without hesitation.

Naming Consistency4/5

Both names are single lowercase verbs with a consistent, predictable style, so the set reads cleanly. It is not a strict verb_noun pattern (no noun component), which slightly limits the score.

Tool Count4/5

A code-mode server intentionally concentrates capability into a discover-and-execute pair, so 2 tools is defensible rather than a thin surface. It is on the low end though, since discovery (search) and execution (execute) are the only entry points.

Completeness4/5

The domain is programmatic Slack access, and the pair covers the full lifecycle: search to discover allowed Web API methods and referenced types, execute to call them. Minor gaps exist (no explicit auth/progress/error tooling), but the code-mode design lets users work around these by invoking the API directly.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides secure execution of arbitrary JavaScript code within a sandboxed QuickJS WASM environment, allowing language models or other MCP clients to safely run JavaScript code snippets without compromising the host system.
    5
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables LLMs to interact with MCP servers by writing TypeScript/JavaScript code instead of direct tool calls. Provides a code execution sandbox that accesses MCP servers through HTTP proxy endpoints.
    23 npm
    126
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides a sandboxed environment for AI coding agents to execute TypeScript AWS SDK queries securely, with cross-account aggregation and no host credential exposure.
    14 npm
    7
    Apache 2.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to interact with the Roark API by writing and executing TypeScript SDK code in an isolated sandbox, with built-in documentation search to guide those tasks.
    991 npm
    Apache 2.0