Slack Code Mode MCP
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 MCPFind 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 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 ciCelld is a separate binary. Put it on PATH, or point the server at it with SLACK_CODE_CELLD_BIN.
celld --versionConfigure the Slack app
Create an internal app at https://api.slack.com/apps.
Open OAuth & Permissions and enable PKCE. This is one-way and makes the app a public client, so no client secret is distributed.
Add the redirect URL
http://localhost:33417/callback.Add the user token scopes the server expects:
npm run scopesA 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 authThis opens Slack, completes the PKCE exchange, and stores the token in the macOS Keychain or ~/.config/slack-codemode/token on Linux.
npm run doctorThe 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 |
| Find an allowed method by name, or fetch a TypeScript type. |
| Run JavaScript with |
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 bridgeThe 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 generategate 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 installCI runs the gate on Ubuntu and macOS (.github/workflows/ci.yml).
Docs
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.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | JavaScript body. Use `return` for the value you want back. | |
| timeout_ms | No | Execution limit in milliseconds (default 30000). |
TDQS
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.
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Exact TypeScript type name, e.g. "ChangeWithContent". | |
| limit | No | Maximum results (default 4). | |
| query | No | Method name fragment, e.g. "canvases", "postMessage". | |
| include_types | No | Include the argument interface (default true). | |
| include_blocked | No | Also search methods this server does not allow (default false). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose a real behavioral constraint: results are filtered to methods this server allows, and `include_blocked` relaxes it. It also describes the return payload (signature, JSDoc, argument interface). It does not mention rate limits, error conditions, or whether fetching a `type` returns anything different in shape.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, zero filler, front-loaded with the core purpose and returning format before the optional parameter hints. Every sentence adds information an agent can act on.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by naming the return payload, so an agent knows what a hit looks like. Scoping behavior and the main parameter escape hatches are covered. Minor gaps remain around result ordering/pagination and how a `type` lookup result differs from a method lookup.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, and the description nudges above it by giving purpose-level meaning to two params: `type` fetches a referenced (defined-elsewhere) type, and `include_blocked` widens the search to the full Slack API rather than this server's allowlist. It still does not clarify the interaction between a name-fragment `query` and an exact `type`, which the schema leaves ambiguous.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Find Slack Web API methods by name, description, or argument type,' and adds the scope constraint 'searches only the methods this server allows.' It also names what is returned (TS signature, JSDoc, argument interface). It does not explicitly contrast with the sibling `execute`, so an agent must infer search-vs-run on its own.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage guidance is limited to parameter selection ('Use `type` to fetch a referenced type, or `include_blocked` to search the full API') rather than when to call this tool instead of `execute`. The discovery-before-execution workflow is only implied by the tool name and description. No exclusions or prerequisites are stated.
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.
2 tool updates
v0.4.0- First observed
execute - First observed
search
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.
Scoped agent execution. Server-side credentials, policy, budgets and verifiable receipts.
- mcp-serverOAuthai.cdbx
Build Apps and run code in 30 languages — sandboxed, with persistent sessions for agent loops.
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.23 npm126Apache 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.14 npm7Apache 2.0

@roarkanalytics/sdk-mcpofficial
AlicenseNot gradedqualityAmaintenanceEnables 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 npmApache 2.0