@mcp-z/mcp-outlook 1.0.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/LICENSE +21 -0
- package/README.md +165 -0
- package/bin/server.js +5 -0
- package/dist/cjs/constants.d.cts +10 -0
- package/dist/cjs/constants.d.ts +10 -0
- package/dist/cjs/constants.js +35 -0
- package/dist/cjs/constants.js.map +1 -0
- package/dist/cjs/email/composition/outlook-message-builder.d.cts +36 -0
- package/dist/cjs/email/composition/outlook-message-builder.d.ts +36 -0
- package/dist/cjs/email/composition/outlook-message-builder.js +56 -0
- package/dist/cjs/email/composition/outlook-message-builder.js.map +1 -0
- package/dist/cjs/email/messages/messages.d.cts +7 -0
- package/dist/cjs/email/messages/messages.d.ts +7 -0
- package/dist/cjs/email/messages/messages.js +61 -0
- package/dist/cjs/email/messages/messages.js.map +1 -0
- package/dist/cjs/email/parsing/header-parsing.d.cts +18 -0
- package/dist/cjs/email/parsing/header-parsing.d.ts +18 -0
- package/dist/cjs/email/parsing/header-parsing.js +42 -0
- package/dist/cjs/email/parsing/header-parsing.js.map +1 -0
- package/dist/cjs/email/parsing/message-extraction.d.cts +4 -0
- package/dist/cjs/email/parsing/message-extraction.d.ts +4 -0
- package/dist/cjs/email/parsing/message-extraction.js +192 -0
- package/dist/cjs/email/parsing/message-extraction.js.map +1 -0
- package/dist/cjs/email/parsing/message-mapping.d.cts +21 -0
- package/dist/cjs/email/parsing/message-mapping.d.ts +21 -0
- package/dist/cjs/email/parsing/message-mapping.js +47 -0
- package/dist/cjs/email/parsing/message-mapping.js.map +1 -0
- package/dist/cjs/email/querying/execute-query.d.cts +20 -0
- package/dist/cjs/email/querying/execute-query.d.ts +20 -0
- package/dist/cjs/email/querying/execute-query.js +268 -0
- package/dist/cjs/email/querying/execute-query.js.map +1 -0
- package/dist/cjs/email/querying/query-builder.d.cts +32 -0
- package/dist/cjs/email/querying/query-builder.d.ts +32 -0
- package/dist/cjs/email/querying/query-builder.js +528 -0
- package/dist/cjs/email/querying/query-builder.js.map +1 -0
- package/dist/cjs/email/querying/search-execution.d.cts +24 -0
- package/dist/cjs/email/querying/search-execution.d.ts +24 -0
- package/dist/cjs/email/querying/search-execution.js +261 -0
- package/dist/cjs/email/querying/search-execution.js.map +1 -0
- package/dist/cjs/index.d.cts +8 -0
- package/dist/cjs/index.d.ts +8 -0
- package/dist/cjs/index.js +314 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/lib/create-store.d.cts +2 -0
- package/dist/cjs/lib/create-store.d.ts +2 -0
- package/dist/cjs/lib/create-store.js +166 -0
- package/dist/cjs/lib/create-store.js.map +1 -0
- package/dist/cjs/lib/messages-to-row.d.cts +39 -0
- package/dist/cjs/lib/messages-to-row.d.ts +39 -0
- package/dist/cjs/lib/messages-to-row.js +177 -0
- package/dist/cjs/lib/messages-to-row.js.map +1 -0
- package/dist/cjs/lib/outlook/index.d.cts +7 -0
- package/dist/cjs/lib/outlook/index.d.ts +7 -0
- package/dist/cjs/lib/outlook/index.js +56 -0
- package/dist/cjs/lib/outlook/index.js.map +1 -0
- package/dist/cjs/lib/outlook/types.d.cts +22 -0
- package/dist/cjs/lib/outlook/types.d.ts +22 -0
- package/dist/cjs/lib/outlook/types.js +6 -0
- package/dist/cjs/lib/outlook/types.js.map +1 -0
- package/dist/cjs/mcp/index.d.cts +3 -0
- package/dist/cjs/mcp/index.d.ts +3 -0
- package/dist/cjs/mcp/index.js +66 -0
- package/dist/cjs/mcp/index.js.map +1 -0
- package/dist/cjs/mcp/prompts/draft-email.d.cts +30 -0
- package/dist/cjs/mcp/prompts/draft-email.d.ts +30 -0
- package/dist/cjs/mcp/prompts/draft-email.js +184 -0
- package/dist/cjs/mcp/prompts/draft-email.js.map +1 -0
- package/dist/cjs/mcp/prompts/index.d.cts +2 -0
- package/dist/cjs/mcp/prompts/index.d.ts +2 -0
- package/dist/cjs/mcp/prompts/index.js +26 -0
- package/dist/cjs/mcp/prompts/index.js.map +1 -0
- package/dist/cjs/mcp/prompts/query-syntax.d.cts +19 -0
- package/dist/cjs/mcp/prompts/query-syntax.d.ts +19 -0
- package/dist/cjs/mcp/prompts/query-syntax.js +169 -0
- package/dist/cjs/mcp/prompts/query-syntax.js.map +1 -0
- package/dist/cjs/mcp/resources/email.d.cts +11 -0
- package/dist/cjs/mcp/resources/email.d.ts +11 -0
- package/dist/cjs/mcp/resources/email.js +233 -0
- package/dist/cjs/mcp/resources/email.js.map +1 -0
- package/dist/cjs/mcp/resources/index.d.cts +1 -0
- package/dist/cjs/mcp/resources/index.d.ts +1 -0
- package/dist/cjs/mcp/resources/index.js +17 -0
- package/dist/cjs/mcp/resources/index.js.map +1 -0
- package/dist/cjs/mcp/tools/categories-list.d.cts +96 -0
- package/dist/cjs/mcp/tools/categories-list.d.ts +96 -0
- package/dist/cjs/mcp/tools/categories-list.js +252 -0
- package/dist/cjs/mcp/tools/categories-list.js.map +1 -0
- package/dist/cjs/mcp/tools/index.d.cts +11 -0
- package/dist/cjs/mcp/tools/index.d.ts +11 -0
- package/dist/cjs/mcp/tools/index.js +62 -0
- package/dist/cjs/mcp/tools/index.js.map +1 -0
- package/dist/cjs/mcp/tools/label-add.d.cts +44 -0
- package/dist/cjs/mcp/tools/label-add.d.ts +44 -0
- package/dist/cjs/mcp/tools/label-add.js +249 -0
- package/dist/cjs/mcp/tools/label-add.js.map +1 -0
- package/dist/cjs/mcp/tools/label-delete.d.cts +54 -0
- package/dist/cjs/mcp/tools/label-delete.d.ts +54 -0
- package/dist/cjs/mcp/tools/label-delete.js +497 -0
- package/dist/cjs/mcp/tools/label-delete.js.map +1 -0
- package/dist/cjs/mcp/tools/labels-list.d.cts +96 -0
- package/dist/cjs/mcp/tools/labels-list.d.ts +96 -0
- package/dist/cjs/mcp/tools/labels-list.js +252 -0
- package/dist/cjs/mcp/tools/labels-list.js.map +1 -0
- package/dist/cjs/mcp/tools/message-get.d.cts +110 -0
- package/dist/cjs/mcp/tools/message-get.d.ts +110 -0
- package/dist/cjs/mcp/tools/message-get.js +289 -0
- package/dist/cjs/mcp/tools/message-get.js.map +1 -0
- package/dist/cjs/mcp/tools/message-mark-read.d.cts +42 -0
- package/dist/cjs/mcp/tools/message-mark-read.d.ts +42 -0
- package/dist/cjs/mcp/tools/message-mark-read.js +254 -0
- package/dist/cjs/mcp/tools/message-mark-read.js.map +1 -0
- package/dist/cjs/mcp/tools/message-move-to-trash.d.cts +54 -0
- package/dist/cjs/mcp/tools/message-move-to-trash.d.ts +54 -0
- package/dist/cjs/mcp/tools/message-move-to-trash.js +460 -0
- package/dist/cjs/mcp/tools/message-move-to-trash.js.map +1 -0
- package/dist/cjs/mcp/tools/message-respond.d.cts +52 -0
- package/dist/cjs/mcp/tools/message-respond.d.ts +52 -0
- package/dist/cjs/mcp/tools/message-respond.js +263 -0
- package/dist/cjs/mcp/tools/message-respond.js.map +1 -0
- package/dist/cjs/mcp/tools/message-search.d.cts +138 -0
- package/dist/cjs/mcp/tools/message-search.d.ts +138 -0
- package/dist/cjs/mcp/tools/message-search.js +408 -0
- package/dist/cjs/mcp/tools/message-search.js.map +1 -0
- package/dist/cjs/mcp/tools/message-send.d.cts +66 -0
- package/dist/cjs/mcp/tools/message-send.d.ts +66 -0
- package/dist/cjs/mcp/tools/message-send.js +298 -0
- package/dist/cjs/mcp/tools/message-send.js.map +1 -0
- package/dist/cjs/mcp/tools/messages-export-csv.d.cts +72 -0
- package/dist/cjs/mcp/tools/messages-export-csv.d.ts +72 -0
- package/dist/cjs/mcp/tools/messages-export-csv.js +540 -0
- package/dist/cjs/mcp/tools/messages-export-csv.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/schemas/index.d.cts +2 -0
- package/dist/cjs/schemas/index.d.ts +2 -0
- package/dist/cjs/schemas/index.js +20 -0
- package/dist/cjs/schemas/index.js.map +1 -0
- package/dist/cjs/schemas/outlook-query-schema.d.cts +53 -0
- package/dist/cjs/schemas/outlook-query-schema.d.ts +53 -0
- package/dist/cjs/schemas/outlook-query-schema.js +115 -0
- package/dist/cjs/schemas/outlook-query-schema.js.map +1 -0
- package/dist/cjs/schemas/outlook-validation.d.cts +428 -0
- package/dist/cjs/schemas/outlook-validation.d.ts +428 -0
- package/dist/cjs/schemas/outlook-validation.js +420 -0
- package/dist/cjs/schemas/outlook-validation.js.map +1 -0
- package/dist/cjs/setup/config.d.cts +50 -0
- package/dist/cjs/setup/config.d.ts +50 -0
- package/dist/cjs/setup/config.js +217 -0
- package/dist/cjs/setup/config.js.map +1 -0
- package/dist/cjs/setup/http.d.cts +8 -0
- package/dist/cjs/setup/http.d.ts +8 -0
- package/dist/cjs/setup/http.js +267 -0
- package/dist/cjs/setup/http.js.map +1 -0
- package/dist/cjs/setup/index.d.cts +5 -0
- package/dist/cjs/setup/index.d.ts +5 -0
- package/dist/cjs/setup/index.js +46 -0
- package/dist/cjs/setup/index.js.map +1 -0
- package/dist/cjs/setup/oauth-microsoft.d.cts +43 -0
- package/dist/cjs/setup/oauth-microsoft.d.ts +43 -0
- package/dist/cjs/setup/oauth-microsoft.js +366 -0
- package/dist/cjs/setup/oauth-microsoft.js.map +1 -0
- package/dist/cjs/setup/runtime.d.cts +11 -0
- package/dist/cjs/setup/runtime.d.ts +11 -0
- package/dist/cjs/setup/runtime.js +489 -0
- package/dist/cjs/setup/runtime.js.map +1 -0
- package/dist/cjs/setup/stdio.d.cts +7 -0
- package/dist/cjs/setup/stdio.d.ts +7 -0
- package/dist/cjs/setup/stdio.js +239 -0
- package/dist/cjs/setup/stdio.js.map +1 -0
- package/dist/cjs/types.d.cts +54 -0
- package/dist/cjs/types.d.ts +54 -0
- package/dist/cjs/types.js +5 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/constants.d.ts +10 -0
- package/dist/esm/constants.js +13 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/email/composition/outlook-message-builder.d.ts +36 -0
- package/dist/esm/email/composition/outlook-message-builder.js +46 -0
- package/dist/esm/email/composition/outlook-message-builder.js.map +1 -0
- package/dist/esm/email/messages/messages.d.ts +7 -0
- package/dist/esm/email/messages/messages.js +42 -0
- package/dist/esm/email/messages/messages.js.map +1 -0
- package/dist/esm/email/parsing/header-parsing.d.ts +18 -0
- package/dist/esm/email/parsing/header-parsing.js +18 -0
- package/dist/esm/email/parsing/header-parsing.js.map +1 -0
- package/dist/esm/email/parsing/message-extraction.d.ts +4 -0
- package/dist/esm/email/parsing/message-extraction.js +26 -0
- package/dist/esm/email/parsing/message-extraction.js.map +1 -0
- package/dist/esm/email/parsing/message-mapping.d.ts +21 -0
- package/dist/esm/email/parsing/message-mapping.js +35 -0
- package/dist/esm/email/parsing/message-mapping.js.map +1 -0
- package/dist/esm/email/querying/execute-query.d.ts +20 -0
- package/dist/esm/email/querying/execute-query.js +48 -0
- package/dist/esm/email/querying/execute-query.js.map +1 -0
- package/dist/esm/email/querying/query-builder.d.ts +32 -0
- package/dist/esm/email/querying/query-builder.js +424 -0
- package/dist/esm/email/querying/query-builder.js.map +1 -0
- package/dist/esm/email/querying/search-execution.d.ts +24 -0
- package/dist/esm/email/querying/search-execution.js +96 -0
- package/dist/esm/email/querying/search-execution.js.map +1 -0
- package/dist/esm/index.d.ts +8 -0
- package/dist/esm/index.js +34 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lib/create-store.d.ts +2 -0
- package/dist/esm/lib/create-store.js +6 -0
- package/dist/esm/lib/create-store.js.map +1 -0
- package/dist/esm/lib/messages-to-row.d.ts +39 -0
- package/dist/esm/lib/messages-to-row.js +141 -0
- package/dist/esm/lib/messages-to-row.js.map +1 -0
- package/dist/esm/lib/outlook/index.d.ts +7 -0
- package/dist/esm/lib/outlook/index.js +7 -0
- package/dist/esm/lib/outlook/index.js.map +1 -0
- package/dist/esm/lib/outlook/types.d.ts +22 -0
- package/dist/esm/lib/outlook/types.js +2 -0
- package/dist/esm/lib/outlook/types.js.map +1 -0
- package/dist/esm/mcp/index.d.ts +3 -0
- package/dist/esm/mcp/index.js +6 -0
- package/dist/esm/mcp/index.js.map +1 -0
- package/dist/esm/mcp/prompts/draft-email.d.ts +30 -0
- package/dist/esm/mcp/prompts/draft-email.js +37 -0
- package/dist/esm/mcp/prompts/draft-email.js.map +1 -0
- package/dist/esm/mcp/prompts/index.d.ts +2 -0
- package/dist/esm/mcp/prompts/index.js +2 -0
- package/dist/esm/mcp/prompts/index.js.map +1 -0
- package/dist/esm/mcp/prompts/query-syntax.d.ts +19 -0
- package/dist/esm/mcp/prompts/query-syntax.js +75 -0
- package/dist/esm/mcp/prompts/query-syntax.js.map +1 -0
- package/dist/esm/mcp/resources/email.d.ts +11 -0
- package/dist/esm/mcp/resources/email.js +69 -0
- package/dist/esm/mcp/resources/email.js.map +1 -0
- package/dist/esm/mcp/resources/index.d.ts +1 -0
- package/dist/esm/mcp/resources/index.js +1 -0
- package/dist/esm/mcp/resources/index.js.map +1 -0
- package/dist/esm/mcp/tools/categories-list.d.ts +96 -0
- package/dist/esm/mcp/tools/categories-list.js +78 -0
- package/dist/esm/mcp/tools/categories-list.js.map +1 -0
- package/dist/esm/mcp/tools/index.d.ts +11 -0
- package/dist/esm/mcp/tools/index.js +11 -0
- package/dist/esm/mcp/tools/index.js.map +1 -0
- package/dist/esm/mcp/tools/label-add.d.ts +44 -0
- package/dist/esm/mcp/tools/label-add.js +75 -0
- package/dist/esm/mcp/tools/label-add.js.map +1 -0
- package/dist/esm/mcp/tools/label-delete.d.ts +54 -0
- package/dist/esm/mcp/tools/label-delete.js +166 -0
- package/dist/esm/mcp/tools/label-delete.js.map +1 -0
- package/dist/esm/mcp/tools/labels-list.d.ts +96 -0
- package/dist/esm/mcp/tools/labels-list.js +78 -0
- package/dist/esm/mcp/tools/labels-list.js.map +1 -0
- package/dist/esm/mcp/tools/message-get.d.ts +110 -0
- package/dist/esm/mcp/tools/message-get.js +117 -0
- package/dist/esm/mcp/tools/message-get.js.map +1 -0
- package/dist/esm/mcp/tools/message-mark-read.d.ts +42 -0
- package/dist/esm/mcp/tools/message-mark-read.js +80 -0
- package/dist/esm/mcp/tools/message-mark-read.js.map +1 -0
- package/dist/esm/mcp/tools/message-move-to-trash.d.ts +54 -0
- package/dist/esm/mcp/tools/message-move-to-trash.js +177 -0
- package/dist/esm/mcp/tools/message-move-to-trash.js.map +1 -0
- package/dist/esm/mcp/tools/message-respond.d.ts +52 -0
- package/dist/esm/mcp/tools/message-respond.js +89 -0
- package/dist/esm/mcp/tools/message-respond.js.map +1 -0
- package/dist/esm/mcp/tools/message-search.d.ts +138 -0
- package/dist/esm/mcp/tools/message-search.js +184 -0
- package/dist/esm/mcp/tools/message-search.js.map +1 -0
- package/dist/esm/mcp/tools/message-send.d.ts +66 -0
- package/dist/esm/mcp/tools/message-send.js +111 -0
- package/dist/esm/mcp/tools/message-send.js.map +1 -0
- package/dist/esm/mcp/tools/messages-export-csv.d.ts +72 -0
- package/dist/esm/mcp/tools/messages-export-csv.js +273 -0
- package/dist/esm/mcp/tools/messages-export-csv.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/schemas/index.d.ts +2 -0
- package/dist/esm/schemas/index.js +2 -0
- package/dist/esm/schemas/index.js.map +1 -0
- package/dist/esm/schemas/outlook-query-schema.d.ts +53 -0
- package/dist/esm/schemas/outlook-query-schema.js +63 -0
- package/dist/esm/schemas/outlook-query-schema.js.map +1 -0
- package/dist/esm/schemas/outlook-validation.d.ts +428 -0
- package/dist/esm/schemas/outlook-validation.js +388 -0
- package/dist/esm/schemas/outlook-validation.js.map +1 -0
- package/dist/esm/setup/config.d.ts +50 -0
- package/dist/esm/setup/config.js +180 -0
- package/dist/esm/setup/config.js.map +1 -0
- package/dist/esm/setup/http.d.ts +8 -0
- package/dist/esm/setup/http.js +61 -0
- package/dist/esm/setup/http.js.map +1 -0
- package/dist/esm/setup/index.d.ts +5 -0
- package/dist/esm/setup/index.js +5 -0
- package/dist/esm/setup/index.js.map +1 -0
- package/dist/esm/setup/oauth-microsoft.d.ts +43 -0
- package/dist/esm/setup/oauth-microsoft.js +169 -0
- package/dist/esm/setup/oauth-microsoft.js.map +1 -0
- package/dist/esm/setup/runtime.d.ts +11 -0
- package/dist/esm/setup/runtime.js +115 -0
- package/dist/esm/setup/runtime.js.map +1 -0
- package/dist/esm/setup/stdio.d.ts +7 -0
- package/dist/esm/setup/stdio.js +38 -0
- package/dist/esm/setup/stdio.js.map +1 -0
- package/dist/esm/types.d.ts +54 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/types.js.map +1 -0
- package/package.json +111 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/** Outlook message CSV export tool - streams results to file without loading all data into context */ import { EmailContentTypeSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText } from '@mcp-z/email';
|
|
2
|
+
import { schemas } from '@mcp-z/oauth-microsoft';
|
|
3
|
+
const { AuthRequiredBranchSchema } = schemas;
|
|
4
|
+
import { getFileUri, reserveFile } from '@mcp-z/server';
|
|
5
|
+
import { Client } from '@microsoft/microsoft-graph-client';
|
|
6
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
7
|
+
import { stringify } from 'csv-stringify/sync';
|
|
8
|
+
import { createWriteStream } from 'fs';
|
|
9
|
+
import { unlink } from 'fs/promises';
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.js';
|
|
12
|
+
import { OutlookQuerySchema } from '../../schemas/outlook-query-schema.js';
|
|
13
|
+
const DEFAULT_PAGE_SIZE = 50;
|
|
14
|
+
const DEFAULT_MAX_ITEMS = 10000;
|
|
15
|
+
const MAX_EXPORT_ITEMS = 50000;
|
|
16
|
+
const ExportResultSchema = z.object({
|
|
17
|
+
uri: z.string().describe('File URI (file:// or http://)'),
|
|
18
|
+
filename: z.string().describe('Stored filename'),
|
|
19
|
+
rowCount: z.number().describe('Number of messages exported'),
|
|
20
|
+
truncated: z.boolean().describe('Whether export was truncated at maxItems')
|
|
21
|
+
});
|
|
22
|
+
const inputSchema = z.object({
|
|
23
|
+
query: OutlookQuerySchema.optional().describe('Structured query object for filtering messages. Use query-syntax prompt for reference.'),
|
|
24
|
+
maxItems: z.number().int().positive().max(MAX_EXPORT_ITEMS).default(DEFAULT_MAX_ITEMS).describe(`Maximum messages to export (default: ${DEFAULT_MAX_ITEMS}, max: ${MAX_EXPORT_ITEMS})`),
|
|
25
|
+
filename: z.string().trim().min(1).default('outlook-messages.csv').describe('Output filename (default: outlook-messages.csv)'),
|
|
26
|
+
contentType: EmailContentTypeSchema,
|
|
27
|
+
excludeThreadHistory: ExcludeThreadHistorySchema
|
|
28
|
+
});
|
|
29
|
+
// Success branch schema
|
|
30
|
+
const successBranchSchema = ExportResultSchema.extend({
|
|
31
|
+
type: z.literal('success')
|
|
32
|
+
});
|
|
33
|
+
// Output schema with auth_required support
|
|
34
|
+
const outputSchema = z.discriminatedUnion('type', [
|
|
35
|
+
successBranchSchema,
|
|
36
|
+
AuthRequiredBranchSchema
|
|
37
|
+
]);
|
|
38
|
+
const config = {
|
|
39
|
+
description: 'Export Outlook messages to CSV with streaming pagination. Returns file URI. Use query-syntax prompt for query reference.',
|
|
40
|
+
inputSchema: inputSchema,
|
|
41
|
+
outputSchema: z.object({
|
|
42
|
+
result: outputSchema
|
|
43
|
+
})
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Handler for outlook-messages-export-csv tool
|
|
47
|
+
*
|
|
48
|
+
* CRITICAL: Streaming implementation per user requirements
|
|
49
|
+
* - Generate UUID upfront
|
|
50
|
+
* - Write CSV header immediately
|
|
51
|
+
* - Append rows as batches arrive
|
|
52
|
+
* - Delete partial file on error
|
|
53
|
+
* - NO RETRIES (fail fast on error)
|
|
54
|
+
*/ async function handler({ query, maxItems, filename, contentType, excludeThreadHistory }, extra) {
|
|
55
|
+
const logger = extra.logger;
|
|
56
|
+
const { storageContext } = extra;
|
|
57
|
+
const { transport, storageDir, baseUrl } = storageContext;
|
|
58
|
+
logger.info('outlook.messages.export-csv called', {
|
|
59
|
+
query,
|
|
60
|
+
maxItems,
|
|
61
|
+
filename,
|
|
62
|
+
accountId: extra.authContext.accountId
|
|
63
|
+
});
|
|
64
|
+
// Reserve file location for streaming write (creates directory, generates ID, formats filename)
|
|
65
|
+
const reservation = await reserveFile(filename, {
|
|
66
|
+
storageDir
|
|
67
|
+
});
|
|
68
|
+
const { storedName, fullPath } = reservation;
|
|
69
|
+
logger.info('outlook.messages.export-csv starting streaming export', {
|
|
70
|
+
path: fullPath,
|
|
71
|
+
maxItems
|
|
72
|
+
});
|
|
73
|
+
try {
|
|
74
|
+
const graph = Client.initWithMiddleware({
|
|
75
|
+
authProvider: extra.authContext.auth
|
|
76
|
+
});
|
|
77
|
+
// Create CSV headers (all email fields)
|
|
78
|
+
const csvHeaders = [
|
|
79
|
+
'id',
|
|
80
|
+
'threadId',
|
|
81
|
+
'from',
|
|
82
|
+
'to',
|
|
83
|
+
'cc',
|
|
84
|
+
'bcc',
|
|
85
|
+
'subject',
|
|
86
|
+
'date',
|
|
87
|
+
'snippet',
|
|
88
|
+
'body',
|
|
89
|
+
'provider',
|
|
90
|
+
'labels'
|
|
91
|
+
];
|
|
92
|
+
// Create write stream and write headers immediately
|
|
93
|
+
const writeStream = createWriteStream(fullPath, {
|
|
94
|
+
encoding: 'utf-8'
|
|
95
|
+
});
|
|
96
|
+
const headerLine = stringify([
|
|
97
|
+
csvHeaders
|
|
98
|
+
], {
|
|
99
|
+
header: false,
|
|
100
|
+
quoted: true,
|
|
101
|
+
quote: '"',
|
|
102
|
+
escape: '"'
|
|
103
|
+
});
|
|
104
|
+
writeStream.write(headerLine);
|
|
105
|
+
// Internal pagination loop - append to CSV with each batch
|
|
106
|
+
// NO RETRIES: If any error occurs, fail the whole operation and clean up
|
|
107
|
+
let totalRows = 0;
|
|
108
|
+
let nextPageToken;
|
|
109
|
+
const started = Date.now();
|
|
110
|
+
while(totalRows < maxItems){
|
|
111
|
+
var _exec_metadata;
|
|
112
|
+
const remainingItems = maxItems - totalRows;
|
|
113
|
+
const pageSize = Math.min(remainingItems, DEFAULT_PAGE_SIZE);
|
|
114
|
+
const exec = await executeOutlookQuery(graph, query, {
|
|
115
|
+
logger,
|
|
116
|
+
pageSize,
|
|
117
|
+
...nextPageToken !== undefined && {
|
|
118
|
+
pageToken: nextPageToken
|
|
119
|
+
},
|
|
120
|
+
includeBody: true,
|
|
121
|
+
limit: pageSize
|
|
122
|
+
}, (m)=>{
|
|
123
|
+
var _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6;
|
|
124
|
+
var _message_from_emailAddress, _message_from, _message_from1, _message_body, _message_body_contentType, _message_body1;
|
|
125
|
+
const message = m;
|
|
126
|
+
const to = Array.isArray(message === null || message === void 0 ? void 0 : message.toRecipients) ? message.toRecipients.map((r)=>{
|
|
127
|
+
var _ref;
|
|
128
|
+
var _r_emailAddress;
|
|
129
|
+
return (_ref = r === null || r === void 0 ? void 0 : (_r_emailAddress = r.emailAddress) === null || _r_emailAddress === void 0 ? void 0 : _r_emailAddress.address) !== null && _ref !== void 0 ? _ref : r === null || r === void 0 ? void 0 : r.address;
|
|
130
|
+
}).filter(Boolean).join(', ') : '';
|
|
131
|
+
const cc = Array.isArray(message === null || message === void 0 ? void 0 : message.ccRecipients) ? message.ccRecipients.map((r)=>{
|
|
132
|
+
var _ref;
|
|
133
|
+
var _r_emailAddress;
|
|
134
|
+
return (_ref = r === null || r === void 0 ? void 0 : (_r_emailAddress = r.emailAddress) === null || _r_emailAddress === void 0 ? void 0 : _r_emailAddress.address) !== null && _ref !== void 0 ? _ref : r === null || r === void 0 ? void 0 : r.address;
|
|
135
|
+
}).filter(Boolean).join(', ') : '';
|
|
136
|
+
const bcc = Array.isArray(message === null || message === void 0 ? void 0 : message.bccRecipients) ? message.bccRecipients.map((r)=>{
|
|
137
|
+
var _ref;
|
|
138
|
+
var _r_emailAddress;
|
|
139
|
+
return (_ref = r === null || r === void 0 ? void 0 : (_r_emailAddress = r.emailAddress) === null || _r_emailAddress === void 0 ? void 0 : _r_emailAddress.address) !== null && _ref !== void 0 ? _ref : r === null || r === void 0 ? void 0 : r.address;
|
|
140
|
+
}).filter(Boolean).join(', ') : '';
|
|
141
|
+
const fromAddr = (_ref = (_ref1 = message === null || message === void 0 ? void 0 : (_message_from = message.from) === null || _message_from === void 0 ? void 0 : (_message_from_emailAddress = _message_from.emailAddress) === null || _message_from_emailAddress === void 0 ? void 0 : _message_from_emailAddress.address) !== null && _ref1 !== void 0 ? _ref1 : message === null || message === void 0 ? void 0 : (_message_from1 = message.from) === null || _message_from1 === void 0 ? void 0 : _message_from1.address) !== null && _ref !== void 0 ? _ref : '';
|
|
142
|
+
const categories = Array.isArray(message === null || message === void 0 ? void 0 : message.categories) ? message.categories.join(';') : '';
|
|
143
|
+
// Process body based on contentType and excludeThreadHistory options
|
|
144
|
+
let body = (_ref2 = message === null || message === void 0 ? void 0 : (_message_body = message.body) === null || _message_body === void 0 ? void 0 : _message_body.content) !== null && _ref2 !== void 0 ? _ref2 : '';
|
|
145
|
+
const isHtml = (message === null || message === void 0 ? void 0 : (_message_body1 = message.body) === null || _message_body1 === void 0 ? void 0 : (_message_body_contentType = _message_body1.contentType) === null || _message_body_contentType === void 0 ? void 0 : _message_body_contentType.toLowerCase()) === 'html';
|
|
146
|
+
if (isHtml && excludeThreadHistory) {
|
|
147
|
+
body = extractCurrentMessageFromHtml(body);
|
|
148
|
+
}
|
|
149
|
+
if (isHtml && contentType === 'text') {
|
|
150
|
+
var _ref7;
|
|
151
|
+
var _message_body2;
|
|
152
|
+
body = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(body) : extractCurrentMessageFromHtmlToText((_ref7 = message === null || message === void 0 ? void 0 : (_message_body2 = message.body) === null || _message_body2 === void 0 ? void 0 : _message_body2.content) !== null && _ref7 !== void 0 ? _ref7 : '');
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
id: String((_ref3 = message === null || message === void 0 ? void 0 : message.id) !== null && _ref3 !== void 0 ? _ref3 : ''),
|
|
156
|
+
threadId: (message === null || message === void 0 ? void 0 : message.conversationId) ? String(message.conversationId) : '',
|
|
157
|
+
from: fromAddr,
|
|
158
|
+
to,
|
|
159
|
+
cc,
|
|
160
|
+
bcc,
|
|
161
|
+
subject: (_ref4 = message === null || message === void 0 ? void 0 : message.subject) !== null && _ref4 !== void 0 ? _ref4 : '',
|
|
162
|
+
date: (_ref5 = message === null || message === void 0 ? void 0 : message.receivedDateTime) !== null && _ref5 !== void 0 ? _ref5 : '',
|
|
163
|
+
snippet: (_ref6 = message === null || message === void 0 ? void 0 : message.bodyPreview) !== null && _ref6 !== void 0 ? _ref6 : '',
|
|
164
|
+
body,
|
|
165
|
+
provider: 'outlook',
|
|
166
|
+
labels: categories
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
const csvRows = exec.items.map((item)=>{
|
|
170
|
+
return [
|
|
171
|
+
item.id,
|
|
172
|
+
item.threadId,
|
|
173
|
+
item.from,
|
|
174
|
+
item.to,
|
|
175
|
+
item.cc,
|
|
176
|
+
item.bcc,
|
|
177
|
+
item.subject,
|
|
178
|
+
item.date,
|
|
179
|
+
item.snippet,
|
|
180
|
+
item.body,
|
|
181
|
+
item.provider,
|
|
182
|
+
item.labels
|
|
183
|
+
];
|
|
184
|
+
});
|
|
185
|
+
// Append rows to CSV file immediately
|
|
186
|
+
if (csvRows.length > 0) {
|
|
187
|
+
const rowsContent = stringify(csvRows, {
|
|
188
|
+
header: false,
|
|
189
|
+
quoted: true,
|
|
190
|
+
quote: '"',
|
|
191
|
+
escape: '"'
|
|
192
|
+
});
|
|
193
|
+
writeStream.write(rowsContent);
|
|
194
|
+
}
|
|
195
|
+
totalRows += exec.items.length;
|
|
196
|
+
nextPageToken = (_exec_metadata = exec.metadata) === null || _exec_metadata === void 0 ? void 0 : _exec_metadata.nextPageToken;
|
|
197
|
+
logger.info('outlook.messages.export-csv batch written', {
|
|
198
|
+
batchSize: exec.items.length,
|
|
199
|
+
totalRows,
|
|
200
|
+
hasMore: Boolean(nextPageToken)
|
|
201
|
+
});
|
|
202
|
+
// Exit if no more results or reached maxItems
|
|
203
|
+
if (!nextPageToken || exec.items.length === 0) {
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Close write stream
|
|
208
|
+
await new Promise((resolve, reject)=>{
|
|
209
|
+
writeStream.end(()=>resolve());
|
|
210
|
+
writeStream.on('error', reject);
|
|
211
|
+
});
|
|
212
|
+
const durationMs = Date.now() - started;
|
|
213
|
+
const truncated = totalRows >= maxItems && Boolean(nextPageToken);
|
|
214
|
+
logger.info('outlook.messages.export-csv completed', {
|
|
215
|
+
rowCount: totalRows,
|
|
216
|
+
truncated,
|
|
217
|
+
durationMs,
|
|
218
|
+
filename: storedName
|
|
219
|
+
});
|
|
220
|
+
// Generate URI based on transport type (stdio: file://, HTTP: http://)
|
|
221
|
+
const uri = getFileUri(storedName, transport, {
|
|
222
|
+
storageDir,
|
|
223
|
+
...baseUrl && {
|
|
224
|
+
baseUrl
|
|
225
|
+
},
|
|
226
|
+
endpoint: '/files'
|
|
227
|
+
});
|
|
228
|
+
const result = {
|
|
229
|
+
type: 'success',
|
|
230
|
+
uri,
|
|
231
|
+
filename: storedName,
|
|
232
|
+
rowCount: totalRows,
|
|
233
|
+
truncated
|
|
234
|
+
};
|
|
235
|
+
return {
|
|
236
|
+
content: [
|
|
237
|
+
{
|
|
238
|
+
type: 'text',
|
|
239
|
+
text: JSON.stringify(result)
|
|
240
|
+
}
|
|
241
|
+
],
|
|
242
|
+
structuredContent: {
|
|
243
|
+
result
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
} catch (error) {
|
|
247
|
+
// CRITICAL: Clean up partial CSV file on error
|
|
248
|
+
try {
|
|
249
|
+
await unlink(fullPath);
|
|
250
|
+
logger.debug('Cleaned up partial CSV file after error', {
|
|
251
|
+
path: fullPath
|
|
252
|
+
});
|
|
253
|
+
} catch (_cleanupError) {
|
|
254
|
+
logger.debug('Could not clean up CSV file (may not exist)', {
|
|
255
|
+
path: fullPath
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
259
|
+
logger.error('outlook.messages.export-csv error', {
|
|
260
|
+
error: message
|
|
261
|
+
});
|
|
262
|
+
throw new McpError(ErrorCode.InternalError, `Error exporting messages to CSV: ${message}`, {
|
|
263
|
+
stack: error instanceof Error ? error.stack : undefined
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
export default function createTool() {
|
|
268
|
+
return {
|
|
269
|
+
name: 'messages-export-csv',
|
|
270
|
+
config,
|
|
271
|
+
handler
|
|
272
|
+
};
|
|
273
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-outlook/src/mcp/tools/messages-export-csv.ts"],"sourcesContent":["/** Outlook message CSV export tool - streams results to file without loading all data into context */\n\nimport { EmailContentTypeSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText } from '@mcp-z/email';\nimport type { EnrichedExtra } from '@mcp-z/oauth-microsoft';\nimport { schemas } from '@mcp-z/oauth-microsoft';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport { getFileUri, reserveFile, type ToolModule } from '@mcp-z/server';\nimport { Client } from '@microsoft/microsoft-graph-client';\nimport type * as MicrosoftGraph from '@microsoft/microsoft-graph-types';\nimport { type CallToolResult, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { stringify } from 'csv-stringify/sync';\nimport { createWriteStream } from 'fs';\nimport { unlink } from 'fs/promises';\nimport { z } from 'zod';\nimport { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.js';\nimport { OutlookQuerySchema } from '../../schemas/outlook-query-schema.js';\nimport type { StorageExtra } from '../../types.js';\n\nconst DEFAULT_PAGE_SIZE = 50;\nconst DEFAULT_MAX_ITEMS = 10000;\nconst MAX_EXPORT_ITEMS = 50000;\n\nconst ExportResultSchema = z.object({\n uri: z.string().describe('File URI (file:// or http://)'),\n filename: z.string().describe('Stored filename'),\n rowCount: z.number().describe('Number of messages exported'),\n truncated: z.boolean().describe('Whether export was truncated at maxItems'),\n});\n\nconst inputSchema = z.object({\n query: OutlookQuerySchema.optional().describe('Structured query object for filtering messages. Use query-syntax prompt for reference.'),\n maxItems: z.number().int().positive().max(MAX_EXPORT_ITEMS).default(DEFAULT_MAX_ITEMS).describe(`Maximum messages to export (default: ${DEFAULT_MAX_ITEMS}, max: ${MAX_EXPORT_ITEMS})`),\n filename: z.string().trim().min(1).default('outlook-messages.csv').describe('Output filename (default: outlook-messages.csv)'),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schema\nconst successBranchSchema = ExportResultSchema.extend({\n type: z.literal('success'),\n});\n\n// Output schema with auth_required support\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Export Outlook messages to CSV with streaming pagination. Returns file URI. Use query-syntax prompt for query reference.',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\n/**\n * Handler for outlook-messages-export-csv tool\n *\n * CRITICAL: Streaming implementation per user requirements\n * - Generate UUID upfront\n * - Write CSV header immediately\n * - Append rows as batches arrive\n * - Delete partial file on error\n * - NO RETRIES (fail fast on error)\n */\nasync function handler({ query, maxItems, filename, contentType, excludeThreadHistory }: Input, extra: EnrichedExtra & StorageExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n const { storageContext } = extra;\n const { transport, storageDir, baseUrl } = storageContext;\n\n logger.info('outlook.messages.export-csv called', {\n query,\n maxItems,\n filename,\n accountId: extra.authContext.accountId,\n });\n\n // Reserve file location for streaming write (creates directory, generates ID, formats filename)\n const reservation = await reserveFile(filename, {\n storageDir,\n });\n const { storedName, fullPath } = reservation;\n\n logger.info('outlook.messages.export-csv starting streaming export', { path: fullPath, maxItems });\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n\n // Create CSV headers (all email fields)\n const csvHeaders = ['id', 'threadId', 'from', 'to', 'cc', 'bcc', 'subject', 'date', 'snippet', 'body', 'provider', 'labels'];\n\n // Create write stream and write headers immediately\n const writeStream = createWriteStream(fullPath, { encoding: 'utf-8' });\n const headerLine = stringify([csvHeaders], { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(headerLine);\n\n // Internal pagination loop - append to CSV with each batch\n // NO RETRIES: If any error occurs, fail the whole operation and clean up\n let totalRows = 0;\n let nextPageToken: string | undefined;\n const started = Date.now();\n\n while (totalRows < maxItems) {\n const remainingItems = maxItems - totalRows;\n const pageSize = Math.min(remainingItems, DEFAULT_PAGE_SIZE);\n\n const exec: {\n items: Array<{\n id: string;\n threadId?: string;\n from: string;\n to: string;\n cc: string;\n bcc: string;\n subject: string;\n date: string;\n snippet: string;\n body: string;\n provider: string;\n labels: string;\n }>;\n metadata?: { nextPageToken?: string };\n } = await executeOutlookQuery(\n graph,\n query,\n {\n logger,\n pageSize,\n ...(nextPageToken !== undefined && { pageToken: nextPageToken }),\n includeBody: true, // Always include body for CSV export\n limit: pageSize,\n },\n (m: unknown) => {\n const message = m as MicrosoftGraph.Message;\n const to = Array.isArray(message?.toRecipients)\n ? message.toRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const cc = Array.isArray(message?.ccRecipients)\n ? message.ccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const bcc = Array.isArray(message?.bccRecipients)\n ? message.bccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address ?? (r as { address?: string })?.address)\n .filter(Boolean)\n .join(', ')\n : '';\n const fromAddr = message?.from?.emailAddress?.address ?? (message?.from as { address?: string })?.address ?? '';\n const categories = Array.isArray(message?.categories) ? message.categories.join(';') : '';\n\n // Process body based on contentType and excludeThreadHistory options\n let body = message?.body?.content ?? '';\n const isHtml = message?.body?.contentType?.toLowerCase() === 'html';\n\n if (isHtml && excludeThreadHistory) {\n body = extractCurrentMessageFromHtml(body);\n }\n\n if (isHtml && contentType === 'text') {\n body = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(body) : extractCurrentMessageFromHtmlToText(message?.body?.content ?? '');\n }\n\n return {\n id: String(message?.id ?? ''),\n threadId: message?.conversationId ? String(message.conversationId) : '',\n from: fromAddr,\n to,\n cc,\n bcc,\n subject: message?.subject ?? '',\n date: message?.receivedDateTime ?? '',\n snippet: message?.bodyPreview ?? '',\n body,\n provider: 'outlook' as const,\n labels: categories,\n };\n }\n );\n\n const csvRows = exec.items.map((item) => {\n return [item.id, item.threadId, item.from, item.to, item.cc, item.bcc, item.subject, item.date, item.snippet, item.body, item.provider, item.labels];\n });\n\n // Append rows to CSV file immediately\n if (csvRows.length > 0) {\n const rowsContent = stringify(csvRows, { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(rowsContent);\n }\n\n totalRows += exec.items.length;\n nextPageToken = exec.metadata?.nextPageToken;\n\n logger.info('outlook.messages.export-csv batch written', {\n batchSize: exec.items.length,\n totalRows,\n hasMore: Boolean(nextPageToken),\n });\n\n // Exit if no more results or reached maxItems\n if (!nextPageToken || exec.items.length === 0) {\n break;\n }\n }\n\n // Close write stream\n await new Promise<void>((resolve, reject) => {\n writeStream.end(() => resolve());\n writeStream.on('error', reject);\n });\n\n const durationMs = Date.now() - started;\n const truncated = totalRows >= maxItems && Boolean(nextPageToken);\n\n logger.info('outlook.messages.export-csv completed', {\n rowCount: totalRows,\n truncated,\n durationMs,\n filename: storedName,\n });\n\n // Generate URI based on transport type (stdio: file://, HTTP: http://)\n const uri = getFileUri(storedName, transport, {\n storageDir,\n ...(baseUrl && { baseUrl }),\n endpoint: '/files',\n });\n\n const result: Output = {\n type: 'success' as const,\n uri,\n filename: storedName,\n rowCount: totalRows,\n truncated,\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result),\n },\n ],\n structuredContent: { result },\n };\n } catch (error) {\n // CRITICAL: Clean up partial CSV file on error\n try {\n await unlink(fullPath);\n logger.debug('Cleaned up partial CSV file after error', { path: fullPath });\n } catch (_cleanupError) {\n logger.debug('Could not clean up CSV file (may not exist)', { path: fullPath });\n }\n\n const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook.messages.export-csv error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error exporting messages to CSV: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'messages-export-csv',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["EmailContentTypeSchema","ExcludeThreadHistorySchema","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","schemas","AuthRequiredBranchSchema","getFileUri","reserveFile","Client","ErrorCode","McpError","stringify","createWriteStream","unlink","z","executeQuery","executeOutlookQuery","OutlookQuerySchema","DEFAULT_PAGE_SIZE","DEFAULT_MAX_ITEMS","MAX_EXPORT_ITEMS","ExportResultSchema","object","uri","string","describe","filename","rowCount","number","truncated","boolean","inputSchema","query","optional","maxItems","int","positive","max","default","trim","min","contentType","excludeThreadHistory","successBranchSchema","extend","type","literal","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","storageContext","transport","storageDir","baseUrl","info","accountId","authContext","reservation","storedName","fullPath","path","graph","initWithMiddleware","authProvider","auth","csvHeaders","writeStream","encoding","headerLine","header","quoted","quote","escape","write","totalRows","nextPageToken","started","Date","now","exec","remainingItems","pageSize","Math","undefined","pageToken","includeBody","limit","m","message","to","Array","isArray","toRecipients","map","r","emailAddress","address","filter","Boolean","join","cc","ccRecipients","bcc","bccRecipients","fromAddr","from","categories","body","content","isHtml","toLowerCase","id","String","threadId","conversationId","subject","date","receivedDateTime","snippet","bodyPreview","provider","labels","csvRows","items","item","length","rowsContent","metadata","batchSize","hasMore","Promise","resolve","reject","end","on","durationMs","endpoint","text","JSON","structuredContent","error","debug","_cleanupError","Error","InternalError","stack","createTool","name"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "type": "module" }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-outlook/src/schemas/index.ts"],"sourcesContent":["export * from './outlook-query-schema.js';\nexport * from './outlook-validation.js';\n"],"names":[],"mappings":"AAAA,cAAc,4BAA4B;AAC1C,cAAc,0BAA0B"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type BaseEmailQueryFields, type FieldOperator } from '@mcp-z/email';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* Outlook system category values.
|
|
5
|
+
* These are the built-in category types that Outlook recognizes.
|
|
6
|
+
* Note: This is distinct from OutlookCategory (user-created category objects with id/displayName/color).
|
|
7
|
+
*/
|
|
8
|
+
export type OutlookSystemCategory = 'work' | 'personal' | 'family' | 'travel' | 'important' | 'urgent';
|
|
9
|
+
/** Zod schema for validating OutlookSystemCategory values */
|
|
10
|
+
export declare const OutlookSystemCategorySchema: z.ZodEnum<{
|
|
11
|
+
work: "work";
|
|
12
|
+
personal: "personal";
|
|
13
|
+
family: "family";
|
|
14
|
+
travel: "travel";
|
|
15
|
+
important: "important";
|
|
16
|
+
urgent: "urgent";
|
|
17
|
+
}>;
|
|
18
|
+
/**
|
|
19
|
+
* Outlook-specific query schema with recursive operators and Outlook features.
|
|
20
|
+
*
|
|
21
|
+
* Includes Microsoft Graph/Outlook-specific features:
|
|
22
|
+
* - exactPhrase: Strict exact phrase matching via KQL $search parameter
|
|
23
|
+
* - categories: Outlook system categories (work, personal, family, travel, important, urgent)
|
|
24
|
+
* - label: User-created Outlook categories (case-sensitive, discovered via outlook-categories-list)
|
|
25
|
+
* - importance: Message importance level (high, normal, low)
|
|
26
|
+
* - kqlQuery: Escape hatch for advanced KQL (Keyword Query Language) syntax
|
|
27
|
+
*
|
|
28
|
+
* Plus all base fields from baseEmailQueryFields:
|
|
29
|
+
* - Email addresses: from, to, cc, bcc (support string or field operators)
|
|
30
|
+
* - Content: subject, body, text
|
|
31
|
+
* - Flags: hasAttachment, isRead
|
|
32
|
+
* - Date range: date { $gte, $lt }
|
|
33
|
+
* - Logical operators: $and, $or, $not (recursive)
|
|
34
|
+
*
|
|
35
|
+
* Note: Cast through unknown to work around Zod's lazy schema type inference issue
|
|
36
|
+
* with exactOptionalPropertyTypes. The runtime schema is correct; this cast ensures
|
|
37
|
+
* TypeScript sees the strict OutlookQuery type everywhere the schema is used.
|
|
38
|
+
*/
|
|
39
|
+
export declare const OutlookQuerySchema: z.ZodType<OutlookQuery>;
|
|
40
|
+
export type OutlookQuery = BaseEmailQueryFields & {
|
|
41
|
+
$and?: OutlookQuery[];
|
|
42
|
+
$or?: OutlookQuery[];
|
|
43
|
+
$not?: OutlookQuery;
|
|
44
|
+
exactPhrase?: string;
|
|
45
|
+
categories?: OutlookSystemCategory | {
|
|
46
|
+
$any?: OutlookSystemCategory[];
|
|
47
|
+
$all?: OutlookSystemCategory[];
|
|
48
|
+
$none?: OutlookSystemCategory[];
|
|
49
|
+
};
|
|
50
|
+
label?: string | FieldOperator;
|
|
51
|
+
importance?: 'high' | 'normal' | 'low';
|
|
52
|
+
kqlQuery?: string;
|
|
53
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { baseEmailQueryFields, FieldOperatorSchema } from '@mcp-z/email';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/** Zod schema for validating OutlookSystemCategory values */ export const OutlookSystemCategorySchema = z.enum([
|
|
4
|
+
'work',
|
|
5
|
+
'personal',
|
|
6
|
+
'family',
|
|
7
|
+
'travel',
|
|
8
|
+
'important',
|
|
9
|
+
'urgent'
|
|
10
|
+
]);
|
|
11
|
+
/**
|
|
12
|
+
* Outlook-specific query schema with recursive operators and Outlook features.
|
|
13
|
+
*
|
|
14
|
+
* Includes Microsoft Graph/Outlook-specific features:
|
|
15
|
+
* - exactPhrase: Strict exact phrase matching via KQL $search parameter
|
|
16
|
+
* - categories: Outlook system categories (work, personal, family, travel, important, urgent)
|
|
17
|
+
* - label: User-created Outlook categories (case-sensitive, discovered via outlook-categories-list)
|
|
18
|
+
* - importance: Message importance level (high, normal, low)
|
|
19
|
+
* - kqlQuery: Escape hatch for advanced KQL (Keyword Query Language) syntax
|
|
20
|
+
*
|
|
21
|
+
* Plus all base fields from baseEmailQueryFields:
|
|
22
|
+
* - Email addresses: from, to, cc, bcc (support string or field operators)
|
|
23
|
+
* - Content: subject, body, text
|
|
24
|
+
* - Flags: hasAttachment, isRead
|
|
25
|
+
* - Date range: date { $gte, $lt }
|
|
26
|
+
* - Logical operators: $and, $or, $not (recursive)
|
|
27
|
+
*
|
|
28
|
+
* Note: Cast through unknown to work around Zod's lazy schema type inference issue
|
|
29
|
+
* with exactOptionalPropertyTypes. The runtime schema is correct; this cast ensures
|
|
30
|
+
* TypeScript sees the strict OutlookQuery type everywhere the schema is used.
|
|
31
|
+
*/ export const OutlookQuerySchema = z.lazy(()=>z.object({
|
|
32
|
+
// Logical operators for combining conditions (recursive)
|
|
33
|
+
$and: z.array(OutlookQuerySchema).optional().describe('Array of conditions that must ALL match'),
|
|
34
|
+
$or: z.array(OutlookQuerySchema).optional().describe('Array of conditions where ANY must match'),
|
|
35
|
+
$not: OutlookQuerySchema.optional().describe('Nested condition that must NOT match'),
|
|
36
|
+
// Spread base email query fields (from, to, subject, body, etc.)
|
|
37
|
+
...baseEmailQueryFields,
|
|
38
|
+
// Outlook-specific features
|
|
39
|
+
// Exact phrase matching - KQL strict search with double quotes
|
|
40
|
+
exactPhrase: z.string().min(1).optional().describe('Exact phrase matching - words must appear together in exact order (strict matching). Outlook uses KQL.'),
|
|
41
|
+
// Outlook system categories with field operator support
|
|
42
|
+
categories: z.union([
|
|
43
|
+
OutlookSystemCategorySchema,
|
|
44
|
+
z.object({
|
|
45
|
+
$any: z.array(OutlookSystemCategorySchema).optional(),
|
|
46
|
+
$all: z.array(OutlookSystemCategorySchema).optional(),
|
|
47
|
+
$none: z.array(OutlookSystemCategorySchema).optional()
|
|
48
|
+
}).strict()
|
|
49
|
+
]).optional().describe('Filter by Outlook system categories (work, personal, family, travel, important, urgent)'),
|
|
50
|
+
// User-created categories
|
|
51
|
+
label: z.union([
|
|
52
|
+
z.string().min(1),
|
|
53
|
+
FieldOperatorSchema
|
|
54
|
+
]).optional().describe('Filter by user-created categories (case-sensitive). Use outlook-categories-list to see available categories'),
|
|
55
|
+
// Message importance level - Outlook-specific property
|
|
56
|
+
importance: z.enum([
|
|
57
|
+
'high',
|
|
58
|
+
'normal',
|
|
59
|
+
'low'
|
|
60
|
+
]).optional().describe('Filter by message importance level (high, normal, low)'),
|
|
61
|
+
// Raw KQL query string - escape hatch for advanced syntax
|
|
62
|
+
kqlQuery: z.string().min(1).optional().describe('Raw KQL (Keyword Query Language) syntax for advanced use cases. Bypasses schema validation - use sparingly.')
|
|
63
|
+
}).strict());
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-outlook/src/schemas/outlook-query-schema.ts"],"sourcesContent":["import { type BaseEmailQueryFields, baseEmailQueryFields, type FieldOperator, FieldOperatorSchema } from '@mcp-z/email';\nimport { z } from 'zod';\n\n/**\n * Outlook system category values.\n * These are the built-in category types that Outlook recognizes.\n * Note: This is distinct from OutlookCategory (user-created category objects with id/displayName/color).\n */\nexport type OutlookSystemCategory = 'work' | 'personal' | 'family' | 'travel' | 'important' | 'urgent';\n\n/** Zod schema for validating OutlookSystemCategory values */\nexport const OutlookSystemCategorySchema = z.enum(['work', 'personal', 'family', 'travel', 'important', 'urgent']);\n\n/**\n * Outlook-specific query schema with recursive operators and Outlook features.\n *\n * Includes Microsoft Graph/Outlook-specific features:\n * - exactPhrase: Strict exact phrase matching via KQL $search parameter\n * - categories: Outlook system categories (work, personal, family, travel, important, urgent)\n * - label: User-created Outlook categories (case-sensitive, discovered via outlook-categories-list)\n * - importance: Message importance level (high, normal, low)\n * - kqlQuery: Escape hatch for advanced KQL (Keyword Query Language) syntax\n *\n * Plus all base fields from baseEmailQueryFields:\n * - Email addresses: from, to, cc, bcc (support string or field operators)\n * - Content: subject, body, text\n * - Flags: hasAttachment, isRead\n * - Date range: date { $gte, $lt }\n * - Logical operators: $and, $or, $not (recursive)\n *\n * Note: Cast through unknown to work around Zod's lazy schema type inference issue\n * with exactOptionalPropertyTypes. The runtime schema is correct; this cast ensures\n * TypeScript sees the strict OutlookQuery type everywhere the schema is used.\n */\nexport const OutlookQuerySchema = z.lazy(() =>\n z\n .object({\n // Logical operators for combining conditions (recursive)\n $and: z.array(OutlookQuerySchema).optional().describe('Array of conditions that must ALL match'),\n $or: z.array(OutlookQuerySchema).optional().describe('Array of conditions where ANY must match'),\n $not: OutlookQuerySchema.optional().describe('Nested condition that must NOT match'),\n\n // Spread base email query fields (from, to, subject, body, etc.)\n ...baseEmailQueryFields,\n\n // Outlook-specific features\n\n // Exact phrase matching - KQL strict search with double quotes\n exactPhrase: z.string().min(1).optional().describe('Exact phrase matching - words must appear together in exact order (strict matching). Outlook uses KQL.'),\n\n // Outlook system categories with field operator support\n categories: z\n .union([\n OutlookSystemCategorySchema,\n z\n .object({\n $any: z.array(OutlookSystemCategorySchema).optional(),\n $all: z.array(OutlookSystemCategorySchema).optional(),\n $none: z.array(OutlookSystemCategorySchema).optional(),\n })\n .strict(),\n ])\n .optional()\n .describe('Filter by Outlook system categories (work, personal, family, travel, important, urgent)'),\n\n // User-created categories\n label: z\n .union([z.string().min(1), FieldOperatorSchema])\n .optional()\n .describe('Filter by user-created categories (case-sensitive). Use outlook-categories-list to see available categories'),\n\n // Message importance level - Outlook-specific property\n importance: z.enum(['high', 'normal', 'low']).optional().describe('Filter by message importance level (high, normal, low)'),\n\n // Raw KQL query string - escape hatch for advanced syntax\n kqlQuery: z.string().min(1).optional().describe('Raw KQL (Keyword Query Language) syntax for advanced use cases. Bypasses schema validation - use sparingly.'),\n })\n .strict()\n) as unknown as z.ZodType<OutlookQuery>;\n\nexport type OutlookQuery = BaseEmailQueryFields & {\n $and?: OutlookQuery[];\n $or?: OutlookQuery[];\n $not?: OutlookQuery;\n exactPhrase?: string;\n categories?:\n | OutlookSystemCategory\n | {\n $any?: OutlookSystemCategory[];\n $all?: OutlookSystemCategory[];\n $none?: OutlookSystemCategory[];\n };\n label?: string | FieldOperator;\n importance?: 'high' | 'normal' | 'low';\n kqlQuery?: string;\n};\n"],"names":["baseEmailQueryFields","FieldOperatorSchema","z","OutlookSystemCategorySchema","enum","OutlookQuerySchema","lazy","object","$and","array","optional","describe","$or","$not","exactPhrase","string","min","categories","union","$any","$all","$none","strict","label","importance","kqlQuery"],"mappings":"AAAA,SAAoCA,oBAAoB,EAAsBC,mBAAmB,QAAQ,eAAe;AACxH,SAASC,CAAC,QAAQ,MAAM;AASxB,2DAA2D,GAC3D,OAAO,MAAMC,8BAA8BD,EAAEE,IAAI,CAAC;IAAC;IAAQ;IAAY;IAAU;IAAU;IAAa;CAAS,EAAE;AAEnH;;;;;;;;;;;;;;;;;;;;CAoBC,GACD,OAAO,MAAMC,qBAAqBH,EAAEI,IAAI,CAAC,IACvCJ,EACGK,MAAM,CAAC;QACN,yDAAyD;QACzDC,MAAMN,EAAEO,KAAK,CAACJ,oBAAoBK,QAAQ,GAAGC,QAAQ,CAAC;QACtDC,KAAKV,EAAEO,KAAK,CAACJ,oBAAoBK,QAAQ,GAAGC,QAAQ,CAAC;QACrDE,MAAMR,mBAAmBK,QAAQ,GAAGC,QAAQ,CAAC;QAE7C,iEAAiE;QACjE,GAAGX,oBAAoB;QAEvB,4BAA4B;QAE5B,+DAA+D;QAC/Dc,aAAaZ,EAAEa,MAAM,GAAGC,GAAG,CAAC,GAAGN,QAAQ,GAAGC,QAAQ,CAAC;QAEnD,wDAAwD;QACxDM,YAAYf,EACTgB,KAAK,CAAC;YACLf;YACAD,EACGK,MAAM,CAAC;gBACNY,MAAMjB,EAAEO,KAAK,CAACN,6BAA6BO,QAAQ;gBACnDU,MAAMlB,EAAEO,KAAK,CAACN,6BAA6BO,QAAQ;gBACnDW,OAAOnB,EAAEO,KAAK,CAACN,6BAA6BO,QAAQ;YACtD,GACCY,MAAM;SACV,EACAZ,QAAQ,GACRC,QAAQ,CAAC;QAEZ,0BAA0B;QAC1BY,OAAOrB,EACJgB,KAAK,CAAC;YAAChB,EAAEa,MAAM,GAAGC,GAAG,CAAC;YAAIf;SAAoB,EAC9CS,QAAQ,GACRC,QAAQ,CAAC;QAEZ,uDAAuD;QACvDa,YAAYtB,EAAEE,IAAI,CAAC;YAAC;YAAQ;YAAU;SAAM,EAAEM,QAAQ,GAAGC,QAAQ,CAAC;QAElE,0DAA0D;QAC1Dc,UAAUvB,EAAEa,MAAM,GAAGC,GAAG,CAAC,GAAGN,QAAQ,GAAGC,QAAQ,CAAC;IAClD,GACCW,MAAM,IAC6B"}
|