UNPKG

outlook-mcp

Version:

Comprehensive MCP server for Claude to access Microsoft Outlook and Teams via Microsoft Graph API - including Email, Calendar, Contacts, Tasks, Teams, Chats, and Online Meetings

868 lines (852 loc) 28.4 kB
/** * Mock data functions for test mode */ /** * Simulates Microsoft Graph API responses for testing * @param {string} method - HTTP method * @param {string} path - API path * @param {object} data - Request data * @param {object} queryParams - Query parameters * @returns {object} - Simulated API response */ function simulateGraphAPIResponse(method, path, data, queryParams) { console.error(`Simulating response for: ${method} ${path}`); if (method === 'GET') { // Contacts endpoints if (path.includes('contacts')) { if (path.includes('/contacts/')) { // Single contact response return { id: "simulated-contact-id", displayName: "John Doe", givenName: "John", surname: "Doe", emailAddresses: [{ address: "john.doe@example.com", name: "John Doe" }], businessPhones: ["+1 555 123 4567"], mobilePhone: "+1 555 987 6543", companyName: "Example Corp", jobTitle: "Software Engineer", department: "Engineering", businessAddress: { street: "123 Business St", city: "Tech City", state: "TC", postalCode: "12345" } }; } else { // Contacts list response return { value: [ { id: "contact-1", displayName: "John Doe", emailAddresses: [{ address: "john.doe@example.com" }], businessPhones: ["+1 555 123 4567"], companyName: "Example Corp", jobTitle: "Software Engineer" }, { id: "contact-2", displayName: "Jane Smith", emailAddresses: [{ address: "jane.smith@example.com" }], businessPhones: ["+1 555 234 5678"], companyName: "Tech Inc", jobTitle: "Product Manager" } ] }; } } // Tasks endpoints if (path.includes('todo')) { if (path.includes('/tasks/')) { // Single task response return { id: "simulated-task-id", title: "Complete project documentation", status: "notStarted", importance: "high", isReminderOn: true, dueDateTime: { dateTime: new Date(Date.now() + 86400000).toISOString(), // Tomorrow timeZone: "UTC" }, body: { content: "Write comprehensive documentation for the new feature", contentType: "text" }, categories: ["Work", "Documentation"] }; } else if (path.includes('/tasks')) { // Tasks list response return { value: [ { id: "task-1", title: "Complete project documentation", status: "notStarted", importance: "high", isReminderOn: true, dueDateTime: { dateTime: new Date(Date.now() + 86400000).toISOString() }, body: { content: "Write comprehensive documentation" } }, { id: "task-2", title: "Review code changes", status: "inProgress", importance: "normal", isReminderOn: false, dueDateTime: { dateTime: new Date(Date.now() + 172800000).toISOString() }, body: { content: "Review pull requests from team" } } ] }; } else if (path.includes('/lists')) { // Task lists response return { value: [ { id: "list-1", displayName: "Tasks", isOwner: true, isShared: false, wellknownListName: "defaultList" }, { id: "list-2", displayName: "Work Projects", isOwner: true, isShared: true, wellknownListName: null } ] }; } } // Calendar endpoints if (path.includes('events')) { if (path.includes('/events/')) { // Single event response return { id: "simulated-event-id", subject: "Team Meeting", start: { dateTime: new Date(Date.now() + 3600000).toISOString(), // 1 hour from now timeZone: "UTC" }, end: { dateTime: new Date(Date.now() + 7200000).toISOString(), // 2 hours from now timeZone: "UTC" }, location: { displayName: "Conference Room A" }, attendees: [ { emailAddress: { name: "John Doe", address: "john.doe@example.com" } } ], organizer: { emailAddress: { name: "Meeting Organizer", address: "organizer@example.com" } }, bodyPreview: "Weekly team sync meeting", isAllDay: false, isCancelled: false }; } else { // Events list response return { value: [ { id: "event-1", subject: "Team Meeting", start: { dateTime: new Date(Date.now() + 3600000).toISOString() }, end: { dateTime: new Date(Date.now() + 7200000).toISOString() }, location: { displayName: "Conference Room A" }, attendees: [{ emailAddress: { name: "John Doe", address: "john.doe@example.com" } }], organizer: { emailAddress: { name: "Organizer", address: "organizer@example.com" } }, bodyPreview: "Weekly team sync meeting", isAllDay: false, isCancelled: false } ] }; } } // Teams endpoints if (path.includes('joinedTeams') || path.includes('teams/')) { if (path.includes('/teams/')) { // Single team response return { id: "simulated-team-id", displayName: "Development Team", description: "Main development team for the project - comprehensive simulation", visibility: "private", createdDateTime: new Date(Date.now() - 86400000 * 30).toISOString(), memberSettings: { allowCreateUpdateChannels: true, allowDeleteChannels: false, allowAddRemoveApps: true, allowCreateUpdateRemoveConnectors: true, allowCreateUpdateRemoveTabs: true }, messagingSettings: { allowUserEditMessages: true, allowUserDeleteMessages: true, allowOwnerDeleteMessages: true, allowTeamMentions: true, allowChannelMentions: true }, guestSettings: { allowCreateUpdateChannels: false, allowDeleteChannels: false }, funSettings: { allowGiphy: true, giphyContentRating: "moderate", allowStickersAndMemes: true, allowCustomMemes: true }, discoverySettings: { showInTeamsSearchAndSuggestions: true }, internalId: "19:team-internal-id-dev" }; } else { // Teams list response return { value: [ { id: "team-1", displayName: "Development Team", description: "Main development team", visibility: "private", memberSettings: { allowCreateUpdateChannels: true }, messagingSettings: { allowUserEditMessages: true }, funSettings: { allowGiphy: true } }, { id: "team-2", displayName: "Marketing Team", description: "Marketing and communications", visibility: "public", memberSettings: { allowCreateUpdateChannels: false }, messagingSettings: { allowUserEditMessages: false }, funSettings: { allowGiphy: false } } ] }; } } // Channels endpoints if (path.includes('channels') && !path.includes('messages')) { if (path.includes('/channels/')) { // Single channel response return { id: "simulated-channel-id", displayName: "General", description: "General discussion channel", email: "general@team.example.com", webUrl: "https://teams.microsoft.com/l/channel/...", membershipType: "standard", createdDateTime: new Date(Date.now() - 86400000 * 20).toISOString(), isFavoriteByDefault: true }; } else { // Channels list response return { value: [ { id: "channel-1", displayName: "General", description: "General discussion", email: "general@team.example.com", webUrl: "https://teams.microsoft.com/l/channel/...", membershipType: "standard", createdDateTime: new Date(Date.now() - 86400000 * 20).toISOString() }, { id: "channel-2", displayName: "Development", description: "Development discussions", email: "dev@team.example.com", webUrl: "https://teams.microsoft.com/l/channel/...", membershipType: "standard", createdDateTime: new Date(Date.now() - 86400000 * 15).toISOString() } ] }; } } // Teams messages endpoints if (path.includes('messages') && (path.includes('teams/') || path.includes('chats/'))) { if (path.includes('/messages/')) { // Single message response return { id: "simulated-message-id", messageType: "message", createdDateTime: new Date(Date.now() - 3600000).toISOString(), lastModifiedDateTime: new Date(Date.now() - 3600000).toISOString(), from: { user: { id: "user-1", displayName: "John Doe", userIdentityType: "aadUser" } }, body: { contentType: "html", content: "<div>This is a simulated Teams message content</div>" }, attachments: [], mentions: [], importance: "normal", locale: "en-US", subject: null, webUrl: "https://teams.microsoft.com/l/message/..." }; } else { // Messages list response return { value: [ { id: "message-1", messageType: "message", createdDateTime: new Date(Date.now() - 3600000).toISOString(), from: { user: { id: "user-1", displayName: "John Doe" } }, body: { contentType: "html", content: "<div>Hello team! How is everyone doing?</div>" }, attachments: [], mentions: [], importance: "normal" }, { id: "message-2", messageType: "message", createdDateTime: new Date(Date.now() - 7200000).toISOString(), from: { user: { id: "user-2", displayName: "Jane Smith" } }, body: { contentType: "html", content: "<div>Good morning! Ready for the sprint review?</div>" }, attachments: [], mentions: [], importance: "high" } ] }; } } // Chats endpoints if (path.includes('chats') && !path.includes('messages')) { if (path.includes('/chats/')) { // Single chat response return { id: "simulated-chat-id", topic: "Project Discussion", chatType: "group", createdDateTime: new Date(Date.now() - 86400000 * 5).toISOString(), lastUpdatedDateTime: new Date(Date.now() - 3600000).toISOString(), webUrl: "https://teams.microsoft.com/l/chat/...", tenantId: "tenant-id", onlineMeetingInfo: null }; } else { // Chats list response return { value: [ { id: "chat-1", topic: "Project Discussion", chatType: "group", createdDateTime: new Date(Date.now() - 86400000 * 5).toISOString(), lastUpdatedDateTime: new Date(Date.now() - 3600000).toISOString(), webUrl: "https://teams.microsoft.com/l/chat/..." }, { id: "chat-2", topic: "One-on-One", chatType: "oneOnOne", createdDateTime: new Date(Date.now() - 86400000 * 10).toISOString(), lastUpdatedDateTime: new Date(Date.now() - 7200000).toISOString(), webUrl: "https://teams.microsoft.com/l/chat/..." } ] }; } } // Presence endpoints if (path.includes('presence')) { return { id: "user-presence-id", availability: "Available", activity: "Available", statusMessage: "Working on important project" }; } // Online meetings endpoints if (path.includes('onlineMeetings')) { if (path.includes('/onlineMeetings/')) { // Single meeting response return { id: "simulated-meeting-id", subject: "Team Sync Meeting", startDateTime: new Date(Date.now() + 3600000).toISOString(), endDateTime: new Date(Date.now() + 7200000).toISOString(), joinWebUrl: "https://teams.microsoft.com/l/meetup-join/...", allowedPresenters: "organizer", isEntryExitAnnounced: false, allowAttendeeToEnableCamera: true, allowAttendeeToEnableMic: true, allowTeamworkReactions: true, audioConferencing: { conferenceId: "123456789", tollNumber: "+1 555-123-4567", tollFreeNumber: "+1 800-123-4567" }, participants: { organizer: { identity: { user: { id: "organizer-id", displayName: "Meeting Organizer" } } } } }; } else { // Meetings list response return { value: [ { id: "meeting-1", subject: "Team Sync Meeting", startDateTime: new Date(Date.now() + 3600000).toISOString(), endDateTime: new Date(Date.now() + 7200000).toISOString(), joinWebUrl: "https://teams.microsoft.com/l/meetup-join/...", allowedPresenters: "organizer", isEntryExitAnnounced: false, audioConferencing: { conferenceId: "123456789" } }, { id: "meeting-2", subject: "Project Review", startDateTime: new Date(Date.now() + 86400000).toISOString(), endDateTime: new Date(Date.now() + 86400000 + 3600000).toISOString(), joinWebUrl: "https://teams.microsoft.com/l/meetup-join/...", allowedPresenters: "everyone", isEntryExitAnnounced: true, audioConferencing: { conferenceId: "987654321" } } ] }; } } // Team members endpoints if (path.includes('members')) { return { value: [ { id: "member-1", displayName: "John Doe", email: "john.doe@example.com", roles: ["owner"], userId: "user-id-1", tenantId: "tenant-id" }, { id: "member-2", displayName: "Jane Smith", email: "jane.smith@example.com", roles: ["member"], userId: "user-id-2", tenantId: "tenant-id" } ] }; } // Calendars endpoints if (path.includes('calendars') && !path.includes('events')) { if (path.includes('/calendars/')) { // Single calendar response return { id: "simulated-calendar-id", name: "Work Calendar", color: "lightBlue", isDefaultCalendar: true, canShare: true, canViewPrivateItems: true, canEdit: true, owner: { name: "You", address: "you@example.com" } }; } else { // Calendars list response return { value: [ { id: "calendar-1", name: "Calendar", color: "lightBlue", isDefaultCalendar: true, canShare: true, canViewPrivateItems: true, canEdit: true, owner: { name: "You", address: "you@example.com" } }, { id: "calendar-2", name: "Work Calendar", color: "lightGreen", isDefaultCalendar: false, canShare: true, canViewPrivateItems: true, canEdit: true, owner: { name: "You", address: "you@example.com" } } ] }; } } if (path.includes('messages') && !path.includes('sendMail')) { // Simulate a successful email list/search response if (path.includes('/messages/')) { // Single email response return { id: "simulated-email-id", subject: "Simulated Email Subject", from: { emailAddress: { name: "Simulated Sender", address: "sender@example.com" } }, toRecipients: [{ emailAddress: { name: "Recipient Name", address: "recipient@example.com" } }], ccRecipients: [], bccRecipients: [], receivedDateTime: new Date().toISOString(), bodyPreview: "This is a simulated email preview...", body: { contentType: "text", content: "This is the full content of the simulated email. Since we can't connect to the real Microsoft Graph API, we're returning this placeholder content instead." }, hasAttachments: false, importance: "normal", isRead: false, internetMessageHeaders: [] }; } else { // Email list response return { value: [ { id: "simulated-email-1", subject: "Important Meeting Tomorrow", from: { emailAddress: { name: "John Doe", address: "john@example.com" } }, toRecipients: [{ emailAddress: { name: "You", address: "you@example.com" } }], ccRecipients: [], receivedDateTime: new Date().toISOString(), bodyPreview: "Let's discuss the project status...", hasAttachments: false, importance: "high", isRead: false }, { id: "simulated-email-2", subject: "Weekly Report", from: { emailAddress: { name: "Jane Smith", address: "jane@example.com" } }, toRecipients: [{ emailAddress: { name: "You", address: "you@example.com" } }], ccRecipients: [], receivedDateTime: new Date(Date.now() - 86400000).toISOString(), // Yesterday bodyPreview: "Please find attached the weekly report...", hasAttachments: true, importance: "normal", isRead: true }, { id: "simulated-email-3", subject: "Question about the project", from: { emailAddress: { name: "Bob Johnson", address: "bob@example.com" } }, toRecipients: [{ emailAddress: { name: "You", address: "you@example.com" } }], ccRecipients: [], receivedDateTime: new Date(Date.now() - 172800000).toISOString(), // 2 days ago bodyPreview: "I had a question about the timeline...", hasAttachments: false, importance: "normal", isRead: false } ] }; } } else if (path.includes('mailFolders')) { // Simulate a mail folders response return { value: [ { id: "inbox", displayName: "Inbox" }, { id: "drafts", displayName: "Drafts" }, { id: "sentItems", displayName: "Sent Items" }, { id: "deleteditems", displayName: "Deleted Items" } ] }; } } else if (method === 'POST') { if (path.includes('sendMail')) { // Simulate a successful email send return {}; } else if (path.includes('contacts')) { // Simulate contact creation return { id: "new-contact-id", displayName: data.displayName || "New Contact", ...data }; } else if (path.includes('todo/lists') && path.includes('/tasks')) { // Simulate task creation return { id: "new-task-id", title: data.title || "New Task", status: "notStarted", importance: data.importance || "normal", ...data }; } else if (path.includes('todo/lists') && !path.includes('/tasks')) { // Simulate task list creation return { id: "new-list-id", displayName: data.displayName || "New List", isOwner: true, isShared: false, ...data }; } else if (path.includes('calendars') && !path.includes('events')) { // Simulate calendar creation return { id: "new-calendar-id", name: data.name || "New Calendar", color: data.color || "lightBlue", isDefaultCalendar: false, canShare: true, canViewPrivateItems: true, canEdit: true, ...data }; } else if (path.includes('events')) { // Simulate event creation return { id: "new-event-id", subject: data.subject || "New Event", start: data.start || { dateTime: new Date().toISOString() }, end: data.end || { dateTime: new Date(Date.now() + 3600000).toISOString() }, ...data }; } else if (path.includes('teams/') && path.includes('channels')) { // Simulate channel creation return { id: "new-channel-id", displayName: data.displayName || "New Channel", description: data.description || "", membershipType: data.membershipType || "standard", email: `${data.displayName?.toLowerCase().replace(/\s+/g, '')}@team.example.com`, webUrl: "https://teams.microsoft.com/l/channel/...", ...data }; } else if (path.includes('chats') && !path.includes('messages')) { // Simulate chat creation return { id: "new-chat-id", topic: data.topic || "New Chat", chatType: data.chatType || "group", createdDateTime: new Date().toISOString(), lastUpdatedDateTime: new Date().toISOString(), webUrl: "https://teams.microsoft.com/l/chat/...", ...data }; } else if (path.includes('messages')) { // Simulate message sending return { id: "new-message-id", messageType: "message", createdDateTime: new Date().toISOString(), lastModifiedDateTime: new Date().toISOString(), from: { user: { id: "current-user-id", displayName: "Current User" } }, body: { contentType: data.body?.contentType || "html", content: data.body?.content || data.content || "Message content" }, importance: data.importance || "normal", ...data }; } else if (path.includes('onlineMeetings')) { // Simulate online meeting creation return { id: "new-meeting-id", subject: data.subject || "New Meeting", startDateTime: data.startDateTime || new Date(Date.now() + 3600000).toISOString(), endDateTime: data.endDateTime || new Date(Date.now() + 7200000).toISOString(), joinWebUrl: "https://teams.microsoft.com/l/meetup-join/...", allowedPresenters: data.allowedPresenters || "organizer", isEntryExitAnnounced: data.isEntryExitAnnounced || false, allowAttendeeToEnableCamera: data.allowAttendeeToEnableCamera !== false, allowAttendeeToEnableMic: data.allowAttendeeToEnableMic !== false, allowTeamworkReactions: data.allowTeamworkReactions !== false, audioConferencing: { conferenceId: "123456789", tollNumber: "+1 555-123-4567" }, ...data }; } else if (path.includes('presence/setPresence')) { // Simulate presence setting return {}; } else if (path.includes('getPresencesByUserId')) { // Simulate multiple users presence return { value: (data.ids || []).map(id => ({ id: id, availability: "Available", activity: "Available", statusMessage: "Simulated status" })) }; } else if (path.includes('reply') || path.includes('forward')) { // Simulate email reply/forward return {}; } } else if (method === 'PATCH') { // Simulate updates - return the updated object if (path.includes('contacts')) { return { id: path.split('/').pop(), displayName: data.displayName || "Updated Contact", ...data }; } else if (path.includes('todo') && path.includes('/tasks/')) { return { id: path.split('/').pop(), title: data.title || "Updated Task", ...data }; } else if (path.includes('calendars') && !path.includes('events')) { return { id: path.split('/').pop(), name: data.name || "Updated Calendar", ...data }; } else if (path.includes('events')) { return { id: path.split('/').pop(), subject: data.subject || "Updated Event", ...data }; } else if (path.includes('messages')) { return { id: path.split('/').pop(), subject: "Updated Email", ...data }; } else if (path.includes('teams/') && path.includes('channels')) { return { id: path.split('/').pop(), displayName: data.displayName || "Updated Channel", description: data.description || "", membershipType: "standard", ...data }; } else if (path.includes('onlineMeetings')) { return { id: path.split('/').pop(), subject: data.subject || "Updated Meeting", startDateTime: data.startDateTime || new Date(Date.now() + 3600000).toISOString(), endDateTime: data.endDateTime || new Date(Date.now() + 7200000).toISOString(), joinWebUrl: "https://teams.microsoft.com/l/meetup-join/...", ...data }; } } else if (method === 'DELETE') { // Simulate successful deletion return {}; } // If we get here, we don't have a simulation for this endpoint console.error(`No simulation available for: ${method} ${path}`); return {}; } module.exports = { simulateGraphAPIResponse };