@jtalk22/slack-mcp 1.2.4 → 3.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.
Files changed (54) hide show
  1. package/README.md +113 -61
  2. package/docs/CLOUDFLARE-BROWSER-TOOLKIT.md +67 -0
  3. package/docs/DEPLOYMENT-MODES.md +10 -3
  4. package/docs/HN-LAUNCH.md +45 -36
  5. package/docs/INDEX.md +9 -0
  6. package/docs/INSTALL-PROOF.md +18 -0
  7. package/docs/LAUNCH-COPY-v3.0.0.md +73 -0
  8. package/docs/LAUNCH-MATRIX.md +22 -0
  9. package/docs/LAUNCH-OPS.md +71 -0
  10. package/docs/RELEASE-HEALTH.md +24 -0
  11. package/docs/TROUBLESHOOTING.md +27 -0
  12. package/docs/WEB-API.md +13 -4
  13. package/docs/images/demo-channel-messages.png +0 -0
  14. package/docs/images/demo-channels.png +0 -0
  15. package/docs/images/demo-claude-mobile-360x800.png +0 -0
  16. package/docs/images/demo-claude-mobile-390x844.png +0 -0
  17. package/docs/images/demo-main-mobile-360x800.png +0 -0
  18. package/docs/images/demo-main-mobile-390x844.png +0 -0
  19. package/docs/images/demo-main.png +0 -0
  20. package/docs/images/demo-poster.png +0 -0
  21. package/docs/images/demo-sidebar.png +0 -0
  22. package/docs/images/web-api-mobile-360x800.png +0 -0
  23. package/docs/images/web-api-mobile-390x844.png +0 -0
  24. package/lib/handlers.js +14 -6
  25. package/lib/slack-client.js +17 -1
  26. package/package.json +28 -12
  27. package/public/demo-claude.html +83 -10
  28. package/public/demo-video.html +33 -4
  29. package/public/demo.html +136 -2
  30. package/public/index.html +132 -69
  31. package/scripts/capture-screenshots.js +103 -53
  32. package/scripts/check-version-parity.js +176 -0
  33. package/scripts/cloudflare-browser-tool.js +237 -0
  34. package/scripts/collect-release-health.js +1 -1
  35. package/scripts/record-demo.js +22 -9
  36. package/scripts/release-preflight.js +243 -0
  37. package/scripts/setup-wizard.js +12 -2
  38. package/scripts/verify-install-flow.js +38 -2
  39. package/scripts/verify-web.js +49 -1
  40. package/server.json +47 -0
  41. package/smithery.yaml +34 -0
  42. package/src/server-http.js +123 -8
  43. package/src/server.js +36 -8
  44. package/src/web-server.js +60 -20
  45. package/docs/images/demo-claude-v1.2.gif +0 -0
  46. package/docs/images/demo-readme.gif +0 -0
  47. package/docs/release-health/2026-02-25.md +0 -33
  48. package/docs/release-health/2026-02-26.md +0 -33
  49. package/docs/release-health/24h-delta.md +0 -21
  50. package/docs/release-health/24h-end.md +0 -33
  51. package/docs/release-health/24h-start.md +0 -33
  52. package/docs/release-health/latest.md +0 -33
  53. package/docs/videos/.gitkeep +0 -0
  54. package/docs/videos/demo-claude-v1.2.webm +0 -0
