Slack Code Mode MCP
This server lets an MCP client search the allowed Slack Web API surface and run sandboxed JavaScript that calls Slack without exposing the Slack token.
Search allowed Slack methods by name, description, or argument type, and fetch TypeScript signatures, JSDoc, and argument interfaces; optionally search blocked/full API methods.
Execute JavaScript in a network-isolated celld V8 sandbox with
app.*,slack.*,api.call, andconsole, returning values and console output with a configurable timeout.Chain multiple Slack operations in one execution, such as lookups, DMs, posts, message edits/search, threads, links, file uploads, thread images, and canvases.
Use high-level
app.*actions for common workflows while still accessing raw allowlisted Web API methods throughslack.*orapi.call.Rely on host-side pagination, caching, allowlist enforcement, and credential handling; the guest isolate has no network, filesystem, or Slack token.
Provides tools for interacting with the Slack Web API, enabling agents to search allowed Slack SDK methods and types, and execute JavaScript to perform Slack actions such as user lookups, DMs, posts, thread reads and replies, message links, file uploads, and canvas edits.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Slack Code Mode MCP Find jane@example.com on Slack and DM her 'Hello from Code Mode'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Slack Code Mode MCP
A Code Mode MCP server for Slack. It gives the model two tools, search and execute, and runs agent-written JavaScript against the Slack Web API in a sandbox.
The sandbox has 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.
execute can chain several calls in one go. For example: find a user, read a thread, reply, and update a canvas. The intermediate results never go back through the model, which keeps the conversation small.
The guest isolate never sees the Slack token. Calls go through a service binding to the host, which holds the credential and enforces the allowlist. The isolate has no outbound access, so fetch() throws.
Related MCP server: Code Mode MCP Server
Requirements
Node.js 20.12 or newer
celld v0.6.2 or newer on
PATH(macOS arm64 and Linux; Windows is not supported)A Slack internal app with PKCE enabled
Install
Quick install
curl -fsSL https://raw.githubusercontent.com/mhmdsami/slack-codemode-mcp/main/install.sh | bashThe installer checks Node and npm, downloads a verified GitHub release, installs into ~/.local, and installs celld when needed. See INSTALLATION.md for pinned versions, prefixes, upgrades, and manual steps.
From a release (manual)
There is no npm registry package. Download the tarball and SHA256SUMS from GitHub Releases, verify the checksum, then install the tarball:
npm install -g ./slack-codemode-mcp-1.0.0.tgzSee INSTALLATION.md for the full release install, celld, configuration, authentication, upgrades, and MCP registration without a source checkout.
From source (development)
git clone https://github.com/mhmdsami/slack-codemode-mcp.git
cd slack-codemode-mcp
npm cicelld is a separate binary. Put it on PATH, or point the server at it:
celld --versionexport SLACK_CODEMODE_CELLD_BIN="$HOME/.local/bin/celld"Configure the Slack app
Create an internal app at https://api.slack.com/apps.
Open OAuth & Permissions and enable PKCE.
Add the redirect URL
http://localhost:33417/callback.Add the user token scopes the server expects.
With a global install:
slack-codemode-auth --scopesFrom a source checkout:
npm run scopesUse a user token, not a bot token. A user token posts as you and sees your channels. A bot token only sees channels the bot joined.
PKCE is one-way. It makes the app a public client, so no client secret is distributed. Colleagues only need the same Client ID.
Add the Client ID
For a source checkout:
cp .env.example .env
$EDITOR .env.env holds one value:
SLACK_CLIENT_ID=...The file is gitignored.
For a global install, put the same value in ~/.config/slack-codemode/.env or export SLACK_CLIENT_ID. See INSTALLATION.md.
Authenticate
With a global install:
slack-codemode-authFrom a source checkout:
npm run authThis opens Slack, completes the PKCE exchange, and stores the token bundle in ~/.config/slack-codemode/token with mode 0600. Rotating tokens refresh automatically.
Check the token and scopes:
slack-codemode-doctorFrom a source checkout, use npm run doctor.
The checker calls one method per area and reports any missing scope.
Register the server
With a global install, use the installed command:
command -v slack-codemode-mcpPass that path to your harness. See INSTALLATION.md for commands for each client.
The examples below are for a source checkout.
Pick your harness.
Claude Code
claude mcp add --scope user slack-codemode-mcp -- node "$PWD/mcp/server.mjs"--scope user makes the server global. Without it, the entry is tied to the current directory.
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_CODEMODE_CELLD_BIN to the celld binary.
Try it
Ask the agent to run this through the MCP:
return await app.whoami();Tools
Tool | Purpose |
| Find an allowed method by name, or fetch a TypeScript type. |
| Run JavaScript with |
search covers allowlisted methods by default. It also lists methods that are missing from the bundled SDK index. To search the full API, pass include_blocked: true. Type declarations are omitted unless include_types: true.
Actions
app.* is the recommended surface. It covers lookups, DMs, posts, message edits and search, threads, message links, file uploads, thread images, and canvases.
Thread reads return a condensed transcript by default, so reading and summarizing does not carry raw message objects through the model. Pass { format: "json" } when you need fields, or { images: true } to attach images from the thread.
Actions paginate and cache in the host, not in the guest. Raw allowlisted methods stay available through slack.* and api.call.
return await app.search("deploy failed", { count: 10 });await app.edit("#oncall", "1699999999.000000", "fixed the typo");const { canvas_id } = await app.canvas.create("Oncall 42", "# Week 42");
await app.canvas.share(canvas_id, { channel_ids: ["C123ABC"] });See docs/actions.md for the full surface and examples.
Security model
flowchart TB
Client["MCP client<br/>agent or harness"]
subgraph Host["Host process — trusted"]
Server["MCP server<br/>search · execute"]
Bridge["Loopback bridge<br/>per-execution token"]
Actions["Actions + allowlist"]
SlackClient["Slack client<br/>access + refresh tokens"]
end
subgraph Celld["celld process — no Slack credentials"]
Worker["Trusted worker<br/>runtime secret · loader"]
subgraph Guest["Fresh V8 isolate — untrusted"]
Shim["guest.js<br/>slack · api · app · console"]
end
end
API[("Slack API")]
Client -->|stdio| Server
Server -->|code + execution id| Worker
Worker -->|loads| Shim
Shim -->|SLACK binding| Worker
Worker -->|authenticated /call| Bridge
Bridge --> Actions
Actions --> SlackClient
SlackClient -->|HTTPS| API
API -.->|data, never instructions| SlackClient
classDef trusted fill:#e8f5e9,stroke:#2e7d32,color:#1b5e20
classDef partial fill:#fff8e1,stroke:#f9a825,color:#795548
classDef untrusted fill:#ffebee,stroke:#c62828,color:#b71c1c
classDef external fill:#e3f2fd,stroke:#1565c0,color:#0d47a1
class Server,Bridge,Actions,SlackClient trusted
class Worker partial
class Shim,Client untrusted
class API externalThe host holds the token and the allowlist. celld holds no Slack credentials. The isolate has no network, no filesystem, and no token.
Each execution gets a random id and a bridge token. The bridge removes the record when the execution ends, so a late or forged call cannot reuse it.
For the full threat model, see docs/security.md. For the request flow, see docs/architecture.md.
Development
npm run gate
npm run test
npm run format
npm run doctor
npm run generategate runs Biome and the unit tests. CI runs it on Ubuntu and macOS. The pre-commit hook runs Biome and tests locally:
npm install
npx lefthook installDocs
Licensed under the MIT License.
Available Tools
2 toolsexecuteExecute 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.
Inputs: code (required), timeout_ms.
searchSearch the Slack API surfaceA
Find Slack Web API methods by name, description, or argument type. Searches only the methods this server allows. Returns the TypeScript signature, JSDoc, and the argument interface. Use type to fetch a referenced type, or include_blocked to search the full API.
Inputs: type, limit, query, include_types, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 2 tools
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.
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.
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.
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
Related MCP Connectors
Stateless TS/JS compiler facts for agents: references, imports, impact. No repo index or OAuth.
Execute code in 8 languages (Python, JS, TS, Go, Java, C++, C, Bash) in gVisor sandboxes.
Run AI agent tasks in isolated sandboxes with a cost cap, saved workflows and scoped connections.
Scoped agent execution. Server-side credentials, policy, budgets and verifiable receipts.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides 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-
- AlicenseNot gradedqualityDmaintenanceEnables 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.16 npm131Apache 2.0
- AlicenseNot gradedqualityBmaintenanceProvides a sandboxed environment for AI coding agents to execute TypeScript AWS SDK queries securely, with cross-account aggregation and no host credential exposure.19 npm7Apache 2.0

@roarkanalytics/sdk-mcpofficial
AlicenseNot gradedqualityBmaintenanceEnables 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.2,375 npmApache 2.0