slack-workspace-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 (46) hide show
  1. package/README.md +122 -0
  2. package/build/index.d.ts +2 -0
  3. package/build/index.integration-with-mock.d.ts +2 -0
  4. package/build/index.integration-with-mock.js +34 -0
  5. package/build/index.js +76 -0
  6. package/package.json +47 -0
  7. package/shared/index.d.ts +4 -0
  8. package/shared/index.js +7 -0
  9. package/shared/logging.d.ts +10 -0
  10. package/shared/logging.js +21 -0
  11. package/shared/server.d.ts +134 -0
  12. package/shared/server.js +68 -0
  13. package/shared/slack-client/lib/add-reaction.d.ts +5 -0
  14. package/shared/slack-client/lib/add-reaction.js +30 -0
  15. package/shared/slack-client/lib/get-channel.d.ts +5 -0
  16. package/shared/slack-client/lib/get-channel.js +24 -0
  17. package/shared/slack-client/lib/get-channels.d.ts +10 -0
  18. package/shared/slack-client/lib/get-channels.js +37 -0
  19. package/shared/slack-client/lib/get-messages.d.ts +16 -0
  20. package/shared/slack-client/lib/get-messages.js +38 -0
  21. package/shared/slack-client/lib/get-thread.d.ts +16 -0
  22. package/shared/slack-client/lib/get-thread.js +39 -0
  23. package/shared/slack-client/lib/post-message.d.ts +10 -0
  24. package/shared/slack-client/lib/post-message.js +44 -0
  25. package/shared/slack-client/lib/update-message.d.ts +5 -0
  26. package/shared/slack-client/lib/update-message.js +32 -0
  27. package/shared/slack-client/slack-client.integration-mock.d.ts +16 -0
  28. package/shared/slack-client/slack-client.integration-mock.js +106 -0
  29. package/shared/tools/get-channel.d.ts +55 -0
  30. package/shared/tools/get-channel.js +136 -0
  31. package/shared/tools/get-channels.d.ts +46 -0
  32. package/shared/tools/get-channels.js +107 -0
  33. package/shared/tools/get-thread.d.ts +54 -0
  34. package/shared/tools/get-thread.js +130 -0
  35. package/shared/tools/post-message.d.ts +44 -0
  36. package/shared/tools/post-message.js +81 -0
  37. package/shared/tools/react-to-message.d.ts +51 -0
  38. package/shared/tools/react-to-message.js +90 -0
  39. package/shared/tools/reply-to-thread.d.ts +59 -0
  40. package/shared/tools/reply-to-thread.js +97 -0
  41. package/shared/tools/update-message.d.ts +51 -0
  42. package/shared/tools/update-message.js +87 -0
  43. package/shared/tools.d.ts +18 -0
  44. package/shared/tools.js +78 -0
  45. package/shared/types.d.ts +112 -0
  46. package/shared/types.js +5 -0