@@ -0,0 +1,71 @@
1
+ # Launch Ops Runbook (v3.0.0)
2
+
3
+ This runbook defines launch-day monitoring and distribution for technical/operator channels (no X/Reddit dependency).
4
+
5
+ ## Same-Day Fanout Order (9 Channels)
6
+
7
+ 1. GitHub release page refresh (`v3.0.0` copy + install-proof block)
8
+ 2. npm parity confirm (`@jtalk22/slack-mcp@3.0.0`)
9
+ 3. MCP registry parity confirm (`3.0.0`)
10
+ 4. Smithery listing metadata/parity update (or timestamped propagation note)
11
+ 5. `awesome-mcp-servers` listing PR refresh
12
+ 6. Glama metadata sync and canonical link verification
13
+ 7. HN thread update comment (high-signal install proof + support path)
14
+ 8. GitHub Discussions announcement/support threads update
15
+ 9. GitHub Pages/docs surface publish + link verification
16
+
17
+ ## Monitoring Cadence
18
+
19
+ - First 4 hours: every 30 minutes
20
+ - Up to 24 hours: every 60 minutes
21
+
22
+ Track:
23
+ - install reports and blocker count
24
+ - npm/MCP parity state
25
+ - listing propagation status (Smithery/Glama)
26
+ - inbound issue and discussion severity
27
+ - hosted migration questions (`SLACK_MCP_HTTP_AUTH_TOKEN`, CORS allowlist)
28
+
29
+ ## Triage Rules
30
+
31
+ P1 install blocker:
32
+ - acknowledge within 30-60 minutes
33
+ - provide immediate workaround
34
+ - add fix to patch queue
35
+
36
+ Non-blocking request:
37
+ - acknowledge and route to issue/discussion template
38
+ - provide timeline as best effort
39
+
40
+ ## Escalation Triggers
41
+
42
+ 1. If install failures exceed 3 unique reports in 24h:
43
+ - pause outbound promotion
44
+ - prioritize hotfix
45
+
46
+ 2. If support load exceeds 2 hours/day for 2 days:
47
+ - switch to stability-only mode
48
+ - defer non-critical requests
49
+
50
+ ## 24h / 48h / 72h Follow-Up
51
+
52
+ 24h:
53
+ - publish release-health delta and short technical summary
54
+
55
+ 48h:
56
+ - patch docs for top recurring setup questions
57
+
58
+ 72h:
59
+ - ship `v3.0.1` only if launch defects are confirmed
60
+
61
+ ## Evidence Log
62
+
63
+ Use:
64
+ - `docs/release-health/launch-log-template.md`
65
+
66
+ Capture:
67
+ - channel
68
+ - UTC timestamp
69
+ - URL or command evidence
70
+ - action taken
71
+ - observed result (`success|partial|blocked`)
@@ -13,6 +13,30 @@ Outputs:
13
13
  - `docs/release-health/YYYY-MM-DD.md`
14
14
  - `docs/release-health/automation-delta.md` (when delta script is run)
15
15
 
16
+ ## Version parity report
17
+
18
+ ```bash
19
+ npm run verify:version-parity
20
+ ```
21
+
22
+ Output:
23
+ - `docs/release-health/version-parity.md`
24
+
25
+ If external registries are still propagating immediately after publish:
26
+
27
+ ```bash
28
+ npm run verify:version-parity -- --allow-propagation
29
+ ```
30
+
31
+ ## Prepublish dry run
32
+
33
+ ```bash
34
+ npm run verify:release-dry-run
35
+ ```
36
+
37
+ Output:
38
+ - `docs/release-health/prepublish-dry-run.md`
39
+
16
40
  24-hour loop artifacts:
17
41
  - `docs/release-health/24h-start.md`
18
42
  - `docs/release-health/24h-end.md`
@@ -161,6 +161,33 @@ cat /tmp/slack-web-api.log
161
161
  cat /tmp/slack-web-api.error.log
