@jbctechsolutions/mcp-outlook-mac 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -26,7 +26,8 @@ import { createContactsTools } from './tools/contacts.js';
26
26
  import { createTasksTools } from './tools/tasks.js';
27
27
  import { createNotesTools } from './tools/notes.js';
28
28
  import { createMailboxOrganizationTools } from './tools/mailbox-organization.js';
29
- import { createMailSendTools } from './tools/mail-send.js';
29
+ import { createMailSendTools, SetSignatureInput, GetSignatureInput, } from './tools/mail-send.js';
30
+ import { createSchedulingTools, CheckAvailabilityInput, FindMeetingTimesInput, } from './tools/scheduling.js';
30
31
  import { ListEmailsInput, SearchEmailsInput, GetEmailInput, GetUnreadCountInput, ListAttachmentsInput, DownloadAttachmentInput, ListCalendarsInput, ListEventsInput, GetEventInput, SearchEventsInput, CreateEventInput, RespondToEventInput, ListContactsInput, SearchContactsInput, GetContactInput, ListTasksInput, SearchTasksInput, GetTaskInput, ListNotesInput, GetNoteInput, SearchNotesInput, PrepareDeleteEmailInput, ConfirmDeleteEmailInput, PrepareMoveEmailInput, ConfirmMoveEmailInput, PrepareArchiveEmailInput, ConfirmArchiveEmailInput, PrepareJunkEmailInput, ConfirmJunkEmailInput, PrepareDeleteFolderInput, ConfirmDeleteFolderInput, PrepareEmptyFolderInput, ConfirmEmptyFolderInput, PrepareBatchDeleteEmailsInput, PrepareBatchMoveEmailsInput, ConfirmBatchOperationInput, MarkEmailReadInput, MarkEmailUnreadInput, SetEmailFlagInput, ClearEmailFlagInput, SetEmailCategoriesInput, CreateFolderInput, RenameFolderInput, MoveFolderInput, CreateDraftInput, UpdateDraftInput, ListDraftsInput, PrepareSendDraftInput, ConfirmSendDraftInput, PrepareSendEmailInput, ConfirmSendEmailInput, PrepareReplyEmailInput, ConfirmReplyEmailInput, PrepareForwardEmailInput, ConfirmForwardEmailInput, ReplyAsDraftInput, ForwardAsDraftInput, } from './tools/index.js';
31
32
  import { ApprovalTokenManager, hashEventForApproval, hashContactForApproval, hashTaskForApproval } from './approval/index.js';
32
33
  import { wrapError, OutlookNotRunningError, GraphError, } from './utils/errors.js';
@@ -1213,6 +1214,11 @@ const TOOLS = [
1213
1214
  default: 'text',
1214
1215
  description: 'Body content type (default: text)',
1215
1216
  },
1217
+ include_signature: {
1218
+ type: 'boolean',
1219
+ default: true,
1220
+ description: 'Include email signature (default: true)',
1221
+ },
1216
1222
  attachments: {
1217
1223
  type: 'array',
1218
1224
  description: 'File attachments',
@@ -1354,6 +1360,11 @@ const TOOLS = [
1354
1360
  default: 'text',
1355
1361
  description: 'Body content type (default: text)',
1356
1362
  },
1363
+ include_signature: {
1364
+ type: 'boolean',
1365
+ default: true,
1366
+ description: 'Include email signature (default: true)',
1367
+ },
1357
1368
  attachments: {
1358
1369
  type: 'array',
1359
1370
  description: 'File attachments',
@@ -1450,6 +1461,11 @@ const TOOLS = [
1450
1461
  message_id: { type: 'number', description: 'The message ID to reply to' },
1451
1462
  comment: { type: 'string', description: 'Initial reply body text' },
1452
1463
  reply_all: { type: 'boolean', default: false, description: 'Reply to all recipients (default: false)' },
1464
+ include_signature: {
1465
+ type: 'boolean',
1466
+ default: true,
1467
+ description: 'Include email signature (default: true)',
1468
+ },
1453
1469
  },
1454
1470
  required: ['message_id'],
1455
1471
  },
@@ -1467,10 +1483,90 @@ const TOOLS = [
1467
1483
  description: 'Forward recipients (can also add later via update_draft)',
1468
1484
  },
1469
1485
  comment: { type: 'string', description: 'Initial forward body text' },
1486
+ include_signature: {
1487
+ type: 'boolean',
1488
+ default: true,
1489
+ description: 'Include email signature (default: true)',
1490
+ },
1470
1491
  },
