@jtalk22/slack-mcp 1.0.4 ā 1.1.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.
- package/README.md +276 -193
- package/lib/handlers.js +182 -30
- package/lib/slack-client.js +168 -21
- package/lib/token-store.js +84 -10
- package/lib/tools.js +14 -2
- package/package.json +1 -1
- package/public/demo.html +715 -611
- package/public/index.html +128 -16
- package/scripts/verify-v106.js +159 -0
- package/scripts/verify-web.js +221 -0
- package/src/server.js +35 -2
- package/src/web-server.js +51 -9
package/src/web-server.js
CHANGED
|
@@ -5,16 +5,21 @@
|
|
|
5
5
|
* Exposes Slack MCP tools as REST endpoints for browser access.
|
|
6
6
|
* Run alongside or instead of the MCP server for web-based access.
|
|
7
7
|
*
|
|
8
|
-
* @version 1.
|
|
8
|
+
* @version 1.1.0
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import express from "express";
|
|
12
|
+
import { randomBytes } from "crypto";
|
|
12
13
|
import { fileURLToPath } from "url";
|
|
13
14
|
import { dirname, join } from "path";
|
|
15
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
16
|
+
import { execSync } from "child_process";
|
|
17
|
+
import { homedir } from "os";
|
|
14
18
|
import { loadTokens } from "../lib/token-store.js";
|
|
15
19
|
|
|
16
20
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
17
21
|
import {
|
|
22
|
+
handleTokenStatus,
|
|
18
23
|
handleHealthCheck,
|
|
19
24
|
handleRefreshTokens,
|
|
20
25
|
handleListConversations,
|
|
@@ -30,9 +35,33 @@ import {
|
|
|
30
35
|
const app = express();
|
|
31
36
|
const PORT = process.env.PORT || 3000;
|
|
32
37
|
|
|
33
|
-
//
|
|
34
|
-
const
|
|
35
|
-
|
|
38
|
+
// Secure API key management
|
|
39
|
+
const API_KEY_FILE = join(homedir(), ".slack-mcp-api-key");
|
|
40
|
+
|
|
41
|
+
function getOrCreateAPIKey() {
|
|
42
|
+
// Priority 1: Environment variable
|
|
43
|
+
if (process.env.SLACK_API_KEY) {
|
|
44
|
+
return process.env.SLACK_API_KEY;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Priority 2: Key file
|
|
48
|
+
if (existsSync(API_KEY_FILE)) {
|
|
49
|
+
try {
|
|
50
|
+
return readFileSync(API_KEY_FILE, "utf-8").trim();
|
|
51
|
+
} catch {}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Priority 3: Generate new secure key
|
|
55
|
+
const newKey = `smcp_${randomBytes(24).toString('base64url')}`;
|
|
56
|
+
try {
|
|
57
|
+
writeFileSync(API_KEY_FILE, newKey);
|
|
58
|
+
execSync(`chmod 600 "${API_KEY_FILE}"`);
|
|
59
|
+
} catch {}
|
|
60
|
+
|
|
61
|
+
return newKey;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const API_KEY = getOrCreateAPIKey();
|
|
36
65
|
|
|
37
66
|
// Middleware
|
|
38
67
|
app.use(express.json());
|
|
@@ -94,6 +123,16 @@ app.get("/", (req, res) => {
|
|
|
94
123
|
});
|
|
95
124
|
});
|
|
96
125
|
|
|
126
|
+
// Token status (detailed health + cache info)
|
|
127
|
+
app.get("/token-status", authenticate, async (req, res) => {
|
|
128
|
+
try {
|
|
129
|
+
const result = await handleTokenStatus();
|
|
130
|
+
res.json(extractContent(result));
|
|
131
|
+
} catch (e) {
|
|
132
|
+
res.status(500).json({ error: e.message });
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
97
136
|
// Health check
|
|
98
137
|
app.get("/health", authenticate, async (req, res) => {
|
|
99
138
|
try {
|
|
@@ -242,11 +281,14 @@ async function main() {
|
|
|
242
281
|
}
|
|
243
282
|
|
|
244
283
|
app.listen(PORT, () => {
|
|
245
|
-
|
|
246
|
-
console.
|
|
247
|
-
console.
|
|
248
|
-
console.
|
|
249
|
-
console.
|
|
284
|
+
// Print to stderr to keep logs clean (stdout reserved for JSON in some setups)
|
|
285
|
+
console.error(`\n${"ā".repeat(60)}`);
|
|
286
|
+
console.error(` Slack Web API Server v1.1.0`);
|
|
287
|
+
console.error(`${"ā".repeat(60)}`);
|
|
288
|
+
console.error(`\n Dashboard: http://localhost:${PORT}/?key=${API_KEY}`);
|
|
289
|
+
console.error(`\n API Key: ${API_KEY}`);
|
|
290
|
+
console.error(`\n curl -H "Authorization: Bearer ${API_KEY}" http://localhost:${PORT}/health`);
|
|
291
|
+
console.error(`\n${"ā".repeat(60)}\n`);
|
|
250
292
|
});
|
|
251
293
|
}
|
|
252
294
|
|