@@ -0,0 +1,54 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { z } from 'zod';
3
+ import type { ClientFactory } from '../server.js';
4
+ export declare const GetThreadSchema: z.ZodObject<{
5
+ channel_id: z.ZodString;
6
+ thread_ts: z.ZodString;
7
+ reply_limit: z.ZodDefault<z.ZodNumber>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ channel_id: string;
10
+ thread_ts: string;
11
+ reply_limit: number;
12
+ }, {
13
+ channel_id: string;
14
+ thread_ts: string;
15
+ reply_limit?: number | undefined;
16
+ }>;
17
+ export declare function getThreadTool(server: Server, clientFactory: ClientFactory): {
18
+ name: string;
19
+ description: string;
20
+ inputSchema: {
21
+ type: "object";
22
+ properties: {
23
+ channel_id: {
24
+ type: string;
25
+ description: string;
26
+ };
27
+ thread_ts: {
28
+ type: string;
29
+ description: string;
30
+ };
31
+ reply_limit: {
32
+ type: string;
33
+ default: number;
34
+ minimum: number;
35
+ maximum: number;
36
+ description: string;
37
+ };
38
+ };
39
+ required: string[];
40
+ };
41
+ handler: (args: unknown) => Promise<{
42
+ content: {
43
+ type: string;
44
+ text: string;
45
+ }[];
46
+ isError?: undefined;
47
+ } | {
48
+ content: {
49
+ type: string;
50
+ text: string;
51
+ }[];
52
+ isError: boolean;
53
+ }>;
54
+ };
@@ -0,0 +1,130 @@
1
+ import { z } from 'zod';
2
+ const PARAM_DESCRIPTIONS = {
3
+ channel_id: 'The channel ID where the thread exists (e.g., "C1234567890"). ' +
4
+ 'Get channel IDs using the slack_get_channels tool.',
5
+ thread_ts: 'The timestamp of the parent message that started the thread (e.g., "1234567890.123456"). ' +
6
+ 'This is shown as "ts" in message outputs.',
7
+ reply_limit: 'Maximum number of replies to return. Default: 50. Maximum: 200. ' +
8
+ 'The parent message is always included.',
9
+ };
10
+ export const GetThreadSchema = z.object({
11
+ channel_id: z.string().min(1).describe(PARAM_DESCRIPTIONS.channel_id),
12
+ thread_ts: z.string().min(1).describe(PARAM_DESCRIPTIONS.thread_ts),
13
+ reply_limit: z.number().min(1).max(200).default(50).describe(PARAM_DESCRIPTIONS.reply_limit),
14
+ });
15
+ const TOOL_DESCRIPTION = `Get a thread conversation with all its replies.
16
+
17
+ Returns the parent message and all replies in a thread. This is equivalent to clicking on "X replies" in Slack to expand a thread.
18
+
19
+ **Returns:**
20
+ - Parent message with full content
21
+ - All reply messages in chronological order
22
+ - Reactions on each message
23
+ - Timestamps for each message
24
+
25
+ **Use cases:**
26
+ - Read an entire threaded conversation
27
+ - Get context before replying to a thread
28
+ - Review discussion history on a topic
29
+ - Find the latest reply timestamp for adding new replies
30
+
31
+ **Note:** The thread_ts parameter is the timestamp of the parent message, not a reply.`;
32
+ export function getThreadTool(server, clientFactory) {
33
+ return {
34
+ name: 'slack_get_thread',
35
+ description: TOOL_DESCRIPTION,
36
+ inputSchema: {
37
+ type: 'object',
38
+ properties: {
39
+ channel_id: {
40
+ type: 'string',
41
+ description: PARAM_DESCRIPTIONS.channel_id,
42
+ },
43
+ thread_ts: {
44
+ type: 'string',
45
+ description: PARAM_DESCRIPTIONS.thread_ts,
46
+ },
47
+ reply_limit: {
48
+ type: 'number',
49
+ default: 50,
50
+ minimum: 1,
51
+ maximum: 200,
52
+ description: PARAM_DESCRIPTIONS.reply_limit,
53
+ },
54
+ },
55
+ required: ['channel_id', 'thread_ts'],
56
+ },
57
+ handler: async (args) => {
58
+ try {
59
+ const parsed = GetThreadSchema.parse(args);
60
+ const client = clientFactory();
61
+ const { messages, hasMore } = await client.getThread(parsed.channel_id, parsed.thread_ts, {
62
+ limit: parsed.reply_limit,
63
+ });
64
+ if (messages.length === 0) {
65
+ return {
66
+ content: [
67
+ {
68
+ type: 'text',
69
+ text: 'Thread not found or has no messages.',
70
+ },
71
+ ],
72
+ };
73
+ }
74
+ // First message is the parent
75
+ const parent = messages[0];
76
+ const replies = messages.slice(1);
77
+ let output = `# Thread in channel ${parsed.channel_id}\n\n`;
78
+ // Format parent message
79
+ const parentTime = new Date(parseFloat(parent.ts) * 1000).toISOString();
80
+ const parentSender = parent.user || parent.bot_id || 'unknown';
81
+ const parentReactions = parent.reactions
82
+ ? `\nReactions: ${parent.reactions.map((r) => `:${r.name}: ${r.count}`).join(' ')}`
83
+ : '';
84
+ output += `## Parent Message\n`;
85
+ output += `**${parentSender}** (${parentTime})\n`;
86
+ output += `${parent.text}${parentReactions}\n`;
87
+ output += `ts: ${parent.ts}\n\n`;
88
+ // Format replies
89
+ if (replies.length > 0) {
90
+ output += `## Replies (${replies.length}${hasMore ? '+' : ''}):\n\n`;
91
+ for (const reply of replies) {
92
+ const time = new Date(parseFloat(reply.ts) * 1000).toISOString();
93
+ const sender = reply.user || reply.bot_id || 'unknown';
94
+ const reactions = reply.reactions
95
+ ? `\nReactions: ${reply.reactions.map((r) => `:${r.name}: ${r.count}`).join(' ')}`
96
+ : '';
97
+ output += `**${sender}** (${time})\n`;
98
+ output += `${reply.text}${reactions}\n`;
99
+ output += `ts: ${reply.ts}\n\n`;
100
+ }
101
+ if (hasMore) {
102
+ output += `_More replies available. Increase reply_limit to see more._\n`;
103
+ }
104
+ }
105
+ else {
106
+ output += '_No replies yet._\n';
107
+ }
108
+ return {
109
+ content: [
110
+ {
111
+ type: 'text',
112
+ text: output,
113
+ },
114
+ ],
115
+ };
116
+ }
117
+ catch (error) {
118
+ return {
119
+ content: [
120
+ {
121
+ type: 'text',
122
+ text: `Error fetching thread: ${error instanceof Error ? error.message : 'Unknown error'}`,
123
+ },
124
+ ],
125
+ isError: true,
126
+ };
127
+ }
128
+ },
129
+ };
130
+ }
@@ -0,0 +1,44 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { z } from 'zod';
3
+ import type { ClientFactory } from '../server.js';
4
+ export declare const PostMessageSchema: z.ZodObject<{
5
+ channel_id: z.ZodString;
6
+ text: z.ZodString;
7
+ }, "strip", z.ZodTypeAny, {
8
+ text: string;
9
+ channel_id: string;
10
+ }, {
11
+ text: string;
12
+ channel_id: string;
13
+ }>;
14
+ export declare function postMessageTool(server: Server, clientFactory: ClientFactory): {
15
+ name: string;
16
+ description: string;
17
+ inputSchema: {
18
+ type: "object";
19
+ properties: {
20
+ channel_id: {
21
+ type: string;
22
+ description: string;
23
+ };
24
+ text: {
25
+ type: string;
26
+ description: string;
27
+ };
28
+ };
29
+ required: string[];
30
+ };
31
+ handler: (args: unknown) => Promise<{
32
+ content: {
33
+ type: string;
34
+ text: string;
35
+ }[];
36
+ isError?: undefined;
37
+ } | {
38
+ content: {
39
+ type: string;
40
+ text: string;
41
+ }[];
42
+ isError: boolean;
43
+ }>;
44
+ };
@@ -0,0 +1,81 @@
1
+ import { z } from 'zod';
2
+ const PARAM_DESCRIPTIONS = {
3
+ channel_id: 'The channel ID to post the message to (e.g., "C1234567890"). ' +
4
+ 'Get channel IDs using the slack_get_channels tool.',
5
+ text: 'The message content to post. Supports Slack markdown formatting: ' +
6
+ '*bold*, _italic_, `code`, ```code blocks```, and <URL|link text>.',
7
+ };
8
+ export const PostMessageSchema = z.object({
9
+ channel_id: z.string().min(1).describe(PARAM_DESCRIPTIONS.channel_id),
10
+ text: z.string().min(1).describe(PARAM_DESCRIPTIONS.text),
11
+ });
12
+ const TOOL_DESCRIPTION = `Post a new message to a Slack channel.
13
+
14
+ Creates a new message in the specified channel. The message appears as a new post, not as a reply to any thread.
15
+
16
+ **Returns:**
17
+ - Confirmation of the posted message
18
+ - The message timestamp (ts) which can be used to:
19
+ - Start a thread by replying with slack_reply_to_thread
20
+ - Edit the message with slack_update_message
21
+ - Add reactions with slack_react_to_message
22
+
23
+ **Use cases:**
24
+ - Share information with a channel
25
+ - Start a new discussion topic
26
+ - Post announcements or updates
27
+ - Ask questions to the channel
28
+
29
+ **Note:** To reply to an existing thread, use slack_reply_to_thread instead.`;
30
+ export function postMessageTool(server, clientFactory) {
31
+ return {
32
+ name: 'slack_post_message',
33
+ description: TOOL_DESCRIPTION,
34
+ inputSchema: {
35
+ type: 'object',
36
+ properties: {
37
+ channel_id: {
38
+ type: 'string',
39
+ description: PARAM_DESCRIPTIONS.channel_id,
40
+ },
41
+ text: {
42
+ type: 'string',
43
+ description: PARAM_DESCRIPTIONS.text,
44
+ },
45
+ },
46
+ required: ['channel_id', 'text'],
47
+ },
48
+ handler: async (args) => {
49
+ try {
50
+ const parsed = PostMessageSchema.parse(args);
51
+ const client = clientFactory();
52
+ const message = await client.postMessage(parsed.channel_id, parsed.text);
53
+ const time = new Date(parseFloat(message.ts) * 1000).toISOString();
54
+ return {
55
+ content: [
56
+ {
57
+ type: 'text',
58
+ text: `Message posted successfully!\n\n` +
59
+ `Channel: ${parsed.channel_id}\n` +
60
+ `Timestamp: ${message.ts}\n` +
61
+ `Posted at: ${time}\n\n` +
62
+ `Content:\n${parsed.text}\n\n` +
63
+ `Use the timestamp (ts: ${message.ts}) to reply to this message or add reactions.`,
64
+ },
65
+ ],
66
+ };
67
+ }
68
+ catch (error) {
69
+ return {
70
+ content: [
71
+ {
72
+ type: 'text',
73
+ text: `Error posting message: ${error instanceof Error ? error.message : 'Unknown error'}`,
74
+ },
75
+ ],
76
+ isError: true,
77
+ };
78
+ }
79
+ },
80
+ };
81
+ }
@@ -0,0 +1,51 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { z } from 'zod';
3
+ import type { ClientFactory } from '../server.js';
4
+ export declare const ReactToMessageSchema: z.ZodObject<{
5
+ channel_id: z.ZodString;
6
+ message_ts: z.ZodString;
7
+ emoji: z.ZodString;
8
+ }, "strip", z.ZodTypeAny, {
9
+ emoji: string;
10
+ channel_id: string;
11
+ message_ts: string;
12
+ }, {
13
+ emoji: string;
14
+ channel_id: string;
15
+ message_ts: string;
16
+ }>;
17
+ export declare function reactToMessageTool(server: Server, clientFactory: ClientFactory): {
18
+ name: string;
19
+ description: string;
20
+ inputSchema: {
21
+ type: "object";
22
+ properties: {
23
+ channel_id: {
24
+ type: string;
25
+ description: string;
26
+ };
27
+ message_ts: {
28
+ type: string;
29
+ description: string;
30
+ };
31
+ emoji: {
32
+ type: string;
33
+ description: string;
34
+ };
35
+ };
36
+ required: string[];
37
+ };
38
+ handler: (args: unknown) => Promise<{
39
+ content: {
40
+ type: string;
41
+ text: string;
42
+ }[];
43
+ isError?: undefined;
44
+ } | {
45
+ content: {
46
+ type: string;
47
+ text: string;
48
+ }[];
49
+ isError: boolean;
50
+ }>;
51
+ };
@@ -0,0 +1,90 @@
1
+ import { z } from 'zod';
2
+ const PARAM_DESCRIPTIONS = {
3
+ channel_id: 'The channel ID where the message exists (e.g., "C1234567890"). ' +
4
+ 'Get channel IDs using the slack_get_channels tool.',
5
+ message_ts: 'The timestamp of the message to react to (e.g., "1234567890.123456"). ' +
6
+ 'This is shown as "ts" in message outputs.',
7
+ emoji: 'The emoji name without colons (e.g., "thumbsup", "white_check_mark", "eyes"). ' +
8
+ 'Common reactions: thumbsup, thumbsdown, heart, eyes, white_check_mark, x, tada.',
9
+ };
10
+ export const ReactToMessageSchema = z.object({
11
+ channel_id: z.string().min(1).describe(PARAM_DESCRIPTIONS.channel_id),
12
+ message_ts: z.string().min(1).describe(PARAM_DESCRIPTIONS.message_ts),
13
+ emoji: z.string().min(1).describe(PARAM_DESCRIPTIONS.emoji),
14
+ });
15
+ const TOOL_DESCRIPTION = `Add an emoji reaction to a message in Slack.
16
+
17
+ Adds a reaction (emoji) to a specific message. Reactions are a lightweight way to acknowledge or respond to messages without creating a new message.
18
+
19
+ **Returns:**
20
+ - Confirmation that the reaction was added
21
+
22
+ **Common emoji names:**
23
+ - Positive: thumbsup, +1, heart, tada, star, clap
24
+ - Acknowledgment: eyes, white_check_mark, ok_hand
25
+ - Negative: thumbsdown, -1, x
26
+ - Status: hourglass, warning, question, exclamation
27
+
28
+ **Use cases:**
29
+ - Acknowledge that you've seen a message (:eyes:)
30
+ - Mark a task as complete (:white_check_mark:)
31
+ - Show approval or agreement (:thumbsup:)
32
+ - Celebrate achievements (:tada:)
33
+ - Signal that something needs attention (:warning:)
34
+
35
+ **Note:** If the reaction already exists from this bot, no error is returned.`;
36
+ export function reactToMessageTool(server, clientFactory) {
37
+ return {
38
+ name: 'slack_react_to_message',
39
+ description: TOOL_DESCRIPTION,
40
+ inputSchema: {
41
+ type: 'object',
42
+ properties: {
43
+ channel_id: {
44
+ type: 'string',
45
+ description: PARAM_DESCRIPTIONS.channel_id,
46
+ },
47
+ message_ts: {
48
+ type: 'string',
49
+ description: PARAM_DESCRIPTIONS.message_ts,
50
+ },
51
+ emoji: {
52
+ type: 'string',
53
+ description: PARAM_DESCRIPTIONS.emoji,
54
+ },
55
+ },
56
+ required: ['channel_id', 'message_ts', 'emoji'],
57
+ },
58
+ handler: async (args) => {
59
+ try {
60
+ const parsed = ReactToMessageSchema.parse(args);
61
+ const client = clientFactory();
62
+ // Remove colons if the user included them
63
+ const emojiName = parsed.emoji.replace(/^:/, '').replace(/:$/, '');
64
+ await client.addReaction(parsed.channel_id, parsed.message_ts, emojiName);
65
+ return {
66
+ content: [
67
+ {
68
+ type: 'text',
69
+ text: `Reaction added successfully!\n\n` +
70
+ `Channel: ${parsed.channel_id}\n` +
71
+ `Message: ${parsed.message_ts}\n` +
72
+ `Reaction: :${emojiName}:`,
73
+ },
74
+ ],
75
+ };
76
+ }
77
+ catch (error) {
78
+ return {
79
+ content: [
80
+ {
81
+ type: 'text',
82
+ text: `Error adding reaction: ${error instanceof Error ? error.message : 'Unknown error'}`,
83
+ },
84
+ ],
85
+ isError: true,
86
+ };
87
+ }
88
+ },
89
+ };
90
+ }
@@ -0,0 +1,59 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { z } from 'zod';
3
+ import type { ClientFactory } from '../server.js';
4
+ export declare const ReplyToThreadSchema: z.ZodObject<{
5
+ channel_id: z.ZodString;
6
+ thread_ts: z.ZodString;
7
+ text: z.ZodString;
8
+ broadcast: z.ZodDefault<z.ZodBoolean>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ text: string;
11
+ channel_id: string;
12
+ thread_ts: string;
13
+ broadcast: boolean;
14
+ }, {
15
+ text: string;
16
+ channel_id: string;
17
+ thread_ts: string;
18
+ broadcast?: boolean | undefined;
19
+ }>;
20
+ export declare function replyToThreadTool(server: Server, clientFactory: ClientFactory): {
21
+ name: string;
22
+ description: string;
23
+ inputSchema: {
24
+ type: "object";
25
+ properties: {
26
+ channel_id: {
27
+ type: string;
28
+ description: string;
29
+ };
30
+ thread_ts: {
31
+ type: string;
32
+ description: string;
33
+ };
34
+ text: {
35
+ type: string;
36
+ description: string;
37
+ };
38
+ broadcast: {
39
+ type: string;
40
+ default: boolean;
41
+ description: string;
42
+ };
43
+ };
44
+ required: string[];
45
+ };
46
+ handler: (args: unknown) => Promise<{
47
+ content: {
48
+ type: string;
49
+ text: string;
50
+ }[];
51
+ isError?: undefined;
52
+ } | {
53
+ content: {
54
+ type: string;
55
+ text: string;
56
+ }[];
57
+ isError: boolean;
58
+ }>;
59
+ };
@@ -0,0 +1,97 @@
1
+ import { z } from 'zod';
2
+ const PARAM_DESCRIPTIONS = {
3
+ channel_id: 'The channel ID where the thread exists (e.g., "C1234567890"). ' +
4
+ 'Get channel IDs using the slack_get_channels tool.',
5
+ thread_ts: 'The timestamp of the parent message to reply to (e.g., "1234567890.123456"). ' +
6
+ 'This creates a threaded reply under that message.',
7
+ text: 'The reply content. Supports Slack markdown formatting: ' +
8
+ '*bold*, _italic_, `code`, ```code blocks```, and <URL|link text>.',
9
+ broadcast: 'Also post the reply to the channel (not just the thread). Default: false. ' +
10
+ 'When true, the reply appears both in the thread and as a channel message.',
11
+ };
12
+ export const ReplyToThreadSchema = z.object({
13
+ channel_id: z.string().min(1).describe(PARAM_DESCRIPTIONS.channel_id),
14
+ thread_ts: z.string().min(1).describe(PARAM_DESCRIPTIONS.thread_ts),
15
+ text: z.string().min(1).describe(PARAM_DESCRIPTIONS.text),
16
+ broadcast: z.boolean().default(false).describe(PARAM_DESCRIPTIONS.broadcast),
17
+ });
18
+ const TOOL_DESCRIPTION = `Reply to an existing thread in Slack.
19
+
20
+ Posts a message as a reply to a specific thread. The reply will appear nested under the parent message.
21
+
22
+ **Returns:**
23
+ - Confirmation of the posted reply
24
+ - The reply's timestamp (ts) for further operations
25
+
26
+ **Use cases:**
27
+ - Continue a threaded conversation
28
+ - Answer a question in a thread
29
+ - Provide follow-up information
30
+ - Keep discussions organized within threads
31
+
32
+ **Note:** Use slack_get_thread first to read the conversation before replying.`;
33
+ export function replyToThreadTool(server, clientFactory) {
34
+ return {
35
+ name: 'slack_reply_to_thread',
36
+ description: TOOL_DESCRIPTION,
37
+ inputSchema: {
38
+ type: 'object',
39
+ properties: {
40
+ channel_id: {
41
+ type: 'string',
42
+ description: PARAM_DESCRIPTIONS.channel_id,
43
+ },
44
+ thread_ts: {
45
+ type: 'string',
46
+ description: PARAM_DESCRIPTIONS.thread_ts,
47
+ },
48
+ text: {
49
+ type: 'string',
50
+ description: PARAM_DESCRIPTIONS.text,
51
+ },
52
+ broadcast: {
53
+ type: 'boolean',
54
+ default: false,
55
+ description: PARAM_DESCRIPTIONS.broadcast,
56
+ },
57
+ },
58
+ required: ['channel_id', 'thread_ts', 'text'],
59
+ },
60
+ handler: async (args) => {
61
+ try {
62
+ const parsed = ReplyToThreadSchema.parse(args);
63
+ const client = clientFactory();
64
+ const message = await client.postMessage(parsed.channel_id, parsed.text, {
65
+ threadTs: parsed.thread_ts,
66
+ replyBroadcast: parsed.broadcast,
67
+ });
68
+ const time = new Date(parseFloat(message.ts) * 1000).toISOString();
69
+ return {
70
+ content: [
71
+ {
72
+ type: 'text',
73
+ text: `Reply posted successfully!\n\n` +
74
+ `Channel: ${parsed.channel_id}\n` +
75
+ `Thread: ${parsed.thread_ts}\n` +
76
+ `Reply timestamp: ${message.ts}\n` +
77
+ `Posted at: ${time}\n` +
78
+ (parsed.broadcast ? 'Broadcasted to channel: Yes\n' : '') +
79
+ `\nContent:\n${parsed.text}`,
80
+ },
81
+ ],
82
+ };
83
+ }
84
+ catch (error) {
85
+ return {
86
+ content: [
87
+ {
88
+ type: 'text',
89
+ text: `Error posting reply: ${error instanceof Error ? error.message : 'Unknown error'}`,
90
+ },
91
+ ],
92
+ isError: true,
93
+ };
94
+ }
95
+ },
96
+ };
97
+ }
@@ -0,0 +1,51 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { z } from 'zod';
3
+ import type { ClientFactory } from '../server.js';
4
+ export declare const UpdateMessageSchema: z.ZodObject<{
5
+ channel_id: z.ZodString;
6
+ message_ts: z.ZodString;
7
+ text: z.ZodString;
8
+ }, "strip", z.ZodTypeAny, {
9
+ text: string;
10
+ channel_id: string;
11
+ message_ts: string;
12
+ }, {
13
+ text: string;
14
+ channel_id: string;
15
+ message_ts: string;
16
+ }>;
17
+ export declare function updateMessageTool(server: Server, clientFactory: ClientFactory): {
18
+ name: string;
19
+ description: string;
20
+ inputSchema: {
21
+ type: "object";
22
+ properties: {
23
+ channel_id: {
24
+ type: string;
25
+ description: string;
26
+ };
27
+ message_ts: {
28
+ type: string;
29
+ description: string;
30
+ };
31
+ text: {
32
+ type: string;
33
+ description: string;
34
+ };
35
+ };
36
+ required: string[];
37
+ };
38
+ handler: (args: unknown) => Promise<{
39
+ content: {
40
+ type: string;
41
+ text: string;
42
+ }[];
43
+ isError?: undefined;
44
+ } | {
45
+ content: {
46
+ type: string;
47
+ text: string;
48
+ }[];
49
+ isError: boolean;
50
+ }>;
51
+ };