Skip to main content
Glama

Mattermost MCP Server

index.ts6.81 kB
import { MattermostClient } from '../client/mattermost-client'; import { MattermostConfig } from '../config/config'; import { ActionTracker } from '../utils/action-tracker'; import { HandlerChannel } from './handler-channel'; import { HandlerPost } from './handler-post'; import { HandlerReaction } from './handler-reaction'; import { HandlerUser } from './handler-user'; import { HandlerNeo4j } from './handler-neo4j'; let mattermostClient: MattermostClient | null = null; let actionTracker: ActionTracker | null = null; let clientInitializationPromise: Promise<void> | null = null; /** * Initialize Neo4j Action Tracker if configuration is available * @returns ActionTracker instance or null if not configured */ async function initializeActionTracker(): Promise<ActionTracker | null> { if (actionTracker) { return actionTracker; } const neo4jUri = process.env.NEO4J_URI; const neo4jUsername = process.env.NEO4J_USERNAME; const neo4jPassword = process.env.NEO4J_PASSWORD; if (neo4jUri && neo4jUsername && neo4jPassword) { try { actionTracker = new ActionTracker(neo4jUri, neo4jUsername, neo4jPassword); await actionTracker.connect(); console.error('Neo4j Action Tracker initialized successfully'); return actionTracker; } catch (error) { console.warn('Failed to initialize Neo4j Action Tracker:', error); return null; } } else { console.error('Neo4j configuration not found. Action tracking will be disabled.'); return null; } } /** * Initialize Mattermost client lazily * @param config Mattermost configuration * @returns Promise that resolves when client is initialized */ async function initializeMattermostClient(config: MattermostConfig): Promise<void> { if (mattermostClient) { return; } if (clientInitializationPromise) { return clientInitializationPromise; } clientInitializationPromise = (async () => { try { mattermostClient = new MattermostClient(config); await mattermostClient.init(); console.error('Mattermost client initialized successfully'); } catch (e) { mattermostClient = null; clientInitializationPromise = null; throw new Error( `Initializing mattermost client failed, please check your configuration, Error: ${e}`, ); } })(); return clientInitializationPromise; } /** * Get initialized Mattermost client * @param config Mattermost configuration * @returns Initialized Mattermost client */ async function getMattermostClient(config: MattermostConfig): Promise<MattermostClient> { if (!mattermostClient) { await initializeMattermostClient(config); } if (!mattermostClient) { throw new Error('Mattermost client failed to initialize'); } return mattermostClient; } /** * Create a lazy MCP tool that initializes the client on first use * @param config Mattermost configuration * @param toolFactory Function that creates tools given initialized handlers * @returns Lazy MCP tool */ function createLazyMcpTool( config: MattermostConfig, toolFactory: (handlers: { handlerUser: HandlerUser; handlerChannel: HandlerChannel; handlerPost: HandlerPost; handlerReaction: HandlerReaction; handlerNeo4j: HandlerNeo4j; }) => any, ) { return { ...toolFactory({} as any), // Provide dummy handlers for tool definition handler: async (...args: any[]) => { // Initialize client on first tool invocation const client = await getMattermostClient(config); const tracker = await initializeActionTracker(); // Create real handlers const handlerUser = new HandlerUser(client, tracker); const handlerChannel = new HandlerChannel(client, tracker); const handlerPost = new HandlerPost(client, tracker); const handlerReaction = new HandlerReaction(client, tracker); const handlerNeo4j = new HandlerNeo4j(client, tracker); // Get the actual tool and call its handler const actualTool = toolFactory({ handlerUser, handlerChannel, handlerPost, handlerReaction, handlerNeo4j, }); return actualTool.handler(...args); }, }; } /** * Get MCP tools for Mattermost with lazy initialization * @param config Mattermost configuration * @returns Array of MCP tools */ export async function getMattermostMcpTools(config: MattermostConfig) { // Initialize action tracker early (it's independent of Mattermost) const tracker = await initializeActionTracker(); // Create dummy client for tool definitions (no network calls) const dummyClient = new MattermostClient(config); // Create handlers with dummy client for tool definitions const handlerUser = new HandlerUser(dummyClient, tracker); const handlerChannel = new HandlerChannel(dummyClient, tracker); const handlerPost = new HandlerPost(dummyClient, tracker); const handlerReaction = new HandlerReaction(dummyClient, tracker); const handlerNeo4j = new HandlerNeo4j(dummyClient, tracker); // Get all tool definitions const userTools = handlerUser.getMcpTools(); const channelTools = handlerChannel.getMcpTools(); const postTools = handlerPost.getMcpTools(); const reactionTools = handlerReaction.getMcpTools(); const neo4jTools = handlerNeo4j.getMcpTools(); // Wrap each tool with lazy initialization const tools = [ ...userTools.map(tool => ({ ...tool, handler: async (args: any) => { const client = await getMattermostClient(config); const realHandler = new HandlerUser(client, tracker); const realTool = realHandler.getMcpTools().find(t => t.name === tool.name); return realTool?.handler(args); }, })), ...channelTools.map(tool => ({ ...tool, handler: async (args: any) => { const client = await getMattermostClient(config); const realHandler = new HandlerChannel(client, tracker); const realTool = realHandler.getMcpTools().find(t => t.name === tool.name); return realTool?.handler(args); }, })), ...postTools.map(tool => ({ ...tool, handler: async (args: any) => { const client = await getMattermostClient(config); const realHandler = new HandlerPost(client, tracker); const realTool = realHandler.getMcpTools().find(t => t.name === tool.name); return realTool?.handler(args); }, })), ...reactionTools.map(tool => ({ ...tool, handler: async (args: any) => { const client = await getMattermostClient(config); const realHandler = new HandlerReaction(client, tracker); const realTool = realHandler.getMcpTools().find(t => t.name === tool.name); return realTool?.handler(args); }, })), ...neo4jTools, ]; return tools; }

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/Wagmi-Tech-Co/mcp-mattermost'

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