Skip to main content
Glama

Github Project Manager

channel-operations.ts8.22 kB
import { BaseSlackTool } from './base-slack-tool.js'; import { SlackChannel } from '../types/slack-channel.js'; /** * Tool for Slack channel operations */ export class ChannelOperationsTool extends BaseSlackTool { /** * List channels in the workspace * * @param limit Maximum number of channels to return (default: 100, max: 200) * @param cursor Pagination cursor for next page * @returns Formatted response with channels information */ async listChannels(limit?: number, cursor?: string) { try { // Set reasonable defaults and limits const actualLimit = limit && limit > 0 ? Math.min(limit, 200) : 100; const result = await this.client.conversations.list({ limit: actualLimit, cursor: cursor, types: 'public_channel', exclude_archived: true, }); const channels = result.channels as unknown as SlackChannel[]; const formattedChannels = channels.map((channel) => ({ id: channel.id, name: channel.name, is_private: channel.is_private, num_members: channel.num_members, topic: channel.topic?.value ? channel.topic.value : '', purpose: channel.purpose?.value ? channel.purpose.value : '', })); let responseText = `Found ${formattedChannels.length} channels`; if (result.response_metadata?.next_cursor) { responseText += `\nUse cursor: ${result.response_metadata.next_cursor} to get the next page`; } responseText += `\n\n${JSON.stringify(formattedChannels, null, 2)}`; return this.createResponse(responseText); } catch (error) { return this.handleError(error, 'list channels'); } } /** * Get channel history (recent messages) * * @param channelId The channel ID * @param limit Number of messages to retrieve (default: 10) * @returns Formatted response with channel messages */ async getChannelHistory(channelId: string, limit?: number) { try { // Set reasonable defaults const actualLimit = limit && limit > 0 ? Math.min(limit, 100) : 10; const result = await this.client.conversations.history({ channel: channelId, limit: actualLimit, }); const messages = result.messages || []; let responseText = `Retrieved ${messages.length} messages from channel ${channelId}`; responseText += `\n\n${JSON.stringify(messages, null, 2)}`; return this.createResponse(responseText); } catch (error) { return this.handleError(error, `get history for channel ${channelId}`); } } /** * Create a new channel * * @param name Channel name (must be lowercase, no spaces/special chars except underscore) * @param isPrivate Whether to create a private channel * @param description Optional initial description/purpose for the channel * @returns Formatted response with the new channel information */ async createChannel(name: string, isPrivate: boolean, description?: string) { try { // Channel names must only contain lowercase letters, numbers, hyphens, and underscores const sanitizedName = name.toLowerCase().replace(/[^a-z0-9-_]/g, ''); if (sanitizedName !== name) { console.warn(`Channel name was sanitized from "${name}" to "${sanitizedName}"`); } const result = await this.client.conversations.create({ name: sanitizedName, is_private: isPrivate, }); // Set channel purpose if provided if (description && result.channel?.id) { await this.client.conversations.setPurpose({ channel: result.channel.id, purpose: description, }); } const channel = result.channel as unknown as SlackChannel; let responseText = `Successfully created ${isPrivate ? 'private' : 'public'} channel #${channel.name} (${channel.id})`; if (description) { responseText += ` with purpose: "${description}"`; } responseText += `\n\n${JSON.stringify(channel, null, 2)}`; return this.createResponse(responseText); } catch (error) { return this.handleError(error, 'create channel'); } } /** * Archive a channel * * @param channelId The channel ID to archive * @returns Formatted response with the operation result */ async archiveChannel(channelId: string) { try { await this.client.conversations.archive({ channel: channelId, }); return this.createResponse(`Successfully archived channel ${channelId}`); } catch (error) { return this.handleError(error, `archive channel ${channelId}`); } } /** * Unarchive a channel * * @param channelId The channel ID to unarchive * @returns Formatted response with the operation result */ async unarchiveChannel(channelId: string) { try { await this.client.conversations.unarchive({ channel: channelId, }); return this.createResponse(`Successfully unarchived channel ${channelId}`); } catch (error) { return this.handleError(error, `unarchive channel ${channelId}`); } } /** * Invite users to a channel * * @param channelId The channel ID * @param userIds Array of user IDs to invite * @returns Formatted response with the operation result */ async inviteToChannel(channelId: string, userIds: string[]) { try { if (!userIds.length) { return this.createResponse('No users specified to invite'); } const promises = userIds.map((userId) => this.client.conversations.invite({ channel: channelId, users: userId, }), ); await Promise.all(promises); return this.createResponse(`Successfully invited ${userIds.length} user(s) to channel ${channelId}`); } catch (error) { return this.handleError(error, `invite users to channel ${channelId}`); } } /** * Get detailed information about a channel * * @param channelId The channel ID * @returns Formatted response with channel information */ async getChannelInfo(channelId: string) { try { const result = await this.client.conversations.info({ channel: channelId, }); const channel = result.channel as unknown as SlackChannel; // Get member count const memberResult = await this.client.conversations.members({ channel: channelId, limit: 1, // We only need the count, not the actual members }); const memberCount = memberResult.members?.length || 0; const hasMoreMembers = !!memberResult.response_metadata?.next_cursor; let responseText = `Channel Information for ${channel.name} (${channel.id}):\n`; responseText += `- Type: ${channel.is_private ? 'Private' : 'Public'}\n`; responseText += `- Members: ${memberCount}${hasMoreMembers ? '+' : ''}\n`; if (channel.topic?.value) { responseText += `- Topic: ${channel.topic.value}\n`; } if (channel.purpose?.value) { responseText += `- Purpose: ${channel.purpose.value}\n`; } responseText += `\n${JSON.stringify(channel, null, 2)}`; return this.createResponse(responseText); } catch (error) { return this.handleError(error, `get info for channel ${channelId}`); } } }

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/Monsoft-Solutions/model-context-protocols'

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