msexchange-mcp
Version:
MCP server for Microsoft Exchange/Outlook email operations via Microsoft Graph API
206 lines (203 loc) • 9.27 kB
JavaScript
import { AliasManager } from '../services/aliasManager.js';
import { MailService } from '../services/mail.js';
import { logger } from '../utils/logger.js';
import { z } from 'zod';
const inputSchema = z.object({
action: z.enum(['list', 'add', 'relate', 'learn', 'resolve']).describe('Action to perform'),
// Optional fields for different actions
name: z.string().optional().describe('The name/alias to add or resolve (for add/resolve actions)'),
email: z.string().email().optional().describe('The email address to associate (for add action)'),
displayName: z.string().optional().describe('Optional display name (for add action)'),
name1: z.string().optional().describe('First name/alias (for relate action)'),
name2: z.string().optional().describe('Second name/alias (for relate action)'),
accountId: z.string().optional().default('default').describe('Account ID (for learn action)'),
});
export const manageEmailAliasesTool = {
name: 'manage_email_aliases',
description: `Manage email aliases and name mappings for better search.
Actions:
- list: Show all configured aliases and relationships
- add: Add a new name-to-email mapping
- relate: Create a relationship between two names (e.g., "Doss" = "Mads")
- learn: Automatically learn aliases from recent email history
- resolve: Test resolving a name to email addresses
Examples:
- List all aliases: {"action": "list"}
- Add alias: {"action": "add", "name": "john", "email": "john.doe@example.com"}
- Create relationship: {"action": "relate", "name1": "doss", "name2": "mads"}
- Learn from emails: {"action": "learn"}
- Test resolution: {"action": "resolve", "name": "florian"}
Pre-configured aliases include:
- florian → florian.semrau@allianz.de
- mads/doss → mads.schwartz@example.com
- justinas/jl → justinas@example.com
- noewe → team@noewe.com`,
parameters: inputSchema,
execute: async (input) => {
try {
const aliasManager = AliasManager.getInstance();
await aliasManager.initialize();
// Validate required fields for each action
switch (input.action) {
case 'add':
if (!input.name || !input.email) {
return {
content: [
{
type: 'text',
text: '❌ Add action requires "name" and "email" fields',
},
],
};
}
break;
case 'relate':
if (!input.name1 || !input.name2) {
return {
content: [
{
type: 'text',
text: '❌ Relate action requires "name1" and "name2" fields',
},
],
};
}
break;
case 'resolve':
if (!input.name) {
return {
content: [
{
type: 'text',
text: '❌ Resolve action requires "name" field',
},
],
};
}
break;
}
switch (input.action) {
case 'list': {
const aliases = aliasManager.getAllAliases();
let response = '📧 Email Aliases and Relationships\n\n';
// Group aliases by email for better display
const emailToNames = {};
for (const [name, aliasesArray] of Object.entries(aliases.aliases)) {
for (const alias of aliasesArray) {
if (!emailToNames[alias.email]) {
emailToNames[alias.email] = [];
}
emailToNames[alias.email].push(name);
if (alias.displayName && !emailToNames[alias.email].includes(alias.displayName)) {
emailToNames[alias.email].push(alias.displayName);
}
}
}
response += '**Email Mappings:**\n';
for (const [email, names] of Object.entries(emailToNames)) {
response += `• ${email}\n Names: ${names.join(', ')}\n`;
}
response += '\n**Name Relationships:**\n';
for (const [name, related] of Object.entries(aliases.relationships)) {
if (related.length > 0) {
response += `• ${name} ↔ ${related.join(', ')}\n`;
}
}
response += `\nLast updated: ${aliases.lastUpdated.toLocaleString()}`;
return {
content: [
{
type: 'text',
text: response,
},
],
};
}
case 'add': {
aliasManager.addAlias(input.name, input.email, input.displayName);
return {
content: [
{
type: 'text',
text: `✅ Added alias: ${input.name} → ${input.email}${input.displayName ? ` (${input.displayName})` : ''}`,
},
],
};
}
case 'relate': {
aliasManager.addRelationship(input.name1, input.name2);
return {
content: [
{
type: 'text',
text: `✅ Created relationship: ${input.name1} ↔ ${input.name2}`,
},
],
};
}
case 'learn': {
const mailService = MailService.getInstance();
await aliasManager.learnFromEmails(mailService, input.accountId || 'default');
const aliases = aliasManager.getAllAliases();
const totalAliases = Object.keys(aliases.aliases).length;
return {
content: [
{
type: 'text',
text: `✅ Learned from recent emails!\n\nTotal aliases: ${totalAliases}\nUse {"action": "list"} to see all mappings.`,
},
],
};
}
case 'resolve': {
const resolved = aliasManager.resolveAlias(input.name);
const variations = aliasManager.getNameVariations(input.name);
let response = `🔍 Resolving "${input.name}":\n\n`;
if (resolved.length > 0) {
response += `**Email addresses:**\n`;
resolved.forEach(email => {
const displayName = aliasManager.getDisplayName(email);
response += `• ${email}${displayName ? ` (${displayName})` : ''}\n`;
});
}
else {
response += `No email addresses found for "${input.name}".\n`;
}
if (variations.length > 1) {
response += `\n**Name variations:**\n`;
variations.forEach(v => response += `• ${v}\n`);
}
return {
content: [
{
type: 'text',
text: response,
},
],
};
}
default:
return {
content: [
{
type: 'text',
text: '❌ Invalid action. Use: list, add, relate, learn, or resolve.',
},
],
};
}
}
catch (error) {
logger.error('Alias management error', { error });
return {
content: [
{
type: 'text',
text: `❌ Failed to manage aliases: ${error instanceof Error ? error.message : String(error)}`,
},
],
};
}
},
};
//# sourceMappingURL=manageEmailAliases.js.map