@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,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: "Delete Outlook categories permanently (irreversible). Categories organize messages by color and name.";
|
|
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,166 @@
|
|
|
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 categories requested to delete'),
|
|
9
|
+
successCount: z.number().describe('Number of categories successfully deleted'),
|
|
10
|
+
failureCount: z.number().describe('Number of categories that failed to delete'),
|
|
11
|
+
results: z.array(z.object({
|
|
12
|
+
id: z.string().describe('Category 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 category')
|
|
16
|
+
});
|
|
17
|
+
const inputSchema = z.object({
|
|
18
|
+
ids: z.array(z.coerce.string().trim().min(1)).min(1).max(MAX_BATCH_SIZE).describe('Outlook category IDs to delete')
|
|
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: 'Delete Outlook categories permanently (irreversible). Categories organize messages by color and name.',
|
|
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-label-delete called', {
|
|
39
|
+
count: ids.length
|
|
40
|
+
});
|
|
41
|
+
// Validate IDs for Outlook-specific constraints
|
|
42
|
+
// Note: Schema already validates non-empty, trimmed strings with min/max length
|
|
43
|
+
// This check enforces business rule: Outlook category IDs cannot contain path separators or angle brackets
|
|
44
|
+
const invalidIds = [];
|
|
45
|
+
for (const id of ids){
|
|
46
|
+
if (id.includes('/') || id.includes('\\') || id.includes('<') || id.includes('>')) {
|
|
47
|
+
invalidIds.push(id);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (invalidIds.length > 0) {
|
|
51
|
+
logger.info('outlook-label-delete found invalid ids', {
|
|
52
|
+
invalidIds,
|
|
53
|
+
count: invalidIds.length
|
|
54
|
+
});
|
|
55
|
+
throw new McpError(ErrorCode.InvalidParams, `Found ${invalidIds.length} invalid IDs (contain invalid characters): ${invalidIds.join(', ')}`);
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const graph = Client.initWithMiddleware({
|
|
59
|
+
authProvider: extra.authContext.auth
|
|
60
|
+
});
|
|
61
|
+
// Process deletions in chunks to prevent memory exhaustion
|
|
62
|
+
const allResults = [];
|
|
63
|
+
for(let i = 0; i < ids.length; i += CHUNK_SIZE){
|
|
64
|
+
const chunk = ids.slice(i, i + CHUNK_SIZE);
|
|
65
|
+
logger.info('Processing chunk', {
|
|
66
|
+
chunkIndex: i / CHUNK_SIZE + 1,
|
|
67
|
+
chunkSize: chunk.length,
|
|
68
|
+
totalChunks: Math.ceil(ids.length / CHUNK_SIZE)
|
|
69
|
+
});
|
|
70
|
+
// Delete categories sequentially to avoid API lock conflicts
|
|
71
|
+
const chunkResults = [];
|
|
72
|
+
for (const id of chunk){
|
|
73
|
+
try {
|
|
74
|
+
await graph.api(`/me/outlook/masterCategories/${encodeURIComponent(id)}`).delete();
|
|
75
|
+
chunkResults.push({
|
|
76
|
+
status: 'fulfilled',
|
|
77
|
+
value: {
|
|
78
|
+
id,
|
|
79
|
+
success: true
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
} catch (error) {
|
|
83
|
+
chunkResults.push({
|
|
84
|
+
status: 'rejected',
|
|
85
|
+
reason: error
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Process chunk results
|
|
90
|
+
const processedChunkResults = chunkResults.map((result, chunkIndex)=>{
|
|
91
|
+
const id = chunk[chunkIndex];
|
|
92
|
+
if (!id) {
|
|
93
|
+
throw new Error(`Chunk index ${chunkIndex} is out of bounds for chunk of size ${chunk.length}`);
|
|
94
|
+
}
|
|
95
|
+
if (result.status === 'fulfilled') {
|
|
96
|
+
return {
|
|
97
|
+
id,
|
|
98
|
+
success: true
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// Extract error message more robustly
|
|
102
|
+
let errorMessage = 'Unknown error';
|
|
103
|
+
if (result.reason) {
|
|
104
|
+
if (typeof result.reason === 'string') {
|
|
105
|
+
errorMessage = result.reason;
|
|
106
|
+
} else if (result.reason instanceof Error) {
|
|
107
|
+
errorMessage = result.reason.message;
|
|
108
|
+
} else if (result.reason && typeof result.reason === 'object' && 'message' in result.reason) {
|
|
109
|
+
errorMessage = String(result.reason.message);
|
|
110
|
+
} else if (result.reason && typeof result.reason === 'object' && 'error' in result.reason) {
|
|
111
|
+
errorMessage = String(result.reason.error);
|
|
112
|
+
} else {
|
|
113
|
+
errorMessage = String(result.reason);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
id,
|
|
118
|
+
success: false,
|
|
119
|
+
error: errorMessage
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
allResults.push(...processedChunkResults);
|
|
123
|
+
}
|
|
124
|
+
const successCount = allResults.filter((r)=>r.success).length;
|
|
125
|
+
const failureCount = allResults.filter((r)=>!r.success).length;
|
|
126
|
+
const result = {
|
|
127
|
+
type: 'success',
|
|
128
|
+
totalRequested: ids.length,
|
|
129
|
+
successCount,
|
|
130
|
+
failureCount,
|
|
131
|
+
results: allResults
|
|
132
|
+
};
|
|
133
|
+
logger.info('outlook-label-delete completed', {
|
|
134
|
+
totalRequested: ids.length,
|
|
135
|
+
successCount,
|
|
136
|
+
failureCount,
|
|
137
|
+
chunksProcessed: Math.ceil(ids.length / CHUNK_SIZE)
|
|
138
|
+
});
|
|
139
|
+
return {
|
|
140
|
+
content: [
|
|
141
|
+
{
|
|
142
|
+
type: 'text',
|
|
143
|
+
text: JSON.stringify(result)
|
|
144
|
+
}
|
|
145
|
+
],
|
|
146
|
+
structuredContent: {
|
|
147
|
+
result
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
} catch (error) {
|
|
151
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
152
|
+
logger.error('outlook-label-delete error', {
|
|
153
|
+
error: message
|
|
154
|
+
});
|
|
155
|
+
throw new McpError(ErrorCode.InternalError, `Error deleting categories: ${message}`, {
|
|
156
|
+
stack: error instanceof Error ? error.stack : undefined
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
export default function createTool() {
|
|
161
|
+
return {
|
|
162
|
+
name: 'label-delete',
|
|
163
|
+
config,
|
|
164
|
+
handler
|
|
165
|
+
};
|
|
166
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-outlook/src/mcp/tools/label-delete.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 categories requested to delete'),\n successCount: z.number().describe('Number of categories successfully deleted'),\n failureCount: z.number().describe('Number of categories that failed to delete'),\n results: z\n .array(\n z.object({\n id: z.string().describe('Category 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 category'),\n});\n\nconst inputSchema = z.object({\n ids: z.array(z.coerce.string().trim().min(1)).min(1).max(MAX_BATCH_SIZE).describe('Outlook category IDs to delete'),\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: 'Delete Outlook categories permanently (irreversible). Categories organize messages by color and name.',\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-label-delete called', { count: ids.length });\n\n // Validate IDs for Outlook-specific constraints\n // Note: Schema already validates non-empty, trimmed strings with min/max length\n // This check enforces business rule: Outlook category IDs cannot contain path separators or angle brackets\n const invalidIds: string[] = [];\n for (const id of ids) {\n if (id.includes('/') || id.includes('\\\\') || id.includes('<') || id.includes('>')) {\n invalidIds.push(id);\n }\n }\n\n if (invalidIds.length > 0) {\n logger.info('outlook-label-delete found invalid ids', { invalidIds, count: invalidIds.length });\n throw new McpError(ErrorCode.InvalidParams, `Found ${invalidIds.length} invalid IDs (contain invalid characters): ${invalidIds.join(', ')}`);\n }\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n // Process deletions in chunks to prevent memory exhaustion\n const allResults: Array<{ id: string; success: boolean; error?: string }> = [];\n\n for (let i = 0; i < ids.length; i += CHUNK_SIZE) {\n const chunk = ids.slice(i, i + CHUNK_SIZE);\n logger.info('Processing chunk', { chunkIndex: i / CHUNK_SIZE + 1, chunkSize: chunk.length, totalChunks: Math.ceil(ids.length / CHUNK_SIZE) });\n\n // Delete categories sequentially to avoid API lock conflicts\n const chunkResults: Array<{ status: string; value?: unknown; reason?: unknown }> = [];\n for (const id of chunk) {\n try {\n await graph.api(`/me/outlook/masterCategories/${encodeURIComponent(id)}`).delete();\n chunkResults.push({ status: 'fulfilled', value: { id, success: true } });\n } catch (error) {\n chunkResults.push({ status: 'rejected', reason: error });\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: ids.length,\n successCount,\n failureCount,\n results: allResults,\n };\n\n logger.info('outlook-label-delete completed', {\n totalRequested: ids.length,\n successCount,\n failureCount,\n chunksProcessed: Math.ceil(ids.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-label-delete error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error deleting categories: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'label-delete',\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","max","successBranchSchema","extend","type","literal","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","info","count","length","invalidIds","includes","push","InvalidParams","join","graph","initWithMiddleware","authProvider","authContext","auth","allResults","i","chunk","slice","chunkIndex","chunkSize","totalChunks","Math","ceil","chunkResults","api","encodeURIComponent","delete","status","value","reason","processedChunkResults","map","Error","errorMessage","message","String","filter","r","chunksProcessed","content","text","JSON","stringify","structuredContent","InternalError","stack","undefined","createTool","name"],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
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<{}, z.core.$strip>;
|
|
5
|
+
declare const outputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
6
|
+
type: z.ZodLiteral<"success">;
|
|
7
|
+
items: z.ZodArray<z.ZodObject<{
|
|
8
|
+
id: z.ZodString;
|
|
9
|
+
displayName: z.ZodString;
|
|
10
|
+
color: z.ZodEnum<{
|
|
11
|
+
preset0: "preset0";
|
|
12
|
+
preset1: "preset1";
|
|
13
|
+
preset2: "preset2";
|
|
14
|
+
preset3: "preset3";
|
|
15
|
+
preset4: "preset4";
|
|
16
|
+
preset5: "preset5";
|
|
17
|
+
preset6: "preset6";
|
|
18
|
+
preset7: "preset7";
|
|
19
|
+
preset8: "preset8";
|
|
20
|
+
preset9: "preset9";
|
|
21
|
+
preset10: "preset10";
|
|
22
|
+
preset11: "preset11";
|
|
23
|
+
preset12: "preset12";
|
|
24
|
+
preset13: "preset13";
|
|
25
|
+
preset14: "preset14";
|
|
26
|
+
preset15: "preset15";
|
|
27
|
+
preset16: "preset16";
|
|
28
|
+
preset17: "preset17";
|
|
29
|
+
preset18: "preset18";
|
|
30
|
+
preset19: "preset19";
|
|
31
|
+
preset20: "preset20";
|
|
32
|
+
preset21: "preset21";
|
|
33
|
+
preset22: "preset22";
|
|
34
|
+
preset23: "preset23";
|
|
35
|
+
preset24: "preset24";
|
|
36
|
+
}>;
|
|
37
|
+
}, z.core.$strip>>;
|
|
38
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
39
|
+
type: z.ZodLiteral<"auth_required">;
|
|
40
|
+
provider: z.ZodString;
|
|
41
|
+
message: z.ZodString;
|
|
42
|
+
url: z.ZodOptional<z.ZodString>;
|
|
43
|
+
}, z.core.$strip>], "type">;
|
|
44
|
+
export type Input = z.infer<typeof inputSchema>;
|
|
45
|
+
export type Output = z.infer<typeof outputSchema>;
|
|
46
|
+
declare function handler(_: Input, extra: EnrichedExtra): Promise<CallToolResult>;
|
|
47
|
+
export default function createTool(): {
|
|
48
|
+
name: string;
|
|
49
|
+
config: {
|
|
50
|
+
readonly description: "List Outlook categories for label: query syntax. Case-sensitive.";
|
|
51
|
+
readonly inputSchema: z.ZodObject<{}, z.core.$strip>;
|
|
52
|
+
readonly outputSchema: z.ZodObject<{
|
|
53
|
+
result: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
54
|
+
type: z.ZodLiteral<"success">;
|
|
55
|
+
items: z.ZodArray<z.ZodObject<{
|
|
56
|
+
id: z.ZodString;
|
|
57
|
+
displayName: z.ZodString;
|
|
58
|
+
color: z.ZodEnum<{
|
|
59
|
+
preset0: "preset0";
|
|
60
|
+
preset1: "preset1";
|
|
61
|
+
preset2: "preset2";
|
|
62
|
+
preset3: "preset3";
|
|
63
|
+
preset4: "preset4";
|
|
64
|
+
preset5: "preset5";
|
|
65
|
+
preset6: "preset6";
|
|
66
|
+
preset7: "preset7";
|
|
67
|
+
preset8: "preset8";
|
|
68
|
+
preset9: "preset9";
|
|
69
|
+
preset10: "preset10";
|
|
70
|
+
preset11: "preset11";
|
|
71
|
+
preset12: "preset12";
|
|
72
|
+
preset13: "preset13";
|
|
73
|
+
preset14: "preset14";
|
|
74
|
+
preset15: "preset15";
|
|
75
|
+
preset16: "preset16";
|
|
76
|
+
preset17: "preset17";
|
|
77
|
+
preset18: "preset18";
|
|
78
|
+
preset19: "preset19";
|
|
79
|
+
preset20: "preset20";
|
|
80
|
+
preset21: "preset21";
|
|
81
|
+
preset22: "preset22";
|
|
82
|
+
preset23: "preset23";
|
|
83
|
+
preset24: "preset24";
|
|
84
|
+
}>;
|
|
85
|
+
}, z.core.$strip>>;
|
|
86
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
87
|
+
type: z.ZodLiteral<"auth_required">;
|
|
88
|
+
provider: z.ZodString;
|
|
89
|
+
message: z.ZodString;
|
|
90
|
+
url: z.ZodOptional<z.ZodString>;
|
|
91
|
+
}, z.core.$strip>], "type">;
|
|
92
|
+
}, z.core.$strip>;
|
|
93
|
+
};
|
|
94
|
+
handler: typeof handler;
|
|
95
|
+
};
|
|
96
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
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 { OutlookCategorySchema } from '../../schemas/index.js';
|
|
7
|
+
const inputSchema = z.object({});
|
|
8
|
+
// Success branch schema
|
|
9
|
+
const successBranchSchema = z.object({
|
|
10
|
+
type: z.literal('success'),
|
|
11
|
+
items: z.array(OutlookCategorySchema)
|
|
12
|
+
});
|
|
13
|
+
// Output schema with auth_required support
|
|
14
|
+
const outputSchema = z.discriminatedUnion('type', [
|
|
15
|
+
successBranchSchema,
|
|
16
|
+
AuthRequiredBranchSchema
|
|
17
|
+
]);
|
|
18
|
+
const config = {
|
|
19
|
+
description: 'List Outlook categories for label: query syntax. Case-sensitive.',
|
|
20
|
+
inputSchema: inputSchema,
|
|
21
|
+
outputSchema: z.object({
|
|
22
|
+
result: outputSchema
|
|
23
|
+
})
|
|
24
|
+
};
|
|
25
|
+
async function handler(_, extra) {
|
|
26
|
+
const logger = extra.logger;
|
|
27
|
+
logger.info('outlook.labels.list called');
|
|
28
|
+
try {
|
|
29
|
+
const graph = Client.initWithMiddleware({
|
|
30
|
+
authProvider: extra.authContext.auth
|
|
31
|
+
});
|
|
32
|
+
const started = Date.now();
|
|
33
|
+
// Call Microsoft Graph API to get master categories (same as categories tool)
|
|
34
|
+
const response = await graph.api('/me/outlook/masterCategories').get();
|
|
35
|
+
const categories = Array.isArray(response.value) ? response.value : [];
|
|
36
|
+
const durationMs = Date.now() - started;
|
|
37
|
+
logger.info('outlook.labels.list returning', {
|
|
38
|
+
labelsCount: categories.length
|
|
39
|
+
});
|
|
40
|
+
logger.info('outlook.labels.list metrics', {
|
|
41
|
+
durationMs
|
|
42
|
+
});
|
|
43
|
+
const result = {
|
|
44
|
+
type: 'success',
|
|
45
|
+
items: categories.map((category)=>({
|
|
46
|
+
id: category.id || undefined,
|
|
47
|
+
displayName: category.displayName || undefined,
|
|
48
|
+
color: category.color || undefined
|
|
49
|
+
}))
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
content: [
|
|
53
|
+
{
|
|
54
|
+
type: 'text',
|
|
55
|
+
text: JSON.stringify(result)
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
structuredContent: {
|
|
59
|
+
result
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
} catch (error) {
|
|
63
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
64
|
+
logger.error('outlook.labels.list error', {
|
|
65
|
+
error: message
|
|
66
|
+
});
|
|
67
|
+
throw new McpError(ErrorCode.InternalError, `Error listing labels: ${message}`, {
|
|
68
|
+
stack: error instanceof Error ? error.stack : undefined
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export default function createTool() {
|
|
73
|
+
return {
|
|
74
|
+
name: 'labels-list',
|
|
75
|
+
config,
|
|
76
|
+
handler
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-outlook/src/mcp/tools/labels-list.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 * as MicrosoftGraph from '@microsoft/microsoft-graph-types';\nimport { type CallToolResult, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\nimport { OutlookCategorySchema } from '../../schemas/index.js';\n\nconst inputSchema = z.object({});\n\n// Success branch schema\nconst successBranchSchema = z.object({\n type: z.literal('success'),\n items: z.array(OutlookCategorySchema),\n});\n\n// Output schema with auth_required support\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'List Outlook categories for label: query syntax. Case-sensitive.',\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(_: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n logger.info('outlook.labels.list called');\n\n try {\n const graph = Client.initWithMiddleware({ authProvider: extra.authContext.auth });\n const started = Date.now();\n\n // Call Microsoft Graph API to get master categories (same as categories tool)\n const response = await graph.api('/me/outlook/masterCategories').get();\n const categories = Array.isArray(response.value) ? response.value : [];\n\n const durationMs = Date.now() - started;\n logger.info('outlook.labels.list returning', { labelsCount: categories.length });\n logger.info('outlook.labels.list metrics', { durationMs });\n\n const result: Output = {\n type: 'success' as const,\n items: categories.map((category: MicrosoftGraph.OutlookCategory) => ({\n id: category.id || undefined,\n displayName: category.displayName || undefined,\n color: category.color || undefined,\n })),\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.labels.list error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error listing labels: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'labels-list',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["schemas","AuthRequiredBranchSchema","Client","ErrorCode","McpError","z","OutlookCategorySchema","inputSchema","object","successBranchSchema","type","literal","items","array","outputSchema","discriminatedUnion","config","description","result","handler","_","extra","logger","info","graph","initWithMiddleware","authProvider","authContext","auth","started","Date","now","response","api","get","categories","Array","isArray","value","durationMs","labelsCount","length","map","category","id","undefined","displayName","color","content","text","JSON","stringify","structuredContent","error","message","Error","String","InternalError","stack","createTool","name"],"mappings":"AACA,SAASA,OAAO,QAAQ,yBAAyB;AAEjD,MAAM,EAAEC,wBAAwB,EAAE,GAAGD;AAGrC,SAASE,MAAM,QAAQ,oCAAoC;AAE3D,SAA8BC,SAAS,EAAEC,QAAQ,QAAQ,qCAAqC;AAC9F,SAASC,CAAC,QAAQ,MAAM;AACxB,SAASC,qBAAqB,QAAQ,yBAAyB;AAE/D,MAAMC,cAAcF,EAAEG,MAAM,CAAC,CAAC;AAE9B,wBAAwB;AACxB,MAAMC,sBAAsBJ,EAAEG,MAAM,CAAC;IACnCE,MAAML,EAAEM,OAAO,CAAC;IAChBC,OAAOP,EAAEQ,KAAK,CAACP;AACjB;AAEA,2CAA2C;AAC3C,MAAMQ,eAAeT,EAAEU,kBAAkB,CAAC,QAAQ;IAACN;IAAqBR;CAAyB;AAEjG,MAAMe,SAAS;IACbC,aAAa;IACbV,aAAaA;IACbO,cAAcT,EAAEG,MAAM,CAAC;QACrBU,QAAQJ;IACV;AACF;AAKA,eAAeK,QAAQC,CAAQ,EAAEC,KAAoB;IACnD,MAAMC,SAASD,MAAMC,MAAM;IAC3BA,OAAOC,IAAI,CAAC;IAEZ,IAAI;QACF,MAAMC,QAAQtB,OAAOuB,kBAAkB,CAAC;YAAEC,cAAcL,MAAMM,WAAW,CAACC,IAAI;QAAC;QAC/E,MAAMC,UAAUC,KAAKC,GAAG;QAExB,8EAA8E;QAC9E,MAAMC,WAAW,MAAMR,MAAMS,GAAG,CAAC,gCAAgCC,GAAG;QACpE,MAAMC,aAAaC,MAAMC,OAAO,CAACL,SAASM,KAAK,IAAIN,SAASM,KAAK,GAAG,EAAE;QAEtE,MAAMC,aAAaT,KAAKC,GAAG,KAAKF;QAChCP,OAAOC,IAAI,CAAC,iCAAiC;YAAEiB,aAAaL,WAAWM,MAAM;QAAC;QAC9EnB,OAAOC,IAAI,CAAC,+BAA+B;YAAEgB;QAAW;QAExD,MAAMrB,SAAiB;YACrBR,MAAM;YACNE,OAAOuB,WAAWO,GAAG,CAAC,CAACC,WAA8C,CAAA;oBACnEC,IAAID,SAASC,EAAE,IAAIC;oBACnBC,aAAaH,SAASG,WAAW,IAAID;oBACrCE,OAAOJ,SAASI,KAAK,IAAIF;gBAC3B,CAAA;QACF;QAEA,OAAO;YACLG,SAAS;gBACP;oBACEtC,MAAM;oBACNuC,MAAMC,KAAKC,SAAS,CAACjC;gBACvB;aACD;YACDkC,mBAAmB;gBAAElC;YAAO;QAC9B;IACF,EAAE,OAAOmC,OAAO;QACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,OAAO,GAAGE,OAAOH;QAChE/B,OAAO+B,KAAK,CAAC,6BAA6B;YAAEA,OAAOC;QAAQ;QAE3D,MAAM,IAAIlD,SAASD,UAAUsD,aAAa,EAAE,CAAC,sBAAsB,EAAEH,SAAS,EAAE;YAC9EI,OAAOL,iBAAiBE,QAAQF,MAAMK,KAAK,GAAGb;QAChD;IACF;AACF;AAEA,eAAe,SAASc;IACtB,OAAO;QACLC,MAAM;QACN5C;QACAG;IACF;AACF"}
|
|
@@ -0,0 +1,110 @@
|
|
|
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
|
+
fields: z.ZodOptional<z.ZodString>;
|
|
7
|
+
contentType: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
8
|
+
text: "text";
|
|
9
|
+
html: "html";
|
|
10
|
+
}>>>;
|
|
11
|
+
excludeThreadHistory: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
declare const outputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
14
|
+
type: z.ZodLiteral<"success">;
|
|
15
|
+
item: z.ZodObject<{
|
|
16
|
+
id: z.ZodOptional<z.ZodString>;
|
|
17
|
+
threadId: z.ZodOptional<z.ZodString>;
|
|
18
|
+
subject: z.ZodOptional<z.ZodString>;
|
|
19
|
+
from: z.ZodOptional<z.ZodString>;
|
|
20
|
+
fromName: z.ZodOptional<z.ZodString>;
|
|
21
|
+
to: z.ZodOptional<z.ZodString>;
|
|
22
|
+
cc: z.ZodOptional<z.ZodString>;
|
|
23
|
+
bcc: z.ZodOptional<z.ZodString>;
|
|
24
|
+
date: z.ZodOptional<z.ZodString>;
|
|
25
|
+
receivedDateTime: z.ZodOptional<z.ZodString>;
|
|
26
|
+
snippet: z.ZodOptional<z.ZodString>;
|
|
27
|
+
isRead: z.ZodOptional<z.ZodBoolean>;
|
|
28
|
+
isImportant: z.ZodOptional<z.ZodBoolean>;
|
|
29
|
+
hasAttachments: z.ZodOptional<z.ZodBoolean>;
|
|
30
|
+
attachmentCount: z.ZodOptional<z.ZodNumber>;
|
|
31
|
+
labelIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
32
|
+
folderName: z.ZodOptional<z.ZodString>;
|
|
33
|
+
body: z.ZodOptional<z.ZodString>;
|
|
34
|
+
bodyContentType: z.ZodOptional<z.ZodEnum<{
|
|
35
|
+
text: "text";
|
|
36
|
+
html: "html";
|
|
37
|
+
}>>;
|
|
38
|
+
attachments: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
39
|
+
id: z.ZodString;
|
|
40
|
+
filename: z.ZodString;
|
|
41
|
+
mimeType: z.ZodString;
|
|
42
|
+
size: z.ZodOptional<z.ZodNumber>;
|
|
43
|
+
}, z.core.$strip>>>;
|
|
44
|
+
}, z.core.$strip>;
|
|
45
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
46
|
+
type: z.ZodLiteral<"auth_required">;
|
|
47
|
+
provider: z.ZodString;
|
|
48
|
+
message: z.ZodString;
|
|
49
|
+
url: z.ZodOptional<z.ZodString>;
|
|
50
|
+
}, z.core.$strip>], "type">;
|
|
51
|
+
export type Input = z.infer<typeof inputSchema>;
|
|
52
|
+
export type Output = z.infer<typeof outputSchema>;
|
|
53
|
+
declare function handler({ id, fields, contentType, excludeThreadHistory }: Input, extra: EnrichedExtra): Promise<CallToolResult>;
|
|
54
|
+
export default function createTool(): {
|
|
55
|
+
name: string;
|
|
56
|
+
config: {
|
|
57
|
+
readonly description: "Get an Outlook message by ID with flexible field selection";
|
|
58
|
+
readonly inputSchema: z.ZodObject<{
|
|
59
|
+
id: z.ZodCoercedString<unknown>;
|
|
60
|
+
fields: z.ZodOptional<z.ZodString>;
|
|
61
|
+
contentType: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
62
|
+
text: "text";
|
|
63
|
+
html: "html";
|
|
64
|
+
}>>>;
|
|
65
|
+
excludeThreadHistory: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
66
|
+
}, z.core.$strip>;
|
|
67
|
+
readonly outputSchema: z.ZodObject<{
|
|
68
|
+
result: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
69
|
+
type: z.ZodLiteral<"success">;
|
|
70
|
+
item: z.ZodObject<{
|
|
71
|
+
id: z.ZodOptional<z.ZodString>;
|
|
72
|
+
threadId: z.ZodOptional<z.ZodString>;
|
|
73
|
+
subject: z.ZodOptional<z.ZodString>;
|
|
74
|
+
from: z.ZodOptional<z.ZodString>;
|
|
75
|
+
fromName: z.ZodOptional<z.ZodString>;
|
|
76
|
+
to: z.ZodOptional<z.ZodString>;
|
|
77
|
+
cc: z.ZodOptional<z.ZodString>;
|
|
78
|
+
bcc: z.ZodOptional<z.ZodString>;
|
|
79
|
+
date: z.ZodOptional<z.ZodString>;
|
|
80
|
+
receivedDateTime: z.ZodOptional<z.ZodString>;
|
|
81
|
+
snippet: z.ZodOptional<z.ZodString>;
|
|
82
|
+
isRead: z.ZodOptional<z.ZodBoolean>;
|
|
83
|
+
isImportant: z.ZodOptional<z.ZodBoolean>;
|
|
84
|
+
hasAttachments: z.ZodOptional<z.ZodBoolean>;
|
|
85
|
+
attachmentCount: z.ZodOptional<z.ZodNumber>;
|
|
86
|
+
labelIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
87
|
+
folderName: z.ZodOptional<z.ZodString>;
|
|
88
|
+
body: z.ZodOptional<z.ZodString>;
|
|
89
|
+
bodyContentType: z.ZodOptional<z.ZodEnum<{
|
|
90
|
+
text: "text";
|
|
91
|
+
html: "html";
|
|
92
|
+
}>>;
|
|
93
|
+
attachments: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
94
|
+
id: z.ZodString;
|
|
95
|
+
filename: z.ZodString;
|
|
96
|
+
mimeType: z.ZodString;
|
|
97
|
+
size: z.ZodOptional<z.ZodNumber>;
|
|
98
|
+
}, z.core.$strip>>>;
|
|
99
|
+
}, z.core.$strip>;
|
|
100
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
101
|
+
type: z.ZodLiteral<"auth_required">;
|
|
102
|
+
provider: z.ZodString;
|
|
103
|
+
message: z.ZodString;
|
|
104
|
+
url: z.ZodOptional<z.ZodString>;
|
|
105
|
+
}, z.core.$strip>], "type">;
|
|
106
|
+
}, z.core.$strip>;
|
|
107
|
+
};
|
|
108
|
+
handler: typeof handler;
|
|
109
|
+
};
|
|
110
|
+
export {};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { EMAIL_COMMON_PATTERNS, EMAIL_FIELD_DESCRIPTIONS, EMAIL_FIELDS, EmailContentTypeSchema, EmailDetailSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText, normalizeDateToISO as toIsoUtc } from '@mcp-z/email';
|
|
2
|
+
import { schemas } from '@mcp-z/oauth-microsoft';
|
|
3
|
+
const { AuthRequiredBranchSchema } = schemas;
|
|
4
|
+
import { createFieldsSchema, filterFields, parseFields } from '@mcp-z/server';
|
|
5
|
+
import { Client } from '@microsoft/microsoft-graph-client';
|
|
6
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
const inputSchema = z.object({
|
|
9
|
+
id: z.coerce.string().trim().min(1).describe('Outlook message ID to retrieve'),
|
|
10
|
+
fields: createFieldsSchema({
|
|
11
|
+
availableFields: EMAIL_FIELDS,
|
|
12
|
+
fieldDescriptions: EMAIL_FIELD_DESCRIPTIONS,
|
|
13
|
+
commonPatterns: EMAIL_COMMON_PATTERNS,
|
|
14
|
+
resourceName: 'email message'
|
|
15
|
+
}),
|
|
16
|
+
contentType: EmailContentTypeSchema,
|
|
17
|
+
excludeThreadHistory: ExcludeThreadHistorySchema
|
|
18
|
+
});
|
|
19
|
+
// Success branch schema - uses item: wrapper for consistency with standard vocabulary
|
|
20
|
+
const successBranchSchema = z.object({
|
|
21
|
+
type: z.literal('success'),
|
|
22
|
+
item: EmailDetailSchema
|
|
23
|
+
});
|
|
24
|
+
// Output schema with auth_required support
|
|
25
|
+
const outputSchema = z.discriminatedUnion('type', [
|
|
26
|
+
successBranchSchema,
|
|
27
|
+
AuthRequiredBranchSchema
|
|
28
|
+
]);
|
|
29
|
+
const config = {
|
|
30
|
+
description: 'Get an Outlook message by ID with flexible field selection',
|
|
31
|
+
inputSchema: inputSchema,
|
|
32
|
+
outputSchema: z.object({
|
|
33
|
+
result: outputSchema
|
|
34
|
+
})
|
|
35
|
+
};
|
|
36
|
+
async function handler({ id, fields, contentType, excludeThreadHistory }, extra) {
|
|
37
|
+
const logger = extra.logger;
|
|
38
|
+
const requestedFields = parseFields(fields, EMAIL_FIELDS);
|
|
39
|
+
logger.info('outlook.message.get called', {
|
|
40
|
+
id,
|
|
41
|
+
fields: fields || 'all'
|
|
42
|
+
});
|
|
43
|
+
if (!id) {
|
|
44
|
+
logger.info('outlook.message.get missing id');
|
|
45
|
+
throw new McpError(ErrorCode.InvalidParams, 'Missing id');
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
var _ref;
|
|
49
|
+
var _message_body, _message_body_contentType, _message_body1, _message_from_emailAddress, _message_from;
|
|
50
|
+
const graph = Client.initWithMiddleware({
|
|
51
|
+
authProvider: extra.authContext.auth
|
|
52
|
+
});
|
|
53
|
+
const message = await graph.api(`/me/messages/${encodeURIComponent(id)}`).get();
|
|
54
|
+
// Process body based on contentType and excludeThreadHistory options
|
|
55
|
+
let bodyContent = (_ref = (_message_body = message.body) === null || _message_body === void 0 ? void 0 : _message_body.content) !== null && _ref !== void 0 ? _ref : '';
|
|
56
|
+
const isHtml = ((_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';
|
|
57
|
+
if (isHtml && excludeThreadHistory) {
|
|
58
|
+
// Remove thread history from HTML
|
|
59
|
+
bodyContent = extractCurrentMessageFromHtml(bodyContent);
|
|
60
|
+
}
|
|
61
|
+
if (isHtml && contentType === 'text') {
|
|
62
|
+
var _ref1;
|
|
63
|
+
var _message_body2;
|
|
64
|
+
// Convert HTML to plain text (thread extraction happens inside if excludeThreadHistory was true)
|
|
65
|
+
bodyContent = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(bodyContent) : extractCurrentMessageFromHtmlToText((_ref1 = (_message_body2 = message.body) === null || _message_body2 === void 0 ? void 0 : _message_body2.content) !== null && _ref1 !== void 0 ? _ref1 : '');
|
|
66
|
+
}
|
|
67
|
+
// Build full message data
|
|
68
|
+
const payload = {
|
|
69
|
+
id: message.id,
|
|
70
|
+
subject: message.subject,
|
|
71
|
+
from: (_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,
|
|
72
|
+
date: toIsoUtc(message.receivedDateTime) || message.receivedDateTime,
|
|
73
|
+
snippet: message.bodyPreview,
|
|
74
|
+
body: bodyContent,
|
|
75
|
+
bodyContentType: contentType
|
|
76
|
+
};
|
|
77
|
+
// Filter based on requested fields
|
|
78
|
+
const filteredPayload = filterFields(payload, requestedFields);
|
|
79
|
+
logger.info('outlook.message.get success', {
|
|
80
|
+
id: payload.id,
|
|
81
|
+
subject: payload.subject,
|
|
82
|
+
from: payload.from,
|
|
83
|
+
date: payload.date,
|
|
84
|
+
fields: fields || 'all'
|
|
85
|
+
});
|
|
86
|
+
const result = {
|
|
87
|
+
type: 'success',
|
|
88
|
+
item: filteredPayload
|
|
89
|
+
};
|
|
90
|
+
return {
|
|
91
|
+
content: [
|
|
92
|
+
{
|
|
93
|
+
type: 'text',
|
|
94
|
+
text: JSON.stringify(result)
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
structuredContent: {
|
|
98
|
+
result
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
} catch (error) {
|
|
102
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
103
|
+
logger.error('outlook.message.get error', {
|
|
104
|
+
error: message
|
|
105
|
+
});
|
|
106
|
+
throw new McpError(ErrorCode.InternalError, `Error getting message: ${message}`, {
|
|
107
|
+
stack: error instanceof Error ? error.stack : undefined
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export default function createTool() {
|
|
112
|
+
return {
|
|
113
|
+
name: 'message-get',
|
|
114
|
+
config,
|
|
115
|
+
handler
|
|
116
|
+
};
|
|
117
|
+
}
|