Skip to main content
Glama

Enhanced Outlook MCP Server

by jibberish69
create.js11.5 kB
const config = require('../config'); const logger = require('../utils/logger'); const { GraphApiClient } = require('../utils/graph-api'); /** * Create a new mail rule * @param {Object} params - Tool parameters * @returns {Promise<Object>} - Creation result */ async function createRuleHandler(params = {}) { const userId = params.userId || 'default'; if (!params.displayName) { return { status: 'error', message: 'Rule display name is required' }; } // Validate that at least one condition is provided if (!params.conditions || Object.keys(params.conditions).length === 0) { return { status: 'error', message: 'At least one condition is required for the rule' }; } // Validate that at least one action is provided if (!params.actions || Object.keys(params.actions).length === 0) { return { status: 'error', message: 'At least one action is required for the rule' }; } try { logger.info(`Creating mail rule "${params.displayName}" for user ${userId}`); const graphClient = new GraphApiClient(userId); // Format conditions object const conditions = formatRuleConditions(params.conditions); // Format actions object const actions = formatRuleActions(params.actions); // Create rule data const ruleData = { displayName: params.displayName, sequence: params.sequence || 0, isEnabled: params.isEnabled !== false, conditions, actions }; // Create the rule const rule = await graphClient.post('/me/mailFolders/inbox/messageRules', ruleData); return { status: 'success', message: 'Rule created successfully', ruleId: rule.id, displayName: rule.displayName }; } catch (error) { logger.error(`Error creating mail rule: ${error.message}`); return { status: 'error', message: `Failed to create mail rule: ${error.message}` }; } } /** * Update an existing mail rule * @param {Object} params - Tool parameters * @returns {Promise<Object>} - Update result */ async function updateRuleHandler(params = {}) { const userId = params.userId || 'default'; const ruleId = params.ruleId; if (!ruleId) { return { status: 'error', message: 'Rule ID is required' }; } try { logger.info(`Updating mail rule ${ruleId} for user ${userId}`); const graphClient = new GraphApiClient(userId); // Prepare update data const updateData = {}; if (params.displayName) { updateData.displayName = params.displayName; } if (params.sequence !== undefined) { updateData.sequence = params.sequence; } if (params.isEnabled !== undefined) { updateData.isEnabled = params.isEnabled; } if (params.conditions) { updateData.conditions = formatRuleConditions(params.conditions); } if (params.actions) { updateData.actions = formatRuleActions(params.actions); } // Update the rule await graphClient.patch(`/me/mailFolders/inbox/messageRules/${ruleId}`, updateData); return { status: 'success', message: 'Rule updated successfully', ruleId }; } catch (error) { logger.error(`Error updating mail rule: ${error.message}`); return { status: 'error', message: `Failed to update mail rule: ${error.message}` }; } } /** * Delete a mail rule * @param {Object} params - Tool parameters * @returns {Promise<Object>} - Deletion result */ async function deleteRuleHandler(params = {}) { const userId = params.userId || 'default'; const ruleId = params.ruleId; if (!ruleId) { return { status: 'error', message: 'Rule ID is required' }; } try { logger.info(`Deleting mail rule ${ruleId} for user ${userId}`); const graphClient = new GraphApiClient(userId); // Delete the rule await graphClient.delete(`/me/mailFolders/inbox/messageRules/${ruleId}`); return { status: 'success', message: 'Rule deleted successfully', ruleId }; } catch (error) { logger.error(`Error deleting mail rule: ${error.message}`); return { status: 'error', message: `Failed to delete mail rule: ${error.message}` }; } } /** * Format rule conditions for API * @param {Object} conditions - Rule conditions from user * @returns {Object} - Formatted conditions for Graph API */ function formatRuleConditions(conditions) { const formattedConditions = {}; // Process each condition type if (conditions.bodyContains) { formattedConditions.bodyContains = Array.isArray(conditions.bodyContains) ? conditions.bodyContains : [conditions.bodyContains]; } if (conditions.bodyOrSubjectContains) { formattedConditions.bodyOrSubjectContains = Array.isArray(conditions.bodyOrSubjectContains) ? conditions.bodyOrSubjectContains : [conditions.bodyOrSubjectContains]; } if (conditions.categories) { formattedConditions.categories = Array.isArray(conditions.categories) ? conditions.categories : [conditions.categories]; } if (conditions.fromAddresses) { formattedConditions.fromAddresses = formatEmailAddresses(conditions.fromAddresses); } if (conditions.hasAttachments !== undefined) { formattedConditions.hasAttachments = conditions.hasAttachments; } if (conditions.headerContains) { formattedConditions.headerContains = Array.isArray(conditions.headerContains) ? conditions.headerContains : [conditions.headerContains]; } if (conditions.importance) { formattedConditions.importance = conditions.importance; } if (conditions.isApprovalRequest !== undefined) { formattedConditions.isApprovalRequest = conditions.isApprovalRequest; } if (conditions.isAutomaticForward !== undefined) { formattedConditions.isAutomaticForward = conditions.isAutomaticForward; } if (conditions.isAutomaticReply !== undefined) { formattedConditions.isAutomaticReply = conditions.isAutomaticReply; } if (conditions.isEncrypted !== undefined) { formattedConditions.isEncrypted = conditions.isEncrypted; } if (conditions.isMeetingRequest !== undefined) { formattedConditions.isMeetingRequest = conditions.isMeetingRequest; } if (conditions.isMeetingResponse !== undefined) { formattedConditions.isMeetingResponse = conditions.isMeetingResponse; } if (conditions.isReadReceipt !== undefined) { formattedConditions.isReadReceipt = conditions.isReadReceipt; } if (conditions.messageActionFlag) { formattedConditions.messageActionFlag = conditions.messageActionFlag; } if (conditions.notSentToMe !== undefined) { formattedConditions.notSentToMe = conditions.notSentToMe; } if (conditions.recipientContains) { formattedConditions.recipientContains = Array.isArray(conditions.recipientContains) ? conditions.recipientContains : [conditions.recipientContains]; } if (conditions.senderContains) { formattedConditions.senderContains = Array.isArray(conditions.senderContains) ? conditions.senderContains : [conditions.senderContains]; } if (conditions.sensitivity) { formattedConditions.sensitivity = conditions.sensitivity; } if (conditions.sentCcMe !== undefined) { formattedConditions.sentCcMe = conditions.sentCcMe; } if (conditions.sentOnlyToMe !== undefined) { formattedConditions.sentOnlyToMe = conditions.sentOnlyToMe; } if (conditions.sentToAddresses) { formattedConditions.sentToAddresses = formatEmailAddresses(conditions.sentToAddresses); } if (conditions.sentToMe !== undefined) { formattedConditions.sentToMe = conditions.sentToMe; } if (conditions.sentToOrCcMe !== undefined) { formattedConditions.sentToOrCcMe = conditions.sentToOrCcMe; } if (conditions.subjectContains) { formattedConditions.subjectContains = Array.isArray(conditions.subjectContains) ? conditions.subjectContains : [conditions.subjectContains]; } if (conditions.withinSizeRange) { formattedConditions.withinSizeRange = conditions.withinSizeRange; } return formattedConditions; } /** * Format rule actions for API * @param {Object} actions - Rule actions from user * @returns {Object} - Formatted actions for Graph API */ function formatRuleActions(actions) { const formattedActions = {}; // Process each action type if (actions.assignCategories) { formattedActions.assignCategories = Array.isArray(actions.assignCategories) ? actions.assignCategories : [actions.assignCategories]; } if (actions.copyToFolder) { formattedActions.copyToFolder = actions.copyToFolder; } if (actions.delete !== undefined) { formattedActions.delete = actions.delete; } if (actions.forwardAsAttachmentTo) { formattedActions.forwardAsAttachmentTo = formatEmailAddresses(actions.forwardAsAttachmentTo); } if (actions.forwardTo) { formattedActions.forwardTo = formatEmailAddresses(actions.forwardTo); } if (actions.markAsRead !== undefined) { formattedActions.markAsRead = actions.markAsRead; } if (actions.markImportance) { formattedActions.markImportance = actions.markImportance; } if (actions.moveToFolder) { formattedActions.moveToFolder = actions.moveToFolder; } if (actions.permanentDelete !== undefined) { formattedActions.permanentDelete = actions.permanentDelete; } if (actions.redirectTo) { formattedActions.redirectTo = formatEmailAddresses(actions.redirectTo); } if (actions.stopProcessingRules !== undefined) { formattedActions.stopProcessingRules = actions.stopProcessingRules; } return formattedActions; } /** * Format email addresses for API * @param {Array|string|Object} addresses - Email addresses in various formats * @returns {Array} - Formatted email addresses */ function formatEmailAddresses(addresses) { if (!addresses) { return []; } // Handle string with comma or semicolon separators if (typeof addresses === 'string') { addresses = addresses.split(/[,;]/).map(a => a.trim()).filter(Boolean); } // Ensure it's an array if (!Array.isArray(addresses)) { addresses = [addresses]; } // Format each address return addresses.map(address => { // If already in the correct format if (typeof address === 'object' && address.emailAddress) { return address; } // Handle string in format "Name <email@example.com>" if (typeof address === 'string') { const match = address.match(/^(.*?)\s*<([^>]+)>$/); if (match) { return { emailAddress: { name: match[1].trim(), address: match[2].trim() } }; } // Just an email address return { emailAddress: { address: address.trim() } }; } // Handle object with name and email properties if (typeof address === 'object' && address.email) { return { emailAddress: { name: address.name || '', address: address.email } }; } // Default case return { emailAddress: { address: String(address) } }; }); } module.exports = { createRuleHandler, updateRuleHandler, deleteRuleHandler };

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/jibberish69/enhanced-outlook-mcp'

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