@jtalk22/slack-mcp 4.1.2 → 4.2.1
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 +43 -14
- package/docs/DEPLOYMENT-MODES.md +56 -0
- package/docs/TROUBLESHOOTING.md +3 -1
- package/lib/handlers.js +92 -0
- package/lib/public-metadata.js +1 -1
- package/lib/public-pages.js +4 -4
- package/lib/tools.js +160 -0
- package/lib/workflow-store.js +188 -0
- package/package.json +6 -3
- package/public/index.html +3 -2
- package/public/share.html +5 -5
- package/scripts/apply-template.js +117 -0
- package/scripts/setup-wizard.js +19 -0
- package/server.json +3 -3
- package/smithery.yaml +2 -0
- package/src/cli.js +3 -0
- package/src/server.js +22 -0
- package/templates/workflow-profiles/customer-feedback.json +10 -0
- package/templates/workflow-profiles/exec-monday.json +10 -0
- package/templates/workflow-profiles/incident-room.json +10 -0
- package/templates/workflow-profiles/oncall-handoff.json +10 -0
- package/templates/workflow-profiles/sprint-tracker.json +10 -0
- package/templates/workflow-profiles/support-triage.json +10 -0
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://registry.modelcontextprotocol.io)
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
|
|
7
|
-
Give your AI agent full Slack access. No app registration, no admin approval, no OAuth. One command,
|
|
7
|
+
Give your AI agent full Slack access — and structured workflow output the AI can actually use. No app registration, no admin approval, no OAuth. One command, 21 tools, works with any MCP client.
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
npx -y @jtalk22/slack-mcp --setup
|
|
@@ -39,9 +39,29 @@ This server uses your browser's session tokens instead. If you can see it in Sla
|
|
|
39
39
|
| Works with Gemini CLI | No | **Yes** |
|
|
40
40
|
| Works with Codex CLI | No | **Yes** |
|
|
41
41
|
| Setup time | ~30 min | **~2 min** |
|
|
42
|
-
| Tools | Limited | **
|
|
42
|
+
| Tools | Limited | **21** |
|
|
43
43
|
| Visible to admins | Yes | **No — session-token transport** |
|
|
44
44
|
|
|
45
|
+
## Workflow Primitives (new in 4.2)
|
|
46
|
+
|
|
47
|
+
Save a workflow profile that binds a `workflow_kind` to channels + priority people + retention + cadence. Stored locally at `~/.slack-mcp-workflows.json`. The hosted brain at [mcp.revasserlabs.com](https://mcp.revasserlabs.com) reads these profiles and returns **structured JSON per workflow_kind** — downstream automation (Linear, Notion, status dashboards) consumes the JSON directly.
|
|
48
|
+
|
|
49
|
+
| `workflow_kind` | Returns (structured JSON) |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `incident_room` | `{incident_summary, timeline, open_risks, owner_gaps, next_actions}` |
|
|
52
|
+
| `exec_brief` | `{summary, decisions, risks, asks, action_items}` |
|
|
53
|
+
| `support_inbox` | `{open_threads, ack_lag, owner_gaps, escalations, next_actions}` |
|
|
54
|
+
| `product_launch_watch` | `{launch_signals, feedback_themes, blockers, metrics, next_actions}` |
|
|
55
|
+
| `custom` | `{summary, highlights, open_questions, next_actions}` |
|
|
56
|
+
|
|
57
|
+
Six prebuilt templates ship with the package:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx -y @jtalk22/slack-mcp --apply-template oncall-handoff --channels C012345,C067890
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Available templates: `oncall-handoff`, `support-triage`, `exec-monday`, `sprint-tracker`, `customer-feedback`, `incident-room`. The structural primitives (`slack_workflow_save`, `slack_workflows`) are free forever in OSS; the hosted brain is `$0` to start (no card) and `$9/mo` Pro for unlimited AI tools (scheduled morning catch-up DM rolling out Q2 2026).
|
|
64
|
+
|
|
45
65
|
## Quick Start per Client
|
|
46
66
|
|
|
47
67
|
<details>
|
|
@@ -129,11 +149,18 @@ Or via CLI: `codex mcp add slack -- npx -y @jtalk22/slack-mcp`
|
|
|
129
149
|
| `slack_add_reaction` | Add an emoji reaction to a message | **destructive** |
|
|
130
150
|
| `slack_remove_reaction` | Remove an emoji reaction from a message | **destructive** |
|
|
131
151
|
| `slack_conversations_mark` | Mark a conversation as read | **destructive** |
|
|
152
|
+
| `slack_workflow_save` | Save a workflow profile (channels, kind, retention, cadence) to `~/.slack-mcp-workflows.json` | local-write |
|
|
153
|
+
| `slack_workflows` | List saved workflow profiles | read-only |
|
|
154
|
+
| `slack_smart_search` | Semantic search across indexed channels — hosted brain | hosted-stub† |
|
|
155
|
+
| `slack_catch_me_up` | AI-summarized digest of unreads + priority threads — hosted brain | hosted-stub† |
|
|
156
|
+
| `slack_triage` | Prioritized action queue across channels — hosted brain | hosted-stub† |
|
|
132
157
|
|
|
133
|
-
12 read-only, 4 write-path. All carry [MCP safety annotations](https://modelcontextprotocol.io/specification/2025-03-26/server/tools#annotations).
|
|
158
|
+
21 tools total: 12 read-only Slack, 4 write-path Slack, 2 workflow profile primitives (1 local-write, 1 read-only), 3 hosted stubs. All carry [MCP safety annotations](https://modelcontextprotocol.io/specification/2025-03-26/server/tools#annotations).
|
|
134
159
|
|
|
135
160
|
\* `slack_refresh_tokens` modifies local token file only.
|
|
136
161
|
|
|
162
|
+
† Hosted stubs return a structured upgrade payload (`signup_url`, `free_tier_quota`, `pro_value_prop`) — no Slack write occurs from OSS. Activate the brain at [mcp.revasserlabs.com](https://mcp.revasserlabs.com) (free tier, no card).
|
|
163
|
+
|
|
137
164
|
## Install
|
|
138
165
|
|
|
139
166
|
**Node.js 20+**
|
|
@@ -234,11 +261,11 @@ Hosted tiers at [mcp.revasserlabs.com](https://mcp.revasserlabs.com):
|
|
|
234
261
|
|
|
235
262
|
| Tier | Price | What it owns |
|
|
236
263
|
|------|-------|-------------|
|
|
237
|
-
| Self-host | Free | Local stdio, all
|
|
238
|
-
|
|
|
239
|
-
|
|
|
240
|
-
|
|
|
241
|
-
|
|
|
264
|
+
| Self-host | Free (MIT) | Local stdio, all 21 tools (16 read/write Slack + 2 workflow profile primitives + 3 discoverable upgrade stubs to hosted brain) |
|
|
265
|
+
| Hosted Free | $0 (no card) | Email signup, 1 workspace, 10 smart_search/mo + 3 catch_me_up/mo + 5 triage/day. All 5 workflow profile types. 7-day index retention. |
|
|
266
|
+
| Pro | $9/mo | Unlimited AI tools, **scheduled morning catch-up DM** *(rolling out Q2 2026, 8am workspace tz)*, permanent OAuth, 90-day Vectorize, 2 workspaces |
|
|
267
|
+
| Team | $49/mo flat | Pro + shared workflow profiles + audit log + 24h support + scheduled catch-up to channel + 5 workspaces |
|
|
268
|
+
| Ops | from $199/mo (custom) | SLA, custom retention, SOC2 evidence path, multi-tenant isolation, 10+ workspaces, dedicated workflow tuning |
|
|
242
269
|
|
|
243
270
|
</details>
|
|
244
271
|
|
|
@@ -278,13 +305,15 @@ Session tokens (`xoxc-` + `xoxd-`) from your browser. If you can see it in Slack
|
|
|
278
305
|
|
|
279
306
|
Tokens expire. The server notices before you do — proactive health monitoring, automatic refresh on macOS, warnings when tokens age out. File writes are atomic (temp file → chmod → rename) to prevent corruption. Concurrent refresh attempts are mutex-locked.
|
|
280
307
|
|
|
281
|
-
## What's New in 4.
|
|
308
|
+
## What's New in 4.2.0
|
|
282
309
|
|
|
283
|
-
- **
|
|
284
|
-
- **
|
|
285
|
-
- **
|
|
310
|
+
- **Workflow primitives** — `slack_workflow_save` + `slack_workflows` bind a `workflow_kind` (`incident_room`, `exec_brief`, `support_inbox`, `product_launch_watch`, `custom`) to channels, priority people, retention, and cadence. The hosted brain returns structured JSON per kind — `incident_room` returns `{incident_summary, timeline, open_risks, owner_gaps, next_actions}`, `exec_brief` returns `{summary, decisions, risks, asks, action_items}`. Downstream automation (Linear, Notion, dashboards) consumes the JSON directly.
|
|
311
|
+
- **Discoverable upgrade stubs** — `slack_smart_search`, `slack_catch_me_up`, `slack_triage` appear in OSS as upgrade payloads pointing at the hosted brain. Response shape is `{signup_url, free_tier_quota, pro_value_prop}` — no interruptions, the AI routes the user cleanly.
|
|
312
|
+
- **Six prebuilt templates** — apply with `npx -y @jtalk22/slack-mcp --apply-template <name> --channels C012,C034`. Names: `oncall-handoff`, `support-triage`, `exec-monday`, `sprint-tracker`, `customer-feedback`, `incident-room`. Read them, fork them, edit them — they're JSON profiles.
|
|
313
|
+
- **Setup wizard hosted bridge** — six in-wizard moments surface the hosted free tier (no card) where it matches the user's pain. Stays out of the way otherwise.
|
|
314
|
+
- **Prior reliability fixes carried forward** — LevelDB token extraction, multi-profile enumeration, and explicit SIGTERM/SIGINT/SIGHUP/stdin shutdown handlers ship in 4.2.0 too.
|
|
286
315
|
|
|
287
|
-
Full release notes
|
|
316
|
+
Full release notes on [GitHub releases/latest](https://github.com/jtalk22/slack-mcp-server/releases/latest).
|
|
288
317
|
|
|
289
318
|
## Hosted HTTP Mode
|
|
290
319
|
|
|
@@ -342,4 +371,4 @@ Not affiliated with Slack Technologies, Inc. Uses browser session credentials
|
|
|
342
371
|
|
|
343
372
|
---
|
|
344
373
|
|
|
345
|
-
Hosted
|
|
374
|
+
Hosted version live at [mcp.revasserlabs.com](https://mcp.revasserlabs.com): Free tier (no card), $9/mo Pro, $49/mo Team flat, Ops from $199/mo. Hosted owns the AI brain (smart_search, catch_me_up, triage), the scheduled morning catch-up DM at 8am workspace time *(rolling out Q2 2026)*, permanent OAuth (no 2-week token rotation), 90-day Vectorize retention, and shared workflow profiles. The OSS package owns local stdio + all 16 read/write Slack tools + workflow profile primitives (slack_workflow_save, slack_workflows). The 3 paid stubs (slack_smart_search, slack_catch_me_up, slack_triage) appear in OSS as discoverable upgrade prompts.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Deployment Modes
|
|
2
|
+
|
|
3
|
+
Use this guide to choose the right operating mode before rollout.
|
|
4
|
+
|
|
5
|
+
## Quick Chooser
|
|
6
|
+
|
|
7
|
+
- Choose `stdio` for personal self-hosted use in Claude Desktop/Claude Code.
|
|
8
|
+
- Choose local `web` for browser workflows and manual Slack browsing.
|
|
9
|
+
- Choose hosted HTTP only when you need remote execution and can handle token operations.
|
|
10
|
+
- Choose Smithery/Worker only when your consumers require registry-hosted MCP transport.
|
|
11
|
+
- A managed **Hosted** version is live at [mcp.revasserlabs.com](https://mcp.revasserlabs.com) — Free tier (no card), Pro $9/mo, Team $49/mo flat, Ops from $199/mo. See [pricing](https://mcp.revasserlabs.com/pricing).
|
|
12
|
+
|
|
13
|
+
## Mode Matrix
|
|
14
|
+
|
|
15
|
+
| Mode | Start Command | Best For | Auth Material | Exposure | Notes |
|
|
16
|
+
|------|---------------|----------|---------------|----------|-------|
|
|
17
|
+
| Local MCP (`stdio`) | `npx -y @jtalk22/slack-mcp` | Individual daily usage in Claude | `SLACK_TOKEN` + `SLACK_COOKIE` via token file/env | Local process | Lowest ops burden. Free. 21 tools (16 read/write + 2 workflow profile primitives + 3 discoverable upgrade stubs to hosted). |
|
|
18
|
+
| Local Web UI (`web`) | `npx -y @jtalk22/slack-mcp web` | Browser-first usage, manual search/send | Same as above + generated API key | `localhost` by default | Useful when MCP is not available |
|
|
19
|
+
| Hosted MCP (`http`) | `node src/server-http.js` | Controlled hosted integration | Env-injected Slack token/cookie + HTTP bearer token | Remote endpoint | `/mcp` is bearer-protected by default; configure CORS allowlist |
|
|
20
|
+
| Smithery/Worker | `wrangler deploy` + Smithery publish flow | Registry distribution for hosted consumers | Query/env token handoff | Remote endpoint | Keep worker version parity with npm release |
|
|
21
|
+
|
|
22
|
+
## Team Deployment Guidance
|
|
23
|
+
|
|
24
|
+
If you are deploying for more than one operator:
|
|
25
|
+
|
|
26
|
+
1. Start with one maintainer on local `stdio`.
|
|
27
|
+
2. Document token lifecycle and rotation ownership.
|
|
28
|
+
3. Define support window and incident contact before enabling hosted mode.
|
|
29
|
+
4. Validate `/health` and MCP initialize responses on every release.
|
|
30
|
+
|
|
31
|
+
## Release Checklist by Mode
|
|
32
|
+
|
|
33
|
+
### Local `stdio`
|
|
34
|
+
|
|
35
|
+
1. `npx -y @jtalk22/slack-mcp --status`
|
|
36
|
+
2. `npx -y @jtalk22/slack-mcp --help`
|
|
37
|
+
3. Confirm tool list in Claude client.
|
|
38
|
+
|
|
39
|
+
### Local `web`
|
|
40
|
+
|
|
41
|
+
1. `npx -y @jtalk22/slack-mcp web`
|
|
42
|
+
2. Verify API key generation at `~/.slack-mcp-api-key`.
|
|
43
|
+
3. Verify `/health`, `/conversations`, and `/search` endpoints.
|
|
44
|
+
|
|
45
|
+
### Hosted (`http` or Worker)
|
|
46
|
+
|
|
47
|
+
1. Verify `version` parity across `package.json`, server metadata, and health responses.
|
|
48
|
+
2. Verify HTTP auth behavior:
|
|
49
|
+
- missing `SLACK_MCP_HTTP_AUTH_TOKEN` returns `503`
|
|
50
|
+
- bad bearer token returns `401`
|
|
51
|
+
- valid bearer token succeeds
|
|
52
|
+
3. Verify CORS behavior:
|
|
53
|
+
- denied by default
|
|
54
|
+
- allowed origins work when listed in `SLACK_MCP_HTTP_ALLOWED_ORIGINS`
|
|
55
|
+
4. Confirm `slack_get_thread`, `slack_search_messages`, and `slack_users_info` behavior.
|
|
56
|
+
5. Confirm token handling mode (ephemeral vs env persistence) is documented.
|
package/docs/TROUBLESHOOTING.md
CHANGED
|
@@ -31,7 +31,9 @@ If `--version` fails here, the issue is install/runtime path, not Slack credenti
|
|
|
31
31
|
|
|
32
32
|
## Hosted Version
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
The hosted version is live at [mcp.revasserlabs.com](https://mcp.revasserlabs.com). Free tier (no card) ships 10 smart_search/mo + 3 catch_me_up/mo + 5 triage/day + all 5 workflow profile types. Pro at $9/mo unlocks unlimited AI tools, the scheduled morning catch-up DM at 8am workspace time *(rolling out Q2 2026)*, permanent OAuth (no 2-week token rotation), and 90-day Vectorize retention. Team at $49/mo flat covers 5 workspaces with shared workflow profiles and audit log. Ops engagement starts at $199/mo (custom) for 10+ workspace organizations with SLA, custom retention, SOC2 evidence, or multi-tenant isolation.
|
|
35
|
+
|
|
36
|
+
The OSS package keeps the local-machine path. The hosted version adds the AI brain (smart_search, catch_me_up, triage) — these tools also appear in the OSS package as discoverable upgrade stubs that point at the hosted signup.
|
|
35
37
|
|
|
36
38
|
---
|
|
37
39
|
|
package/lib/handlers.js
CHANGED
|
@@ -16,6 +16,11 @@ import {
|
|
|
16
16
|
getLastExtractionError
|
|
17
17
|
} from "./token-store.js";
|
|
18
18
|
import { slackAPI, resolveUser, formatTimestamp, sleep, checkTokenHealth, getUserCacheStats } from "./slack-client.js";
|
|
19
|
+
import {
|
|
20
|
+
saveProfile as workflowSaveProfile,
|
|
21
|
+
listProfiles as workflowListProfiles,
|
|
22
|
+
ALLOWED_WORKFLOW_KINDS_LIST,
|
|
23
|
+
} from "./workflow-store.js";
|
|
19
24
|
|
|
20
25
|
// ============ Utilities ============
|
|
21
26
|
|
|
@@ -773,3 +778,90 @@ export async function handleUsersSearch(args) {
|
|
|
773
778
|
users: allUsers.slice(0, limit)
|
|
774
779
|
});
|
|
775
780
|
}
|
|
781
|
+
|
|
782
|
+
// ============ Workflow Profile Primitives (OSS) ============
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Save (or update) a workflow profile to ~/.slack-mcp-workflows.json
|
|
786
|
+
* Profile binds a workflow_kind to channels + priority_people + retention + cadence.
|
|
787
|
+
*/
|
|
788
|
+
export async function handleWorkflowSave(args) {
|
|
789
|
+
const safeArgs = args || {};
|
|
790
|
+
const result = workflowSaveProfile({
|
|
791
|
+
profile_name: safeArgs.profile_name,
|
|
792
|
+
workflow_kind: safeArgs.workflow_kind,
|
|
793
|
+
channels: safeArgs.channels,
|
|
794
|
+
priority_people: safeArgs.priority_people,
|
|
795
|
+
retention_mode: safeArgs.retention_mode,
|
|
796
|
+
summary_cadence: safeArgs.summary_cadence,
|
|
797
|
+
});
|
|
798
|
+
if (!result.ok) {
|
|
799
|
+
return asMcpJson({ error: "invalid_workflow_profile", errors: result.errors }, true);
|
|
800
|
+
}
|
|
801
|
+
return asMcpJson({
|
|
802
|
+
ok: true,
|
|
803
|
+
profile_name: result.profile_name,
|
|
804
|
+
profile: result.profile,
|
|
805
|
+
note: "Profile saved locally. Hosted free tier syncs profiles automatically when you connect your account; OSS-only mode keeps them on your machine.",
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* List saved workflow profiles, optionally filtered by workflow_kind.
|
|
811
|
+
*/
|
|
812
|
+
export async function handleWorkflows(args) {
|
|
813
|
+
const result = workflowListProfiles({ workflow_kind: args && args.workflow_kind });
|
|
814
|
+
if (!result.ok) {
|
|
815
|
+
return asMcpJson({ error: "invalid_workflow_filter", errors: result.errors }, true);
|
|
816
|
+
}
|
|
817
|
+
return asMcpJson({
|
|
818
|
+
ok: true,
|
|
819
|
+
count: result.profiles.length,
|
|
820
|
+
workflow_kinds: ALLOWED_WORKFLOW_KINDS_LIST,
|
|
821
|
+
profiles: result.profiles,
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// ============ Hosted-Only AI Tool Stubs ============
|
|
826
|
+
// These three tools appear in the OSS package's MCP tool list so users
|
|
827
|
+
// discover them. The handlers return a structured upgrade message —
|
|
828
|
+
// actual execution happens on the hosted worker (mcp.revasserlabs.com).
|
|
829
|
+
|
|
830
|
+
const HOSTED_UPGRADE_PAYLOAD = {
|
|
831
|
+
error: "tool_requires_hosted",
|
|
832
|
+
message: "This tool needs hosted mode (Vectorize + Workers AI). Get free monthly credits at mcp.revasserlabs.com — no card required.",
|
|
833
|
+
signup_url: "https://mcp.revasserlabs.com/signup",
|
|
834
|
+
upgrade_url: "https://mcp.revasserlabs.com/pricing",
|
|
835
|
+
free_tier_quota: "10 smart_search + 3 catch_me_up per month, 5 triage per day",
|
|
836
|
+
pro_value_prop: "Pro $9/mo unlocks unlimited AI tools (scheduled morning catch-up DM at 8am workspace time rolling out Q2 2026).",
|
|
837
|
+
};
|
|
838
|
+
|
|
839
|
+
export async function handleSmartSearch(args) {
|
|
840
|
+
return asMcpJson(
|
|
841
|
+
{
|
|
842
|
+
...HOSTED_UPGRADE_PAYLOAD,
|
|
843
|
+
requested: { tool: "slack_smart_search", args: args || {} },
|
|
844
|
+
},
|
|
845
|
+
true
|
|
846
|
+
);
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
export async function handleCatchMeUp(args) {
|
|
850
|
+
return asMcpJson(
|
|
851
|
+
{
|
|
852
|
+
...HOSTED_UPGRADE_PAYLOAD,
|
|
853
|
+
requested: { tool: "slack_catch_me_up", args: args || {} },
|
|
854
|
+
},
|
|
855
|
+
true
|
|
856
|
+
);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
export async function handleTriage(args) {
|
|
860
|
+
return asMcpJson(
|
|
861
|
+
{
|
|
862
|
+
...HOSTED_UPGRADE_PAYLOAD,
|
|
863
|
+
requested: { tool: "slack_triage", args: args || {} },
|
|
864
|
+
},
|
|
865
|
+
true
|
|
866
|
+
);
|
|
867
|
+
}
|
package/lib/public-metadata.js
CHANGED
|
@@ -18,5 +18,5 @@ export const PUBLIC_METADATA = Object.freeze({
|
|
|
18
18
|
cloudSupportUrl: "https://mcp.revasserlabs.com/support",
|
|
19
19
|
cloudStatusUrl: "https://mcp.revasserlabs.com/status",
|
|
20
20
|
supportEmail: "support@revasserlabs.com",
|
|
21
|
-
selfHostedToolCount:
|
|
21
|
+
selfHostedToolCount: 21,
|
|
22
22
|
});
|
package/lib/public-pages.js
CHANGED
|
@@ -63,7 +63,7 @@ function shareLinks() {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
function shareNote() {
|
|
66
|
-
return `<strong>Verify in 30 seconds:</strong> <code>--version</code>, <code>--doctor</code>, <code>--status</code>. Self-host gives ${PUBLIC_METADATA.selfHostedToolCount} tools with session-based auth. Works with any MCP client — Claude, ChatGPT, Cursor, Copilot, Gemini, Windsurf. Hosted
|
|
66
|
+
return `<strong>Verify in 30 seconds:</strong> <code>--version</code>, <code>--doctor</code>, <code>--status</code>. Self-host gives ${PUBLIC_METADATA.selfHostedToolCount} tools with session-based auth. Works with any MCP client — Claude, ChatGPT, Cursor, Copilot, Gemini, Windsurf. Hosted free tier (no card) live at <a href="${PUBLIC_METADATA.canonicalSiteUrl}">mcp.revasserlabs.com</a> — Pro $9/mo unlocks unlimited AI tools (scheduled morning catch-up DM rolling out Q2 2026).`;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
function demoLinks() {
|
|
@@ -75,7 +75,7 @@ function demoLinks() {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
function demoNote() {
|
|
78
|
-
return `Self-host free for ${PUBLIC_METADATA.selfHostedToolCount} tools with session-based auth. Works with Claude, ChatGPT, Cursor, Copilot, Gemini, Windsurf, and any other MCP client. No OAuth app, no admin approval. Hosted
|
|
78
|
+
return `Self-host free for ${PUBLIC_METADATA.selfHostedToolCount} tools with session-based auth. Works with Claude, ChatGPT, Cursor, Copilot, Gemini, Windsurf, and any other MCP client. No OAuth app, no admin approval. Hosted free tier (no card) live at <a href="${PUBLIC_METADATA.canonicalSiteUrl}" target="_blank" rel="noopener noreferrer">mcp.revasserlabs.com</a> — Pro $9/mo unlocks unlimited AI tools (scheduled morning catch-up DM rolling out Q2 2026).`;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
function demoFooterLinks() {
|
|
@@ -113,8 +113,8 @@ function commonTokens() {
|
|
|
113
113
|
SELF_HOSTED_TOOL_COUNT: String(PUBLIC_METADATA.selfHostedToolCount),
|
|
114
114
|
CLOUD_MANAGED_TOOL_COUNT: "15",
|
|
115
115
|
TEAM_AI_WORKFLOW_COUNT: "3",
|
|
116
|
-
CLOUD_SOLO_PRICE: "
|
|
117
|
-
CLOUD_TEAM_PRICE: "
|
|
116
|
+
CLOUD_SOLO_PRICE: "$9/mo",
|
|
117
|
+
CLOUD_TEAM_PRICE: "$49/mo",
|
|
118
118
|
CLOUD_TURNKEY_LAUNCH_PRICE: "contact us",
|
|
119
119
|
CLOUD_MANAGED_RELIABILITY_PRICE: "contact us",
|
|
120
120
|
SUPPORT_EMAIL: PUBLIC_METADATA.supportEmail,
|
package/lib/tools.js
CHANGED
|
@@ -399,5 +399,165 @@ export const TOOLS = [
|
|
|
399
399
|
idempotentHint: true,
|
|
400
400
|
openWorldHint: true
|
|
401
401
|
}
|
|
402
|
+
},
|
|
403
|
+
// ============ Workflow Profile Primitives (OSS) ============
|
|
404
|
+
// Local JSON storage at ~/.slack-mcp-workflows.json. Defines the
|
|
405
|
+
// structural primitive that the hosted AI brain (smart_search,
|
|
406
|
+
// catch_me_up, triage) consumes to return structured JSON.
|
|
407
|
+
{
|
|
408
|
+
name: "slack_workflow_save",
|
|
409
|
+
description: "Save or update a workflow profile that binds a workflow_kind (support_inbox | incident_room | exec_brief | product_launch_watch | custom) to channels, priority people, retention mode, and summary cadence. Stored locally at ~/.slack-mcp-workflows.json. Hosted brain reads these to return structured JSON per the workflow_kind.",
|
|
410
|
+
inputSchema: {
|
|
411
|
+
type: "object",
|
|
412
|
+
properties: {
|
|
413
|
+
profile_name: {
|
|
414
|
+
type: "string",
|
|
415
|
+
description: "Unique name for this workflow profile (e.g. 'morning-exec-brief', 'on-call-rotation')"
|
|
416
|
+
},
|
|
417
|
+
workflow_kind: {
|
|
418
|
+
type: "string",
|
|
419
|
+
enum: ["support_inbox", "incident_room", "exec_brief", "product_launch_watch", "custom"],
|
|
420
|
+
description: "Workflow kind. Determines structured JSON output shape from the hosted AI brain."
|
|
421
|
+
},
|
|
422
|
+
channels: {
|
|
423
|
+
type: "array",
|
|
424
|
+
items: { type: "string" },
|
|
425
|
+
description: "Slack channel IDs to read (e.g. ['C012345', 'C067890'])"
|
|
426
|
+
},
|
|
427
|
+
priority_people: {
|
|
428
|
+
type: "array",
|
|
429
|
+
items: { type: "string" },
|
|
430
|
+
description: "Slack user IDs whose messages get extra weight in summaries"
|
|
431
|
+
},
|
|
432
|
+
retention_mode: {
|
|
433
|
+
type: "string",
|
|
434
|
+
enum: ["ephemeral", "persistent"],
|
|
435
|
+
description: "Token retention mode for hosted execution. Default ephemeral."
|
|
436
|
+
},
|
|
437
|
+
summary_cadence: {
|
|
438
|
+
type: "string",
|
|
439
|
+
enum: ["on_demand", "daily_8am", "weekly_monday"],
|
|
440
|
+
description: "When the hosted brain auto-runs slack_catch_me_up against this profile. on_demand only on hosted free; daily_8am and weekly_monday require Pro or Team."
|
|
441
|
+
}
|
|
442
|
+
},
|
|
443
|
+
required: ["profile_name", "workflow_kind"]
|
|
444
|
+
},
|
|
445
|
+
annotations: {
|
|
446
|
+
title: "Save Workflow Profile",
|
|
447
|
+
readOnlyHint: false,
|
|
448
|
+
destructiveHint: false,
|
|
449
|
+
idempotentHint: true,
|
|
450
|
+
openWorldHint: false
|
|
451
|
+
}
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
name: "slack_workflows",
|
|
455
|
+
description: "List all saved workflow profiles from ~/.slack-mcp-workflows.json. Optionally filter by workflow_kind. Returns profile_name, channels, priority_people, retention_mode, summary_cadence, structured_keys, created_at, updated_at.",
|
|
456
|
+
inputSchema: {
|
|
457
|
+
type: "object",
|
|
458
|
+
properties: {
|
|
459
|
+
workflow_kind: {
|
|
460
|
+
type: "string",
|
|
461
|
+
enum: ["support_inbox", "incident_room", "exec_brief", "product_launch_watch", "custom"],
|
|
462
|
+
description: "Optional filter — return only profiles of this workflow_kind"
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
},
|
|
466
|
+
annotations: {
|
|
467
|
+
title: "List Workflow Profiles",
|
|
468
|
+
readOnlyHint: true,
|
|
469
|
+
idempotentHint: true,
|
|
470
|
+
openWorldHint: false
|
|
471
|
+
}
|
|
472
|
+
},
|
|
473
|
+
// ============ Hosted-Only AI Tools (OSS = upgrade stubs) ============
|
|
474
|
+
// These tool definitions appear in every MCP client's tool list so users
|
|
475
|
+
// discover them. The OSS handlers return a structured upgrade message
|
|
476
|
+
// pointing at mcp.revasserlabs.com — the hosted worker actually runs them.
|
|
477
|
+
{
|
|
478
|
+
name: "slack_smart_search",
|
|
479
|
+
description: "Semantic + lexical hybrid search across your indexed Slack history. Returns ranked results with relevance scores, channel context, thread context, and matched terms. Hosted-only (requires Vectorize + Workers AI). Free tier ships 10 calls/month; upgrade to Pro $9/mo for unlimited at mcp.revasserlabs.com/pricing.",
|
|
480
|
+
inputSchema: {
|
|
481
|
+
type: "object",
|
|
482
|
+
properties: {
|
|
483
|
+
query: {
|
|
484
|
+
type: "string",
|
|
485
|
+
description: "Natural language or keyword query (semantic + lexical hybrid)"
|
|
486
|
+
},
|
|
487
|
+
channel_ids: {
|
|
488
|
+
type: "array",
|
|
489
|
+
items: { type: "string" },
|
|
490
|
+
description: "Optional — restrict search to these channel IDs"
|
|
491
|
+
},
|
|
492
|
+
days_back: {
|
|
493
|
+
type: "number",
|
|
494
|
+
description: "Optional — restrict search to the last N days (max 90 on Pro+, 7 on Free)"
|
|
495
|
+
},
|
|
496
|
+
limit: {
|
|
497
|
+
type: "number",
|
|
498
|
+
description: "Maximum results to return (default 10, max 50)"
|
|
499
|
+
}
|
|
500
|
+
},
|
|
501
|
+
required: ["query"]
|
|
502
|
+
},
|
|
503
|
+
annotations: {
|
|
504
|
+
title: "Smart Search (hosted)",
|
|
505
|
+
readOnlyHint: true,
|
|
506
|
+
idempotentHint: true,
|
|
507
|
+
openWorldHint: true
|
|
508
|
+
}
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
name: "slack_catch_me_up",
|
|
512
|
+
description: "Run a structured catch-up against a saved workflow profile. Returns structured JSON per the profile's workflow_kind: support_inbox returns {open_threads, ack_lag, owner_gaps, escalations, next_actions}; incident_room returns {incident_summary, timeline, open_risks, owner_gaps, next_actions}; exec_brief returns {summary, decisions, risks, asks, action_items}; product_launch_watch returns {launch_signals, feedback_themes, blockers, metrics, next_actions}; custom returns {summary, highlights, open_questions, next_actions}. Hosted-only. Free tier ships 3 calls/month; Pro $9/mo unlocks unlimited (scheduled morning DM at 8am workspace tz rolling out Q2 2026).",
|
|
513
|
+
inputSchema: {
|
|
514
|
+
type: "object",
|
|
515
|
+
properties: {
|
|
516
|
+
profile_name: {
|
|
517
|
+
type: "string",
|
|
518
|
+
description: "Name of a workflow profile saved via slack_workflow_save (or use --apply-template at install time to seed one)"
|
|
519
|
+
},
|
|
520
|
+
since: {
|
|
521
|
+
type: "string",
|
|
522
|
+
description: "Optional ISO8601 timestamp — only consider Slack messages newer than this. Default: 24 hours ago for daily-cadence profiles, 7 days for weekly."
|
|
523
|
+
}
|
|
524
|
+
},
|
|
525
|
+
required: ["profile_name"]
|
|
526
|
+
},
|
|
527
|
+
annotations: {
|
|
528
|
+
title: "Catch Me Up (hosted)",
|
|
529
|
+
readOnlyHint: true,
|
|
530
|
+
idempotentHint: false,
|
|
531
|
+
openWorldHint: true
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
name: "slack_triage",
|
|
536
|
+
description: "Classify and route Slack threads against a workflow profile. Returns triage decisions per thread: priority (low|medium|high|urgent), suggested owner, escalation flag, time-sensitivity, and a routing recommendation. Hosted-only. Free tier ships 5 triage runs per day; Pro $9/mo unlocks unlimited.",
|
|
537
|
+
inputSchema: {
|
|
538
|
+
type: "object",
|
|
539
|
+
properties: {
|
|
540
|
+
profile_name: {
|
|
541
|
+
type: "string",
|
|
542
|
+
description: "Name of a workflow profile saved via slack_workflow_save"
|
|
543
|
+
},
|
|
544
|
+
channel_ids: {
|
|
545
|
+
type: "array",
|
|
546
|
+
items: { type: "string" },
|
|
547
|
+
description: "Optional — restrict triage to these channels (defaults to profile's channels)"
|
|
548
|
+
},
|
|
549
|
+
thread_ts: {
|
|
550
|
+
type: "string",
|
|
551
|
+
description: "Optional — triage a specific thread instead of the full inbox"
|
|
552
|
+
}
|
|
553
|
+
},
|
|
554
|
+
required: ["profile_name"]
|
|
555
|
+
},
|
|
556
|
+
annotations: {
|
|
557
|
+
title: "Triage (hosted)",
|
|
558
|
+
readOnlyHint: true,
|
|
559
|
+
idempotentHint: false,
|
|
560
|
+
openWorldHint: true
|
|
561
|
+
}
|
|
402
562
|
}
|
|
403
563
|
];
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Profile Store (local JSON, OSS-only)
|
|
3
|
+
*
|
|
4
|
+
* Stores user-defined workflow profiles that bind a workflow_kind
|
|
5
|
+
* (support_inbox | incident_room | exec_brief | product_launch_watch | custom)
|
|
6
|
+
* to a set of channels, priority people, retention mode, and summary cadence.
|
|
7
|
+
*
|
|
8
|
+
* The hosted AI brain (smart_search, catch_me_up, triage) consumes these
|
|
9
|
+
* profiles and returns structured JSON per the workflow_kind. The OSS
|
|
10
|
+
* package ships the profile primitives but not the AI brain — it's
|
|
11
|
+
* hosted-only because it needs Vectorize + Workers AI.
|
|
12
|
+
*
|
|
13
|
+
* File: ~/.slack-mcp-workflows.json (chmod 600)
|
|
14
|
+
* Atomic write pattern (temp → chmod → rename) prevents corruption from
|
|
15
|
+
* concurrent writes by multiple slack-mcp-server instances.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { writeFileSync, readFileSync, existsSync, renameSync, unlinkSync, chmodSync } from "fs";
|
|
19
|
+
import { homedir, platform } from "os";
|
|
20
|
+
import { join } from "path";
|
|
21
|
+
|
|
22
|
+
const STORE_FILE = join(homedir(), ".slack-mcp-workflows.json");
|
|
23
|
+
const STORE_VERSION = 1;
|
|
24
|
+
|
|
25
|
+
const ALLOWED_WORKFLOW_KINDS = new Set([
|
|
26
|
+
"support_inbox",
|
|
27
|
+
"incident_room",
|
|
28
|
+
"exec_brief",
|
|
29
|
+
"product_launch_watch",
|
|
30
|
+
"custom",
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
const ALLOWED_RETENTION_MODES = new Set(["ephemeral", "persistent"]);
|
|
34
|
+
const ALLOWED_SUMMARY_CADENCES = new Set(["on_demand", "daily_8am", "weekly_monday"]);
|
|
35
|
+
|
|
36
|
+
const STRUCTURED_KEYS_BY_KIND = {
|
|
37
|
+
support_inbox: ["open_threads", "ack_lag", "owner_gaps", "escalations", "next_actions"],
|
|
38
|
+
incident_room: ["incident_summary", "timeline", "open_risks", "owner_gaps", "next_actions"],
|
|
39
|
+
exec_brief: ["summary", "decisions", "risks", "asks", "action_items"],
|
|
40
|
+
product_launch_watch: ["launch_signals", "feedback_themes", "blockers", "metrics", "next_actions"],
|
|
41
|
+
custom: ["summary", "highlights", "open_questions", "next_actions"],
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
function emptyStore() {
|
|
45
|
+
return { version: STORE_VERSION, profiles: {} };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function atomicWriteSync(filePath, content) {
|
|
49
|
+
const tempPath = `${filePath}.${process.pid}.tmp`;
|
|
50
|
+
try {
|
|
51
|
+
writeFileSync(tempPath, content);
|
|
52
|
+
if (platform() === "darwin" || platform() === "linux") {
|
|
53
|
+
try { chmodSync(tempPath, 0o600); } catch {}
|
|
54
|
+
}
|
|
55
|
+
renameSync(tempPath, filePath);
|
|
56
|
+
} catch (e) {
|
|
57
|
+
try { unlinkSync(tempPath); } catch {}
|
|
58
|
+
throw e;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function loadStore() {
|
|
63
|
+
if (!existsSync(STORE_FILE)) return emptyStore();
|
|
64
|
+
let raw;
|
|
65
|
+
try {
|
|
66
|
+
raw = readFileSync(STORE_FILE, "utf-8");
|
|
67
|
+
} catch {
|
|
68
|
+
return emptyStore();
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const data = JSON.parse(raw);
|
|
72
|
+
if (!data || typeof data !== "object" || !data.profiles) {
|
|
73
|
+
backupCorruptStore(raw, "shape-invalid");
|
|
74
|
+
return emptyStore();
|
|
75
|
+
}
|
|
76
|
+
if (data.version !== STORE_VERSION) {
|
|
77
|
+
// Future: migration logic. For now, back up the unrecognized version
|
|
78
|
+
// before falling back to empty so the old data is recoverable.
|
|
79
|
+
backupCorruptStore(raw, `version-${data.version}`);
|
|
80
|
+
return emptyStore();
|
|
81
|
+
}
|
|
82
|
+
return data;
|
|
83
|
+
} catch {
|
|
84
|
+
backupCorruptStore(raw, "json-parse-error");
|
|
85
|
+
return emptyStore();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function backupCorruptStore(raw, reasonTag) {
|
|
90
|
+
try {
|
|
91
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
92
|
+
const backupPath = `${STORE_FILE}.bak.${reasonTag}.${stamp}`;
|
|
93
|
+
writeFileSync(backupPath, raw);
|
|
94
|
+
if (platform() === "darwin" || platform() === "linux") {
|
|
95
|
+
try { chmodSync(backupPath, 0o600); } catch {}
|
|
96
|
+
}
|
|
97
|
+
} catch {
|
|
98
|
+
// Backup is best-effort; do not throw on backup failure.
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function saveStore(store) {
|
|
103
|
+
atomicWriteSync(STORE_FILE, JSON.stringify(store, null, 2));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function structuredKeysFor(workflowKind) {
|
|
107
|
+
return STRUCTURED_KEYS_BY_KIND[workflowKind] || STRUCTURED_KEYS_BY_KIND.custom;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function validateProfile(input) {
|
|
111
|
+
const errors = [];
|
|
112
|
+
if (!input || typeof input !== "object") {
|
|
113
|
+
return { valid: false, errors: ["profile must be an object"] };
|
|
114
|
+
}
|
|
115
|
+
if (!input.profile_name || typeof input.profile_name !== "string" || !input.profile_name.trim()) {
|
|
116
|
+
errors.push("profile_name is required (non-empty string)");
|
|
117
|
+
}
|
|
118
|
+
if (!input.workflow_kind || !ALLOWED_WORKFLOW_KINDS.has(input.workflow_kind)) {
|
|
119
|
+
errors.push(`workflow_kind must be one of: ${Array.from(ALLOWED_WORKFLOW_KINDS).join(", ")}`);
|
|
120
|
+
}
|
|
121
|
+
if (input.channels && (!Array.isArray(input.channels) || input.channels.some((c) => typeof c !== "string"))) {
|
|
122
|
+
errors.push("channels must be an array of strings (Slack channel IDs)");
|
|
123
|
+
}
|
|
124
|
+
if (input.priority_people && (!Array.isArray(input.priority_people) || input.priority_people.some((p) => typeof p !== "string"))) {
|
|
125
|
+
errors.push("priority_people must be an array of strings (Slack user IDs)");
|
|
126
|
+
}
|
|
127
|
+
if (input.retention_mode && !ALLOWED_RETENTION_MODES.has(input.retention_mode)) {
|
|
128
|
+
errors.push(`retention_mode must be one of: ${Array.from(ALLOWED_RETENTION_MODES).join(", ")}`);
|
|
129
|
+
}
|
|
130
|
+
if (input.summary_cadence && !ALLOWED_SUMMARY_CADENCES.has(input.summary_cadence)) {
|
|
131
|
+
errors.push(`summary_cadence must be one of: ${Array.from(ALLOWED_SUMMARY_CADENCES).join(", ")}`);
|
|
132
|
+
}
|
|
133
|
+
return { valid: errors.length === 0, errors };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function saveProfile(input) {
|
|
137
|
+
const { valid, errors } = validateProfile(input);
|
|
138
|
+
if (!valid) {
|
|
139
|
+
return { ok: false, errors };
|
|
140
|
+
}
|
|
141
|
+
const store = loadStore();
|
|
142
|
+
const now = new Date().toISOString();
|
|
143
|
+
const existing = store.profiles[input.profile_name];
|
|
144
|
+
const profile = {
|
|
145
|
+
workflow_kind: input.workflow_kind,
|
|
146
|
+
channels: Array.isArray(input.channels) ? [...input.channels] : [],
|
|
147
|
+
priority_people: Array.isArray(input.priority_people) ? [...input.priority_people] : [],
|
|
148
|
+
retention_mode: input.retention_mode || "ephemeral",
|
|
149
|
+
summary_cadence: input.summary_cadence || "on_demand",
|
|
150
|
+
structured_keys: structuredKeysFor(input.workflow_kind),
|
|
151
|
+
created_at: existing && existing.created_at ? existing.created_at : now,
|
|
152
|
+
updated_at: now,
|
|
153
|
+
};
|
|
154
|
+
store.profiles[input.profile_name] = profile;
|
|
155
|
+
saveStore(store);
|
|
156
|
+
return { ok: true, profile_name: input.profile_name, profile };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function listProfiles({ workflow_kind } = {}) {
|
|
160
|
+
const store = loadStore();
|
|
161
|
+
const entries = Object.entries(store.profiles).map(([name, profile]) => ({ profile_name: name, ...profile }));
|
|
162
|
+
if (workflow_kind) {
|
|
163
|
+
if (!ALLOWED_WORKFLOW_KINDS.has(workflow_kind)) {
|
|
164
|
+
return { ok: false, errors: [`workflow_kind filter must be one of: ${Array.from(ALLOWED_WORKFLOW_KINDS).join(", ")}`] };
|
|
165
|
+
}
|
|
166
|
+
return { ok: true, profiles: entries.filter((p) => p.workflow_kind === workflow_kind) };
|
|
167
|
+
}
|
|
168
|
+
return { ok: true, profiles: entries };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function deleteProfile(profile_name) {
|
|
172
|
+
const store = loadStore();
|
|
173
|
+
if (!store.profiles[profile_name]) {
|
|
174
|
+
return { ok: false, errors: [`profile_name "${profile_name}" not found`] };
|
|
175
|
+
}
|
|
176
|
+
delete store.profiles[profile_name];
|
|
177
|
+
saveStore(store);
|
|
178
|
+
return { ok: true, profile_name };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function getProfile(profile_name) {
|
|
182
|
+
const store = loadStore();
|
|
183
|
+
const profile = store.profiles[profile_name];
|
|
184
|
+
if (!profile) return null;
|
|
185
|
+
return { profile_name, ...profile };
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export const ALLOWED_WORKFLOW_KINDS_LIST = Array.from(ALLOWED_WORKFLOW_KINDS);
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jtalk22/slack-mcp",
|
|
3
3
|
"mcpName": "io.github.jtalk22/slack-mcp-server",
|
|
4
|
-
"version": "4.1
|
|
5
|
-
"description": "Slack MCP without OAuth
|
|
4
|
+
"version": "4.2.1",
|
|
5
|
+
"description": "Slack MCP without OAuth. 21 tools (16 read/write Slack + 2 workflow profile primitives + 3 hosted-brain upgrade stubs). Free OSS or hosted (free tier no card; $9/mo Pro = unlimited; morning DM rolling out Q2 2026).",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "src/server.js",
|
|
8
8
|
"bin": {
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
},
|
|
91
91
|
"dependencies": {
|
|
92
92
|
"@modelcontextprotocol/sdk": "^1.27.0",
|
|
93
|
-
"express": "^
|
|
93
|
+
"express": "^5.2.1"
|
|
94
94
|
},
|
|
95
95
|
"files": [
|
|
96
96
|
"src/",
|
|
@@ -99,9 +99,12 @@
|
|
|
99
99
|
"public/share.html",
|
|
100
100
|
"scripts/setup-wizard.js",
|
|
101
101
|
"scripts/token-cli.js",
|
|
102
|
+
"scripts/apply-template.js",
|
|
103
|
+
"templates/workflow-profiles/",
|
|
102
104
|
"docs/SETUP.md",
|
|
103
105
|
"docs/API.md",
|
|
104
106
|
"docs/TROUBLESHOOTING.md",
|
|
107
|
+
"docs/DEPLOYMENT-MODES.md",
|
|
105
108
|
"docs/assets/icon.svg",
|
|
106
109
|
"docs/assets/icon-512.png",
|
|
107
110
|
"README.md",
|
package/public/index.html
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Slack MCP Server — Web Dashboard</title>
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=Space+Grotesk:wght@500;600;700&display=swap">
|
|
7
10
|
<style>
|
|
8
|
-
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=Space+Grotesk:wght@500;600;700&display=swap');
|
|
9
|
-
|
|
10
11
|
:root {
|
|
11
12
|
--font-heading: "Space Grotesk", "Avenir Next", "Segoe UI", sans-serif;
|
|
12
13
|
--font-body: "IBM Plex Sans", "Inter", "Segoe UI", sans-serif;
|
package/public/share.html
CHANGED
|
@@ -4,17 +4,17 @@
|
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<title>Slack MCP Server</title>
|
|
7
|
-
<meta name="description" content="No OAuth. No admin.
|
|
7
|
+
<meta name="description" content="No OAuth. No admin. 21 Slack tools for Claude, Cursor, Copilot, Gemini, and any MCP client. One command: npx -y @jtalk22/slack-mcp --setup">
|
|
8
8
|
<meta property="og:type" content="website">
|
|
9
9
|
<meta property="og:title" content="Slack MCP Server — No OAuth, no admin, just your browser session">
|
|
10
|
-
<meta property="og:description" content="Slack's official MCP needs OAuth + admin. This one uses your browser session.
|
|
10
|
+
<meta property="og:description" content="Slack's official MCP needs OAuth + admin. This one uses your browser session. 21 tools, works with Claude, Cursor, Copilot, Gemini.">
|
|
11
11
|
<meta property="og:url" content="https://jtalk22.github.io/slack-mcp-server/public/share.html">
|
|
12
12
|
<meta property="og:image" content="https://jtalk22.github.io/slack-mcp-server/docs/images/social-preview-v3.png">
|
|
13
13
|
<meta property="og:image:width" content="1280">
|
|
14
14
|
<meta property="og:image:height" content="640">
|
|
15
15
|
<meta name="twitter:card" content="summary_large_image">
|
|
16
16
|
<meta name="twitter:title" content="Slack MCP Server — No OAuth, no admin, just your browser session">
|
|
17
|
-
<meta name="twitter:description" content="
|
|
17
|
+
<meta name="twitter:description" content="21 tools for Claude, Cursor, Copilot, Gemini. npx -y @jtalk22/slack-mcp --setup">
|
|
18
18
|
<meta name="twitter:image" content="https://jtalk22.github.io/slack-mcp-server/docs/images/social-preview-v3.png">
|
|
19
19
|
<link rel="icon" href="https://jtalk22.github.io/slack-mcp-server/docs/assets/icon-512.png" type="image/png">
|
|
20
20
|
<style>
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
<body>
|
|
108
108
|
<main class="wrap">
|
|
109
109
|
<h1>Slack MCP Server</h1>
|
|
110
|
-
<p class="sub">Give Claude full access to your Slack. Self-host
|
|
110
|
+
<p class="sub">Give Claude full access to your Slack. Self-host 21 tools for free (16 read/write + 2 workflow profile primitives + 3 paid stubs that point at hosted). Hosted free tier — workflow continuity + AI catch-up. Sign up no card at <a href="https://mcp.revasserlabs.com">mcp.revasserlabs.com</a>.</p>
|
|
111
111
|
|
|
112
112
|
<a class="preview" href="https://github.com/jtalk22/slack-mcp-server" rel="noopener">
|
|
113
113
|
<img src="https://jtalk22.github.io/slack-mcp-server/docs/images/social-preview-v3.png" alt="Slack MCP Server social preview card">
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
<a href="https://mcp.revasserlabs.com" rel="noopener" style="background:rgba(240,194,70,0.18);border-color:rgba(240,194,70,0.45);color:#f0c246">Hosted</a>
|
|
124
124
|
</div>
|
|
125
125
|
|
|
126
|
-
<p class="note"><strong>Verify in 30 seconds:</strong> <code>--version</code>, <code>--doctor</code>, <code>--status</code>. Self-host gives
|
|
126
|
+
<p class="note"><strong>Verify in 30 seconds:</strong> <code>--version</code>, <code>--doctor</code>, <code>--status</code>. Self-host gives 21 tools with session-based auth. Works with any MCP client — Claude, ChatGPT, Cursor, Copilot, Gemini, Windsurf. Hosted free tier (no card) live at <a href="https://mcp.revasserlabs.com">mcp.revasserlabs.com</a> — Pro $9/mo unlocks unlimited AI tools (scheduled morning catch-up DM rolling out Q2 2026).</p>
|
|
127
127
|
</main>
|
|
128
128
|
</body>
|
|
129
129
|
</html>
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Apply a workflow profile template to ~/.slack-mcp-workflows.json
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* slack-mcp --apply-template <template-name>
|
|
7
|
+
* slack-mcp --apply-template <template-name> --channels C012,C067 [--priority-people U0PRIME]
|
|
8
|
+
*
|
|
9
|
+
* Templates ship in templates/workflow-profiles/. Available templates:
|
|
10
|
+
* oncall-handoff, support-triage, exec-monday, sprint-tracker,
|
|
11
|
+
* customer-feedback, incident-room
|
|
12
|
+
*
|
|
13
|
+
* If --channels is not provided, the template is applied with empty
|
|
14
|
+
* channels — you can add them later via slack_workflow_save.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { readFileSync, existsSync, readdirSync } from "fs";
|
|
18
|
+
import { dirname, join } from "path";
|
|
19
|
+
import { fileURLToPath } from "url";
|
|
20
|
+
import { saveProfile } from "../lib/workflow-store.js";
|
|
21
|
+
|
|
22
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const TEMPLATES_DIR = join(__dirname, "..", "templates", "workflow-profiles");
|
|
24
|
+
|
|
25
|
+
const args = process.argv.slice(2);
|
|
26
|
+
|
|
27
|
+
function listTemplates() {
|
|
28
|
+
if (!existsSync(TEMPLATES_DIR)) return [];
|
|
29
|
+
return readdirSync(TEMPLATES_DIR)
|
|
30
|
+
.filter((f) => f.endsWith(".json"))
|
|
31
|
+
.map((f) => f.replace(/\.json$/, ""));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function printUsage() {
|
|
35
|
+
console.log("Usage: slack-mcp --apply-template <template-name> [--channels C012,C067] [--priority-people U0PRIME,U0SECONDARY] [--profile-name custom-name]");
|
|
36
|
+
console.log("");
|
|
37
|
+
console.log("Available templates:");
|
|
38
|
+
for (const t of listTemplates()) {
|
|
39
|
+
console.log(" " + t);
|
|
40
|
+
}
|
|
41
|
+
console.log("");
|
|
42
|
+
console.log("Example:");
|
|
43
|
+
console.log(" slack-mcp --apply-template support-triage --channels C012345,C067890");
|
|
44
|
+
console.log("");
|
|
45
|
+
console.log("Templates write to ~/.slack-mcp-workflows.json. The hosted AI brain at");
|
|
46
|
+
console.log("mcp.revasserlabs.com (free tier or Pro $9/mo) reads these profiles and");
|
|
47
|
+
console.log("returns structured JSON per the workflow_kind. The OSS package ships the");
|
|
48
|
+
console.log("profile primitives + 3 discoverable upgrade stubs (slack_smart_search,");
|
|
49
|
+
console.log("slack_catch_me_up, slack_triage). The brain is hosted-only.");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function parseFlag(flag) {
|
|
53
|
+
const idx = args.indexOf(flag);
|
|
54
|
+
if (idx === -1) return null;
|
|
55
|
+
return args[idx + 1];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const templateName = args[0];
|
|
59
|
+
if (!templateName || templateName === "--help" || templateName === "-h") {
|
|
60
|
+
printUsage();
|
|
61
|
+
process.exit(templateName ? 0 : 1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (templateName.startsWith("--") || templateName.startsWith("-")) {
|
|
65
|
+
console.error(`Missing template name. Got "${templateName}" as the first positional argument.`);
|
|
66
|
+
console.error("");
|
|
67
|
+
printUsage();
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const templatePath = join(TEMPLATES_DIR, `${templateName}.json`);
|
|
72
|
+
if (!existsSync(templatePath)) {
|
|
73
|
+
console.error(`Template "${templateName}" not found at ${templatePath}`);
|
|
74
|
+
console.error("");
|
|
75
|
+
console.error("Available templates: " + listTemplates().join(", "));
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let template;
|
|
80
|
+
try {
|
|
81
|
+
template = JSON.parse(readFileSync(templatePath, "utf-8"));
|
|
82
|
+
} catch (err) {
|
|
83
|
+
console.error(`Failed to parse template "${templateName}": ${err.message}`);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const channelsArg = parseFlag("--channels");
|
|
88
|
+
const priorityArg = parseFlag("--priority-people");
|
|
89
|
+
const profileNameOverride = parseFlag("--profile-name");
|
|
90
|
+
|
|
91
|
+
const profile = {
|
|
92
|
+
profile_name: profileNameOverride || template.profile_name,
|
|
93
|
+
workflow_kind: template.workflow_kind,
|
|
94
|
+
channels: channelsArg ? channelsArg.split(",").map((s) => s.trim()).filter(Boolean) : (template.channels || []),
|
|
95
|
+
priority_people: priorityArg ? priorityArg.split(",").map((s) => s.trim()).filter(Boolean) : (template.priority_people || []),
|
|
96
|
+
retention_mode: template.retention_mode || "ephemeral",
|
|
97
|
+
summary_cadence: template.summary_cadence || "on_demand",
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const result = saveProfile(profile);
|
|
101
|
+
if (!result.ok) {
|
|
102
|
+
console.error("Failed to save profile:");
|
|
103
|
+
for (const err of result.errors) console.error(" " + err);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
console.log(`Saved workflow profile "${result.profile_name}" to ~/.slack-mcp-workflows.json`);
|
|
108
|
+
console.log(JSON.stringify(result.profile, null, 2));
|
|
109
|
+
console.log("");
|
|
110
|
+
if (!profile.channels.length) {
|
|
111
|
+
console.log("Note: no channels set. Add channels with:");
|
|
112
|
+
console.log(` slack-mcp --apply-template ${templateName} --channels C012345,C067890`);
|
|
113
|
+
console.log("Or call slack_workflow_save from your MCP client to update.");
|
|
114
|
+
} else {
|
|
115
|
+
console.log("Profile is ready. Run slack_catch_me_up against it from your MCP client.");
|
|
116
|
+
console.log(`(Free tier: 3 catch_me_up calls/month. Pro $9/mo unlocks unlimited; scheduled morning DM rolling out Q2 2026.)`);
|
|
117
|
+
}
|
package/scripts/setup-wizard.js
CHANGED
|
@@ -148,6 +148,9 @@ async function runMacOSSetup(rl) {
|
|
|
148
148
|
print(" 1. Chrome is running");
|
|
149
149
|
print(" 2. You have a Slack tab open (app.slack.com)");
|
|
150
150
|
print(" 3. You're logged into that workspace");
|
|
151
|
+
print();
|
|
152
|
+
print(`${colors.dim}Chrome-free or non-macOS? Hosted tier bypasses Chrome entirely:${colors.reset}`);
|
|
153
|
+
print(`${colors.dim} https://mcp.revasserlabs.com${colors.reset}`);
|
|
151
154
|
}
|
|
152
155
|
print();
|
|
153
156
|
|
|
@@ -283,6 +286,9 @@ async function runManualSetup(rl) {
|
|
|
283
286
|
print(" • Tokens expired - try refreshing Slack and copying again");
|
|
284
287
|
print(" • Wrong workspace - make sure you copied from the right tab");
|
|
285
288
|
print(" • Incomplete copy - ensure you got the full token/cookie");
|
|
289
|
+
print();
|
|
290
|
+
print(`${colors.dim}Tired of paste-the-token loops? Hosted tier uses OAuth:${colors.reset}`);
|
|
291
|
+
print(`${colors.dim} https://mcp.revasserlabs.com${colors.reset}`);
|
|
286
292
|
return false;
|
|
287
293
|
}
|
|
288
294
|
|
|
@@ -402,6 +408,9 @@ async function runDoctor() {
|
|
|
402
408
|
print();
|
|
403
409
|
print("Next action:");
|
|
404
410
|
print(" npx -y @jtalk22/slack-mcp --setup");
|
|
411
|
+
print();
|
|
412
|
+
print(`${colors.dim}Prefer no local tokens? Hosted tier uses OAuth:${colors.reset}`);
|
|
413
|
+
print(`${colors.dim} https://mcp.revasserlabs.com${colors.reset}`);
|
|
405
414
|
process.exit(1);
|
|
406
415
|
}
|
|
407
416
|
|
|
@@ -424,6 +433,9 @@ async function runDoctor() {
|
|
|
424
433
|
print("Next action:");
|
|
425
434
|
if (exitCode === 2) {
|
|
426
435
|
print(" npx -y @jtalk22/slack-mcp --setup");
|
|
436
|
+
print();
|
|
437
|
+
print(`${colors.dim}Tokens expire every 1-2 weeks. Hosted tier has permanent OAuth:${colors.reset}`);
|
|
438
|
+
print(`${colors.dim} https://mcp.revasserlabs.com${colors.reset}`);
|
|
427
439
|
} else {
|
|
428
440
|
print(" Check network connectivity and retry:");
|
|
429
441
|
print(" npx -y @jtalk22/slack-mcp --doctor");
|
|
@@ -460,6 +472,10 @@ async function showHelp() {
|
|
|
460
472
|
print();
|
|
461
473
|
print(`${colors.bold}More info:${colors.reset}`);
|
|
462
474
|
print(" https://github.com/jtalk22/slack-mcp-server");
|
|
475
|
+
print();
|
|
476
|
+
print(`${colors.bold}Hosted tier:${colors.reset}`);
|
|
477
|
+
print(" https://mcp.revasserlabs.com — $9/mo Pro, permanent OAuth,");
|
|
478
|
+
print(" semantic search, workflow continuity across channels.");
|
|
463
479
|
}
|
|
464
480
|
|
|
465
481
|
async function main() {
|
|
@@ -530,6 +546,9 @@ async function main() {
|
|
|
530
546
|
print(" • Verify: npx -y @jtalk22/slack-mcp --status");
|
|
531
547
|
print(" • Start server: npx -y @jtalk22/slack-mcp");
|
|
532
548
|
print(" • Or add to Claude Desktop config");
|
|
549
|
+
print();
|
|
550
|
+
print(`${colors.dim}Want permanent tokens, semantic search, and workflow continuity?${colors.reset}`);
|
|
551
|
+
print(`${colors.dim}Hosted tier: https://mcp.revasserlabs.com — $9/mo Pro, 10 free paid calls.${colors.reset}`);
|
|
533
552
|
} else {
|
|
534
553
|
print(`${colors.red}Setup failed.${colors.reset} See errors above.`);
|
|
535
554
|
process.exit(1);
|
package/server.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
3
|
"name": "io.github.jtalk22/slack-mcp-server",
|
|
4
4
|
"title": "Slack MCP Server",
|
|
5
|
-
"description": "Slack MCP without OAuth
|
|
5
|
+
"description": "Slack MCP without OAuth. 21 tools (16 read/write Slack + 2 workflow profile primitives + 3 hosted-brain upgrade stubs). Free OSS or hosted (free tier no card; $9/mo Pro = unlimited; morning DM rolling out Q2 2026).",
|
|
6
6
|
"websiteUrl": "https://mcp.revasserlabs.com",
|
|
7
7
|
"icons": [
|
|
8
8
|
{
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"url": "https://github.com/jtalk22/slack-mcp-server",
|
|
18
18
|
"source": "github"
|
|
19
19
|
},
|
|
20
|
-
"version": "4.1
|
|
20
|
+
"version": "4.2.1",
|
|
21
21
|
"remotes": [
|
|
22
22
|
{
|
|
23
23
|
"type": "streamable-http",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
{
|
|
29
29
|
"registryType": "npm",
|
|
30
30
|
"identifier": "@jtalk22/slack-mcp",
|
|
31
|
-
"version": "4.1
|
|
31
|
+
"version": "4.2.1",
|
|
32
32
|
"transport": {
|
|
33
33
|
"type": "stdio"
|
|
34
34
|
},
|
package/smithery.yaml
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Smithery configuration for slack-mcp-server
|
|
2
2
|
# https://smithery.ai/docs/build/project-config/smithery-yaml
|
|
3
|
+
# Slack MCP — free OSS or hosted (free tier + $9/mo Pro). 21 tools:
|
|
4
|
+
# read/write Slack + workflow profile primitives + AI brain via hosted upgrade.
|
|
3
5
|
|
|
4
6
|
startCommand:
|
|
5
7
|
type: stdio
|
package/src/cli.js
CHANGED
|
@@ -34,6 +34,9 @@ if (firstArg === "web") {
|
|
|
34
34
|
} else if (firstArg === "http") {
|
|
35
35
|
scriptPath = join(__dirname, "server-http.js");
|
|
36
36
|
scriptArgs = args.slice(1);
|
|
37
|
+
} else if (firstArg === "--apply-template" || firstArg === "apply-template") {
|
|
38
|
+
scriptPath = join(__dirname, "../scripts/apply-template.js");
|
|
39
|
+
scriptArgs = args.slice(1);
|
|
37
40
|
} else if (WIZARD_ARGS.has(firstArg)) {
|
|
38
41
|
scriptPath = join(__dirname, "../scripts/setup-wizard.js");
|
|
39
42
|
scriptArgs = args;
|
package/src/server.js
CHANGED
|
@@ -46,6 +46,11 @@ import {
|
|
|
46
46
|
handleConversationsMark,
|
|
47
47
|
handleConversationsUnreads,
|
|
48
48
|
handleUsersSearch,
|
|
49
|
+
handleWorkflowSave,
|
|
50
|
+
handleWorkflows,
|
|
51
|
+
handleSmartSearch,
|
|
52
|
+
handleCatchMeUp,
|
|
53
|
+
handleTriage,
|
|
49
54
|
} from "../lib/handlers.js";
|
|
50
55
|
|
|
51
56
|
// Background refresh interval (4 hours)
|
|
@@ -275,6 +280,23 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
275
280
|
case "slack_users_search":
|
|
276
281
|
return await handleUsersSearch(args);
|
|
277
282
|
|
|
283
|
+
// Workflow profile primitives (OSS local JSON store)
|
|
284
|
+
case "slack_workflow_save":
|
|
285
|
+
return await handleWorkflowSave(args);
|
|
286
|
+
|
|
287
|
+
case "slack_workflows":
|
|
288
|
+
return await handleWorkflows(args);
|
|
289
|
+
|
|
290
|
+
// Hosted-only AI tools (OSS = upgrade stubs)
|
|
291
|
+
case "slack_smart_search":
|
|
292
|
+
return await handleSmartSearch(args);
|
|
293
|
+
|
|
294
|
+
case "slack_catch_me_up":
|
|
295
|
+
return await handleCatchMeUp(args);
|
|
296
|
+
|
|
297
|
+
case "slack_triage":
|
|
298
|
+
return await handleTriage(args);
|
|
299
|
+
|
|
278
300
|
default:
|
|
279
301
|
return {
|
|
280
302
|
content: [{
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"profile_name": "customer-feedback",
|
|
3
|
+
"workflow_kind": "product_launch_watch",
|
|
4
|
+
"channels": [],
|
|
5
|
+
"priority_people": [],
|
|
6
|
+
"retention_mode": "persistent",
|
|
7
|
+
"summary_cadence": "daily_8am",
|
|
8
|
+
"structured_keys": ["launch_signals", "feedback_themes", "blockers", "metrics", "next_actions"],
|
|
9
|
+
"_template_notes": "Apply with: slack-mcp --apply-template customer-feedback --channels C0FEEDBACK,C0CUSTOMERS,C0SUPPORT. retention_mode=persistent so feedback themes accumulate across days. Weekly synthesis becomes more valuable as the index grows."
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"profile_name": "exec-monday",
|
|
3
|
+
"workflow_kind": "exec_brief",
|
|
4
|
+
"channels": [],
|
|
5
|
+
"priority_people": [],
|
|
6
|
+
"retention_mode": "ephemeral",
|
|
7
|
+
"summary_cadence": "weekly_monday",
|
|
8
|
+
"structured_keys": ["summary", "decisions", "risks", "asks", "action_items"],
|
|
9
|
+
"_template_notes": "Apply with: slack-mcp --apply-template exec-monday --channels C0EXEC,C0PRODUCT,C0OPS --priority-people U0CEO,U0CTO. Weekly Monday cadence requires Pro or Team. Posts a structured brief to your DM at 8am workspace time on Mondays."
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"profile_name": "incident-room",
|
|
3
|
+
"workflow_kind": "incident_room",
|
|
4
|
+
"channels": [],
|
|
5
|
+
"priority_people": [],
|
|
6
|
+
"retention_mode": "persistent",
|
|
7
|
+
"summary_cadence": "on_demand",
|
|
8
|
+
"structured_keys": ["incident_summary", "timeline", "open_risks", "owner_gaps", "next_actions"],
|
|
9
|
+
"_template_notes": "Apply with: slack-mcp --apply-template incident-room --channels C0INCIDENTS --priority-people U0ONCALL. on_demand cadence — call slack_catch_me_up at handoff or before stakeholder updates. retention_mode=persistent so post-incident review has the timeline."
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"profile_name": "oncall-handoff",
|
|
3
|
+
"workflow_kind": "incident_room",
|
|
4
|
+
"channels": [],
|
|
5
|
+
"priority_people": [],
|
|
6
|
+
"retention_mode": "persistent",
|
|
7
|
+
"summary_cadence": "on_demand",
|
|
8
|
+
"structured_keys": ["incident_summary", "timeline", "open_risks", "owner_gaps", "next_actions"],
|
|
9
|
+
"_template_notes": "Apply with: slack-mcp --apply-template oncall-handoff --channels C012345,C067890 --priority-people U0PRIME,U0SECONDARY. retention_mode=persistent so the next responder can see prior incident context. Run slack_catch_me_up against this profile before each handoff."
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"profile_name": "sprint-tracker",
|
|
3
|
+
"workflow_kind": "product_launch_watch",
|
|
4
|
+
"channels": [],
|
|
5
|
+
"priority_people": [],
|
|
6
|
+
"retention_mode": "ephemeral",
|
|
7
|
+
"summary_cadence": "daily_8am",
|
|
8
|
+
"structured_keys": ["launch_signals", "feedback_themes", "blockers", "metrics", "next_actions"],
|
|
9
|
+
"_template_notes": "Apply with: slack-mcp --apply-template sprint-tracker --channels C0SPRINT,C0BUGS,C0LAUNCHES. Use during active release cycles. Returns structured JSON so downstream automation (Linear, Notion, status dashboards) can consume directly."
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"profile_name": "support-triage",
|
|
3
|
+
"workflow_kind": "support_inbox",
|
|
4
|
+
"channels": [],
|
|
5
|
+
"priority_people": [],
|
|
6
|
+
"retention_mode": "ephemeral",
|
|
7
|
+
"summary_cadence": "daily_8am",
|
|
8
|
+
"structured_keys": ["open_threads", "ack_lag", "owner_gaps", "escalations", "next_actions"],
|
|
9
|
+
"_template_notes": "Apply with: slack-mcp --apply-template support-triage --channels C0SUPPORT,C0ESCALATIONS. summary_cadence=daily_8am needs Pro or Team for the scheduled morning DM (rolling out Q2 2026). Free tier can run on_demand."
|
|
10
|
+
}
|