bn-slack-mcp-server 0.0.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.
Files changed (71) hide show
  1. package/README.md +243 -0
  2. package/dist/debug-middleware.d.ts +12 -0
  3. package/dist/debug-middleware.d.ts.map +1 -0
  4. package/dist/debug-middleware.js +36 -0
  5. package/dist/debug-middleware.js.map +1 -0
  6. package/dist/helpers.d.ts +86 -0
  7. package/dist/helpers.d.ts.map +1 -0
  8. package/dist/helpers.js +235 -0
  9. package/dist/helpers.js.map +1 -0
  10. package/dist/index.d.ts +9 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +162 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/schemas.d.ts +286 -0
  15. package/dist/schemas.d.ts.map +1 -0
  16. package/dist/schemas.js +840 -0
  17. package/dist/schemas.js.map +1 -0
  18. package/dist/slack-api-client.d.ts +51 -0
  19. package/dist/slack-api-client.d.ts.map +1 -0
  20. package/dist/slack-api-client.js +227 -0
  21. package/dist/slack-api-client.js.map +1 -0
  22. package/dist/tool-loader.d.ts +35 -0
  23. package/dist/tool-loader.d.ts.map +1 -0
  24. package/dist/tool-loader.js +121 -0
  25. package/dist/tool-loader.js.map +1 -0
  26. package/dist/tool-registry.d.ts +44 -0
  27. package/dist/tool-registry.d.ts.map +1 -0
  28. package/dist/tool-registry.js +56 -0
  29. package/dist/tool-registry.js.map +1 -0
  30. package/dist/tools/cache.d.ts +69 -0
  31. package/dist/tools/cache.d.ts.map +1 -0
  32. package/dist/tools/cache.js +94 -0
  33. package/dist/tools/cache.js.map +1 -0
  34. package/dist/tools/channels.d.ts +76 -0
  35. package/dist/tools/channels.d.ts.map +1 -0
  36. package/dist/tools/channels.js +251 -0
  37. package/dist/tools/channels.js.map +1 -0
  38. package/dist/tools/conversations.d.ts +77 -0
  39. package/dist/tools/conversations.d.ts.map +1 -0
  40. package/dist/tools/conversations.js +302 -0
  41. package/dist/tools/conversations.js.map +1 -0
  42. package/dist/tools/files.d.ts +15 -0
  43. package/dist/tools/files.d.ts.map +1 -0
  44. package/dist/tools/files.js +30 -0
  45. package/dist/tools/files.js.map +1 -0
  46. package/dist/tools/index.d.ts +12 -0
  47. package/dist/tools/index.d.ts.map +1 -0
  48. package/dist/tools/index.js +20 -0
  49. package/dist/tools/index.js.map +1 -0
  50. package/dist/tools/messages.d.ts +20 -0
  51. package/dist/tools/messages.d.ts.map +1 -0
  52. package/dist/tools/messages.js +40 -0
  53. package/dist/tools/messages.js.map +1 -0
  54. package/dist/tools/system.d.ts +48 -0
  55. package/dist/tools/system.d.ts.map +1 -0
  56. package/dist/tools/system.js +124 -0
  57. package/dist/tools/system.js.map +1 -0
  58. package/dist/tools/users.d.ts +69 -0
  59. package/dist/tools/users.d.ts.map +1 -0
  60. package/dist/tools/users.js +179 -0
  61. package/dist/tools/users.js.map +1 -0
  62. package/dist/tools/workspace.d.ts +50 -0
  63. package/dist/tools/workspace.d.ts.map +1 -0
  64. package/dist/tools/workspace.js +56 -0
  65. package/dist/tools/workspace.js.map +1 -0
  66. package/dist/types.d.ts +160 -0
  67. package/dist/types.d.ts.map +1 -0
  68. package/dist/types.js +2 -0
  69. package/dist/types.js.map +1 -0
  70. package/package.json +48 -0
  71. package/tools.json +483 -0
