From 7a1a210d308283dafc2e5111b3bb7371ff4f9c94 Mon Sep 17 00:00:00 2001 From: Jonas Jesus Date: Fri, 10 Apr 2026 13:47:36 -0300 Subject: [PATCH 1/2] feat(slack): add SLACK_LIST_DMS tool and sender name in DMs Add a dedicated tool to list the bot DM conversations with resolved user names, and inject the sender display name into DM messages so the LLM agent knows who it is talking to. Co-Authored-By: Claude Opus 4.6 --- slack-mcp/server/lib/types.ts | 1 + .../server/slack/handlers/eventHandler.ts | 24 +++++- slack-mcp/server/tools/channels.ts | 76 +++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/slack-mcp/server/lib/types.ts b/slack-mcp/server/lib/types.ts index 177e684a..4b9c4a23 100644 --- a/slack-mcp/server/lib/types.ts +++ b/slack-mcp/server/lib/types.ts @@ -141,6 +141,7 @@ export interface SlackChannel { is_member: boolean; created: number; creator: string; + user?: string; topic?: { value: string; creator: string; diff --git a/slack-mcp/server/slack/handlers/eventHandler.ts b/slack-mcp/server/slack/handlers/eventHandler.ts index 4e81d292..0996d695 100644 --- a/slack-mcp/server/slack/handlers/eventHandler.ts +++ b/slack-mcp/server/slack/handlers/eventHandler.ts @@ -17,6 +17,7 @@ import { addReaction, removeReaction, deleteMessage, + getUserInfo, } from "../../lib/slack-client.ts"; import type { SlackEvent, @@ -845,8 +846,29 @@ async function handleDirectMessage( await removeReaction(channel, ts, "eyes"); } + // Resolve sender name so the LLM knows who it's talking to + let senderText = text; + try { + const userInfo = await getUserInfo(user); + const senderName = userInfo + ? userInfo.profile?.display_name || userInfo.real_name || userInfo.name + : null; + if (senderName) { + senderText = `[Mensagem de ${senderName}]\n${text}`; + console.log(`[EventHandler] DM sender resolved: ${senderName}`); + } + } catch (err) { + console.warn(`[EventHandler] Failed to resolve DM sender name:`, err); + } + console.log(`[EventHandler] Building LLM messages for DM...`); - const messages = await buildLLMMessages(channel, text, ts, undefined, media); + const messages = await buildLLMMessages( + channel, + senderText, + ts, + undefined, + media, + ); console.log(`[EventHandler] LLM messages built: ${messages.length} messages`); messages.forEach((msg, i) => { console.log( diff --git a/slack-mcp/server/tools/channels.ts b/slack-mcp/server/tools/channels.ts index 098f8607..beb49c8d 100644 --- a/slack-mcp/server/tools/channels.ts +++ b/slack-mcp/server/tools/channels.ts @@ -14,6 +14,7 @@ import { getChannelMembers, openDM, inviteToChannel, + getUserInfo, } from "../lib/slack-client.ts"; /** @@ -98,6 +99,80 @@ export const createListChannelsTool = (_env: Env) => }, }); +/** + * List all direct message conversations + */ +export const createListDMsTool = (_env: Env) => + createTool({ + id: "SLACK_LIST_DMS", + description: + "List all direct message conversations the bot has. Returns channel IDs that can be used with SLACK_GET_CHANNEL_HISTORY to read DM messages.", + annotations: { readOnlyHint: true }, + inputSchema: z + .object({ + limit: z + .number() + .optional() + .default(100) + .describe("Maximum number of DMs to return"), + }) + .strict(), + outputSchema: z + .object({ + success: z.boolean(), + dms: z.array( + z.object({ + channel_id: z.string(), + user_id: z.string(), + user_name: z.string(), + }), + ), + error: z.string().optional(), + }) + .strict(), + execute: async ({ context }: { context: unknown }) => { + const input = context as { limit?: number }; + + try { + const channels = await listChannels({ + types: "im", + limit: input.limit, + skipCache: true, + }); + + const imChannels = channels.filter((c) => c.is_im && c.user); + + const dms = await Promise.all( + imChannels.map(async (c) => { + const userInfo = await getUserInfo(c.user!); + const userName = userInfo + ? userInfo.profile?.display_name || + userInfo.real_name || + userInfo.name + : "(unknown user)"; + + return { + channel_id: c.id, + user_id: c.user!, + user_name: userName, + }; + }), + ); + + return { + success: true, + dms, + }; + } catch (error) { + return { + success: false, + dms: [], + error: error instanceof Error ? error.message : String(error), + }; + } + }, + }); + /** * Get channel info */ @@ -356,6 +431,7 @@ export const createInviteToChannelTool = (_env: Env) => */ export const channelTools = [ createListChannelsTool, + createListDMsTool, createGetChannelInfoTool, createJoinChannelTool, createGetChannelMembersTool, From 989175f118dd497d16d23fa1fe57e6c7a4ab66d6 Mon Sep 17 00:00:00 2001 From: Jonas Jesus Date: Fri, 10 Apr 2026 14:02:12 -0300 Subject: [PATCH 2/2] fix(slack): remove unused baseUrl/paths from tsconfig TypeScript 7.0 deprecated baseUrl. The path aliases were not used anywhere in the codebase, so removing them fixes the CI check. Co-Authored-By: Claude Opus 4.6 --- slack-mcp/tsconfig.json | 7 ------- 1 file changed, 7 deletions(-) diff --git a/slack-mcp/tsconfig.json b/slack-mcp/tsconfig.json index cf5c6b05..ae4ab5c0 100644 --- a/slack-mcp/tsconfig.json +++ b/slack-mcp/tsconfig.json @@ -21,13 +21,6 @@ "noUnusedParameters": false, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true, - /* Path Aliases */ - "baseUrl": ".", - "paths": { - "server/*": [ - "./server/*" - ] - }, /* Types */ "types": [ "@types/node"