From d1e7c6311dad1b7e3181c3d8426f8ecfb3f14283 Mon Sep 17 00:00:00 2001 From: Ayush7614 Date: Fri, 24 Jul 2026 02:16:46 +0530 Subject: [PATCH] feat: add Slack built-in MCP preset Enable Slack via /mcp enable slack using the official @modelcontextprotocol/server-slack package (SLACK_BOT_TOKEN + SLACK_TEAM_ID). --- README.md | 2 +- src/mcp/presets.test.ts | 23 +++++++++++++++++++++++ src/mcp/presets.ts | 11 +++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 src/mcp/presets.test.ts diff --git a/README.md b/README.md index bf341ac..43eeaa5 100644 --- a/README.md +++ b/README.md @@ -282,7 +282,7 @@ Three-layer model — safe read-only tools run silently; everything else asks: Full MCP client, both transports: -- **stdio** — local servers, configured in `.klaatai/mcp.json`, built-in presets (filesystem, GitHub, Postgres, Puppeteer, Brave Search, Fetch, …) +- **stdio** — local servers, configured in `.klaatai/mcp.json`, built-in presets (filesystem, GitHub, Postgres, Puppeteer, Brave Search, SQLite, Slack, …) - **Streamable HTTP** — remote servers via `"url"` config or `/mcp add `; SSE and JSON responses, session management, and **OAuth 2.1** (discovery + dynamic client registration + PKCE browser flow) when the server requires auth — tokens cached in `~/.klaatai/mcp-oauth.json` Manage live with `/mcp`. diff --git a/src/mcp/presets.test.ts b/src/mcp/presets.test.ts new file mode 100644 index 0000000..40aae8a --- /dev/null +++ b/src/mcp/presets.test.ts @@ -0,0 +1,23 @@ +import { describe, expect, test } from "bun:test"; +import { MCP_PRESETS, getMCPPreset } from "./presets"; + +describe("MCP presets", () => { + test("slack preset is registered", () => { + const slack = getMCPPreset("slack"); + expect(slack).toBeDefined(); + expect(slack!.name).toBe("Slack"); + expect(slack!.envVars).toContain("SLACK_BOT_TOKEN"); + expect(slack!.envVars).toContain("SLACK_TEAM_ID"); + expect(slack!.config.command).toBe("npx"); + expect(slack!.config.args).toEqual(["-y", "@modelcontextprotocol/server-slack"]); + }); + + test("preset lookup is case-insensitive", () => { + expect(getMCPPreset("Slack")?.id).toBe("slack"); + }); + + test("ids are unique", () => { + const ids = MCP_PRESETS.map(p => p.id); + expect(new Set(ids).size).toBe(ids.length); + }); +}); diff --git a/src/mcp/presets.ts b/src/mcp/presets.ts index 07afc8e..bd908f4 100644 --- a/src/mcp/presets.ts +++ b/src/mcp/presets.ts @@ -100,6 +100,17 @@ export const MCP_PRESETS: MCPPreset[] = [ description: "SQLite access via MCP", }, }, + { + id: "slack", + name: "Slack", + description: "Read channels, post messages, and search Slack history", + envVars: ["SLACK_BOT_TOKEN", "SLACK_TEAM_ID"], + config: { + command: "npx", + args: ["-y", "@modelcontextprotocol/server-slack"], + description: "Slack API via MCP — requires SLACK_BOT_TOKEN and SLACK_TEAM_ID env vars", + }, + }, ]; /** Look up a preset by id (case-insensitive). */