1471
1492
  required: ['message_id'],
1472
1493
  },
1473
1494
  },
1495
+ // Signature management tools
1496
+ {
1497
+ name: 'set_signature',
1498
+ description: 'Save an email signature that will be auto-appended to outgoing emails',
1499
+ inputSchema: {
1500
+ type: 'object',
1501
+ properties: {
1502
+ content: { type: 'string', description: 'Signature content (HTML or plain text)' },
1503
+ content_type: {
1504
+ type: 'string',
1505
+ enum: ['html', 'text'],
1506
+ default: 'html',
1507
+ description: 'Content type of the signature (default: html)',
1508
+ },
1509
+ },
1510
+ required: ['content'],
1511
+ },
1512
+ },
1513
+ {
1514
+ name: 'get_signature',
1515
+ description: 'Get the currently stored email signature',
1516
+ inputSchema: {
1517
+ type: 'object',
1518
+ properties: {},
1519
+ required: [],
1520
+ },
1521
+ },
1522
+ // Calendar scheduling tools
1523
+ {
1524
+ name: 'check_availability',
1525
+ description: 'Check free/busy availability for one or more people in a time window',
1526
+ inputSchema: {
1527
+ type: 'object',
1528
+ properties: {
1529
+ email_addresses: {
1530
+ type: 'array',
1531
+ items: { type: 'string' },
1532
+ minItems: 1,
1533
+ description: 'Email addresses to check availability for',
1534
+ },
1535
+ start_time: { type: 'string', description: 'Start of time window (ISO 8601)' },
1536
+ end_time: { type: 'string', description: 'End of time window (ISO 8601)' },
1537
+ availability_view_interval: {
1538
+ type: 'number',
1539
+ default: 30,
1540
+ description: 'Time slot interval in minutes (default: 30)',
1541
+ },
1542
+ },
1543
+ required: ['email_addresses', 'start_time', 'end_time'],
1544
+ },
1545
+ },
1546
+ {
1547
+ name: 'find_meeting_times',
1548
+ description: 'Find available meeting time slots for a group of attendees',
1549
+ inputSchema: {
1550
+ type: 'object',
1551
+ properties: {
1552
+ attendees: {
1553
+ type: 'array',
1554
+ items: { type: 'string' },
1555
+ minItems: 1,
1556
+ description: 'Attendee email addresses',
1557
+ },
1558
+ duration_minutes: { type: 'number', description: 'Meeting duration in minutes' },
1559
+ start_time: { type: 'string', description: 'Start of search window (ISO 8601, optional)' },
1560
+ end_time: { type: 'string', description: 'End of search window (ISO 8601, optional)' },
1561
+ max_candidates: {
1562
+ type: 'number',
1563
+ default: 5,
1564
+ description: 'Maximum number of time suggestions (default: 5)',
1565
+ },
1566
+ },
1567
+ required: ['attendees', 'duration_minutes'],
1568
+ },
1569
+ },
1474
1570
  ];
1475
1571
  // =============================================================================
1476
1572
  // Server Creation
@@ -1501,6 +1597,7 @@ export function createServer() {
1501
1597
  let notesTools = null;
1502
1598
  let orgTools = null;
1503
1599
  let sendTools = null;
1600
+ let schedulingTools = null;
1504
1601
  let calendarWriter = null;
1505
1602
  let calendarManager = null;
1506
1603
  let mailSender = null;
@@ -1543,6 +1640,7 @@ export function createServer() {
1543
1640
  const adapter = new GraphMailboxAdapter(graphRepository);
1544
1641
  orgTools = createMailboxOrganizationTools(adapter, tokenManager);
1545
1642
  sendTools = createMailSendTools(graphRepository, tokenManager);
1643
+ schedulingTools = createSchedulingTools(graphRepository);
1546
1644
  initialized = true;
1547
1645
  });
