Skip to main content
Glama
oregpt

Slack MCP Server

by oregpt

conversations_history

Retrieve message history from Slack channels, DMs, or threads with pagination and filtering options for efficient conversation analysis.

Instructions

Retrieves message history from a Slack channel, DM, or thread. Supports pagination and filtering.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
accessTokenYesSlack OAuth token (xoxp-... or xoxb-...)
channel_idYesChannel ID (e.g., C1234567890), channel name (#general), or DM (@username)
limitNoTime range (1d, 7d, 1m, 90d) or message count (e.g., 100)
cursorNoPagination cursor from previous response
include_activity_messagesNoInclude join/leave system messages (default: false)

Implementation Reference

  • The main handler function `conversationsHistory` that executes the tool logic: validates input with Zod schema, resolves channel ID, parses limit parameters, fetches history from Slack API using WebClient, filters messages, handles pagination and errors.
    export async function conversationsHistory(args: any): Promise<ToolResponse> {
      try {
        const validated = ConversationsHistorySchema.parse(args);
        const client = new WebClient(validated.accessToken);
    
        console.log('Fetching conversation history for channel:', validated.channel_id);
    
        // Resolve channel name/username to ID if needed
        const channelId = await resolveChannelId(client, validated.channel_id);
    
        // Parse limit parameter
        const limitParams = parseLimit(validated.limit);
    
        // Fetch conversation history
        const result = await client.conversations.history({
          channel: channelId,
          cursor: validated.cursor,
          ...limitParams
        });
    
        // Filter out activity messages if not requested
        let messages = result.messages || [];
        if (!validated.include_activity_messages) {
          messages = messages.filter((msg: any) => !msg.subtype || !['channel_join', 'channel_leave'].includes(msg.subtype));
        }
    
        return {
          success: true,
          data: {
            messages,
            has_more: result.has_more,
            cursor: result.response_metadata?.next_cursor,
            channel_id: channelId
          }
        };
      } catch (error: any) {
        if (error.name === 'ZodError') {
          return { success: false, error: `Validation error: ${error.errors.map((e: any) => e.message).join(', ')}` };
        }
        return handleSlackError(error);
      }
    }
  • Zod schema `ConversationsHistorySchema` defining the input parameters and validation for the conversations_history tool.
    export const ConversationsHistorySchema = z.object({
      accessToken: z.string().describe("Slack OAuth token (xoxp-... or xoxb-...)"),
      channel_id: z.string().describe("Channel ID (e.g., C1234567890), channel name (#general), or DM (@username)"),
      limit: z.union([z.string(), z.number()]).optional().describe("Time range (1d, 7d, 1m, 90d) or message count (e.g., 100)"),
      cursor: z.string().optional().describe("Pagination cursor from previous response"),
      include_activity_messages: z.boolean().optional().describe("Include join/leave system messages (default: false)")
    });
  • src/index.ts:95-99 (registration)
    Tool registration in the MCP server's `listTools` response, specifying name, description, and converted input schema.
    {
      name: 'conversations_history',
      description: 'Retrieves message history from a Slack channel, DM, or thread. Supports pagination and filtering.',
      inputSchema: zodToMCPSchema(ConversationsHistorySchema)
    },
  • src/index.ts:129-131 (registration)
    Dispatch registration in the MCP server's `callTool` request handler switch statement that invokes the handler function.
    case 'conversations_history':
      result = await conversationsHistory(args);
      break;
  • Helper function `resolveChannelId` used by the handler to convert channel names (#channel) or usernames (@user) to actual Slack channel IDs.
    async function resolveChannelId(client: WebClient, channelInput: string): Promise<string> {
      // If already an ID (starts with C, D, or G), return as-is
      if (/^[CDG][A-Z0-9]+$/.test(channelInput)) {
        return channelInput;
      }
    
      // Handle #channel format
      if (channelInput.startsWith('#')) {
        const channelName = channelInput.slice(1);
        const result = await client.conversations.list({ types: 'public_channel,private_channel' });
        const channel = result.channels?.find((ch: any) => ch.name === channelName);
        if (channel) {
          return channel.id!;
        }
        throw new Error(`Channel not found: ${channelInput}`);
      }
    
      // Handle @username format for DMs
      if (channelInput.startsWith('@')) {
        const username = channelInput.slice(1);
        const usersResult = await client.users.list({});
        const user = usersResult.members?.find((u: any) => u.name === username);
        if (user) {
          // Open or get existing DM
          const dmResult = await client.conversations.open({ users: user.id! });
          return dmResult.channel!.id!;
        }
        throw new Error(`User not found: ${channelInput}`);
      }
    
      return channelInput; // Return as-is if no special format
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/oregpt/Agenticledger_MCP_Slack'

If you have feedback or need assistance with the MCP directory API, please join our Discord server