@@ -0,0 +1,840 @@
1
+ /**
2
+ * Zod schemas for Slack MCP Server tools
3
+ *
4
+ * Each schema includes comprehensive .describe() documentation for LLM-friendly usage.
5
+ * Descriptions include: use cases, examples, parameter relationships, and best practices.
6
+ */
7
+ import { z } from "zod";
8
+ // ============================================================================
9
+ // Conversation Tools (5)
10
+ // ============================================================================
11
+ export const ConversationsHistorySchema = z.object({
12
+ channel_id: z.string().describe(`The Slack channel or direct message to fetch messages from.
13
+
14
+ **Accepted Formats:**
15
+ 1. **Channel ID** (recommended for reliability):
16
+ - Public channels: C followed by 10 alphanumeric chars (e.g., "C01ABC2DEF3")
17
+ - Private channels: C or G followed by 10 chars (e.g., "G01ABC2DEF3")
18
+ - Direct messages: D followed by 10 chars (e.g., "D01ABC2DEF3")
19
+ - Group DMs: G followed by 10 chars
20
+
21
+ 2. **Channel Name** (auto-resolved to ID):
22
+ - "#general" - Public channel named "general"
23
+ - "#engineering-team" - Channel with hyphenated name
24
+ - "#project-alpha-2024" - Any public/private channel name
25
+
26
+ 3. **DM Shortcut** (opens/finds DM with user):
27
+ - "@john" - DM with user named john
28
+ - "@john_dm" - Alternative DM format
29
+ - "@john.smith" - User with period in name
30
+
31
+ **How to Find Channel IDs:**
32
+ - Use \`channels_list\` tool with channel_types="public_channel,private_channel"
33
+ - From Slack URL: https://workspace.slack.com/archives/C01ABC2DEF3 → "C01ABC2DEF3"
34
+ - In Slack app: Right-click channel → "Copy link" → extract ID from URL
35
+
36
+ **Best Practice:** Use channel IDs for reliability; names may change.`),
37
+ limit: z.string().optional().default("1d").describe(`Controls how many messages to retrieve. Accepts time-based OR numeric formats.
38
+
39
+ **Time-Based Limits (Recommended for recent messages):**
40
+ - "1d" - Messages from the last 1 day (DEFAULT)
41
+ - "2d" - Messages from the last 2 days
42
+ - "1w" - Messages from the last 7 days (1 week)
43
+ - "2w" - Messages from the last 14 days
44
+ - "30d" - Messages from the last 30 days
45
+ - "90d" - Messages from the last 90 days
46
+
47
+ **Numeric Limits (For fixed count):**
48
+ - "10" - Last 10 messages
49
+ - "50" - Last 50 messages
50
+ - "100" - Last 100 messages
51
+ - "500" - Last 500 messages
52
+ - "1000" - Maximum 1000 messages (API limit)
53
+
54
+ **Choosing the Right Limit:**
55
+ - For daily standups/recent activity: "1d" or "2d"
56
+ - For weekly summaries: "1w"
57
+ - For project retrospectives: "30d"
58
+ - For specific message count: Use numeric like "50"
59
+ - For high-traffic channels: Use time-based to avoid overwhelming data
60
+
61
+ **Note:** Time-based limits internally set limit=1000 with oldest timestamp filter.`),
62
+ include_activity_messages: z.boolean().optional().default(false).describe(`Whether to include system/activity messages in the response.
63
+
64
+ **When false (DEFAULT):** Only user-posted messages are returned. Best for:
65
+ - Reading actual conversations
66
+ - Summarizing discussions
67
+ - Searching for specific content
68
+
69
+ **When true:** Includes system messages like:
70
+ - "john joined the channel"
71
+ - "jane left the channel"
72
+ - "Channel topic changed to: Q4 Planning"
73
+ - "Channel purpose updated"
74
+ - Bot integration messages
75
+ - App notifications
76
+
77
+ **Use Cases for true:**
78
+ - Auditing channel membership changes
79
+ - Tracking when users joined/left
80
+ - Understanding channel timeline including config changes`),
81
+ include_user_details: z.boolean().optional().default(true).describe(`Whether to enrich each message with detailed user information.
82
+
83
+ **When true (DEFAULT):** Each message includes user_details object:
84
+ {
85
+ "user": "U01ABC2DEF3",
86
+ "user_details": {
87
+ "username": "john.smith",
88
+ "real_name": "John Smith",
89
+ "display_name": "John",
90
+ "is_bot": false
91
+ }
92
+ }
93
+
94
+ **Benefits:**
95
+ - Immediately see WHO sent each message
96
+ - No need for separate user_info calls
97
+ - Useful for generating readable summaries
98
+
99
+ **When false:** Only user ID is included (e.g., "user": "U01ABC2DEF3")
100
+ - Faster response
101
+ - Smaller payload
102
+ - Use when you only need message content`),
103
+ cursor: z.string().optional().describe(`Pagination cursor for fetching additional messages beyond the first page.
104
+
105
+ **How Pagination Works:**
106
+ 1. First call: Don't provide cursor
107
+ 2. Check response: Look for "has_more": true and "next_cursor": "dXNlc..."
108
+ 3. Next call: Pass the next_cursor value as cursor parameter
109
+ 4. Repeat until has_more is false
110
+
111
+ **Example Flow:**
112
+ Call 1: conversations_history(channel_id="#general", limit="100")
113
+ Response: { messages: [...100...], has_more: true, next_cursor: "dXNlc..." }
114
+
115
+ Call 2: conversations_history(channel_id="#general", limit="100", cursor="dXNlc...")
116
+ Response: { messages: [...100...], has_more: true, next_cursor: "abc123..." }
117
+
118
+ Call 3: ... continue until has_more: false
119
+
120
+ **Note:** Cursor is typically not needed with time-based limits unless channel is very active.`),
121
+ });
122
+ export const ConversationsRepliesSchema = z.object({
123
+ channel_id: z.string().describe(`The channel containing the thread. Same formats as conversations_history:
124
+ - Channel ID: "C01ABC2DEF3" (recommended)
125
+ - Channel name: "#general", "#engineering"
126
+ - DM: "@username" or "@username_dm"
127
+
128
+ **Important:** The channel_id must match where the thread exists.
129
+ Threads in DMs use the DM channel ID.`),
130
+ thread_ts: z.string().describe(`The timestamp of the parent message (thread starter).
131
+
132
+ **Format:** Unix timestamp with microseconds as a string.
133
+ Example: "1609459200.000100" (6 digits before dot, 6 after)
134
+
135
+ **How to Find thread_ts:**
136
+ 1. From conversations_history response: Look for messages with "reply_count" > 0
137
+ The "ts" field of that message is the thread_ts
138
+
139
+ 2. From Slack URL: https://workspace.slack.com/archives/C01ABC/p1609459200000100
140
+ - Remove 'p' prefix: 1609459200000100
141
+ - Insert decimal: 1609459200.000100
142
+
143
+ 3. From message object: Use the "ts" field of the parent message
144
+
145
+ **Example:**
146
+ Parent message: { "ts": "1609459200.000100", "text": "Let's discuss...", "reply_count": 5 }
147
+ To get replies: conversations_replies(channel_id="C01ABC", thread_ts="1609459200.000100")`),
148
+ limit: z.string().optional().default("1d").describe(`Limit for thread replies. Same format as conversations_history:
149
+ - Time-based: "1d", "1w", "30d"
150
+ - Numeric: "50", "100"
151
+
152
+ Most threads have fewer than 100 replies, so numeric "100" usually gets all.`),
153
+ include_activity_messages: z.boolean().optional().default(false).describe(`Include system messages within the thread (rare in threads).`),
154
+ cursor: z.string().optional().describe(`Pagination cursor for long threads. Use next_cursor from previous response.`),
155
+ });
156
+ export const ConversationsAddMessageSchema = z.object({
157
+ channel_id: z.string().describe(`Where to post the message.
158
+
159
+ **Accepted Formats:**
160
+ - Channel ID: "C01ABC2DEF3" (most reliable)
161
+ - Channel name: "#general", "#announcements"
162
+ - DM to user: "@john" (creates/uses existing DM)
163
+ - DM by ID: "D01ABC2DEF3"
164
+
165
+ **Permissions Required:**
166
+ - Public channels: chat:write scope
167
+ - Private channels: Must be a member + chat:write
168
+ - DMs: im:write scope
169
+
170
+ **Tips:**
171
+ - Use channel IDs to avoid issues with renamed channels
172
+ - For DMs, @username will automatically open the DM conversation`),
173
+ payload: z.string().describe(`The message content to send.
174
+
175
+ **Plain Text:**
176
+ Just type your message: "Hello team!"
177
+
178
+ **Slack Formatting (mrkdwn):**
179
+ - *bold* → **bold text**
180
+ - _italic_ → _italic text_
181
+ - ~strikethrough~ → ~~struck through~~
182
+ - \`code\` → inline code
183
+ - \`\`\`code block\`\`\` → multi-line code
184
+
185
+ **Links:**
186
+ - Auto-linked: https://example.com
187
+ - Named link: <https://example.com|Click here>
188
+
189
+ **Mentions:**
190
+ - User: <@U01ABC2DEF3> or @username (auto-resolved)
191
+ - Channel: <#C01ABC2DEF3> or #channel-name
192
+ - @here: <!here> - notify active members
193
+ - @channel: <!channel> - notify all members
194
+
195
+ **Emojis:**
196
+ - :thumbsup: :rocket: :white_check_mark:
197
+ - Custom workspace emojis work too
198
+
199
+ **Lists:**
200
+ • Bullet point (use • character)
201
+ 1. Numbered list
202
+
203
+ **Example Messages:**
204
+ - Status update: "Deployment complete :white_check_mark:"
205
+ - Question: "Hey <@U01ABC2DEF3>, can you review the PR?"
206
+ - Announcement: "*Important:* Team meeting at 3pm <!here>"`),
207
+ thread_ts: z.string().optional().describe(`Optional: Reply to a specific thread instead of posting a new message.
208
+
209
+ **When to Use:**
210
+ - Replying to a question in a thread
211
+ - Keeping related discussion together
212
+ - Following up on a previous message
213
+
214
+ **Format:** Same as thread_ts in conversations_replies
215
+ Example: "1609459200.000100"
216
+
217
+ **How to Get thread_ts:**
218
+ - From the parent message's "ts" field
219
+ - From conversations_history response
220
+
221
+ **Behavior:**
222
+ - If provided: Posts as reply in that thread
223
+ - If omitted: Posts as new message in channel`),
224
+ content_type: z.string().optional().default("text/markdown").describe(`Content type of the message payload.
225
+
226
+ **Options:**
227
+ - "text/markdown" (DEFAULT): Markdown syntax is converted to Slack mrkdwn
228
+ - **bold** → *bold*
229
+ - __italic__ → _italic_
230
+
231
+ - "text/plain": Message sent as-is without conversion
232
+ - Use when you want literal asterisks
233
+ - Use for pre-formatted content
234
+
235
+ Most use cases should use the default "text/markdown".`),
236
+ });
237
+ export const ConversationsSearchMessagesSchema = z.object({
238
+ search_query: z.string().optional().describe(`The search term(s) to find in messages, OR a Slack message URL.
239
+
240
+ **Simple Text Search:**
241
+ - "quarterly report" - Messages containing these words
242
+ - "bug fix" - Messages about bug fixes
243
+ - "deployment" - Deployment-related messages
244
+
245
+ **Phrase Search (exact match):**
246
+ - "\\"release notes\\"" - Exact phrase
247
+ - "\\"action items\\"" - Exact phrase match
248
+
249
+ **URL Lookup (retrieve specific message):**
250
+ - Paste a Slack message URL directly:
251
+ "https://workspace.slack.com/archives/C01ABC/p1609459200000100"
252
+ - The tool will parse the URL and return that exact message
253
+
254
+ **Combining with Filters:**
255
+ For precise results, combine search_query with filter parameters:
256
+ - search_query="deployment" + filter_in_channel="#engineering"
257
+ - search_query="review" + filter_users_from="@john"
258
+ - search_query="bug" + filter_date_after="2024-01-01"
259
+
260
+ **Note:** Either search_query OR at least one filter is required.`),
261
+ filter_in_channel: z.string().optional().describe(`Restrict search to a specific channel.
262
+
263
+ **Formats:**
264
+ - "#channel-name" - Channel by name
265
+ - "C01ABC2DEF3" - Channel by ID
266
+
267
+ **Examples:**
268
+ - "#engineering" - Only engineering channel
269
+ - "#support" - Only support channel
270
+
271
+ **Use Case:** Find discussions about a topic within a specific team's channel.`),
272
+ filter_in_im_or_mpim: z.string().optional().describe(`Restrict search to a DM or group DM conversation.
273
+
274
+ **Formats:**
275
+ - "@username" - DM with specific user
276
+ - "D01ABC2DEF3" - DM by channel ID
277
+ - "G01ABC2DEF3" - Group DM by ID
278
+
279
+ **Use Case:** Find past discussion with a specific colleague.`),
280
+ filter_users_from: z.string().optional().describe(`Only messages sent BY a specific user.
281
+
282
+ **Formats:**
283
+ - "@john" - Messages from user john
284
+ - "@john.smith" - User with period in name
285
+ - "U01ABC2DEF3" - User by ID
286
+
287
+ **Use Case:**
288
+ - Find all updates posted by a team lead
289
+ - Review what a specific person said about a topic`),
290
+ filter_users_with: z.string().optional().describe(`Messages in conversations that include a specific user.
291
+
292
+ **Formats:** Same as filter_users_from
293
+
294
+ **Difference from filter_users_from:**
295
+ - filter_users_from: Messages SENT BY the user
296
+ - filter_users_with: Messages in channels/DMs WHERE the user is present
297
+
298
+ **Use Case:** Find all conversations a user was part of (even if they didn't send the message).`),
299
+ filter_date_before: z.string().optional().describe(`Messages sent BEFORE this date (exclusive).
300
+
301
+ **Formats:**
302
+ - "2024-01-15" - Before January 15, 2024
303
+ - "2024-12-01" - Before December 1, 2024
304
+ - "yesterday" - Before yesterday
305
+ - "last week" - Before last week started
306
+
307
+ **Examples:**
308
+ - Find old discussions: filter_date_before="2023-01-01"
309
+ - Q4 messages: filter_date_before="2024-01-01" + filter_date_after="2023-10-01"`),
310
+ filter_date_after: z.string().optional().describe(`Messages sent AFTER this date (exclusive).
311
+
312
+ **Formats:**
313
+ - "2024-01-01" - After January 1, 2024
314
+ - "2024-06-15" - After June 15, 2024
315
+ - "yesterday" - After yesterday
316
+ - "last month" - After last month started
317
+
318
+ **Examples:**
319
+ - Recent discussions: filter_date_after="2024-11-01"
320
+ - This year: filter_date_after="2024-01-01"`),
321
+ filter_date_on: z.string().optional().describe(`Messages sent ON a specific date only.
322
+
323
+ **Formats:**
324
+ - "2024-01-15" - On January 15, 2024 only
325
+ - "today" - Today only
326
+ - "yesterday" - Yesterday only
327
+
328
+ **Use Case:** Find what was discussed on a specific day (e.g., day of an incident).`),
329
+ filter_date_during: z.string().optional().describe(`Messages during a named time period.
330
+
331
+ **Formats:**
332
+ - "today" - Today's messages
333
+ - "yesterday" - Yesterday's messages
334
+ - "this week" - Current week
335
+ - "last week" - Previous week
336
+ - "this month" - Current month
337
+ - "last month" - Previous month
338
+ - "January" - During January (current or recent year)
339
+ - "Q4" - Fourth quarter
340
+
341
+ **Examples:**
342
+ - "January" - All January messages
343
+ - "last month" - Previous month's messages`),
344
+ filter_threads_only: z.boolean().optional().default(false).describe(`Only return messages that are part of threads.
345
+
346
+ **When true:** Only returns:
347
+ - Thread parent messages (with replies)
348
+ - Thread reply messages
349
+
350
+ **Use Case:**
351
+ - Find threaded discussions (indicates deeper conversations)
352
+ - Ignore simple announcements without engagement`),
353
+ limit: z.number().optional().default(20).describe(`Maximum number of search results to return.
354
+
355
+ **Range:** 1 to 100
356
+ **Default:** 20
357
+
358
+ **Recommendations:**
359
+ - Quick lookup: 10-20
360
+ - Comprehensive search: 50-100
361
+ - Finding specific message: 10
362
+
363
+ **Note:** Results are sorted by relevance/timestamp.`),
364
+ cursor: z.string().optional().describe(`Pagination cursor for more search results. Use next_cursor from previous response.`),
365
+ });
366
+ export const BulkConversationsHistorySchema = z.object({
367
+ channel_ids: z.string().describe(`Comma-separated list of channels to fetch messages from.
368
+
369
+ **Formats (can be mixed):**
370
+ - "#general, #engineering, #support"
371
+ - "C01ABC, C02DEF, C03GHI"
372
+ - "#general, C01ABC, @john_dm"
373
+
374
+ **Examples:**
375
+ - All team channels: "#frontend, #backend, #devops"
376
+ - Project channels: "#project-alpha, #project-beta"
377
+ - Mix: "#general, @john, C01ABC2DEF3"
378
+
379
+ **Why Use This Instead of Multiple conversations_history Calls:**
380
+ 1. **Performance:** Single cache load for all channels
381
+ 2. **Efficiency:** Better rate limit management
382
+ 3. **Convenience:** Results organized by channel
383
+
384
+ **Response Structure:**
385
+ {
386
+ "channels": [
387
+ { "channel_id": "C01ABC", "messages": [...], "message_count": 50 },
388
+ { "channel_id": "C02DEF", "messages": [...], "message_count": 30 }
389
+ ],
390
+ "summary": { "total_messages": 80, "api_calls": 2 }
391
+ }
392
+
393
+ **Limit:** Reasonable limit is 5-10 channels per call to avoid timeout.`),
394
+ limit: z.string().optional().default("1d").describe(`Message limit PER CHANNEL (not total). Same format as conversations_history:
395
+ - "1d" (DEFAULT) - Last 24 hours from each channel
396
+ - "1w" - Last 7 days from each channel
397
+ - "50" - Last 50 messages from each channel
398
+
399
+ **Tip:** Use time-based limits for consistent date ranges across channels.`),
400
+ include_user_details: z.boolean().optional().default(true).describe(`Enrich messages with user details (name, display_name). Default: true.
401
+
402
+ Uses single cached user lookup for efficiency across all channels.`),
403
+ include_activity_messages: z.boolean().optional().default(false).describe(`Include system/activity messages. Default: false.`),
404
+ filter_user: z.string().optional().describe(`Filter to only return messages from a specific user across ALL channels.
405
+
406
+ **Formats:**
407
+ - "@username" - By username
408
+ - "U01ABC2DEF3" - By user ID
409
+ - "john.doe" - By name (without @)
410
+
411
+ **Use Case:** See all messages from a specific person across multiple channels.
412
+ Great for reviewing someone's updates across the organization.`),
413
+ });
414
+ // ============================================================================
415
+ // User Tools (3)
416
+ // ============================================================================
417
+ export const UsersListSchema = z.object({
418
+ filter_type: z.string().optional().default("active").describe(`Filter users by their account status.
419
+
420
+ **Options:**
421
+ - "active" (DEFAULT) - Users with active accounts (not deleted)
422
+ - Best for: Finding current team members
423
+
424
+ - "deleted" - Only deactivated/deleted users
425
+ - Best for: Auditing removed accounts
426
+
427
+ - "admins" - Only workspace administrators
428
+ - Best for: Finding who has admin privileges
429
+
430
+ - "all" - All users regardless of status
431
+ - Best for: Complete user audit
432
+
433
+ **Note:** This tool always uses cached data (24h TTL) for performance.`),
434
+ include_bots: z.boolean().optional().default(false).describe(`Whether to include bot users in results.
435
+
436
+ **When false (DEFAULT):** Only human users returned
437
+ - Best for: Team member lists
438
+ - Skips Slackbot, integration bots, apps
439
+
440
+ **When true:** Includes all bot accounts
441
+ - Useful for: Auditing installed apps/integrations
442
+ - Bot users have is_bot: true in response`),
443
+ limit: z.number().optional().default(50).describe(`Maximum number of users to return.
444
+
445
+ **Default:** 50
446
+ **Set to 0:** Returns all users (no limit)
447
+
448
+ **Recommendations:**
449
+ - Small team lookup: 20-50
450
+ - Full organization: 0 (unlimited)
451
+ - Quick check: 10-20
452
+
453
+ **Note:** Results come from cache, so large limits are fast.`),
454
+ });
455
+ export const UserInfoSchema = z.object({
456
+ user_ids: z.string().describe(`One or more users to get detailed information about.
457
+
458
+ **Single User:**
459
+ - "@john" - By username
460
+ - "@john.smith" - Username with period
461
+ - "U01ABC2DEF3" - By user ID
462
+ - "john" - Without @ (also works)
463
+
464
+ **Multiple Users (comma-separated):**
465
+ - "@john, @jane, @bob"
466
+ - "U01ABC, U02DEF, U03GHI"
467
+ - "@john, U01ABC2DEF3" - Mixed formats
468
+
469
+ **What's Returned:**
470
+ - Full profile (name, email, title, phone)
471
+ - Status (deleted, admin, bot)
472
+ - Timezone information
473
+ - Profile image URLs
474
+
475
+ **Name Matching:** Flexibly matches:
476
+ - username (e.g., "john.smith")
477
+ - display_name (e.g., "John")
478
+ - real_name (e.g., "John Smith")`),
479
+ use_cache: z.boolean().optional().default(true).describe(`Whether to try the local cache before making API calls.
480
+
481
+ **When true (DEFAULT):**
482
+ - Faster response (no API call if cached)
483
+ - Data may be up to 24 hours old
484
+ - Best for: Most lookups
485
+
486
+ **When false:**
487
+ - Always fetches fresh data from Slack API
488
+ - Slower but guaranteed current
489
+ - Best for: When you need real-time accuracy`),
490
+ });
491
+ export const UserPresenceSchema = z.object({
492
+ user_id: z.string().describe(`The user to check presence status for.
493
+
494
+ **Formats:**
495
+ - "@username" - By username
496
+ - "U01ABC2DEF3" - By user ID
497
+
498
+ **Returns:**
499
+ - presence: "active" or "away"
500
+ - online: true/false
501
+ - auto_away: true if Slack set away automatically
502
+ - manual_away: true if user set away manually
503
+ - last_activity: timestamp of last activity
504
+
505
+ **Use Cases:**
506
+ - Check if someone is available before messaging
507
+ - Verify if a user is currently online
508
+ - See when someone was last active`),
509
+ });
510
+ // ============================================================================
511
+ // Channel Tools (6)
512
+ // ============================================================================
513
+ export const ChannelInfoSchema = z.object({
514
+ channel_id: z.string().describe(`The channel to get information about.
515
+
516
+ **Formats:**
517
+ - "C01ABC2DEF3" - Channel ID (recommended)
518
+ - "#general" - Channel name
519
+ - "@username_dm" - DM channel
520
+
521
+ **Returns:**
522
+ - Basic info: name, id, created timestamp
523
+ - Content: topic, purpose
524
+ - Membership: member_count, is_member
525
+ - Status: is_archived, is_private`),
526
+ include_locale: z.boolean().optional().default(false).describe(`Include locale/language information for the channel.
527
+
528
+ Usually not needed. Set true for internationalization needs.`),
529
+ use_cache: z.boolean().optional().default(true).describe(`Try local cache first (6h TTL for channels).
530
+
531
+ **true (DEFAULT):** Fast response from cache
532
+ **false:** Fresh data from Slack API`),
533
+ });
534
+ export const ChannelMembersSchema = z.object({
535
+ channel_id: z.string().describe(`The channel to list members of.
536
+
537
+ **Formats:**
538
+ - "C01ABC2DEF3" - Channel ID
539
+ - "#general" - Channel name
540
+
541
+ **Returns:** List of members with:
542
+ - User ID
543
+ - Username, real_name, display_name
544
+ - Admin status
545
+ - Bot status`),
546
+ limit: z.number().optional().default(100).describe(`Maximum members to return.
547
+
548
+ **Range:** 1 to 1000
549
+ **Default:** 100
550
+
551
+ For large channels, use pagination with cursor.`),
552
+ cursor: z.string().optional().describe(`Pagination cursor from previous response. Use for channels with 100+ members.`),
553
+ });
554
+ export const ChannelsListSchema = z.object({
555
+ channel_types: z.string().describe(`Types of channels to list (comma-separated).
556
+
557
+ **Channel Types:**
558
+ - "public_channel" - Public channels anyone can join
559
+ - "private_channel" - Private channels (only those you're in)
560
+ - "im" - Direct messages (1:1 conversations)
561
+ - "mpim" - Multi-person direct messages (group DMs)
562
+
563
+ **Common Combinations:**
564
+ - "public_channel" - Just public channels
565
+ - "public_channel,private_channel" - All regular channels
566
+ - "im,mpim" - All direct messages
567
+ - "public_channel,private_channel,im,mpim" - Everything
568
+
569
+ **Note:** You can only see private channels you're a member of.`),
570
+ sort: z.string().optional().describe(`Sort order for results.
571
+
572
+ **Options:**
573
+ - "popularity" - Sort by member count (most members first)
574
+ - (omit) - Default order from Slack API
575
+
576
+ **Use Case:** Find most active/popular channels with sort="popularity"`),
577
+ limit: z.number().optional().default(100).describe(`Maximum channels to return.
578
+
579
+ **Range:** 1 to 999
580
+ **Default:** 100`),
581
+ cursor: z.string().optional().describe(`Pagination cursor for workspaces with many channels.`),
582
+ });
583
+ export const ChannelsDetailedSchema = z.object({
584
+ channel_types: z.string().optional().default("public_channel,private_channel").describe(`Channel types to fetch. Same options as channels_list.
585
+
586
+ **Default:** "public_channel,private_channel"`),
587
+ sort: z.string().optional().describe(`Sort by "popularity" (member count) or omit for default order.`),
588
+ limit: z.number().optional().default(100).describe(`Maximum channels (1-999). Default: 100.`),
589
+ include_detailed_info: z.boolean().optional().default(false).describe(`Fetch extra details with additional API calls.
590
+
591
+ **When false (DEFAULT):**
592
+ - Single API call
593
+ - Basic channel info
594
+ - Fast and efficient
595
+
596
+ **When true:**
597
+ - Makes additional conversations.info call per channel
598
+ - Gets full channel details
599
+ - Slower but more complete
600
+
601
+ **Recommendation:** Use false unless you need every detail.`),
602
+ });
603
+ export const SetChannelTopicSchema = z.object({
604
+ channel_id: z.string().describe(`Channel to update topic.
605
+
606
+ **Formats:** "C01ABC2DEF3" or "#channel-name"
607
+
608
+ **Permissions:** Must be able to edit channel (member with permissions or admin).`),
609
+ topic: z.string().describe(`New topic text for the channel.
610
+
611
+ **Display:** Shows at the top of the channel
612
+ **Max Length:** 250 characters
613
+ **Formatting:** Plain text only (no markdown)
614
+
615
+ **Examples:**
616
+ - "Q4 Planning - Meeting Thursdays at 2pm"
617
+ - "Support escalations - @oncall for urgent issues"
618
+ - "Read-only announcements channel"`),
619
+ });
620
+ export const SetChannelPurposeSchema = z.object({
621
+ channel_id: z.string().describe(`Channel to update purpose.
622
+
623
+ **Formats:** "C01ABC2DEF3" or "#channel-name"`),
624
+ purpose: z.string().describe(`New purpose text for the channel.
625
+
626
+ **Display:** Shows in channel details/about section
627
+ **Max Length:** 250 characters
628
+ **Use:** Describes what the channel is for
629
+
630
+ **Examples:**
631
+ - "Engineering team discussions and updates"
632
+ - "Customer support ticket overflow and escalations"
633
+ - "Random watercooler chat and team bonding"`),
634
+ });
635
+ // ============================================================================
636
+ // Message Tools (2)
637
+ // ============================================================================
638
+ export const MessagePermalinkSchema = z.object({
639
+ channel_id: z.string().describe(`Channel containing the message.
640
+
641
+ **Formats:** "C01ABC2DEF3" or "#channel-name"`),
642
+ message_ts: z.string().describe(`Timestamp of the message to get permalink for.
643
+
644
+ **Format:** "1609459200.000100" (Unix timestamp with microseconds)
645
+
646
+ **Source:** From the "ts" field in any message object from conversations_history or search results.
647
+
648
+ **Returns:** Permanent URL like:
649
+ https://workspace.slack.com/archives/C01ABC/p1609459200000100`),
650
+ });
651
+ export const AddReactionSchema = z.object({
652
+ channel_id: z.string().describe(`Channel containing the message to react to.
653
+
654
+ **Formats:** "C01ABC2DEF3" or "#channel-name"`),
655
+ message_ts: z.string().describe(`Timestamp of the message to add reaction to.
656
+
657
+ **Format:** "1609459200.000100"
658
+ **Source:** From message "ts" field`),
659
+ emoji_name: z.string().describe(`Emoji name WITHOUT the surrounding colons.
660
+
661
+ **Format:** Just the name, not :name:
662
+
663
+ **Common Emojis:**
664
+ - "thumbsup" (👍) - NOT ":thumbsup:"
665
+ - "thumbsdown" (👎)
666
+ - "heart" (❤️)
667
+ - "rocket" (🚀)
668
+ - "eyes" (👀)
669
+ - "white_check_mark" (✅)
670
+ - "x" (❌)
671
+ - "thinking_face" (🤔)
672
+ - "tada" (🎉)
673
+ - "fire" (🔥)
674
+ - "+1" (same as thumbsup)
675
+ - "-1" (same as thumbsdown)
676
+
677
+ **Custom Emojis:** Your workspace's custom emojis also work.
678
+ Find them in Slack: Type : in message field to see available emojis.`),
679
+ });
680
+ // ============================================================================
681
+ // Files Tool (1)
682
+ // ============================================================================
683
+ export const FilesListSchema = z.object({
684
+ channel_id: z.string().optional().describe(`Filter to files shared in a specific channel.
685
+
686
+ **Formats:** "C01ABC2DEF3" or "#channel-name"
687
+
688
+ **Omit:** Returns files from all accessible channels`),
689
+ user_id: z.string().optional().describe(`Filter to files uploaded by a specific user.
690
+
691
+ **Formats:** "@username" or "U01ABC2DEF3"
692
+
693
+ **Omit:** Returns files from all users`),
694
+ count: z.number().optional().default(10).describe(`Number of files to return.
695
+
696
+ **Range:** 1 to 1000
697
+ **Default:** 10
698
+
699
+ **Recommendation:** Start with 10-20, increase if needed.`),
700
+ types: z.string().optional().default("all").describe(`Filter by file type(s).
701
+
702
+ **Options:**
703
+ - "all" (DEFAULT) - All file types
704
+ - "images" - png, jpg, gif, etc.
705
+ - "videos" - mp4, mov, etc.
706
+ - "pdfs" - PDF documents
707
+ - "docs" - Documents (doc, docx)
708
+ - "gdocs" - Google Docs
709
+ - "zips" - Compressed archives
710
+ - "spaces" - Slack posts/snippets
711
+
712
+ **Multiple types:** Comma-separated
713
+ - "images,pdfs" - Images and PDFs
714
+ - "docs,gdocs,pdfs" - All document types`),
715
+ });
716
+ // ============================================================================
717
+ // Workspace Tool (1)
718
+ // ============================================================================
719
+ export const WorkspaceInfoSchema = z.object({}).describe(`Get information about the current Slack workspace/team.
720
+
721
+ **No parameters required.**
722
+
723
+ **Returns:**
724
+ - id: Team/workspace ID (T01ABC2DEF3)
725
+ - name: Workspace name ("My Company")
726
+ - domain: Slack domain (mycompany.slack.com → "mycompany")
727
+ - email_domain: Email domain for members
728
+ - enterprise_id: Enterprise Grid ID (if applicable)
729
+ - enterprise_name: Enterprise Grid name (if applicable)
730
+
731
+ **Required Scope:** team:read
732
+
733
+ **Use Cases:**
734
+ - Verify which workspace you're connected to
735
+ - Get workspace domain for building URLs
736
+ - Check Enterprise Grid membership`);
737
+ // ============================================================================
738
+ // Cache Tools (3)
739
+ // ============================================================================
740
+ export const InitializeCacheSchema = z.object({}).describe(`Pre-populate local caches with users and channels from Slack API.
741
+
742
+ **No parameters required.**
743
+
744
+ **What It Does:**
745
+ 1. Fetches all users → Saves to ~/slack-cache/users_cache.json
746
+ 2. Fetches all channels → Saves to ~/slack-cache/channels_cache_v2.json
747
+
748
+ **Why Use This:**
749
+ - Call at START of a session
750
+ - Subsequent tools using @username or #channel will be faster
751
+ - Name resolution (e.g., "#general" → "C01ABC") uses cache
752
+ - users_list and channel_info use cache first
753
+
754
+ **Cache Duration:**
755
+ - Users: 24 hours TTL
756
+ - Channels: 6 hours TTL
757
+
758
+ **Best Practice:** Call initialize_cache once when starting work.`);
759
+ export const CacheInfoSchema = z.object({}).describe(`Get details about the local cache files.
760
+
761
+ **No parameters required.**
762
+
763
+ **Returns:**
764
+ - File paths (absolute locations)
765
+ - File sizes (KB)
766
+ - Last modified times
767
+ - Age in hours
768
+ - Freshness status (is_fresh)
769
+
770
+ **Use Cases:**
771
+ - Debug why name resolution isn't working
772
+ - Check if cache is stale
773
+ - Verify cache was created successfully`);
774
+ export const ClearCacheSchema = z.object({
775
+ cache_type: z.enum(["users", "channels", "both"]).optional().default("both").describe(`Which cache file(s) to delete.
776
+
777
+ **Options:**
778
+ - "both" (DEFAULT) - Clear users AND channels cache
779
+ - "users" - Clear only users cache
780
+ - "channels" - Clear only channels cache
781
+
782
+ **After Clearing:**
783
+ Cache files will be recreated on next API call that needs them.
784
+
785
+ **Use Cases:**
786
+ - Force refresh when data seems stale
787
+ - After workspace changes (new users, new channels)
788
+ - Troubleshooting resolution issues`),
789
+ });
790
+ // ============================================================================
791
+ // System Tools (2)
792
+ // ============================================================================
793
+ export const CheckPermissionsSchema = z.object({}).describe(`Test what Slack API scopes/permissions the current token has.
794
+
795
+ **No parameters required.**
796
+
797
+ **Tests These Scopes:**
798
+ - users:read - Can list users
799
+ - channels:read - Can list public channels
800
+ - groups:read - Can list private channels
801
+ - im:read - Can list DMs
802
+ - mpim:read - Can list group DMs
803
+ - team:read - Can get workspace info
804
+ - channels:history - Can read messages
805
+ - chat:write - Can send messages
806
+
807
+ **Returns:**
808
+ - Status for each scope (Available/Failed)
809
+ - Summary: available_scopes, failed_scopes
810
+ - Recommendations for cache/messaging
811
+
812
+ **Use Cases:**
813
+ - Debug "permission denied" errors
814
+ - Verify token has needed scopes
815
+ - Check what operations are possible`);
816
+ export const AnalyticsSummarySchema = z.object({
817
+ date_range: z.string().optional().default("30d").describe(`Time period for analytics (affects label, not actual data).
818
+
819
+ **Options:**
820
+ - "7d" - Label as 7-day period
821
+ - "30d" (DEFAULT) - Label as 30-day period
822
+ - "90d" - Label as 90-day period
823
+
824
+ **Note:** This tool uses CACHED data, so actual analytics are based on
825
+ cached user/channel data, not historical message data.`),
826
+ }).describe(`Get basic workspace analytics from cached data.
827
+
828
+ **Returns:**
829
+ - User stats: total, active (non-deleted), bots, admins
830
+ - Channel stats: public, private, DMs, group DMs
831
+
832
+ **Data Source:** Uses cached users/channels data
833
+ - Not real-time activity metrics
834
+ - Provides snapshot of workspace structure
835
+
836
+ **Use Cases:**
837
+ - Quick workspace overview
838
+ - Understand team size
839
+ - Count channels by type`);
840
+ //# sourceMappingURL=schemas.js.map