UNPKG

teams-mcp-server

Version:

Microsoft Teams MCP server with direct messaging support

136 lines (135 loc) 4.88 kB
import { Client } from '@microsoft/microsoft-graph-client'; import { RateLimiter } from './rateLimiter.js'; export class TeamsClientStateless { rateLimiter; constructor() { this.rateLimiter = new RateLimiter(); } createClient(accessToken) { return Client.init({ authProvider: async (done) => { done(null, accessToken); } }); } async getUserProfile(accessToken) { return this.rateLimiter.execute(async () => { const client = this.createClient(accessToken); try { return await client.api('/me').get(); } catch (error) { throw this.handleError(error); } }); } async listChats(accessToken, limit = 50, filter) { return this.rateLimiter.execute(async () => { const client = this.createClient(accessToken); const chats = []; try { let request = client.api('/chats') .select('id,topic,chatType,createdDateTime,lastUpdatedDateTime,webUrl,tenantId') .top(limit); if (filter) { request = request.filter(filter); } const response = await request.get(); if (response.value) { chats.push(...response.value); } return chats; } catch (error) { throw this.handleError(error); } }); } async createChat(accessToken, request) { return this.rateLimiter.execute(async () => { const client = this.createClient(accessToken); const members = await Promise.all(request.members.map(async (member) => { const userResponse = await client .api(`/users/${member.email}`) .select('id') .get(); return { '@odata.type': '#microsoft.graph.aadUserConversationMember', roles: [member.role || 'owner'], 'user@odata.bind': `https://graph.microsoft.com/v1.0/users('${userResponse.id}')` }; })); const chatData = { chatType: request.chatType, members }; if (request.topic && request.chatType === 'group') { chatData.topic = request.topic; } try { return await client.api('/chats').post(chatData); } catch (error) { throw this.handleError(error); } }); } async sendMessage(accessToken, chatId, request) { return this.rateLimiter.execute(async () => { const client = this.createClient(accessToken); const messageData = { body: { contentType: request.contentType || 'text', content: request.content } }; try { return await client.api(`/chats/${chatId}/messages`).post(messageData); } catch (error) { throw this.handleError(error); } }); } async getMessages(accessToken, chatId, limit = 50, orderBy = 'createdDateTime desc') { return this.rateLimiter.execute(async () => { const client = this.createClient(accessToken); const messages = []; try { const response = await client .api(`/chats/${chatId}/messages`) .top(limit) .orderby(orderBy) .get(); if (response.value) { messages.push(...response.value); } return messages; } catch (error) { throw this.handleError(error); } }); } getRateLimitStats() { return this.rateLimiter.getStats(); } handleError(error) { if (error.statusCode === 401) { return new Error('Authentication failed. Token may be expired or invalid.'); } if (error.statusCode === 403) { return new Error('Insufficient permissions. Make sure the app has the required permissions.'); } if (error.statusCode === 404) { return new Error('Resource not found. Check that the chat or user exists.'); } if (error.statusCode === 429) { return new Error('Rate limit exceeded. Please wait before making more requests.'); } if (error.message) { return new Error(`Teams API error: ${error.message}`); } return new Error('Unknown Teams API error'); } }