outlook-mcp/email/list.js
Seton Carmichael a7886b5b2b Initial commit: Outlook MCP Server v1.0.0
MCP server providing Microsoft Outlook integration via Graph API:
- Email: list, search, read, send, thread reconstruction
- Calendar: list, create, decline, cancel, delete events
- Folders: list, create, move emails
- Inbox rules: list, create, reorder
- MSAL device code flow auth with persistent token cache
- Test mode with mock data
- Comprehensive README with setup, config, and tool reference

20 MCP tools across 5 modules. Node.js >= 14. MIT license.
2026-06-21 19:39:31 -04:00

100 lines
3.2 KiB
JavaScript

/**
* List emails functionality
*/
const config = require('../config');
const { callGraphAPI } = require('../utils/graph-api');
const { ensureAuthenticated } = require('../auth');
const { buildODataFilter, buildDateFilter } = require('../utils/odata-helpers');
const { resolveFolderPath } = require('./folder-utils');
/**
* List emails handler
* @param {object} args - Tool arguments
* @returns {object} - MCP response
*/
async function handleListEmails(args) {
const folder = args.folder || "inbox";
const count = Math.min(parseInt(args.count, 10) || 10, config.MAX_RESULT_COUNT);
try {
// Get access token
const accessToken = await ensureAuthenticated();
// Resolve folder path using the proper folder utilities
const endpoint = await resolveFolderPath(accessToken, folder);
// Add query parameters
const queryParams = {
$top: count,
$orderby: 'receivedDateTime desc',
$select: config.EMAIL_SELECT_FIELDS
};
// Add date filtering if specified
const dateConditions = buildDateFilter(args.dateFrom, args.dateTo, args.dateRange);
if (dateConditions.length > 0) {
queryParams.$filter = buildODataFilter(dateConditions);
}
// Make API call
const response = await callGraphAPI(accessToken, 'GET', endpoint, null, queryParams);
if (!response.value || response.value.length === 0) {
return {
content: [{
type: "text",
text: `No emails found in ${folder}.`
}]
};
}
// Format results
const emailList = response.value.map((email, index) => {
const sender = email.from ? email.from.emailAddress : { name: 'Unknown', address: 'unknown' };
const date = new Date(email.receivedDateTime).toLocaleString();
const readStatus = email.isRead ? '' : '[UNREAD] ';
const convLine = email.conversationId ? `ConversationID: ${email.conversationId}\n` : '';
return `${index + 1}. ${readStatus}${date} - From: ${sender.name} (${sender.address})\nSubject: ${email.subject}\nID: ${email.id}\n${convLine}`;
}).join("\n");
// Build result message with date filter info
let resultMessage = `Found ${response.value.length} emails in ${folder}`;
if (args.dateRange) {
resultMessage += ` (${args.dateRange})`;
} else if (args.dateFrom || args.dateTo) {
const dateInfo = [];
if (args.dateFrom) dateInfo.push(`from: ${args.dateFrom}`);
if (args.dateTo) dateInfo.push(`to: ${args.dateTo}`);
resultMessage += ` (${dateInfo.join(', ')})`;
}
resultMessage += `:\n\n${emailList}`;
return {
content: [{
type: "text",
text: resultMessage
}]
};
} catch (error) {
if (error.message === 'Authentication required') {
return {
content: [{
type: "text",
text: "Authentication required. Please use the 'authenticate' tool first."
}]
};
}
return {
content: [{
type: "text",
text: `Error listing emails: ${error.message}`
}]
};
}
}
module.exports = handleListEmails;