ask-slack-mcp-server 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export declare function getServerPort(): number;
2
+ export declare function getServerApiKey(): string;
package/dist/config.js ADDED
@@ -0,0 +1,11 @@
1
+ export function getServerPort() {
2
+ return parseInt(process.env.PORT ?? "3000", 10);
3
+ }
4
+ export function getServerApiKey() {
5
+ const key = process.env.ASK_SLACK_API_KEY;
6
+ if (!key) {
7
+ throw new Error("Missing ASK_SLACK_API_KEY environment variable");
8
+ }
9
+ return key;
10
+ }
11
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,aAAa;IAC3B,OAAO,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC1C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import "dotenv/config";
package/dist/server.js ADDED
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ import "dotenv/config";
3
+ import http from "node:http";
4
+ import { createRequire } from "module";
5
+ import { sendQuestionAndWait, startBoltApp, stopBoltApp } from "./slack.js";
6
+ import { getServerPort, getServerApiKey } from "./config.js";
7
+ const require = createRequire(import.meta.url);
8
+ const { version: VERSION } = require("../package.json");
9
+ const PORT = getServerPort();
10
+ const API_KEY = getServerApiKey();
11
+ function readBody(req) {
12
+ return new Promise((resolve, reject) => {
13
+ const chunks = [];
14
+ req.on("data", (chunk) => chunks.push(chunk));
15
+ req.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
16
+ req.on("error", reject);
17
+ });
18
+ }
19
+ function sendJson(res, status, body) {
20
+ res.writeHead(status, { "Content-Type": "application/json" });
21
+ res.end(JSON.stringify(body));
22
+ }
23
+ const httpServer = http.createServer(async (req, res) => {
24
+ // Health check
25
+ if (req.method === "GET" && req.url === "/health") {
26
+ sendJson(res, 200, { status: "ok", version: VERSION });
27
+ return;
28
+ }
29
+ // Main endpoint
30
+ if (req.method === "POST" && req.url === "/api/ask") {
31
+ // Validate API key
32
+ const providedKey = req.headers["x-api-key"] ??
33
+ req.headers["authorization"]?.replace(/^Bearer\s+/i, "");
34
+ if (!providedKey || providedKey !== API_KEY) {
35
+ sendJson(res, 401, { error: "Invalid or missing API key" });
36
+ return;
37
+ }
38
+ try {
39
+ const rawBody = await readBody(req);
40
+ const body = JSON.parse(rawBody);
41
+ if (!body.question || typeof body.question !== "string") {
42
+ sendJson(res, 400, { error: "Missing required field: question" });
43
+ return;
44
+ }
45
+ const fullMessage = body.context
46
+ ? `*Context:* ${body.context}\n\n*Question:* ${body.question}`
47
+ : `*Question:* ${body.question}`;
48
+ const answer = await sendQuestionAndWait(fullMessage, body.slack_user_id);
49
+ sendJson(res, 200, { answer });
50
+ }
51
+ catch (err) {
52
+ const message = err instanceof Error ? err.message : String(err);
53
+ console.error("[Server] Error handling /api/ask:", message);
54
+ sendJson(res, 500, { error: message });
55
+ }
56
+ return;
57
+ }
58
+ sendJson(res, 404, { error: "Not found" });
59
+ });
60
+ async function main() {
61
+ console.error(`[ask-slack-mcp-server] v${VERSION}`);
62
+ await startBoltApp();
63
+ httpServer.listen(PORT, () => {
64
+ console.error(`[Server] Listening on port ${PORT}`);
65
+ });
66
+ const shutdown = async () => {
67
+ console.error("[Server] Shutting down...");
68
+ httpServer.close();
69
+ await stopBoltApp();
70
+ process.exit(0);
71
+ };
72
+ process.on("SIGINT", () => shutdown());
73
+ process.on("SIGTERM", () => shutdown());
74
+ }
75
+ main();
76
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function startBoltApp(): Promise<void>;
2
+ export declare function stopBoltApp(): Promise<void>;
3
+ export declare function sendQuestionAndWait(question: string, slackUserId?: string): Promise<string>;
package/dist/slack.js ADDED
@@ -0,0 +1,84 @@
1
+ import { WebClient } from "@slack/web-api";
2
+ import { App } from "@slack/bolt";
3
+ const TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
4
+ const STARTUP_DELAY_MS = 6000; // Wait for stale Slack connections to expire
5
+ // Map: channelId -> resolver of pending Promise
6
+ const pendingQuestions = new Map();
7
+ const web = new WebClient(process.env.SLACK_BOT_TOKEN);
8
+ const boltApp = new App({
9
+ token: process.env.SLACK_BOT_TOKEN,
10
+ signingSecret: process.env.SLACK_SIGNING_SECRET ?? "",
11
+ socketMode: true,
12
+ appToken: process.env.SLACK_APP_TOKEN,
13
+ });
14
+ // Listener: when user replies in DM
15
+ boltApp.message(async ({ message }) => {
16
+ const msg = message;
17
+ console.error("[Bolt] Received message:", {
18
+ channel: msg.channel,
19
+ thread_ts: msg.thread_ts,
20
+ subtype: msg.subtype,
21
+ bot_id: msg.bot_id,
22
+ text: msg.text,
23
+ pendingKeys: [...pendingQuestions.keys()],
24
+ });
25
+ // Ignore bot messages (including own)
26
+ if (msg.bot_id || msg.subtype === "bot_message") {
27
+ console.error("[Bolt] Ignoring bot message, skipping.");
28
+ return;
29
+ }
30
+ // Ignore other subtypes (e.g. message_changed)
31
+ if (msg.subtype !== undefined) {
32
+ console.error("[Bolt] Ignoring message subtype:", msg.subtype);
33
+ return;
34
+ }
35
+ const resolver = pendingQuestions.get(msg.channel);
36
+ if (resolver && msg.text) {
37
+ console.error("[Bolt] Resolver found for channel:", msg.channel, "— resolving with answer.");
38
+ resolver(msg.text);
39
+ pendingQuestions.delete(msg.channel);
40
+ }
41
+ else {
42
+ console.error("[Bolt] No pending question for channel:", msg.channel);
43
+ }
44
+ });
45
+ export async function startBoltApp() {
46
+ // Wait for stale Slack connections to expire (prevents event splitting)
47
+ console.error(`[Bolt] Waiting ${STARTUP_DELAY_MS / 1000}s for stale connections to expire...`);
48
+ await new Promise((r) => setTimeout(r, STARTUP_DELAY_MS));
49
+ await boltApp.start();
50
+ console.error("[Bolt] Socket Mode app started successfully.");
51
+ }
52
+ export async function stopBoltApp() {
53
+ await boltApp.stop();
54
+ console.error("[Bolt] Socket Mode app stopped.");
55
+ }
56
+ export async function sendQuestionAndWait(question, slackUserId) {
57
+ const userId = slackUserId ?? process.env.SLACK_USER_ID;
58
+ if (!userId) {
59
+ throw new Error("Missing slack_user_id parameter and SLACK_USER_ID environment variable");
60
+ }
61
+ // Open DM channel with user
62
+ const dmResult = await web.conversations.open({ users: userId });
63
+ const channelId = dmResult.channel.id;
64
+ // Send message
65
+ await web.chat.postMessage({
66
+ channel: channelId,
67
+ text: question,
68
+ mrkdwn: true,
69
+ });
70
+ // Wait for response (Promise with timeout)
71
+ console.error(`[Slack] Waiting for reply in channel ${channelId} (timeout: ${TIMEOUT_MS / 1000}s)`);
72
+ return new Promise((resolve, reject) => {
73
+ const timer = setTimeout(() => {
74
+ console.error(`[Slack] TIMEOUT — no reply received for channel ${channelId}`);
75
+ pendingQuestions.delete(channelId);
76
+ reject(new Error("Timeout — user did not respond within 5 minutes"));
77
+ }, TIMEOUT_MS);
78
+ pendingQuestions.set(channelId, (answer) => {
79
+ clearTimeout(timer);
80
+ resolve(answer);
81
+ });
82
+ });
83
+ }
84
+ //# sourceMappingURL=slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.js","sourceRoot":"","sources":["../src/slack.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "ask-slack-mcp-server",
3
+ "version": "2.0.0",
4
+ "description": "HTTP API server for ask-slack-mcp — Slack bridge for human-in-the-loop",
5
+ "type": "module",
6
+ "main": "dist/server.js",
7
+ "bin": {
8
+ "ask-slack-mcp-server": "dist/server.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "prepare": "npm run build",
17
+ "start": "node dist/server.js",
18
+ "dev": "tsc --watch",
19
+ "docker:build": "docker build -t ask-slack-mcp-server .",
20
+ "docker:run": "docker run --env-file .env -p 3000:3000 ask-slack-mcp-server"
21
+ },
22
+ "keywords": [
23
+ "slack",
24
+ "human-in-the-loop",
25
+ "api-server",
26
+ "ai",
27
+ "agent"
28
+ ],
29
+ "author": "doctorspider42",
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/doctorspider42/ask-slack-mcp.git",
34
+ "directory": "server"
35
+ },
36
+ "homepage": "https://github.com/doctorspider42/ask-slack-mcp#readme",
37
+ "bugs": {
38
+ "url": "https://github.com/doctorspider42/ask-slack-mcp/issues"
39
+ },
40
+ "engines": {
41
+ "node": ">=18"
42
+ },
43
+ "dependencies": {
44
+ "@slack/bolt": "^4.4.0",
45
+ "@slack/web-api": "^7.8.0",
46
+ "dotenv": "^16.4.7"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^22.14.0",
50
+ "typescript": "^5.8.3"
51
+ }
52
+ }