@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 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-outlook/src/mcp/tools/message-get.ts"],"sourcesContent":["import { EMAIL_COMMON_PATTERNS, EMAIL_FIELD_DESCRIPTIONS, EMAIL_FIELDS, EmailContentTypeSchema, EmailDetailSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText, normalizeDateToISO as toIsoUtc } 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 { createFieldsSchema, filterFields, parseFields, 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 { z } from 'zod';\n\nconst inputSchema = z.object({\n id: z.coerce.string().trim().min(1).describe('Outlook message ID to retrieve'),\n fields: createFieldsSchema({\n availableFields: EMAIL_FIELDS,\n fieldDescriptions: EMAIL_FIELD_DESCRIPTIONS,\n commonPatterns: EMAIL_COMMON_PATTERNS,\n resourceName: 'email message',\n }),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schema - uses item: wrapper for consistency with standard vocabulary\nconst successBranchSchema = z.object({\n type: z.literal('success'),\n item: EmailDetailSchema,\n});\n\n// Output schema with auth_required support\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Get an Outlook message by ID with flexible field selection',\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\nasync function handler({ id, fields, contentType, excludeThreadHistory }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n\n const requestedFields = parseFields(fields, EMAIL_FIELDS);\n\n logger.info('outlook.message.get called', { id, fields: fields || 'all' });\n\n if (!id) {\n logger.info('outlook.message.get missing id');\n throw new McpError(ErrorCode.InvalidParams, 'Missing id');\n }\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n const message = (await graph.api(`/me/messages/${encodeURIComponent(id)}`).get()) as MicrosoftGraph.Message;\n\n // Process body based on contentType and excludeThreadHistory options\n let bodyContent = message.body?.content ?? '';\n const isHtml = message.body?.contentType?.toLowerCase() === 'html';\n\n if (isHtml && excludeThreadHistory) {\n // Remove thread history from HTML\n bodyContent = extractCurrentMessageFromHtml(bodyContent);\n }\n\n if (isHtml && contentType === 'text') {\n // Convert HTML to plain text (thread extraction happens inside if excludeThreadHistory was true)\n bodyContent = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(bodyContent) : extractCurrentMessageFromHtmlToText(message.body?.content ?? '');\n }\n\n // Build full message data\n const payload = {\n id: message.id,\n subject: message.subject,\n from: message.from?.emailAddress?.address,\n date: toIsoUtc(message.receivedDateTime) || message.receivedDateTime,\n snippet: message.bodyPreview,\n body: bodyContent,\n bodyContentType: contentType,\n };\n\n // Filter based on requested fields\n const filteredPayload = filterFields(payload, requestedFields);\n\n logger.info('outlook.message.get success', { id: payload.id, subject: payload.subject, from: payload.from, date: payload.date, fields: fields || 'all' });\n\n const result: Output = {\n type: 'success' as const,\n item: filteredPayload as z.infer<typeof EmailDetailSchema>,\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 const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook.message.get error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error getting message: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-get',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["EMAIL_COMMON_PATTERNS","EMAIL_FIELD_DESCRIPTIONS","EMAIL_FIELDS","EmailContentTypeSchema","EmailDetailSchema","ExcludeThreadHistorySchema","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","normalizeDateToISO","toIsoUtc","schemas","AuthRequiredBranchSchema","createFieldsSchema","filterFields","parseFields","Client","ErrorCode","McpError","z","inputSchema","object","id","coerce","string","trim","min","describe","fields","availableFields","fieldDescriptions","commonPatterns","resourceName","contentType","excludeThreadHistory","successBranchSchema","type","literal","item","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","requestedFields","info","InvalidParams","message","graph","initWithMiddleware","authProvider","authContext","auth","api","encodeURIComponent","get","bodyContent","body","content","isHtml","toLowerCase","payload","subject","from","emailAddress","address","date","receivedDateTime","snippet","bodyPreview","bodyContentType","filteredPayload","text","JSON","stringify","structuredContent","error","Error","String","InternalError","stack","undefined","createTool","name"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { EnrichedExtra } from '@mcp-z/oauth-microsoft';
|
|
2
|
+
import { type CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
declare const inputSchema: z.ZodObject<{
|
|
5
|
+
id: z.ZodCoercedString<unknown>;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
declare const outputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
8
|
+
success: z.ZodBoolean;
|
|
9
|
+
id: z.ZodOptional<z.ZodString>;
|
|
10
|
+
type: z.ZodLiteral<"success">;
|
|
11
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
12
|
+
type: z.ZodLiteral<"auth_required">;
|
|
13
|
+
provider: z.ZodString;
|
|
14
|
+
message: z.ZodString;
|
|
15
|
+
url: z.ZodOptional<z.ZodString>;
|
|
16
|
+
}, z.core.$strip>], "type">;
|
|
17
|
+
export type Input = z.infer<typeof inputSchema>;
|
|
18
|
+
export type Output = z.infer<typeof outputSchema>;
|
|
19
|
+
declare function handler({ id }: Input, extra: EnrichedExtra): Promise<CallToolResult>;
|
|
20
|
+
export default function createTool(): {
|
|
21
|
+
name: string;
|
|
22
|
+
config: {
|
|
23
|
+
readonly description: "Mark an Outlook message as read";
|
|
24
|
+
readonly inputSchema: z.ZodObject<{
|
|
25
|
+
id: z.ZodCoercedString<unknown>;
|
|
26
|
+
}, z.core.$strip>;
|
|
27
|
+
readonly outputSchema: z.ZodObject<{
|
|
28
|
+
result: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
29
|
+
success: z.ZodBoolean;
|
|
30
|
+
id: z.ZodOptional<z.ZodString>;
|
|
31
|
+
type: z.ZodLiteral<"success">;
|
|
32
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
33
|
+
type: z.ZodLiteral<"auth_required">;
|
|
34
|
+
provider: z.ZodString;
|
|
35
|
+
message: z.ZodString;
|
|
36
|
+
url: z.ZodOptional<z.ZodString>;
|
|
37
|
+
}, z.core.$strip>], "type">;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
};
|
|
40
|
+
handler: typeof handler;
|
|
41
|
+
};
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { schemas } from '@mcp-z/oauth-microsoft';
|
|
2
|
+
const { AuthRequiredBranchSchema } = schemas;
|
|
3
|
+
import { Client } from '@microsoft/microsoft-graph-client';
|
|
4
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
const SuccessSchema = z.object({
|
|
7
|
+
success: z.boolean().describe('Whether the operation completed successfully'),
|
|
8
|
+
id: z.string().optional().describe('Message ID that was marked as read')
|
|
9
|
+
});
|
|
10
|
+
const inputSchema = z.object({
|
|
11
|
+
id: z.coerce.string().trim().min(1).describe('Outlook message ID to mark as read')
|
|
12
|
+
});
|
|
13
|
+
// Success branch schema
|
|
14
|
+
const successBranchSchema = SuccessSchema.extend({
|
|
15
|
+
type: z.literal('success')
|
|
16
|
+
});
|
|
17
|
+
// Output schema with auth_required support
|
|
18
|
+
const outputSchema = z.discriminatedUnion('type', [
|
|
19
|
+
successBranchSchema,
|
|
20
|
+
AuthRequiredBranchSchema
|
|
21
|
+
]);
|
|
22
|
+
const config = {
|
|
23
|
+
description: 'Mark an Outlook message as read',
|
|
24
|
+
inputSchema: inputSchema,
|
|
25
|
+
outputSchema: z.object({
|
|
26
|
+
result: outputSchema
|
|
27
|
+
})
|
|
28
|
+
};
|
|
29
|
+
async function handler({ id }, extra) {
|
|
30
|
+
const logger = extra.logger;
|
|
31
|
+
logger.info('outlook-message-mark-read called', {
|
|
32
|
+
id
|
|
33
|
+
});
|
|
34
|
+
if (!id) {
|
|
35
|
+
logger.info('outlook-message-mark-read missing id');
|
|
36
|
+
throw new McpError(ErrorCode.InvalidParams, 'Missing id');
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const graph = Client.initWithMiddleware({
|
|
40
|
+
authProvider: extra.authContext.auth
|
|
41
|
+
});
|
|
42
|
+
await graph.api(`/me/messages/${encodeURIComponent(id)}`).update({
|
|
43
|
+
isRead: true
|
|
44
|
+
});
|
|
45
|
+
logger.info('outlook-message-mark-read success', {
|
|
46
|
+
id
|
|
47
|
+
});
|
|
48
|
+
const result = {
|
|
49
|
+
type: 'success',
|
|
50
|
+
success: true,
|
|
51
|
+
id
|
|
52
|
+
};
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: 'text',
|
|
57
|
+
text: JSON.stringify(result)
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
structuredContent: {
|
|
61
|
+
result
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
} catch (error) {
|
|
65
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
66
|
+
logger.error('outlook-message-mark-read error', {
|
|
67
|
+
error: message
|
|
68
|
+
});
|
|
69
|
+
throw new McpError(ErrorCode.InternalError, `Error marking message as read: ${message}`, {
|
|
70
|
+
stack: error instanceof Error ? error.stack : undefined
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export default function createTool() {
|
|
75
|
+
return {
|
|
76
|
+
name: 'message-mark-read',
|
|
77
|
+
config,
|
|
78
|
+
handler
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-outlook/src/mcp/tools/message-mark-read.ts"],"sourcesContent":["import type { EnrichedExtra } from '@mcp-z/oauth-microsoft';\nimport { schemas } from '@mcp-z/oauth-microsoft';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport type { ToolModule } from '@mcp-z/server';\nimport { Client } from '@microsoft/microsoft-graph-client';\nimport { type CallToolResult, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\n\nconst SuccessSchema = z.object({\n success: z.boolean().describe('Whether the operation completed successfully'),\n id: z.string().optional().describe('Message ID that was marked as read'),\n});\n\nconst inputSchema = z.object({\n id: z.coerce.string().trim().min(1).describe('Outlook message ID to mark as read'),\n});\n\n// Success branch schema\nconst successBranchSchema = SuccessSchema.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: 'Mark an Outlook message as read',\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\nasync function handler({ id }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n logger.info('outlook-message-mark-read called', { id });\n\n if (!id) {\n logger.info('outlook-message-mark-read missing id');\n throw new McpError(ErrorCode.InvalidParams, 'Missing id');\n }\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n await graph.api(`/me/messages/${encodeURIComponent(id)}`).update({ isRead: true });\n\n logger.info('outlook-message-mark-read success', { id });\n\n const result: Output = {\n type: 'success' as const,\n success: true,\n id,\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 const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook-message-mark-read error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error marking message as read: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-mark-read',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["schemas","AuthRequiredBranchSchema","Client","ErrorCode","McpError","z","SuccessSchema","object","success","boolean","describe","id","string","optional","inputSchema","coerce","trim","min","successBranchSchema","extend","type","literal","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","info","InvalidParams","graph","initWithMiddleware","authProvider","authContext","auth","api","encodeURIComponent","update","isRead","content","text","JSON","stringify","structuredContent","error","message","Error","String","InternalError","stack","undefined","createTool","name"],"mappings":"AACA,SAASA,OAAO,QAAQ,yBAAyB;AAEjD,MAAM,EAAEC,wBAAwB,EAAE,GAAGD;AAGrC,SAASE,MAAM,QAAQ,oCAAoC;AAC3D,SAA8BC,SAAS,EAAEC,QAAQ,QAAQ,qCAAqC;AAC9F,SAASC,CAAC,QAAQ,MAAM;AAExB,MAAMC,gBAAgBD,EAAEE,MAAM,CAAC;IAC7BC,SAASH,EAAEI,OAAO,GAAGC,QAAQ,CAAC;IAC9BC,IAAIN,EAAEO,MAAM,GAAGC,QAAQ,GAAGH,QAAQ,CAAC;AACrC;AAEA,MAAMI,cAAcT,EAAEE,MAAM,CAAC;IAC3BI,IAAIN,EAAEU,MAAM,CAACH,MAAM,GAAGI,IAAI,GAAGC,GAAG,CAAC,GAAGP,QAAQ,CAAC;AAC/C;AAEA,wBAAwB;AACxB,MAAMQ,sBAAsBZ,cAAca,MAAM,CAAC;IAC/CC,MAAMf,EAAEgB,OAAO,CAAC;AAClB;AAEA,2CAA2C;AAC3C,MAAMC,eAAejB,EAAEkB,kBAAkB,CAAC,QAAQ;IAACL;IAAqBjB;CAAyB;AAEjG,MAAMuB,SAAS;IACbC,aAAa;IACbX,aAAaA;IACbQ,cAAcjB,EAAEE,MAAM,CAAC;QACrBmB,QAAQJ;IACV;AACF;AAKA,eAAeK,QAAQ,EAAEhB,EAAE,EAAS,EAAEiB,KAAoB;IACxD,MAAMC,SAASD,MAAMC,MAAM;IAC3BA,OAAOC,IAAI,CAAC,oCAAoC;QAAEnB;IAAG;IAErD,IAAI,CAACA,IAAI;QACPkB,OAAOC,IAAI,CAAC;QACZ,MAAM,IAAI1B,SAASD,UAAU4B,aAAa,EAAE;IAC9C;IAEA,IAAI;QACF,MAAMC,QAAQ9B,OAAO+B,kBAAkB,CAAC;YAAEC,cAAcN,MAAMO,WAAW,CAACC,IAAI;QAAC;QAC/E,MAAMJ,MAAMK,GAAG,CAAC,CAAC,aAAa,EAAEC,mBAAmB3B,KAAK,EAAE4B,MAAM,CAAC;YAAEC,QAAQ;QAAK;QAEhFX,OAAOC,IAAI,CAAC,qCAAqC;YAAEnB;QAAG;QAEtD,MAAMe,SAAiB;YACrBN,MAAM;YACNZ,SAAS;YACTG;QACF;QAEA,OAAO;YACL8B,SAAS;gBACP;oBACErB,MAAM;oBACNsB,MAAMC,KAAKC,SAAS,CAAClB;gBACvB;aACD;YACDmB,mBAAmB;gBAAEnB;YAAO;QAC9B;IACF,EAAE,OAAOoB,OAAO;QACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,OAAO,GAAGE,OAAOH;QAChEjB,OAAOiB,KAAK,CAAC,mCAAmC;YAAEA,OAAOC;QAAQ;QAEjE,MAAM,IAAI3C,SAASD,UAAU+C,aAAa,EAAE,CAAC,+BAA+B,EAAEH,SAAS,EAAE;YACvFI,OAAOL,iBAAiBE,QAAQF,MAAMK,KAAK,GAAGC;QAChD;IACF;AACF;AAEA,eAAe,SAASC;IACtB,OAAO;QACLC,MAAM;QACN9B;QACAG;IACF;AACF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { EnrichedExtra } from '@mcp-z/oauth-microsoft';
|
|
2
|
+
import { type CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
declare const inputSchema: z.ZodObject<{
|
|
5
|
+
ids: z.ZodArray<z.ZodCoercedString<unknown>>;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
declare const outputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
8
|
+
totalRequested: z.ZodNumber;
|
|
9
|
+
successCount: z.ZodNumber;
|
|
10
|
+
failureCount: z.ZodNumber;
|
|
11
|
+
results: z.ZodArray<z.ZodObject<{
|
|
12
|
+
id: z.ZodString;
|
|
13
|
+
success: z.ZodBoolean;
|
|
14
|
+
error: z.ZodOptional<z.ZodString>;
|
|
15
|
+
}, z.core.$strip>>;
|
|
16
|
+
type: z.ZodLiteral<"success">;
|
|
17
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
18
|
+
type: z.ZodLiteral<"auth_required">;
|
|
19
|
+
provider: z.ZodString;
|
|
20
|
+
message: z.ZodString;
|
|
21
|
+
url: z.ZodOptional<z.ZodString>;
|
|
22
|
+
}, z.core.$strip>], "type">;
|
|
23
|
+
export type Input = z.infer<typeof inputSchema>;
|
|
24
|
+
export type Output = z.infer<typeof outputSchema>;
|
|
25
|
+
declare function handler({ ids }: Input, extra: EnrichedExtra): Promise<CallToolResult>;
|
|
26
|
+
export default function createTool(): {
|
|
27
|
+
name: string;
|
|
28
|
+
config: {
|
|
29
|
+
readonly description: "Move Outlook messages to trash (recoverable).";
|
|
30
|
+
readonly inputSchema: z.ZodObject<{
|
|
31
|
+
ids: z.ZodArray<z.ZodCoercedString<unknown>>;
|
|
32
|
+
}, z.core.$strip>;
|
|
33
|
+
readonly outputSchema: z.ZodObject<{
|
|
34
|
+
result: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
35
|
+
totalRequested: z.ZodNumber;
|
|
36
|
+
successCount: z.ZodNumber;
|
|
37
|
+
failureCount: z.ZodNumber;
|
|
38
|
+
results: z.ZodArray<z.ZodObject<{
|
|
39
|
+
id: z.ZodString;
|
|
40
|
+
success: z.ZodBoolean;
|
|
41
|
+
error: z.ZodOptional<z.ZodString>;
|
|
42
|
+
}, z.core.$strip>>;
|
|
43
|
+
type: z.ZodLiteral<"success">;
|
|
44
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
45
|
+
type: z.ZodLiteral<"auth_required">;
|
|
46
|
+
provider: z.ZodString;
|
|
47
|
+
message: z.ZodString;
|
|
48
|
+
url: z.ZodOptional<z.ZodString>;
|
|
49
|
+
}, z.core.$strip>], "type">;
|
|
50
|
+
}, z.core.$strip>;
|
|
51
|
+
};
|
|
52
|
+
handler: typeof handler;
|
|
53
|
+
};
|
|
54
|
+
export {};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { schemas } from '@mcp-z/oauth-microsoft';
|
|
2
|
+
const { AuthRequiredBranchSchema } = schemas;
|
|
3
|
+
import { Client } from '@microsoft/microsoft-graph-client';
|
|
4
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { CHUNK_SIZE, MAX_BATCH_SIZE } from '../../constants.js';
|
|
7
|
+
const BatchResultSchema = z.object({
|
|
8
|
+
totalRequested: z.number().describe('Total number of messages requested to trash'),
|
|
9
|
+
successCount: z.number().describe('Number of messages successfully moved to trash'),
|
|
10
|
+
failureCount: z.number().describe('Number of messages that failed to move'),
|
|
11
|
+
results: z.array(z.object({
|
|
12
|
+
id: z.string().describe('Message ID'),
|
|
13
|
+
success: z.boolean().describe('Whether the operation succeeded'),
|
|
14
|
+
error: z.string().optional().describe('Error message if operation failed')
|
|
15
|
+
})).describe('Individual results for each message')
|
|
16
|
+
});
|
|
17
|
+
const inputSchema = z.object({
|
|
18
|
+
ids: z.array(z.coerce.string().trim().min(1)).min(1).describe('Outlook message IDs to move to trash')
|
|
19
|
+
});
|
|
20
|
+
// Success branch schema
|
|
21
|
+
const successBranchSchema = BatchResultSchema.extend({
|
|
22
|
+
type: z.literal('success')
|
|
23
|
+
});
|
|
24
|
+
// Output schema with auth_required support
|
|
25
|
+
const outputSchema = z.discriminatedUnion('type', [
|
|
26
|
+
successBranchSchema,
|
|
27
|
+
AuthRequiredBranchSchema
|
|
28
|
+
]);
|
|
29
|
+
const config = {
|
|
30
|
+
description: 'Move Outlook messages to trash (recoverable).',
|
|
31
|
+
inputSchema: inputSchema,
|
|
32
|
+
outputSchema: z.object({
|
|
33
|
+
result: outputSchema
|
|
34
|
+
})
|
|
35
|
+
};
|
|
36
|
+
async function handler({ ids }, extra) {
|
|
37
|
+
const logger = extra.logger;
|
|
38
|
+
logger.info('outlook-message-move-to-trash called', {
|
|
39
|
+
count: ids.length
|
|
40
|
+
});
|
|
41
|
+
if (!ids || ids.length === 0) {
|
|
42
|
+
logger.info('outlook-message-move-to-trash missing ids');
|
|
43
|
+
throw new McpError(ErrorCode.InvalidParams, 'Missing ids');
|
|
44
|
+
}
|
|
45
|
+
// Validate batch size to prevent memory exhaustion
|
|
46
|
+
if (ids.length > MAX_BATCH_SIZE) {
|
|
47
|
+
logger.info('outlook-message-move-to-trash batch size exceeded', {
|
|
48
|
+
requested: ids.length,
|
|
49
|
+
max: MAX_BATCH_SIZE
|
|
50
|
+
});
|
|
51
|
+
throw new McpError(ErrorCode.InvalidParams, `Batch size ${ids.length} exceeds maximum allowed size of ${MAX_BATCH_SIZE}`);
|
|
52
|
+
}
|
|
53
|
+
// Validate and sanitize IDs
|
|
54
|
+
const validatedIds = [];
|
|
55
|
+
const invalidIds = [];
|
|
56
|
+
for (const id of ids){
|
|
57
|
+
const trimmedId = id.trim();
|
|
58
|
+
if (!trimmedId) {
|
|
59
|
+
invalidIds.push(id);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
// Basic Outlook message ID validation - should not contain certain characters
|
|
63
|
+
if (trimmedId.includes('/') || trimmedId.includes('\\') || trimmedId.includes('<') || trimmedId.includes('>')) {
|
|
64
|
+
invalidIds.push(id);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
validatedIds.push(trimmedId);
|
|
68
|
+
}
|
|
69
|
+
if (invalidIds.length > 0) {
|
|
70
|
+
logger.info('outlook-message-move-to-trash found invalid ids', {
|
|
71
|
+
invalidIds,
|
|
72
|
+
count: invalidIds.length
|
|
73
|
+
});
|
|
74
|
+
throw new McpError(ErrorCode.InvalidParams, `Found ${invalidIds.length} invalid IDs: ${invalidIds.join(', ')}`);
|
|
75
|
+
}
|
|
76
|
+
if (validatedIds.length === 0) {
|
|
77
|
+
logger.info('outlook-message-move-to-trash no valid ids after validation');
|
|
78
|
+
throw new McpError(ErrorCode.InvalidParams, 'No valid IDs found after validation');
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const graph = Client.initWithMiddleware({
|
|
82
|
+
authProvider: extra.authContext.auth
|
|
83
|
+
});
|
|
84
|
+
// Process operations in chunks to prevent memory exhaustion
|
|
85
|
+
const allResults = [];
|
|
86
|
+
for(let i = 0; i < validatedIds.length; i += CHUNK_SIZE){
|
|
87
|
+
const chunk = validatedIds.slice(i, i + CHUNK_SIZE);
|
|
88
|
+
logger.info('Processing chunk', {
|
|
89
|
+
chunkIndex: i / CHUNK_SIZE + 1,
|
|
90
|
+
chunkSize: chunk.length,
|
|
91
|
+
totalChunks: Math.ceil(validatedIds.length / CHUNK_SIZE)
|
|
92
|
+
});
|
|
93
|
+
const chunkResults = await Promise.allSettled(chunk.map(async (id)=>{
|
|
94
|
+
await graph.api(`/me/messages/${encodeURIComponent(id)}`).delete();
|
|
95
|
+
return {
|
|
96
|
+
id,
|
|
97
|
+
success: true
|
|
98
|
+
};
|
|
99
|
+
}));
|
|
100
|
+
// Process chunk results
|
|
101
|
+
const processedChunkResults = chunkResults.map((result, chunkIndex)=>{
|
|
102
|
+
const id = chunk[chunkIndex];
|
|
103
|
+
if (!id) {
|
|
104
|
+
throw new Error(`Chunk index ${chunkIndex} is out of bounds for chunk of size ${chunk.length}`);
|
|
105
|
+
}
|
|
106
|
+
if (result.status === 'fulfilled') {
|
|
107
|
+
return {
|
|
108
|
+
id,
|
|
109
|
+
success: true
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// Extract error message more robustly
|
|
113
|
+
let errorMessage = 'Unknown error';
|
|
114
|
+
if (result.reason) {
|
|
115
|
+
if (typeof result.reason === 'string') {
|
|
116
|
+
errorMessage = result.reason;
|
|
117
|
+
} else if (result.reason instanceof Error) {
|
|
118
|
+
errorMessage = result.reason.message;
|
|
119
|
+
} else if (result.reason && typeof result.reason === 'object' && 'message' in result.reason) {
|
|
120
|
+
errorMessage = String(result.reason.message);
|
|
121
|
+
} else if (result.reason && typeof result.reason === 'object' && 'error' in result.reason) {
|
|
122
|
+
errorMessage = String(result.reason.error);
|
|
123
|
+
} else {
|
|
124
|
+
errorMessage = String(result.reason);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
id,
|
|
129
|
+
success: false,
|
|
130
|
+
error: errorMessage
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
allResults.push(...processedChunkResults);
|
|
134
|
+
}
|
|
135
|
+
const successCount = allResults.filter((r)=>r.success).length;
|
|
136
|
+
const failureCount = allResults.filter((r)=>!r.success).length;
|
|
137
|
+
const result = {
|
|
138
|
+
type: 'success',
|
|
139
|
+
totalRequested: validatedIds.length,
|
|
140
|
+
successCount,
|
|
141
|
+
failureCount,
|
|
142
|
+
results: allResults
|
|
143
|
+
};
|
|
144
|
+
logger.info('outlook-message-move-to-trash completed', {
|
|
145
|
+
totalRequested: validatedIds.length,
|
|
146
|
+
successCount,
|
|
147
|
+
failureCount,
|
|
148
|
+
chunksProcessed: Math.ceil(validatedIds.length / CHUNK_SIZE)
|
|
149
|
+
});
|
|
150
|
+
return {
|
|
151
|
+
content: [
|
|
152
|
+
{
|
|
153
|
+
type: 'text',
|
|
154
|
+
text: JSON.stringify(result)
|
|
155
|
+
}
|
|
156
|
+
],
|
|
157
|
+
structuredContent: {
|
|
158
|
+
result
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
} catch (error) {
|
|
162
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
163
|
+
logger.error('outlook-message-move-to-trash error', {
|
|
164
|
+
error: message
|
|
165
|
+
});
|
|
166
|
+
throw new McpError(ErrorCode.InternalError, `Error moving messages to trash: ${message}`, {
|
|
167
|
+
stack: error instanceof Error ? error.stack : undefined
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
export default function createTool() {
|
|
172
|
+
return {
|
|
173
|
+
name: 'message-move-to-trash',
|
|
174
|
+
config,
|
|
175
|
+
handler
|
|
176
|
+
};
|
|
177
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-outlook/src/mcp/tools/message-move-to-trash.ts"],"sourcesContent":["import type { EnrichedExtra } from '@mcp-z/oauth-microsoft';\nimport { schemas } from '@mcp-z/oauth-microsoft';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport type { ToolModule } from '@mcp-z/server';\nimport { Client } from '@microsoft/microsoft-graph-client';\nimport { type CallToolResult, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\nimport { CHUNK_SIZE, MAX_BATCH_SIZE } from '../../constants.ts';\n\nconst BatchResultSchema = z.object({\n totalRequested: z.number().describe('Total number of messages requested to trash'),\n successCount: z.number().describe('Number of messages successfully moved to trash'),\n failureCount: z.number().describe('Number of messages that failed to move'),\n results: z\n .array(\n z.object({\n id: z.string().describe('Message ID'),\n success: z.boolean().describe('Whether the operation succeeded'),\n error: z.string().optional().describe('Error message if operation failed'),\n })\n )\n .describe('Individual results for each message'),\n});\n\nconst inputSchema = z.object({\n ids: z.array(z.coerce.string().trim().min(1)).min(1).describe('Outlook message IDs to move to trash'),\n});\n\n// Success branch schema\nconst successBranchSchema = BatchResultSchema.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: 'Move Outlook messages to trash (recoverable).',\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\nasync function handler({ ids }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n logger.info('outlook-message-move-to-trash called', { count: ids.length });\n\n if (!ids || ids.length === 0) {\n logger.info('outlook-message-move-to-trash missing ids');\n throw new McpError(ErrorCode.InvalidParams, 'Missing ids');\n }\n\n // Validate batch size to prevent memory exhaustion\n if (ids.length > MAX_BATCH_SIZE) {\n logger.info('outlook-message-move-to-trash batch size exceeded', { requested: ids.length, max: MAX_BATCH_SIZE });\n throw new McpError(ErrorCode.InvalidParams, `Batch size ${ids.length} exceeds maximum allowed size of ${MAX_BATCH_SIZE}`);\n }\n\n // Validate and sanitize IDs\n const validatedIds: string[] = [];\n const invalidIds: string[] = [];\n\n for (const id of ids) {\n const trimmedId = id.trim();\n if (!trimmedId) {\n invalidIds.push(id);\n continue;\n }\n // Basic Outlook message ID validation - should not contain certain characters\n if (trimmedId.includes('/') || trimmedId.includes('\\\\') || trimmedId.includes('<') || trimmedId.includes('>')) {\n invalidIds.push(id);\n continue;\n }\n validatedIds.push(trimmedId);\n }\n\n if (invalidIds.length > 0) {\n logger.info('outlook-message-move-to-trash found invalid ids', { invalidIds, count: invalidIds.length });\n throw new McpError(ErrorCode.InvalidParams, `Found ${invalidIds.length} invalid IDs: ${invalidIds.join(', ')}`);\n }\n\n if (validatedIds.length === 0) {\n logger.info('outlook-message-move-to-trash no valid ids after validation');\n throw new McpError(ErrorCode.InvalidParams, 'No valid IDs found after validation');\n }\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n // Process operations in chunks to prevent memory exhaustion\n const allResults: Array<{ id: string; success: boolean; error?: string }> = [];\n\n for (let i = 0; i < validatedIds.length; i += CHUNK_SIZE) {\n const chunk = validatedIds.slice(i, i + CHUNK_SIZE);\n logger.info('Processing chunk', { chunkIndex: i / CHUNK_SIZE + 1, chunkSize: chunk.length, totalChunks: Math.ceil(validatedIds.length / CHUNK_SIZE) });\n\n const chunkResults = await Promise.allSettled(\n chunk.map(async (id) => {\n await graph.api(`/me/messages/${encodeURIComponent(id)}`).delete();\n return { id, success: true };\n })\n );\n\n // Process chunk results\n const processedChunkResults = chunkResults.map((result, chunkIndex) => {\n const id = chunk[chunkIndex];\n if (!id) {\n throw new Error(`Chunk index ${chunkIndex} is out of bounds for chunk of size ${chunk.length}`);\n }\n if (result.status === 'fulfilled') {\n return { id, success: true };\n }\n\n // Extract error message more robustly\n let errorMessage = 'Unknown error';\n if (result.reason) {\n if (typeof result.reason === 'string') {\n errorMessage = result.reason;\n } else if (result.reason instanceof Error) {\n errorMessage = result.reason.message;\n } else if (result.reason && typeof result.reason === 'object' && 'message' in result.reason) {\n errorMessage = String(result.reason.message);\n } else if (result.reason && typeof result.reason === 'object' && 'error' in result.reason) {\n errorMessage = String(result.reason.error);\n } else {\n errorMessage = String(result.reason);\n }\n }\n\n return { id, success: false, error: errorMessage };\n });\n\n allResults.push(...processedChunkResults);\n }\n\n const successCount = allResults.filter((r) => r.success).length;\n const failureCount = allResults.filter((r) => !r.success).length;\n\n const result: Output = {\n type: 'success' as const,\n totalRequested: validatedIds.length,\n successCount,\n failureCount,\n results: allResults,\n };\n\n logger.info('outlook-message-move-to-trash completed', {\n totalRequested: validatedIds.length,\n successCount,\n failureCount,\n chunksProcessed: Math.ceil(validatedIds.length / CHUNK_SIZE),\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 const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook-message-move-to-trash error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error moving messages to trash: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-move-to-trash',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["schemas","AuthRequiredBranchSchema","Client","ErrorCode","McpError","z","CHUNK_SIZE","MAX_BATCH_SIZE","BatchResultSchema","object","totalRequested","number","describe","successCount","failureCount","results","array","id","string","success","boolean","error","optional","inputSchema","ids","coerce","trim","min","successBranchSchema","extend","type","literal","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","info","count","length","InvalidParams","requested","max","validatedIds","invalidIds","trimmedId","push","includes","join","graph","initWithMiddleware","authProvider","authContext","auth","allResults","i","chunk","slice","chunkIndex","chunkSize","totalChunks","Math","ceil","chunkResults","Promise","allSettled","map","api","encodeURIComponent","delete","processedChunkResults","Error","status","errorMessage","reason","message","String","filter","r","chunksProcessed","content","text","JSON","stringify","structuredContent","InternalError","stack","undefined","createTool","name"],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { EnrichedExtra } from '@mcp-z/oauth-microsoft';
|
|
2
|
+
import { type CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
declare const inputSchema: z.ZodObject<{
|
|
5
|
+
id: z.ZodCoercedString<unknown>;
|
|
6
|
+
body: z.ZodCoercedString<unknown>;
|
|
7
|
+
contentType: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
8
|
+
text: "text";
|
|
9
|
+
html: "html";
|
|
10
|
+
}>>>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
declare const outputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
13
|
+
success: z.ZodBoolean;
|
|
14
|
+
id: z.ZodOptional<z.ZodString>;
|
|
15
|
+
type: z.ZodLiteral<"success">;
|
|
16
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
17
|
+
type: z.ZodLiteral<"auth_required">;
|
|
18
|
+
provider: z.ZodString;
|
|
19
|
+
message: z.ZodString;
|
|
20
|
+
url: z.ZodOptional<z.ZodString>;
|
|
21
|
+
}, z.core.$strip>], "type">;
|
|
22
|
+
export type Input = z.infer<typeof inputSchema>;
|
|
23
|
+
export type Output = z.infer<typeof outputSchema>;
|
|
24
|
+
declare function handler({ id, body, contentType }: Input, extra: EnrichedExtra): Promise<CallToolResult>;
|
|
25
|
+
export default function createTool(): {
|
|
26
|
+
name: string;
|
|
27
|
+
config: {
|
|
28
|
+
readonly description: "Reply to an Outlook message";
|
|
29
|
+
readonly inputSchema: z.ZodObject<{
|
|
30
|
+
id: z.ZodCoercedString<unknown>;
|
|
31
|
+
body: z.ZodCoercedString<unknown>;
|
|
32
|
+
contentType: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
33
|
+
text: "text";
|
|
34
|
+
html: "html";
|
|
35
|
+
}>>>;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
readonly outputSchema: z.ZodObject<{
|
|
38
|
+
result: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
39
|
+
success: z.ZodBoolean;
|
|
40
|
+
id: z.ZodOptional<z.ZodString>;
|
|
41
|
+
type: z.ZodLiteral<"success">;
|
|
42
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
43
|
+
type: z.ZodLiteral<"auth_required">;
|
|
44
|
+
provider: z.ZodString;
|
|
45
|
+
message: z.ZodString;
|
|
46
|
+
url: z.ZodOptional<z.ZodString>;
|
|
47
|
+
}, z.core.$strip>], "type">;
|
|
48
|
+
}, z.core.$strip>;
|
|
49
|
+
};
|
|
50
|
+
handler: typeof handler;
|
|
51
|
+
};
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { ComposeContentTypeSchema } from '@mcp-z/email';
|
|
2
|
+
import { schemas } from '@mcp-z/oauth-microsoft';
|
|
3
|
+
const { AuthRequiredBranchSchema } = schemas;
|
|
4
|
+
import { Client } from '@microsoft/microsoft-graph-client';
|
|
5
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
const SuccessSchema = z.object({
|
|
8
|
+
success: z.boolean().describe('Whether the reply was sent successfully'),
|
|
9
|
+
id: z.string().optional().describe('Original message ID that was replied to')
|
|
10
|
+
});
|
|
11
|
+
const inputSchema = z.object({
|
|
12
|
+
id: z.coerce.string().trim().min(1).describe('Outlook message ID to reply to'),
|
|
13
|
+
body: z.coerce.string().trim().min(1).describe('Reply body content (plain text or HTML)'),
|
|
14
|
+
contentType: ComposeContentTypeSchema
|
|
15
|
+
});
|
|
16
|
+
// Success branch schema
|
|
17
|
+
const successBranchSchema = SuccessSchema.extend({
|
|
18
|
+
type: z.literal('success')
|
|
19
|
+
});
|
|
20
|
+
// Output schema with auth_required support
|
|
21
|
+
const outputSchema = z.discriminatedUnion('type', [
|
|
22
|
+
successBranchSchema,
|
|
23
|
+
AuthRequiredBranchSchema
|
|
24
|
+
]);
|
|
25
|
+
const config = {
|
|
26
|
+
description: 'Reply to an Outlook message',
|
|
27
|
+
inputSchema: inputSchema,
|
|
28
|
+
outputSchema: z.object({
|
|
29
|
+
result: outputSchema
|
|
30
|
+
})
|
|
31
|
+
};
|
|
32
|
+
async function handler({ id, body, contentType }, extra) {
|
|
33
|
+
const logger = extra.logger;
|
|
34
|
+
logger.info('outlook.respond called', {
|
|
35
|
+
id,
|
|
36
|
+
hasBody: !!body
|
|
37
|
+
});
|
|
38
|
+
if (!id || !body) {
|
|
39
|
+
logger.info('outlook.respond missing id or body');
|
|
40
|
+
throw new McpError(ErrorCode.InvalidParams, 'Missing id or body');
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const graph = Client.initWithMiddleware({
|
|
44
|
+
authProvider: extra.authContext.auth
|
|
45
|
+
});
|
|
46
|
+
await graph.api(`/me/messages/${encodeURIComponent(id)}/reply`).post({
|
|
47
|
+
message: {
|
|
48
|
+
body: {
|
|
49
|
+
contentType: contentType === 'html' ? 'HTML' : 'Text',
|
|
50
|
+
content: body
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
logger.info('outlook.respond success', {
|
|
55
|
+
id
|
|
56
|
+
});
|
|
57
|
+
const result = {
|
|
58
|
+
type: 'success',
|
|
59
|
+
success: true,
|
|
60
|
+
id
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
content: [
|
|
64
|
+
{
|
|
65
|
+
type: 'text',
|
|
66
|
+
text: JSON.stringify(result)
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
structuredContent: {
|
|
70
|
+
result
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
} catch (error) {
|
|
74
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
75
|
+
logger.error('outlook.respond error', {
|
|
76
|
+
error: message
|
|
77
|
+
});
|
|
78
|
+
throw new McpError(ErrorCode.InternalError, `Error replying to message: ${message}`, {
|
|
79
|
+
stack: error instanceof Error ? error.stack : undefined
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
export default function createTool() {
|
|
84
|
+
return {
|
|
85
|
+
name: 'message-respond',
|
|
86
|
+
config,
|
|
87
|
+
handler
|
|
88
|
+
};
|
|
89
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-outlook/src/mcp/tools/message-respond.ts"],"sourcesContent":["import { ComposeContentTypeSchema } 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 type { ToolModule } from '@mcp-z/server';\nimport { Client } from '@microsoft/microsoft-graph-client';\nimport { type CallToolResult, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\n\nconst SuccessSchema = z.object({\n success: z.boolean().describe('Whether the reply was sent successfully'),\n id: z.string().optional().describe('Original message ID that was replied to'),\n});\n\nconst inputSchema = z.object({\n id: z.coerce.string().trim().min(1).describe('Outlook message ID to reply to'),\n body: z.coerce.string().trim().min(1).describe('Reply body content (plain text or HTML)'),\n contentType: ComposeContentTypeSchema,\n});\n\n// Success branch schema\nconst successBranchSchema = SuccessSchema.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: 'Reply to an Outlook message',\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\nasync function handler({ id, body, contentType }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n logger.info('outlook.respond called', { id, hasBody: !!body });\n\n if (!id || !body) {\n logger.info('outlook.respond missing id or body');\n throw new McpError(ErrorCode.InvalidParams, 'Missing id or body');\n }\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n await graph.api(`/me/messages/${encodeURIComponent(id)}/reply`).post({ message: { body: { contentType: contentType === 'html' ? 'HTML' : 'Text', content: body } } });\n\n logger.info('outlook.respond success', { id });\n\n const result: Output = {\n type: 'success' as const,\n success: true,\n id,\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 const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook.respond error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error replying to message: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-respond',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["ComposeContentTypeSchema","schemas","AuthRequiredBranchSchema","Client","ErrorCode","McpError","z","SuccessSchema","object","success","boolean","describe","id","string","optional","inputSchema","coerce","trim","min","body","contentType","successBranchSchema","extend","type","literal","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","info","hasBody","InvalidParams","graph","initWithMiddleware","authProvider","authContext","auth","api","encodeURIComponent","post","message","content","text","JSON","stringify","structuredContent","error","Error","String","InternalError","stack","undefined","createTool","name"],"mappings":"AAAA,SAASA,wBAAwB,QAAQ,eAAe;AAExD,SAASC,OAAO,QAAQ,yBAAyB;AAEjD,MAAM,EAAEC,wBAAwB,EAAE,GAAGD;AAGrC,SAASE,MAAM,QAAQ,oCAAoC;AAC3D,SAA8BC,SAAS,EAAEC,QAAQ,QAAQ,qCAAqC;AAC9F,SAASC,CAAC,QAAQ,MAAM;AAExB,MAAMC,gBAAgBD,EAAEE,MAAM,CAAC;IAC7BC,SAASH,EAAEI,OAAO,GAAGC,QAAQ,CAAC;IAC9BC,IAAIN,EAAEO,MAAM,GAAGC,QAAQ,GAAGH,QAAQ,CAAC;AACrC;AAEA,MAAMI,cAAcT,EAAEE,MAAM,CAAC;IAC3BI,IAAIN,EAAEU,MAAM,CAACH,MAAM,GAAGI,IAAI,GAAGC,GAAG,CAAC,GAAGP,QAAQ,CAAC;IAC7CQ,MAAMb,EAAEU,MAAM,CAACH,MAAM,GAAGI,IAAI,GAAGC,GAAG,CAAC,GAAGP,QAAQ,CAAC;IAC/CS,aAAapB;AACf;AAEA,wBAAwB;AACxB,MAAMqB,sBAAsBd,cAAce,MAAM,CAAC;IAC/CC,MAAMjB,EAAEkB,OAAO,CAAC;AAClB;AAEA,2CAA2C;AAC3C,MAAMC,eAAenB,EAAEoB,kBAAkB,CAAC,QAAQ;IAACL;IAAqBnB;CAAyB;AAEjG,MAAMyB,SAAS;IACbC,aAAa;IACbb,aAAaA;IACbU,cAAcnB,EAAEE,MAAM,CAAC;QACrBqB,QAAQJ;IACV;AACF;AAKA,eAAeK,QAAQ,EAAElB,EAAE,EAAEO,IAAI,EAAEC,WAAW,EAAS,EAAEW,KAAoB;IAC3E,MAAMC,SAASD,MAAMC,MAAM;IAC3BA,OAAOC,IAAI,CAAC,0BAA0B;QAAErB;QAAIsB,SAAS,CAAC,CAACf;IAAK;IAE5D,IAAI,CAACP,MAAM,CAACO,MAAM;QAChBa,OAAOC,IAAI,CAAC;QACZ,MAAM,IAAI5B,SAASD,UAAU+B,aAAa,EAAE;IAC9C;IAEA,IAAI;QACF,MAAMC,QAAQjC,OAAOkC,kBAAkB,CAAC;YAAEC,cAAcP,MAAMQ,WAAW,CAACC,IAAI;QAAC;QAC/E,MAAMJ,MAAMK,GAAG,CAAC,CAAC,aAAa,EAAEC,mBAAmB9B,IAAI,MAAM,CAAC,EAAE+B,IAAI,CAAC;YAAEC,SAAS;gBAAEzB,MAAM;oBAAEC,aAAaA,gBAAgB,SAAS,SAAS;oBAAQyB,SAAS1B;gBAAK;YAAE;QAAE;QAEnKa,OAAOC,IAAI,CAAC,2BAA2B;YAAErB;QAAG;QAE5C,MAAMiB,SAAiB;YACrBN,MAAM;YACNd,SAAS;YACTG;QACF;QAEA,OAAO;YACLiC,SAAS;gBACP;oBACEtB,MAAM;oBACNuB,MAAMC,KAAKC,SAAS,CAACnB;gBACvB;aACD;YACDoB,mBAAmB;gBAAEpB;YAAO;QAC9B;IACF,EAAE,OAAOqB,OAAO;QACd,MAAMN,UAAUM,iBAAiBC,QAAQD,MAAMN,OAAO,GAAGQ,OAAOF;QAChElB,OAAOkB,KAAK,CAAC,yBAAyB;YAAEA,OAAON;QAAQ;QAEvD,MAAM,IAAIvC,SAASD,UAAUiD,aAAa,EAAE,CAAC,2BAA2B,EAAET,SAAS,EAAE;YACnFU,OAAOJ,iBAAiBC,QAAQD,MAAMI,KAAK,GAAGC;QAChD;IACF;AACF;AAEA,eAAe,SAASC;IACtB,OAAO;QACLC,MAAM;QACN9B;QACAG;IACF;AACF"}
|