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

113 lines (95 loc) 3.34 kB
/** * Search contacts functionality */ const { callGraphAPI } = require('../utils/graph-api'); const { ensureAuthenticated } = require('../auth'); const config = require('../config'); /** * Search contacts handler * @param {object} args - Tool arguments * @returns {object} - MCP response */ async function handleSearchContacts(args) { try { const { query = '', name = '', email = '', company = '', jobTitle = '', folder = 'contacts', count = config.DEFAULT_PAGE_SIZE } = args; // Ensure user is authenticated const accessToken = await ensureAuthenticated(); // Validate count parameter const validCount = Math.min(Math.max(1, count), config.MAX_RESULT_COUNT); // Build the API path let apiPath = 'me/contacts'; if (folder && folder !== 'contacts') { apiPath = `me/contactFolders/${folder}/contacts`; } // Build filter conditions const filterConditions = []; if (query) { filterConditions.push(`(contains(displayName,'${query}') or contains(companyName,'${query}') or contains(jobTitle,'${query}'))`); } if (name) { filterConditions.push(`contains(displayName,'${name}')`); } if (email) { filterConditions.push(`emailAddresses/any(e: contains(e/address,'${email}'))`); } if (company) { filterConditions.push(`contains(companyName,'${company}')`); } if (jobTitle) { filterConditions.push(`contains(jobTitle,'${jobTitle}')`); } // Build query parameters const queryParams = { '$select': config.CONTACTS_SELECT_FIELDS, '$top': validCount, '$orderby': 'displayName asc' }; if (filterConditions.length > 0) { queryParams['$filter'] = filterConditions.join(' and '); } console.error(`Searching contacts with filters: ${queryParams['$filter'] || 'none'}`); // Make API call const response = await callGraphAPI(accessToken, 'GET', apiPath, null, queryParams); const contacts = response.value || []; return { content: [ { type: "text", text: `Found ${contacts.length} contacts matching your search:\n\n${contacts.map(contact => { const name = contact.displayName || 'No name'; const company = contact.companyName ? ` (${contact.companyName})` : ''; const emails = contact.emailAddresses && contact.emailAddresses.length > 0 ? contact.emailAddresses.map(e => e.address).join(', ') : 'No email'; const phones = contact.businessPhones && contact.businessPhones.length > 0 ? contact.businessPhones.join(', ') : contact.mobilePhone || 'No phone'; return `📧 ${name}${company} ID: ${contact.id} Email: ${emails} Phone: ${phones} ${contact.jobTitle ? `Title: ${contact.jobTitle}` : ''} ${contact.department ? `Department: ${contact.department}` : ''}`; }).join('\n\n')}` } ] }; } catch (error) { console.error('Error in handleSearchContacts:', error); return { error: { code: -32603, message: `Failed to search contacts: ${error.message}` } }; } } module.exports = handleSearchContacts;