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

133 lines (114 loc) 3.94 kB
/** * List tasks functionality */ const { callGraphAPI } = require('../utils/graph-api'); const { ensureAuthenticated } = require('../auth'); const config = require('../config'); /** * List tasks handler * @param {object} args - Tool arguments * @returns {object} - MCP response */ async function handleListTasks(args) { try { const { listId, status = 'all', // all, notStarted, inProgress, completed count = config.DEFAULT_PAGE_SIZE, orderBy = 'createdDateTime desc' } = 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/todo/lists'; // If no specific list ID is provided, get tasks from all lists if (listId) { apiPath = `me/todo/lists/${listId}/tasks`; } else { // Get default task list const listsResponse = await callGraphAPI(accessToken, 'GET', apiPath, null, { '$select': 'id,displayName,isOwner' }); const defaultList = listsResponse.value.find(list => list.displayName === 'Tasks') || listsResponse.value[0]; if (!defaultList) { return { error: { code: -32603, message: "No task lists found" } }; } apiPath = `me/todo/lists/${defaultList.id}/tasks`; } // Build query parameters const queryParams = { '$select': config.TASKS_SELECT_FIELDS, '$top': validCount, '$orderby': orderBy }; // Add status filter if specified if (status !== 'all') { queryParams['$filter'] = `status eq '${status}'`; } console.error(`Fetching ${validCount} tasks with status: ${status}`); // Make API call const response = await callGraphAPI(accessToken, 'GET', apiPath, null, queryParams); const tasks = response.value || []; // Format the response const formatDate = (dateStr) => { if (!dateStr) return 'Not set'; return new Date(dateStr).toLocaleDateString(); }; const formatDateTime = (dateStr) => { if (!dateStr) return 'Not set'; return new Date(dateStr).toLocaleString(); }; const getStatusIcon = (status) => { switch (status) { case 'completed': return '✅'; case 'inProgress': return '🔄'; case 'notStarted': return '📋'; default: return '❓'; } }; const getImportanceIcon = (importance) => { switch (importance) { case 'high': return '🔴'; case 'normal': return '🟡'; case 'low': return '🟢'; default: return '⚪'; } }; return { content: [ { type: "text", text: `Found ${tasks.length} tasks:\n\n${tasks.map(task => { const title = task.title || 'No title'; const statusIcon = getStatusIcon(task.status); const importanceIcon = getImportanceIcon(task.importance); const dueDate = formatDate(task.dueDateTime?.dateTime); const reminderDate = formatDateTime(task.reminderDateTime?.dateTime); const hasReminder = task.isReminderOn ? '🔔' : ''; return `${statusIcon} ${importanceIcon} ${title} ${hasReminder} ID: ${task.id} Status: ${task.status || 'Not set'} Due: ${dueDate} Reminder: ${reminderDate} Created: ${formatDateTime(task.createdDateTime)} ${task.body?.content ? `Notes: ${task.body.content.substring(0, 100)}...` : ''}`; }).join('\n\n')}` } ] }; } catch (error) { console.error('Error in handleListTasks:', error); return { error: { code: -32603, message: `Failed to list tasks: ${error.message}` } }; } } module.exports = handleListTasks;