162
162
  ```
163
163
 
164
+ ### Hosted HTTP `/mcp` Returns 503 or 401
165
+
166
+ If you run `node src/server-http.js`, `/mcp` is protected by default.
167
+
168
+ `503 http_auth_token_missing` means you did not set:
169
+
170
+ ```bash
171
+ SLACK_MCP_HTTP_AUTH_TOKEN=change-this
172
+ ```
173
+
174
+ `401 unauthorized` means your request is missing or using the wrong bearer token.
175
+
176
+ Example request:
177
+
178
+ ```bash
179
+ curl http://localhost:3000/mcp \
180
+ -H "Authorization: Bearer $SLACK_MCP_HTTP_AUTH_TOKEN" \
181
+ -H "Content-Type: application/json" \
182
+ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}'
183
+ ```
184
+
185
+ For local-only testing (not remote exposure), you can opt out:
186
+
187
+ ```bash
188
+ SLACK_MCP_HTTP_INSECURE=1 node src/server-http.js
189
+ ```
190
+
164
191
  ---
165
192
 
166
193
  ## Claude Desktop Issues
package/docs/WEB-API.md CHANGED
@@ -1,6 +1,15 @@
1
1
  # Web API Reference
2
2
 
3
- The Slack Web Server exposes all MCP tools as REST endpoints, accessible from any browser or HTTP client. This is useful for accessing Slack from claude.ai (which doesn't support MCP).
3
+ The Slack Web Server exposes all MCP tools as REST endpoints, accessible from any browser or HTTP client.
4
+
5
+ Claude web now supports remote MCP connectors on paid plans, so this Web API mode is best used for:
6
+ - local localhost dashboard workflows
7
+ - REST/API integrations
8
+ - fallback operation when you do not want to host a remote MCP endpoint
9
+
10
+ References:
11
+ - https://support.anthropic.com/en/articles/11995447-connectors-in-claude
12
+ - https://support.anthropic.com/en/articles/11175166-about-custom-integrations-using-remote-mcp
4
13
 
5
14
  ## Starting the Server
6
15
 
@@ -269,9 +278,9 @@ The UI auto-connects with the default API key:
269
278
  4. Send messages directly from the browser
270
279
 
271
280
  **Using with claude.ai:**
272
- 1. Open the web UI alongside claude.ai
273
- 2. Browse/search for relevant conversations
274
- 3. Copy-paste message content into claude.ai as needed
281
+ 1. Preferred: add a remote MCP connector in Claude settings if you run a remote endpoint.
282
+ 2. Fallback: open the web UI alongside claude.ai for local browsing/search.
283
+ 3. Copy-paste relevant message content as needed.
275
284
 
276
285
  ---
277
286
 
Binary file
Binary file
Binary file
Binary file
package/lib/handlers.js CHANGED
@@ -95,17 +95,25 @@ export async function handleTokenStatus() {
95
95
  const dmCache = loadDMCache();
96
96
  const tokenStatus = health.reason === 'no_tokens'
97
97
  ? "missing"
98
- : health.critical
99
- ? "critical"
100
- : health.warning
101
- ? "warning"
102
- : "healthy";
98
+ : health.age_state === "unknown"
99
+ ? "unknown_age"
100
+ : health.critical
101
+ ? "critical"
102
+ : health.warning
103
+ ? "warning"
104
+ : "healthy";
103
105
 
104
106
  return asMcpJson({
105
107
  status: tokenStatus,
106
- code: health.reason || (health.critical ? "token_critical" : health.warning ? "token_warning" : "ok"),
108
+ code: health.reason
109
+ || (health.age_state === "unknown" ? "unknown_age" : null)
110
+ || (health.critical ? "token_critical" : health.warning ? "token_warning" : "ok"),
107
111
  message: health.message,
108
112
  next_action: health.reason === 'no_tokens' ? "Run npx -y @jtalk22/slack-mcp --setup" : null,
113
+ details: {
114
+ age_known: health.age_known,
115
+ age_state: health.age_state
116
+ },
109
117
  token: {
110
118
  status: tokenStatus,
111
119
  age_hours: health.age_hours,
@@ -97,7 +97,13 @@ export async function checkTokenHealth(logger = console) {
97
97
  const creds = loadTokens(false, silentLogger, { autoExtract: false });
98
98
 
99
99
  if (!creds) {
100
- return { healthy: false, reason: 'no_tokens', message: 'No credentials found' };
100
+ return {
101
+ healthy: false,
102
+ reason: 'no_tokens',
103
+ age_known: false,
104
+ age_state: 'missing',
105
+ message: 'No credentials found'
106
+ };
101
107
  }
102
108
 
103
109
  const updatedAtMs = creds.updatedAt ? new Date(creds.updatedAt).getTime() : Number.NaN;
@@ -120,6 +126,8 @@ export async function checkTokenHealth(logger = console) {
120
126
  healthy: true,
121
127
  refreshed: true,
122
128
  age_hours: 0,
129
+ age_known: true,
130
+ age_state: 'fresh',
123
131
  source: 'chrome-auto',
124
132
  message: 'Tokens refreshed successfully'
125
133
  };
@@ -131,6 +139,14 @@ export async function checkTokenHealth(logger = console) {
131
139
  return {
132
140
  healthy: !hasKnownAge || tokenAge < TOKEN_CRITICAL_AGE,
133
141
  age_hours: ageHours,
142
+ age_known: hasKnownAge,
143
+ age_state: !hasKnownAge
144
+ ? 'unknown'
145
+ : tokenAge > TOKEN_CRITICAL_AGE
146
+ ? 'critical'
147
+ : tokenAge > TOKEN_WARNING_AGE
148
+ ? 'warning'
149
+ : 'healthy',
134
150
  warning: hasKnownAge && tokenAge > TOKEN_WARNING_AGE,
135
151
  critical: hasKnownAge && tokenAge > TOKEN_CRITICAL_AGE,
136
152
  source: creds.source,
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@jtalk22/slack-mcp",
3
3
  "mcpName": "io.github.jtalk22/slack-mcp-server",
4
- "version": "1.2.4",
4
+ "version": "3.0.0",
5
5
  "description": "Session-based Slack access for Claude - DMs, channels, search, and threads. Local-first with your existing Slack session.",
6
6
  "type": "module",
7
7
  "main": "src/server.js",
8
8
  "bin": {
9
- "slack-mcp": "./src/cli.js",
10
- "slack-mcp-server": "./src/server.js",
11
- "slack-mcp-http": "./src/server-http.js",
12
- "slack-mcp-web": "./src/web-server.js",
13
- "slack-mcp-setup": "./scripts/setup-wizard.js"
9
+ "slack-mcp": "src/cli.js",
10
+ "slack-mcp-server": "src/server.js",
11
+ "slack-mcp-http": "src/server-http.js",
12
+ "slack-mcp-web": "src/web-server.js",
13
+ "slack-mcp-setup": "scripts/setup-wizard.js"
14
14
  },
15
15
  "scripts": {
16
16
  "start": "node src/server.js",
@@ -25,8 +25,11 @@
25
25
  "tokens:clear": "node scripts/token-cli.js clear",
26
26
  "screenshot": "node scripts/capture-screenshots.js",
27
27
  "record-demo": "node scripts/record-demo.js",
28
+ "cf:browser": "node scripts/cloudflare-browser-tool.js",
28
29
  "metrics:release-health": "node scripts/collect-release-health.js",
29
- "metrics:release-health:delta": "node scripts/build-release-health-delta.js"
30
+ "metrics:release-health:delta": "node scripts/build-release-health-delta.js",
31
+ "verify:version-parity": "node scripts/check-version-parity.js",
32
+ "verify:release-dry-run": "node scripts/release-preflight.js"
30
33
  },
31
34
  "keywords": [
32
35
  "mcp",
@@ -39,10 +42,10 @@
39
42
  "claude",
40
43
  "claude-desktop",
41
44
  "claude-code",
45
+ "claude-connectors",
46
+ "anthropic",
42
47
  "cursor",
43
48
  "llm",
44
- "ai",
45
- "ai-assistant",
46
49
  "automation",
47
50
  "workflow-automation",
48
51
  "developer-tools",
@@ -54,13 +57,21 @@
54
57
  "channels",
55
58
  "workspace",
56
59
  "session-based",
60
+ "session-mirroring",
61
+ "slack-dm",
62
+ "slack-threads",
63
+ "workspace-search",
64
+ "mcp-tools",
65
+ "mcp-stdio",
66
+ "mcp-http",
67
+ "remote-mcp",
57
68
  "open-source"
58
69
  ],
59
70
  "author": "jtalk22",
60
71
  "license": "MIT",
61
72
  "repository": {
62
73
  "type": "git",
63
- "url": "https://github.com/jtalk22/slack-mcp-server.git"
74
+ "url": "git+https://github.com/jtalk22/slack-mcp-server.git"
64
75
  },
65
76
  "homepage": "https://jtalk22.github.io/slack-mcp-server/public/demo.html",
66
77
  "bugs": {
@@ -78,9 +89,14 @@
78
89
  "lib/",
79
90
  "public/",
80
91
  "scripts/",
81
- "docs/",
92
+ "docs/*.md",
93
+ "docs/assets/",
94
+ "docs/images/*.png",
95
+ "docs/images/*.svg",
82
96
  "README.md",
83
- "LICENSE"
97
+ "LICENSE",
98
+ "server.json",
99
+ "smithery.yaml"
84
100
  ],
85
101
  "devDependencies": {
86
102
  "playwright": "^1.57.0"
@@ -19,22 +19,27 @@
19
19
  <meta property="og:description" content="Session-based Slack access for Claude with your existing workspace permissions. Search, thread, and messaging workflows.">
20
20
  <meta property="og:type" content="website">
21
21
  <meta property="og:url" content="https://jtalk22.github.io/slack-mcp-server/public/demo-claude.html">
22
- <meta property="og:image" content="https://assets-worker.james-20a.workers.dev/projects/slack-mcp-server/demo-claude.gif">
22
+ <meta property="og:image" content="https://raw.githubusercontent.com/jtalk22/slack-mcp-server/main/docs/images/demo-claude.gif">
23
23
 
24
24
  <!-- Twitter Card -->
25
25
  <meta name="twitter:card" content="summary_large_image">
26
26
  <meta name="twitter:title" content="Slack MCP Server - Session-Based Slack Access Demo">
27
27
  <meta name="twitter:description" content="Session-based Slack access for Claude with your existing workspace permissions. Search, thread, and messaging workflows.">
28
- <meta name="twitter:image" content="https://assets-worker.james-20a.workers.dev/projects/slack-mcp-server/demo-claude.gif">
28
+ <meta name="twitter:image" content="https://raw.githubusercontent.com/jtalk22/slack-mcp-server/main/docs/images/demo-claude.gif">
29
29
 
30
30
  <!-- Theme -->
31
31
  <meta name="theme-color" content="#1a1a1a">
32
32
  <link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>💬</text></svg>">
33
33
  <style>
34
+ @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=Space+Grotesk:wght@500;600;700&display=swap');
35
+
34
36
  /* ═══════════════════════════════════════════════════════════════
35
37
  Claude Desktop Color Palette (Dark Mode)
36
38
  ═══════════════════════════════════════════════════════════════ */
37
39
  :root {
40
+ --font-heading: "Space Grotesk", "Avenir Next", "Segoe UI", sans-serif;
41
+ --font-body: "IBM Plex Sans", "Inter", "Segoe UI", sans-serif;
42
+
38
43
  /* Window chrome */
39
44
  --window-bg: #1a1a1a;
40
45
  --window-chrome: #2d2d2d;
@@ -83,7 +88,7 @@
83
88
  }
84
89
 
85
90
  body {
86
- font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
91
+ font-family: var(--font-body);
87
92
  font-size: 15px;
88
93
  line-height: 1.5;
89
94
  -webkit-font-smoothing: antialiased;
@@ -118,6 +123,8 @@
118
123
  align-items: center;
119
124
  justify-content: center;
120
125
  gap: 12px;
126
+ font-family: var(--font-heading);
127
+ letter-spacing: -0.02em;
121
128
  }
122
129
 
123
130
  .page-header p {
@@ -127,11 +134,11 @@
127
134
  .cta-strip {
128
135
  width: 100%;
129
136
  max-width: 960px;
130
- margin-bottom: 16px;
137
+ margin-bottom: 14px;
131
138
  background: rgba(15, 52, 96, 0.72);
132
139
  border: 1px solid rgba(255, 255, 255, 0.15);
133
140
  border-radius: 12px;
134
- padding: 10px 14px;
141
+ padding: 10px 12px;
135
142
  display: flex;
136
143
  justify-content: space-between;
137
144
  align-items: center;
@@ -183,6 +190,7 @@
183
190
  margin-bottom: 24px;
184
191
  flex-wrap: wrap;
185
192
  justify-content: center;
193
+ width: min(100%, 960px);
186
194
  }
187
195
 
188
196
  .scenario-btn {
@@ -257,6 +265,9 @@
257
265
  gap: 12px;
258
266
  margin-bottom: 16px;
259
267
  align-items: center;
268
+ flex-wrap: wrap;
269
+ justify-content: center;
270
+ width: min(100%, 920px);
260
271
  }
261
272
 
262
273
  .speed-control {
@@ -967,31 +978,93 @@
967
978
  /* ═══════════════════════════════════════════════════════════════
968
979
  Responsive
969
980
  ═══════════════════════════════════════════════════════════════ */
981
+ @media (max-width: 900px) {
982
+ body {
983
+ padding: 14px;
984
+ }
985
+
986
+ .page-header {
987
+ margin-bottom: 16px;
988
+ }
989
+
990
+ .page-header h1 {
991
+ font-size: 24px;
992
+ }
993
+
994
+ .scenario-btn {
995
+ padding: 10px 14px;
996
+ }
997
+
998
+ .controls-bar {
999
+ gap: 10px;
1000
+ }
1001
+
1002
+ .claude-window {
1003
+ max-width: 100%;
1004
+ }
1005
+ }
1006
+
970
1007
  @media (max-width: 600px) {
971
1008
  body {
972
1009
  padding: 12px;
973
1010
  }
974
1011
 
1012
+ .cta-strip {
1013
+ padding: 10px;
1014
+ gap: 8px;
1015
+ }
1016
+
1017
+ .cta-strip .links {
1018
+ width: 100%;
1019
+ }
1020
+
1021
+ .cta-strip .note {
1022
+ font-size: 12px;
1023
+ }
1024
+
975
1025
  .page-header h1 {
976
1026
  font-size: 22px;
1027
+ flex-wrap: wrap;
1028
+ gap: 8px;
1029
+ }
1030
+
1031
+ .page-header p {
1032
+ font-size: 14px;
977
1033
  }
978
1034
 
979
1035
  .scenario-bar {
980
1036
  gap: 8px;
1037
+ margin-bottom: 14px;
981
1038
  }
982
1039
 
983
1040
  .scenario-btn {
984
- padding: 10px 14px;
1041
+ padding: 9px 12px;
985
1042
  font-size: 13px;
1043
+ border-radius: 10px;
986
1044
  }
987
1045
 
988
1046
  .scenario-btn .label {
989
1047
  display: none;
990
1048
  }
991
1049
 
1050
+ .controls-bar {
1051
+ gap: 8px;
1052
+ margin-bottom: 12px;
1053
+ }
1054
+
1055
+ .replay-btn,
1056
+ .share-btn {
1057
+ padding: 8px 12px;
1058
+ }
1059
+
1060
+ .speed-control {
1061
+ width: 100%;
1062
+ justify-content: space-between;
1063
+ }
1064
+
992
1065
  .chat-container {
993
- height: 450px;
994
- padding: 16px;
1066
+ height: min(55vh, 450px);
1067
+ padding: 14px;
995
1068
  }
996
1069
 
997
1070
  .tools-dropdown {
@@ -1161,7 +1234,7 @@
1161
1234
  <header class="page-header">
1162
1235
  <h1>
1163
1236
  <span>Slack MCP Server</span>
1164
- <span class="badge">🔧 MCP Demo v1.2.4</span>
1237
+ <span class="badge">🔧 MCP Demo v3.0.0</span>
1165
1238
  </h1>
1166
1239
  <p>See how Claude uses MCP tools to access your Slack workspace</p>
1167
1240
  </header>
@@ -1233,7 +1306,7 @@
1233
1306
  <div class="title-logo">💬</div>
1234
1307
  <h1>Slack MCP Server</h1>
1235
1308
  <p class="title-tagline">Full Slack access for Claude Desktop</p>
1236
- <p class="title-version">v1.2.4 • @jtalk22</p>
1309
+ <p class="title-version">v3.0.0 • @jtalk22</p>
1237
1310
  </div>
1238
1311
 
1239
1312
  <!-- Scenario Caption Overlay -->
@@ -15,13 +15,20 @@
15
15
  <meta name="twitter:description" content="Session-based Slack access for Claude with your existing workspace permissions. Video walkthrough for Slack workflows.">
16
16
  <meta name="twitter:image" content="https://raw.githubusercontent.com/jtalk22/slack-mcp-server/main/docs/images/demo-poster.png">
17
17
  <style>
18
+ @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=Space+Grotesk:wght@500;600;700&display=swap');
19
+
20
+ :root {
21
+ --font-heading: "Space Grotesk", "Avenir Next", "Segoe UI", sans-serif;
22
+ --font-body: "IBM Plex Sans", "Inter", "Segoe UI", sans-serif;
23
+ }
24
+
18
25
  * {
19
26
  margin: 0;
20
27
  padding: 0;
21
28
  box-sizing: border-box;
22
29
  }
23
30
  body {
24
- font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
31
+ font-family: var(--font-body);
25
32
  background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
26
33
  min-height: 100vh;
27
34
  display: flex;
@@ -40,6 +47,8 @@
40
47
  font-weight: 600;
41
48
  text-align: center;
42
49
  margin-bottom: 0.5rem;
50
+ font-family: var(--font-heading);
51
+ letter-spacing: -0.02em;
43
52
  }
44
53
  .subtitle {
45
54
  color: #94a3b8;
@@ -137,6 +146,26 @@
137
146
  .back-link a:hover {
138
147
  color: #ffffff;
139
148
  }
149
+
150
+ @media (max-width: 640px) {
151
+ body {
152
+ padding: 1rem 0.75rem;
153
+ }
154
+
155
+ .cta-strip .links {
156
+ width: 100%;
157
+ }
158
+
159
+ .controls {
160
+ gap: 0.75rem;
161
+ }
162
+
163
+ .btn {
164
+ flex: 1;
165
+ min-width: 0;
166
+ padding: 0.72rem 0.95rem;
167
+ }
168
+ }
140
169
  </style>
141
170
  </head>
142
171
  <body>
@@ -155,9 +184,9 @@
155
184
  </div>
156
185
 
157
186
  <div class="video-wrapper">
158
- <video id="demo" poster="../docs/images/demo-poster.png" playsinline>
159
- <source src="../docs/videos/demo-claude-v1.2.webm" type="video/webm">
160
- <source src="../docs/images/demo-claude-v1.2.gif" type="image/gif">
187
+ <video id="demo" poster="https://jtalk22.github.io/slack-mcp-server/docs/images/demo-poster.png" playsinline>
188
+ <source src="../docs/videos/demo-claude.webm" type="video/webm">
189
+ <source src="https://jtalk22.github.io/slack-mcp-server/docs/videos/demo-claude.webm" type="video/webm">
161
190
  Your browser does not support the video tag.
162
191
  </video>
163
192
  </div>