1548
1646
  /**
@@ -1558,9 +1656,17 @@ export function createServer() {
1558
1656
  initializeAppleScriptBackend();
1559
1657
  }
1560
1658
  }
1659
+ // Tools that only exist when using Graph API (signature + scheduling)
1660
+ const GRAPH_ONLY_TOOL_NAMES = new Set([
1661
+ 'set_signature',
1662
+ 'get_signature',
1663
+ 'check_availability',
1664
+ 'find_meeting_times',
1665
+ ]);
1561
1666
  // Register tool list handler
1562
1667
  server.setRequestHandler(ListToolsRequestSchema, () => {
1563
- return { tools: TOOLS };
1668
+ const tools = useGraphApi ? TOOLS : TOOLS.filter((t) => !GRAPH_ONLY_TOOL_NAMES.has(t.name));
1669
+ return { tools };
1564
1670
  });
1565
1671
  // Register tool call handler (async for Graph API support)
1566
1672
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
@@ -1569,7 +1675,7 @@ export function createServer() {
1569
1675
  await ensureInitialized();
1570
1676
  // Graph API mode - handle async operations directly
1571
1677
  if (useGraphApi && graphRepository != null) {
1572
- return await handleGraphToolCall(name, args, graphRepository, graphContentReaders, orgTools, sendTools, tokenManager);
1678
+ return await handleGraphToolCall(name, args, graphRepository, graphContentReaders, orgTools, sendTools, schedulingTools, tokenManager);
1573
1679
  }
1574
1680
  // AppleScript mode - use sync tool interfaces
1575
1681
  return handleAppleScriptToolCall(name, args, accountRepository, mailTools, calendarTools, contactsTools, tasksTools, notesTools, orgTools, calendarWriter, calendarManager, mailSender);
@@ -1818,6 +1924,35 @@ async function handleSendToolCall(name, args, sendTools) {
1818
1924
  const result = await sendTools.forwardAsDraft(params);
1819
1925
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
1820
1926
  }
1927
+ case 'set_signature': {
1928
+ const params = SetSignatureInput.parse(args);
1929
+ const result = sendTools.setSignature(params);
1930
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
1931
+ }
1932
+ case 'get_signature': {
1933
+ GetSignatureInput.parse(args ?? {});
1934
+ const result = sendTools.getSignature();
1935
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
1936
+ }
1937
+ default:
1938
+ return null;
1939
+ }
1940
+ }
1941
+ // =============================================================================
1942
+ // Scheduling Tool Handler (Graph API only)
1943
+ // =============================================================================
1944
+ async function handleSchedulingToolCall(name, args, schedulingTools) {
1945
+ switch (name) {
1946
+ case 'check_availability': {
1947
+ const params = CheckAvailabilityInput.parse(args);
1948
+ const result = await schedulingTools.checkAvailability(params);
1949
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
1950
+ }
1951
+ case 'find_meeting_times': {
1952
+ const params = FindMeetingTimesInput.parse(args);
1953
+ const result = await schedulingTools.findMeetingTimes(params);
1954
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
1955
+ }
1821
1956
  default:
1822
1957
  return null;
1823
1958
  }
@@ -2322,7 +2457,7 @@ const ConfirmDeleteTaskInput = z.strictObject({
2322
2457
  // =============================================================================
2323
2458
  // Graph API Tool Handler
2324
2459
  // =============================================================================
2325
- async function handleGraphToolCall(name, args, repository, contentReaders, orgTools, sendTools, tokenManager) {
2460
+ async function handleGraphToolCall(name, args, repository, contentReaders, orgTools, sendTools, schedulingTools, tokenManager) {
2326
2461
  // Handle mailbox organization tools (shared between backends)
2327
2462
  const orgResult = await handleOrgToolCall(name, args, orgTools);
2328
2463
  if (orgResult != null)
@@ -2331,6 +2466,10 @@ async function handleGraphToolCall(name, args, repository, contentReaders, orgTo
2331
2466
  const sendResult = await handleSendToolCall(name, args, sendTools);
2332
2467
  if (sendResult != null)
2333
2468
  return sendResult;
2469
+ // Handle scheduling tools (Graph API only)
2470
+ const schedulingResult = await handleSchedulingToolCall(name, args, schedulingTools);
2471
+ if (schedulingResult != null)
2472
+ return schedulingResult;
2334
2473
  try {
2335
2474
  switch (name) {
2336
2475
  // Mail tools