@mcp-z/mcp-gmail 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 +167 -0
- package/bin/server.js +5 -0
- package/dist/cjs/constants.d.cts +11 -0
- package/dist/cjs/constants.d.ts +11 -0
- package/dist/cjs/constants.js +39 -0
- package/dist/cjs/constants.js.map +1 -0
- package/dist/cjs/email/composition/rfc822-builder.d.cts +11 -0
- package/dist/cjs/email/composition/rfc822-builder.d.ts +11 -0
- package/dist/cjs/email/composition/rfc822-builder.js +24 -0
- package/dist/cjs/email/composition/rfc822-builder.js.map +1 -0
- package/dist/cjs/email/messages/fetch-message.d.cts +24 -0
- package/dist/cjs/email/messages/fetch-message.d.ts +24 -0
- package/dist/cjs/email/messages/fetch-message.js +367 -0
- package/dist/cjs/email/messages/fetch-message.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 +146 -0
- package/dist/cjs/email/messages/messages.js.map +1 -0
- package/dist/cjs/email/parsing/header-parsing.d.cts +1 -0
- package/dist/cjs/email/parsing/header-parsing.d.ts +1 -0
- package/dist/cjs/email/parsing/header-parsing.js +20 -0
- package/dist/cjs/email/parsing/header-parsing.js.map +1 -0
- package/dist/cjs/email/parsing/headers-utils.d.cts +5 -0
- package/dist/cjs/email/parsing/headers-utils.d.ts +5 -0
- package/dist/cjs/email/parsing/headers-utils.js +46 -0
- package/dist/cjs/email/parsing/headers-utils.js.map +1 -0
- package/dist/cjs/email/parsing/html-processing.d.cts +8 -0
- package/dist/cjs/email/parsing/html-processing.d.ts +8 -0
- package/dist/cjs/email/parsing/html-processing.js +72 -0
- package/dist/cjs/email/parsing/html-processing.js.map +1 -0
- package/dist/cjs/email/parsing/message-extraction.d.cts +2 -0
- package/dist/cjs/email/parsing/message-extraction.d.ts +2 -0
- package/dist/cjs/email/parsing/message-extraction.js +25 -0
- package/dist/cjs/email/parsing/message-extraction.js.map +1 -0
- package/dist/cjs/email/querying/execute-query.d.cts +17 -0
- package/dist/cjs/email/querying/execute-query.d.ts +17 -0
- package/dist/cjs/email/querying/execute-query.js +265 -0
- package/dist/cjs/email/querying/execute-query.js.map +1 -0
- package/dist/cjs/email/querying/pagination.d.cts +27 -0
- package/dist/cjs/email/querying/pagination.d.ts +27 -0
- package/dist/cjs/email/querying/pagination.js +533 -0
- package/dist/cjs/email/querying/pagination.js.map +1 -0
- package/dist/cjs/email/querying/query-builder.d.cts +47 -0
- package/dist/cjs/email/querying/query-builder.d.ts +47 -0
- package/dist/cjs/email/querying/query-builder.js +387 -0
- package/dist/cjs/email/querying/query-builder.js.map +1 -0
- package/dist/cjs/email/querying/search-execution.d.cts +29 -0
- package/dist/cjs/email/querying/search-execution.d.ts +29 -0
- package/dist/cjs/email/querying/search-execution.js +190 -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/labels/gmail-labels.d.cts +2 -0
- package/dist/cjs/labels/gmail-labels.d.ts +2 -0
- package/dist/cjs/labels/gmail-labels.js +206 -0
- package/dist/cjs/labels/gmail-labels.js.map +1 -0
- package/dist/cjs/lib/base64-encoding.d.cts +2 -0
- package/dist/cjs/lib/base64-encoding.d.ts +2 -0
- package/dist/cjs/lib/base64-encoding.js +32 -0
- package/dist/cjs/lib/base64-encoding.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/date-conversion.d.cts +1 -0
- package/dist/cjs/lib/date-conversion.d.ts +1 -0
- package/dist/cjs/lib/date-conversion.js +16 -0
- package/dist/cjs/lib/date-conversion.js.map +1 -0
- package/dist/cjs/lib/messages-to-row.d.cts +61 -0
- package/dist/cjs/lib/messages-to-row.d.ts +61 -0
- package/dist/cjs/lib/messages-to-row.js +243 -0
- package/dist/cjs/lib/messages-to-row.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 +256 -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 +58 -0
- package/dist/cjs/mcp/tools/categories-list.d.ts +58 -0
- package/dist/cjs/mcp/tools/categories-list.js +298 -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 +61 -0
- package/dist/cjs/mcp/tools/label-add.d.ts +61 -0
- package/dist/cjs/mcp/tools/label-add.js +280 -0
- package/dist/cjs/mcp/tools/label-add.js.map +1 -0
- package/dist/cjs/mcp/tools/label-delete.d.cts +71 -0
- package/dist/cjs/mcp/tools/label-delete.d.ts +71 -0
- package/dist/cjs/mcp/tools/label-delete.js +476 -0
- package/dist/cjs/mcp/tools/label-delete.js.map +1 -0
- package/dist/cjs/mcp/tools/labels-list.d.cts +75 -0
- package/dist/cjs/mcp/tools/labels-list.d.ts +75 -0
- package/dist/cjs/mcp/tools/labels-list.js +298 -0
- package/dist/cjs/mcp/tools/labels-list.js.map +1 -0
- package/dist/cjs/mcp/tools/message-get.d.cts +146 -0
- package/dist/cjs/mcp/tools/message-get.d.ts +146 -0
- package/dist/cjs/mcp/tools/message-get.js +317 -0
- package/dist/cjs/mcp/tools/message-get.js.map +1 -0
- package/dist/cjs/mcp/tools/message-mark-read.d.cts +50 -0
- package/dist/cjs/mcp/tools/message-mark-read.d.ts +50 -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 +71 -0
- package/dist/cjs/mcp/tools/message-move-to-trash.d.ts +71 -0
- package/dist/cjs/mcp/tools/message-move-to-trash.js +450 -0
- package/dist/cjs/mcp/tools/message-move-to-trash.js.map +1 -0
- package/dist/cjs/mcp/tools/message-respond.d.cts +60 -0
- package/dist/cjs/mcp/tools/message-respond.d.ts +60 -0
- package/dist/cjs/mcp/tools/message-respond.js +367 -0
- package/dist/cjs/mcp/tools/message-respond.js.map +1 -0
- package/dist/cjs/mcp/tools/message-search.d.cts +182 -0
- package/dist/cjs/mcp/tools/message-search.d.ts +182 -0
- package/dist/cjs/mcp/tools/message-search.js +405 -0
- package/dist/cjs/mcp/tools/message-search.js.map +1 -0
- package/dist/cjs/mcp/tools/message-send.d.cts +87 -0
- package/dist/cjs/mcp/tools/message-send.d.ts +87 -0
- package/dist/cjs/mcp/tools/message-send.js +288 -0
- package/dist/cjs/mcp/tools/message-send.js.map +1 -0
- package/dist/cjs/mcp/tools/messages-export-csv.d.cts +84 -0
- package/dist/cjs/mcp/tools/messages-export-csv.d.ts +84 -0
- package/dist/cjs/mcp/tools/messages-export-csv.js +530 -0
- package/dist/cjs/mcp/tools/messages-export-csv.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/schemas/gmail-query-schema.d.cts +36 -0
- package/dist/cjs/schemas/gmail-query-schema.d.ts +36 -0
- package/dist/cjs/schemas/gmail-query-schema.js +117 -0
- package/dist/cjs/schemas/gmail-query-schema.js.map +1 -0
- package/dist/cjs/schemas/index.d.cts +1 -0
- package/dist/cjs/schemas/index.d.ts +1 -0
- package/dist/cjs/schemas/index.js +19 -0
- package/dist/cjs/schemas/index.js.map +1 -0
- package/dist/cjs/setup/config.d.cts +48 -0
- package/dist/cjs/setup/config.d.ts +48 -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-google.d.cts +54 -0
- package/dist/cjs/setup/oauth-google.d.ts +54 -0
- package/dist/cjs/setup/oauth-google.js +332 -0
- package/dist/cjs/setup/oauth-google.js.map +1 -0
- package/dist/cjs/setup/runtime.d.cts +12 -0
- package/dist/cjs/setup/runtime.d.ts +12 -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 +11 -0
- package/dist/esm/constants.js +14 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/email/composition/rfc822-builder.d.ts +11 -0
- package/dist/esm/email/composition/rfc822-builder.js +13 -0
- package/dist/esm/email/composition/rfc822-builder.js.map +1 -0
- package/dist/esm/email/messages/fetch-message.d.ts +24 -0
- package/dist/esm/email/messages/fetch-message.js +123 -0
- package/dist/esm/email/messages/fetch-message.js.map +1 -0
- package/dist/esm/email/messages/messages.d.ts +7 -0
- package/dist/esm/email/messages/messages.js +91 -0
- package/dist/esm/email/messages/messages.js.map +1 -0
- package/dist/esm/email/parsing/header-parsing.d.ts +1 -0
- package/dist/esm/email/parsing/header-parsing.js +1 -0
- package/dist/esm/email/parsing/header-parsing.js.map +1 -0
- package/dist/esm/email/parsing/headers-utils.d.ts +5 -0
- package/dist/esm/email/parsing/headers-utils.js +25 -0
- package/dist/esm/email/parsing/headers-utils.js.map +1 -0
- package/dist/esm/email/parsing/html-processing.d.ts +8 -0
- package/dist/esm/email/parsing/html-processing.js +39 -0
- package/dist/esm/email/parsing/html-processing.js.map +1 -0
- package/dist/esm/email/parsing/message-extraction.d.ts +2 -0
- package/dist/esm/email/parsing/message-extraction.js +3 -0
- package/dist/esm/email/parsing/message-extraction.js.map +1 -0
- package/dist/esm/email/querying/execute-query.d.ts +17 -0
- package/dist/esm/email/querying/execute-query.js +45 -0
- package/dist/esm/email/querying/execute-query.js.map +1 -0
- package/dist/esm/email/querying/pagination.d.ts +27 -0
- package/dist/esm/email/querying/pagination.js +152 -0
- package/dist/esm/email/querying/pagination.js.map +1 -0
- package/dist/esm/email/querying/query-builder.d.ts +47 -0
- package/dist/esm/email/querying/query-builder.js +306 -0
- package/dist/esm/email/querying/query-builder.js.map +1 -0
- package/dist/esm/email/querying/search-execution.d.ts +29 -0
- package/dist/esm/email/querying/search-execution.js +35 -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/labels/gmail-labels.d.ts +2 -0
- package/dist/esm/labels/gmail-labels.js +43 -0
- package/dist/esm/labels/gmail-labels.js.map +1 -0
- package/dist/esm/lib/base64-encoding.d.ts +2 -0
- package/dist/esm/lib/base64-encoding.js +13 -0
- package/dist/esm/lib/base64-encoding.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/date-conversion.d.ts +1 -0
- package/dist/esm/lib/date-conversion.js +5 -0
- package/dist/esm/lib/date-conversion.js.map +1 -0
- package/dist/esm/lib/messages-to-row.d.ts +61 -0
- package/dist/esm/lib/messages-to-row.js +188 -0
- package/dist/esm/lib/messages-to-row.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 +74 -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 +92 -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 +58 -0
- package/dist/esm/mcp/tools/categories-list.js +124 -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 +61 -0
- package/dist/esm/mcp/tools/label-add.js +101 -0
- package/dist/esm/mcp/tools/label-add.js.map +1 -0
- package/dist/esm/mcp/tools/label-delete.d.ts +71 -0
- package/dist/esm/mcp/tools/label-delete.js +186 -0
- package/dist/esm/mcp/tools/label-delete.js.map +1 -0
- package/dist/esm/mcp/tools/labels-list.d.ts +75 -0
- package/dist/esm/mcp/tools/labels-list.js +122 -0
- package/dist/esm/mcp/tools/labels-list.js.map +1 -0
- package/dist/esm/mcp/tools/message-get.d.ts +146 -0
- package/dist/esm/mcp/tools/message-get.js +145 -0
- package/dist/esm/mcp/tools/message-get.js.map +1 -0
- package/dist/esm/mcp/tools/message-mark-read.d.ts +50 -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 +71 -0
- package/dist/esm/mcp/tools/message-move-to-trash.js +167 -0
- package/dist/esm/mcp/tools/message-move-to-trash.js.map +1 -0
- package/dist/esm/mcp/tools/message-respond.d.ts +60 -0
- package/dist/esm/mcp/tools/message-respond.js +152 -0
- package/dist/esm/mcp/tools/message-respond.js.map +1 -0
- package/dist/esm/mcp/tools/message-search.d.ts +182 -0
- package/dist/esm/mcp/tools/message-search.js +180 -0
- package/dist/esm/mcp/tools/message-search.js.map +1 -0
- package/dist/esm/mcp/tools/message-send.d.ts +87 -0
- package/dist/esm/mcp/tools/message-send.js +115 -0
- package/dist/esm/mcp/tools/message-send.js.map +1 -0
- package/dist/esm/mcp/tools/messages-export-csv.d.ts +84 -0
- package/dist/esm/mcp/tools/messages-export-csv.js +261 -0
- package/dist/esm/mcp/tools/messages-export-csv.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/schemas/gmail-query-schema.d.ts +36 -0
- package/dist/esm/schemas/gmail-query-schema.js +72 -0
- package/dist/esm/schemas/gmail-query-schema.js.map +1 -0
- package/dist/esm/schemas/index.d.ts +1 -0
- package/dist/esm/schemas/index.js +1 -0
- package/dist/esm/schemas/index.js.map +1 -0
- package/dist/esm/setup/config.d.ts +48 -0
- package/dist/esm/setup/config.js +175 -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-google.d.ts +54 -0
- package/dist/esm/setup/oauth-google.js +142 -0
- package/dist/esm/setup/oauth-google.js.map +1 -0
- package/dist/esm/setup/runtime.d.ts +12 -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 +110 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { EnrichedExtra } from '@mcp-z/oauth-google';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import type { StorageExtra } from '../../types.js';
|
|
4
|
+
declare const inputSchema: z.ZodObject<{
|
|
5
|
+
query: z.ZodOptional<z.ZodType<import("../../types.js").GmailQuery, unknown, z.core.$ZodTypeInternals<import("../../types.js").GmailQuery, unknown>>>;
|
|
6
|
+
maxItems: z.ZodDefault<z.ZodNumber>;
|
|
7
|
+
filename: z.ZodDefault<z.ZodString>;
|
|
8
|
+
contentType: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
9
|
+
text: "text";
|
|
10
|
+
html: "html";
|
|
11
|
+
}>>>;
|
|
12
|
+
excludeThreadHistory: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
declare const outputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
15
|
+
type: z.ZodLiteral<"success">;
|
|
16
|
+
uri: z.ZodString;
|
|
17
|
+
filename: z.ZodString;
|
|
18
|
+
rowCount: z.ZodNumber;
|
|
19
|
+
truncated: z.ZodBoolean;
|
|
20
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
21
|
+
type: z.ZodLiteral<"auth_required">;
|
|
22
|
+
provider: z.ZodString;
|
|
23
|
+
message: z.ZodString;
|
|
24
|
+
url: z.ZodOptional<z.ZodString>;
|
|
25
|
+
}, z.core.$strip>], "type">;
|
|
26
|
+
export type Input = z.infer<typeof inputSchema>;
|
|
27
|
+
export type Output = z.infer<typeof outputSchema>;
|
|
28
|
+
/**
|
|
29
|
+
* Handler for gmail-messages-export-csv tool
|
|
30
|
+
*
|
|
31
|
+
* CRITICAL: Streaming implementation per user requirements
|
|
32
|
+
* - Generate UUID upfront
|
|
33
|
+
* - Write CSV header immediately
|
|
34
|
+
* - Append rows as batches arrive
|
|
35
|
+
* - Delete partial file on error
|
|
36
|
+
* - NO RETRIES (fail fast on error)
|
|
37
|
+
*/
|
|
38
|
+
declare function handler({ query, maxItems, filename, contentType, excludeThreadHistory }: Input, extra: EnrichedExtra & StorageExtra): Promise<{
|
|
39
|
+
content: {
|
|
40
|
+
type: "text";
|
|
41
|
+
text: string;
|
|
42
|
+
}[];
|
|
43
|
+
structuredContent: {
|
|
44
|
+
result: {
|
|
45
|
+
type: "success";
|
|
46
|
+
uri: string;
|
|
47
|
+
filename: string;
|
|
48
|
+
rowCount: number;
|
|
49
|
+
truncated: boolean;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
}>;
|
|
53
|
+
export default function createTool(): {
|
|
54
|
+
name: string;
|
|
55
|
+
config: {
|
|
56
|
+
readonly description: "Export Gmail messages to CSV with streaming pagination. Returns file URI. Use query-syntax prompt for query reference.";
|
|
57
|
+
readonly inputSchema: z.ZodObject<{
|
|
58
|
+
query: z.ZodOptional<z.ZodType<import("../../types.js").GmailQuery, unknown, z.core.$ZodTypeInternals<import("../../types.js").GmailQuery, unknown>>>;
|
|
59
|
+
maxItems: z.ZodDefault<z.ZodNumber>;
|
|
60
|
+
filename: z.ZodDefault<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
|
+
uri: z.ZodString;
|
|
71
|
+
filename: z.ZodString;
|
|
72
|
+
rowCount: z.ZodNumber;
|
|
73
|
+
truncated: z.ZodBoolean;
|
|
74
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
75
|
+
type: z.ZodLiteral<"auth_required">;
|
|
76
|
+
provider: z.ZodString;
|
|
77
|
+
message: z.ZodString;
|
|
78
|
+
url: z.ZodOptional<z.ZodString>;
|
|
79
|
+
}, z.core.$strip>], "type">;
|
|
80
|
+
}, z.core.$strip>;
|
|
81
|
+
};
|
|
82
|
+
handler: typeof handler;
|
|
83
|
+
};
|
|
84
|
+
export {};
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { EmailContentTypeSchema, ExcludeThreadHistorySchema } from '@mcp-z/email';
|
|
2
|
+
import { schemas } from '@mcp-z/oauth-google';
|
|
3
|
+
const { AuthRequiredBranchSchema } = schemas;
|
|
4
|
+
import { getFileUri, reserveFile } from '@mcp-z/server';
|
|
5
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
+
import { stringify } from 'csv-stringify/sync';
|
|
7
|
+
import { createWriteStream } from 'fs';
|
|
8
|
+
import { unlink } from 'fs/promises';
|
|
9
|
+
import { google } from 'googleapis';
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { DEFAULT_PAGE_SIZE } from '../../constants.js';
|
|
12
|
+
import { extractBodyFromPayload } from '../../email/parsing/html-processing.js';
|
|
13
|
+
import { executeQuery as executeGmailQuery } from '../../email/querying/execute-query.js';
|
|
14
|
+
import { GmailQuerySchema } from '../../schemas/gmail-query-schema.js';
|
|
15
|
+
const DEFAULT_MAX_ITEMS = 10000;
|
|
16
|
+
const MAX_EXPORT_ITEMS = 50000;
|
|
17
|
+
const inputSchema = z.object({
|
|
18
|
+
query: GmailQuerySchema.optional().describe('Structured query object for filtering messages. Use query-syntax prompt for reference.'),
|
|
19
|
+
maxItems: z.number().int().positive().max(MAX_EXPORT_ITEMS).default(DEFAULT_MAX_ITEMS).describe(`Maximum messages to export (default: ${DEFAULT_MAX_ITEMS}, max: ${MAX_EXPORT_ITEMS})`),
|
|
20
|
+
filename: z.string().trim().min(1).default('gmail-messages.csv').describe('Output filename (default: gmail-messages.csv)'),
|
|
21
|
+
contentType: EmailContentTypeSchema,
|
|
22
|
+
excludeThreadHistory: ExcludeThreadHistorySchema
|
|
23
|
+
});
|
|
24
|
+
const successBranchSchema = z.object({
|
|
25
|
+
type: z.literal('success'),
|
|
26
|
+
uri: z.string().describe('File URI (file:// or http://)'),
|
|
27
|
+
filename: z.string().describe('Stored filename'),
|
|
28
|
+
rowCount: z.number().describe('Number of messages exported'),
|
|
29
|
+
truncated: z.boolean().describe('Whether export was truncated at maxItems')
|
|
30
|
+
});
|
|
31
|
+
const outputSchema = z.discriminatedUnion('type', [
|
|
32
|
+
successBranchSchema,
|
|
33
|
+
AuthRequiredBranchSchema
|
|
34
|
+
]);
|
|
35
|
+
const config = {
|
|
36
|
+
description: 'Export Gmail messages to CSV with streaming pagination. Returns file URI. Use query-syntax prompt for query reference.',
|
|
37
|
+
inputSchema: inputSchema,
|
|
38
|
+
outputSchema: z.object({
|
|
39
|
+
result: outputSchema
|
|
40
|
+
})
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Handler for gmail-messages-export-csv tool
|
|
44
|
+
*
|
|
45
|
+
* CRITICAL: Streaming implementation per user requirements
|
|
46
|
+
* - Generate UUID upfront
|
|
47
|
+
* - Write CSV header immediately
|
|
48
|
+
* - Append rows as batches arrive
|
|
49
|
+
* - Delete partial file on error
|
|
50
|
+
* - NO RETRIES (fail fast on error)
|
|
51
|
+
*/ async function handler({ query, maxItems, filename, contentType, excludeThreadHistory }, extra) {
|
|
52
|
+
const logger = extra.logger;
|
|
53
|
+
const { storageContext } = extra;
|
|
54
|
+
const { transport, storageDir, baseUrl } = storageContext;
|
|
55
|
+
logger.info('gmail.messages.export-csv called', {
|
|
56
|
+
query,
|
|
57
|
+
maxItems,
|
|
58
|
+
filename,
|
|
59
|
+
accountId: extra.authContext.accountId
|
|
60
|
+
});
|
|
61
|
+
// Reserve file location for streaming write (creates directory, generates ID, formats filename)
|
|
62
|
+
const reservation = await reserveFile(filename, {
|
|
63
|
+
storageDir
|
|
64
|
+
});
|
|
65
|
+
const { storedName, fullPath } = reservation;
|
|
66
|
+
logger.info('gmail.messages.export-csv starting streaming export', {
|
|
67
|
+
path: fullPath,
|
|
68
|
+
maxItems
|
|
69
|
+
});
|
|
70
|
+
try {
|
|
71
|
+
const gmail = google.gmail({
|
|
72
|
+
version: 'v1',
|
|
73
|
+
auth: extra.authContext.auth
|
|
74
|
+
});
|
|
75
|
+
// Create CSV headers (all email fields)
|
|
76
|
+
const csvHeaders = [
|
|
77
|
+
'id',
|
|
78
|
+
'threadId',
|
|
79
|
+
'from',
|
|
80
|
+
'to',
|
|
81
|
+
'cc',
|
|
82
|
+
'bcc',
|
|
83
|
+
'subject',
|
|
84
|
+
'date',
|
|
85
|
+
'snippet',
|
|
86
|
+
'body',
|
|
87
|
+
'provider',
|
|
88
|
+
'labels'
|
|
89
|
+
];
|
|
90
|
+
// Create write stream and write headers immediately
|
|
91
|
+
const writeStream = createWriteStream(fullPath, {
|
|
92
|
+
encoding: 'utf-8'
|
|
93
|
+
});
|
|
94
|
+
const headerLine = stringify([
|
|
95
|
+
csvHeaders
|
|
96
|
+
], {
|
|
97
|
+
header: false,
|
|
98
|
+
quoted: true,
|
|
99
|
+
quote: '"',
|
|
100
|
+
escape: '"'
|
|
101
|
+
});
|
|
102
|
+
writeStream.write(headerLine);
|
|
103
|
+
// Internal pagination loop - append to CSV with each batch
|
|
104
|
+
// NO RETRIES: If any error occurs, fail the whole operation and clean up
|
|
105
|
+
let totalRows = 0;
|
|
106
|
+
let nextPageToken;
|
|
107
|
+
const started = Date.now();
|
|
108
|
+
while(totalRows < maxItems){
|
|
109
|
+
var _exec_metadata;
|
|
110
|
+
const remainingItems = maxItems - totalRows;
|
|
111
|
+
const pageSize = Math.min(remainingItems, DEFAULT_PAGE_SIZE);
|
|
112
|
+
const exec = await executeGmailQuery(query, {
|
|
113
|
+
client: gmail,
|
|
114
|
+
logger,
|
|
115
|
+
pageSize,
|
|
116
|
+
...nextPageToken !== undefined && {
|
|
117
|
+
pageToken: nextPageToken
|
|
118
|
+
},
|
|
119
|
+
includeBody: true
|
|
120
|
+
}, (full)=>{
|
|
121
|
+
var _ref;
|
|
122
|
+
var _fullData_payload;
|
|
123
|
+
// Type-safe property access with guards
|
|
124
|
+
const fullData = full;
|
|
125
|
+
const headersArray = Array.isArray(fullData === null || fullData === void 0 ? void 0 : (_fullData_payload = fullData.payload) === null || _fullData_payload === void 0 ? void 0 : _fullData_payload.headers) ? fullData.payload.headers : [];
|
|
126
|
+
const headers = Object.fromEntries(headersArray.map((h)=>{
|
|
127
|
+
var _header_name, _header_value;
|
|
128
|
+
const header = h;
|
|
129
|
+
return [
|
|
130
|
+
String((_header_name = header.name) !== null && _header_name !== void 0 ? _header_name : ''),
|
|
131
|
+
String((_header_value = header.value) !== null && _header_value !== void 0 ? _header_value : '')
|
|
132
|
+
];
|
|
133
|
+
}));
|
|
134
|
+
const payload = fullData === null || fullData === void 0 ? void 0 : fullData.payload;
|
|
135
|
+
// Cast to Schema$MessagePart for extractBodyFromPayload
|
|
136
|
+
const body = payload ? extractBodyFromPayload(payload, {
|
|
137
|
+
contentType,
|
|
138
|
+
excludeThreadHistory
|
|
139
|
+
}) : '';
|
|
140
|
+
const labelIds = Array.isArray(fullData === null || fullData === void 0 ? void 0 : fullData.labelIds) ? fullData.labelIds.map((id)=>String(id !== null && id !== void 0 ? id : '')) : [];
|
|
141
|
+
return {
|
|
142
|
+
id: String((_ref = fullData === null || fullData === void 0 ? void 0 : fullData.id) !== null && _ref !== void 0 ? _ref : ''),
|
|
143
|
+
threadId: (fullData === null || fullData === void 0 ? void 0 : fullData.threadId) ? String(fullData.threadId) : '',
|
|
144
|
+
from: (headers === null || headers === void 0 ? void 0 : headers.From) || '',
|
|
145
|
+
to: (headers === null || headers === void 0 ? void 0 : headers.To) || '',
|
|
146
|
+
cc: (headers === null || headers === void 0 ? void 0 : headers.Cc) || '',
|
|
147
|
+
bcc: (headers === null || headers === void 0 ? void 0 : headers.Bcc) || '',
|
|
148
|
+
subject: (headers === null || headers === void 0 ? void 0 : headers.Subject) || '',
|
|
149
|
+
date: (headers === null || headers === void 0 ? void 0 : headers.Date) || '',
|
|
150
|
+
snippet: (fullData === null || fullData === void 0 ? void 0 : fullData.snippet) ? String(fullData.snippet) : '',
|
|
151
|
+
body,
|
|
152
|
+
provider: 'gmail',
|
|
153
|
+
labels: labelIds.join(';')
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
// Type-safe CSV row mapping
|
|
157
|
+
const csvRows = exec.items.map((row)=>{
|
|
158
|
+
return [
|
|
159
|
+
row.id,
|
|
160
|
+
row.threadId,
|
|
161
|
+
row.from,
|
|
162
|
+
row.to,
|
|
163
|
+
row.cc,
|
|
164
|
+
row.bcc,
|
|
165
|
+
row.subject,
|
|
166
|
+
row.date,
|
|
167
|
+
row.snippet,
|
|
168
|
+
row.body,
|
|
169
|
+
row.provider,
|
|
170
|
+
row.labels
|
|
171
|
+
];
|
|
172
|
+
});
|
|
173
|
+
// Append rows to CSV file immediately
|
|
174
|
+
if (csvRows.length > 0) {
|
|
175
|
+
const rowsContent = stringify(csvRows, {
|
|
176
|
+
header: false,
|
|
177
|
+
quoted: true,
|
|
178
|
+
quote: '"',
|
|
179
|
+
escape: '"'
|
|
180
|
+
});
|
|
181
|
+
writeStream.write(rowsContent);
|
|
182
|
+
}
|
|
183
|
+
totalRows += exec.items.length;
|
|
184
|
+
nextPageToken = (_exec_metadata = exec.metadata) === null || _exec_metadata === void 0 ? void 0 : _exec_metadata.nextPageToken;
|
|
185
|
+
logger.info('gmail.messages.export-csv batch written', {
|
|
186
|
+
batchSize: exec.items.length,
|
|
187
|
+
totalRows,
|
|
188
|
+
hasMore: Boolean(nextPageToken)
|
|
189
|
+
});
|
|
190
|
+
// Exit if no more results or reached maxItems
|
|
191
|
+
if (!nextPageToken || exec.items.length === 0) {
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Close write stream
|
|
196
|
+
await new Promise((resolve, reject)=>{
|
|
197
|
+
writeStream.end(()=>resolve());
|
|
198
|
+
writeStream.on('error', reject);
|
|
199
|
+
});
|
|
200
|
+
const durationMs = Date.now() - started;
|
|
201
|
+
const truncated = totalRows >= maxItems && Boolean(nextPageToken);
|
|
202
|
+
logger.info('gmail.messages.export-csv completed', {
|
|
203
|
+
rowCount: totalRows,
|
|
204
|
+
truncated,
|
|
205
|
+
durationMs,
|
|
206
|
+
filename: storedName
|
|
207
|
+
});
|
|
208
|
+
// Generate URI based on transport type (stdio: file://, HTTP: http://)
|
|
209
|
+
const uri = getFileUri(storedName, transport, {
|
|
210
|
+
storageDir,
|
|
211
|
+
...baseUrl && {
|
|
212
|
+
baseUrl
|
|
213
|
+
},
|
|
214
|
+
endpoint: '/files'
|
|
215
|
+
});
|
|
216
|
+
const result = {
|
|
217
|
+
type: 'success',
|
|
218
|
+
uri,
|
|
219
|
+
filename: storedName,
|
|
220
|
+
rowCount: totalRows,
|
|
221
|
+
truncated
|
|
222
|
+
};
|
|
223
|
+
return {
|
|
224
|
+
content: [
|
|
225
|
+
{
|
|
226
|
+
type: 'text',
|
|
227
|
+
text: JSON.stringify(result)
|
|
228
|
+
}
|
|
229
|
+
],
|
|
230
|
+
structuredContent: {
|
|
231
|
+
result
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
} catch (error) {
|
|
235
|
+
// CRITICAL: Clean up partial CSV file on error
|
|
236
|
+
try {
|
|
237
|
+
await unlink(fullPath);
|
|
238
|
+
logger.debug('Cleaned up partial CSV file after error', {
|
|
239
|
+
path: fullPath
|
|
240
|
+
});
|
|
241
|
+
} catch (_cleanupError) {
|
|
242
|
+
logger.debug('Could not clean up CSV file (may not exist)', {
|
|
243
|
+
path: fullPath
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
247
|
+
logger.error('gmail.messages.export-csv error', {
|
|
248
|
+
error: message
|
|
249
|
+
});
|
|
250
|
+
throw new McpError(ErrorCode.InternalError, `Error exporting messages to CSV: ${message}`, {
|
|
251
|
+
stack: error instanceof Error ? error.stack : undefined
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
export default function createTool() {
|
|
256
|
+
return {
|
|
257
|
+
name: 'messages-export-csv',
|
|
258
|
+
config,
|
|
259
|
+
handler
|
|
260
|
+
};
|
|
261
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/mcp/tools/messages-export-csv.ts"],"sourcesContent":["import { EmailContentTypeSchema, ExcludeThreadHistorySchema } from '@mcp-z/email';\nimport type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport { schemas } from '@mcp-z/oauth-google';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport { getFileUri, reserveFile, type ToolModule } from '@mcp-z/server';\nimport { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\n\nimport { stringify } from 'csv-stringify/sync';\nimport { createWriteStream } from 'fs';\nimport { unlink } from 'fs/promises';\nimport { type gmail_v1, google } from 'googleapis';\nimport { z } from 'zod';\nimport { DEFAULT_PAGE_SIZE } from '../../constants.ts';\nimport { extractBodyFromPayload } from '../../email/parsing/html-processing.js';\nimport { executeQuery as executeGmailQuery } from '../../email/querying/execute-query.js';\nimport { GmailQuerySchema } from '../../schemas/gmail-query-schema.js';\nimport type { StorageExtra } from '../../types.js';\n\nconst DEFAULT_MAX_ITEMS = 10000;\nconst MAX_EXPORT_ITEMS = 50000;\n\n/**\n * CSV row format based on EmailDetail\n * All fields are strings (empty string instead of undefined)\n * Includes additional CSV-specific fields: provider and labels\n */\ninterface CsvRow {\n id: string;\n threadId: string;\n from: string;\n to: string;\n cc: string;\n bcc: string;\n subject: string;\n date: string;\n snippet: string;\n body: string;\n provider: string;\n labels: string;\n}\n\nconst inputSchema = z.object({\n query: GmailQuerySchema.optional().describe('Structured query object for filtering messages. Use query-syntax prompt for reference.'),\n maxItems: z.number().int().positive().max(MAX_EXPORT_ITEMS).default(DEFAULT_MAX_ITEMS).describe(`Maximum messages to export (default: ${DEFAULT_MAX_ITEMS}, max: ${MAX_EXPORT_ITEMS})`),\n filename: z.string().trim().min(1).default('gmail-messages.csv').describe('Output filename (default: gmail-messages.csv)'),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\nconst successBranchSchema = z.object({\n type: z.literal('success'),\n uri: z.string().describe('File URI (file:// or http://)'),\n filename: z.string().describe('Stored filename'),\n rowCount: z.number().describe('Number of messages exported'),\n truncated: z.boolean().describe('Whether export was truncated at maxItems'),\n});\n\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Export Gmail messages to CSV with streaming pagination. Returns file URI. Use query-syntax prompt for query reference.',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\n/**\n * Handler for gmail-messages-export-csv tool\n *\n * CRITICAL: Streaming implementation per user requirements\n * - Generate UUID upfront\n * - Write CSV header immediately\n * - Append rows as batches arrive\n * - Delete partial file on error\n * - NO RETRIES (fail fast on error)\n */\nasync function handler({ query, maxItems, filename, contentType, excludeThreadHistory }: Input, extra: EnrichedExtra & StorageExtra) {\n const logger = extra.logger;\n const { storageContext } = extra;\n const { transport, storageDir, baseUrl } = storageContext;\n\n logger.info('gmail.messages.export-csv called', {\n query,\n maxItems,\n filename,\n accountId: extra.authContext.accountId,\n });\n\n // Reserve file location for streaming write (creates directory, generates ID, formats filename)\n const reservation = await reserveFile(filename, {\n storageDir,\n });\n const { storedName, fullPath } = reservation;\n\n logger.info('gmail.messages.export-csv starting streaming export', { path: fullPath, maxItems });\n\n try {\n const gmail = google.gmail({ version: 'v1', auth: extra.authContext.auth });\n\n // Create CSV headers (all email fields)\n const csvHeaders = ['id', 'threadId', 'from', 'to', 'cc', 'bcc', 'subject', 'date', 'snippet', 'body', 'provider', 'labels'];\n\n // Create write stream and write headers immediately\n const writeStream = createWriteStream(fullPath, { encoding: 'utf-8' });\n const headerLine = stringify([csvHeaders], { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(headerLine);\n\n // Internal pagination loop - append to CSV with each batch\n // NO RETRIES: If any error occurs, fail the whole operation and clean up\n let totalRows = 0;\n let nextPageToken: string | undefined;\n const started = Date.now();\n\n while (totalRows < maxItems) {\n const remainingItems = maxItems - totalRows;\n const pageSize = Math.min(remainingItems, DEFAULT_PAGE_SIZE);\n\n const exec: {\n items: CsvRow[];\n metadata?: { nextPageToken?: string };\n } = await executeGmailQuery(\n query,\n {\n client: gmail,\n logger,\n pageSize,\n ...(nextPageToken !== undefined && { pageToken: nextPageToken }),\n includeBody: true, // Always include body for CSV export\n },\n (full: unknown): CsvRow => {\n // Type-safe property access with guards\n const fullData = full as {\n id?: unknown;\n threadId?: unknown;\n snippet?: unknown;\n labelIds?: unknown[];\n payload?: { headers?: unknown[] };\n };\n\n const headersArray = Array.isArray(fullData?.payload?.headers) ? fullData.payload.headers : [];\n const headers = Object.fromEntries(\n headersArray.map((h: unknown) => {\n const header = h as { name?: unknown; value?: unknown };\n return [String(header.name ?? ''), String(header.value ?? '')];\n })\n );\n\n const payload = fullData?.payload;\n // Cast to Schema$MessagePart for extractBodyFromPayload\n const body = payload ? extractBodyFromPayload(payload as gmail_v1.Schema$MessagePart, { contentType, excludeThreadHistory }) : '';\n\n const labelIds = Array.isArray(fullData?.labelIds) ? fullData.labelIds.map((id) => String(id ?? '')) : [];\n\n return {\n id: String(fullData?.id ?? ''),\n threadId: fullData?.threadId ? String(fullData.threadId) : '',\n from: headers?.From || '',\n to: headers?.To || '',\n cc: headers?.Cc || '',\n bcc: headers?.Bcc || '',\n subject: headers?.Subject || '',\n date: headers?.Date || '',\n snippet: fullData?.snippet ? String(fullData.snippet) : '',\n body,\n provider: 'gmail',\n labels: labelIds.join(';'),\n };\n }\n );\n\n // Type-safe CSV row mapping\n const csvRows = exec.items.map((row) => {\n return [row.id, row.threadId, row.from, row.to, row.cc, row.bcc, row.subject, row.date, row.snippet, row.body, row.provider, row.labels];\n });\n\n // Append rows to CSV file immediately\n if (csvRows.length > 0) {\n const rowsContent = stringify(csvRows, { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(rowsContent);\n }\n\n totalRows += exec.items.length;\n nextPageToken = exec.metadata?.nextPageToken;\n\n logger.info('gmail.messages.export-csv batch written', {\n batchSize: exec.items.length,\n totalRows,\n hasMore: Boolean(nextPageToken),\n });\n\n // Exit if no more results or reached maxItems\n if (!nextPageToken || exec.items.length === 0) {\n break;\n }\n }\n\n // Close write stream\n await new Promise<void>((resolve, reject) => {\n writeStream.end(() => resolve());\n writeStream.on('error', reject);\n });\n\n const durationMs = Date.now() - started;\n const truncated = totalRows >= maxItems && Boolean(nextPageToken);\n\n logger.info('gmail.messages.export-csv completed', {\n rowCount: totalRows,\n truncated,\n durationMs,\n filename: storedName,\n });\n\n // Generate URI based on transport type (stdio: file://, HTTP: http://)\n const uri = getFileUri(storedName, transport, {\n storageDir,\n ...(baseUrl && { baseUrl }),\n endpoint: '/files',\n });\n\n const result: Output = {\n type: 'success' as const,\n uri,\n filename: storedName,\n rowCount: totalRows,\n truncated,\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result),\n },\n ],\n structuredContent: { result },\n };\n } catch (error) {\n // CRITICAL: Clean up partial CSV file on error\n try {\n await unlink(fullPath);\n logger.debug('Cleaned up partial CSV file after error', { path: fullPath });\n } catch (_cleanupError) {\n logger.debug('Could not clean up CSV file (may not exist)', { path: fullPath });\n }\n\n const message = error instanceof Error ? error.message : String(error);\n logger.error('gmail.messages.export-csv error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error exporting messages to CSV: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'messages-export-csv',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["EmailContentTypeSchema","ExcludeThreadHistorySchema","schemas","AuthRequiredBranchSchema","getFileUri","reserveFile","ErrorCode","McpError","stringify","createWriteStream","unlink","google","z","DEFAULT_PAGE_SIZE","extractBodyFromPayload","executeQuery","executeGmailQuery","GmailQuerySchema","DEFAULT_MAX_ITEMS","MAX_EXPORT_ITEMS","inputSchema","object","query","optional","describe","maxItems","number","int","positive","max","default","filename","string","trim","min","contentType","excludeThreadHistory","successBranchSchema","type","literal","uri","rowCount","truncated","boolean","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","storageContext","transport","storageDir","baseUrl","info","accountId","authContext","reservation","storedName","fullPath","path","gmail","version","auth","csvHeaders","writeStream","encoding","headerLine","header","quoted","quote","escape","write","totalRows","nextPageToken","started","Date","now","exec","remainingItems","pageSize","Math","client","undefined","pageToken","includeBody","full","fullData","headersArray","Array","isArray","payload","headers","Object","fromEntries","map","h","String","name","value","body","labelIds","id","threadId","from","From","to","To","cc","Cc","bcc","Bcc","subject","Subject","date","snippet","provider","labels","join","csvRows","items","row","length","rowsContent","metadata","batchSize","hasMore","Boolean","Promise","resolve","reject","end","on","durationMs","endpoint","content","text","JSON","structuredContent","error","debug","_cleanupError","message","Error","InternalError","stack","createTool"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "type": "module" }
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type BaseEmailQueryFields, type FieldOperator } from '@mcp-z/email';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* Gmail-specific query schema with recursive operators and Gmail features.
|
|
5
|
+
*
|
|
6
|
+
* Includes Gmail-specific features:
|
|
7
|
+
* - fuzzyPhrase: Approximate phrase matching (Gmail's quoted string behavior with relevance ranking)
|
|
8
|
+
* - categories: Gmail system categories (primary, social, promotions, updates, forums)
|
|
9
|
+
* - label: User-created Gmail labels (case-sensitive, discovered via gmail-labels-list)
|
|
10
|
+
* - rawGmailQuery: Escape hatch for advanced Gmail query syntax
|
|
11
|
+
*
|
|
12
|
+
* Plus all base fields from baseEmailQueryFields:
|
|
13
|
+
* - Email addresses: from, to, cc, bcc (support string or field operators)
|
|
14
|
+
* - Content: subject, body, text
|
|
15
|
+
* - Flags: hasAttachment, isRead
|
|
16
|
+
* - Date range: date { $gte, $lt }
|
|
17
|
+
* - Logical operators: $and, $or, $not (recursive)
|
|
18
|
+
*
|
|
19
|
+
* Note: Cast through unknown to work around Zod's lazy schema type inference issue
|
|
20
|
+
* with exactOptionalPropertyTypes. The runtime schema is correct; this cast ensures
|
|
21
|
+
* TypeScript sees the strict GmailQuery type everywhere the schema is used.
|
|
22
|
+
*/
|
|
23
|
+
export declare const GmailQuerySchema: z.ZodType<GmailQuery>;
|
|
24
|
+
export type GmailQuery = BaseEmailQueryFields & {
|
|
25
|
+
$and?: GmailQuery[];
|
|
26
|
+
$or?: GmailQuery[];
|
|
27
|
+
$not?: GmailQuery;
|
|
28
|
+
fuzzyPhrase?: string;
|
|
29
|
+
categories?: 'primary' | 'social' | 'promotions' | 'updates' | 'forums' | {
|
|
30
|
+
$any?: ('primary' | 'social' | 'promotions' | 'updates' | 'forums')[];
|
|
31
|
+
$all?: ('primary' | 'social' | 'promotions' | 'updates' | 'forums')[];
|
|
32
|
+
$none?: ('primary' | 'social' | 'promotions' | 'updates' | 'forums')[];
|
|
33
|
+
};
|
|
34
|
+
label?: string | FieldOperator;
|
|
35
|
+
rawGmailQuery?: string;
|
|
36
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { baseEmailQueryFields, FieldOperatorSchema } from '@mcp-z/email';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* Gmail-specific query schema with recursive operators and Gmail features.
|
|
5
|
+
*
|
|
6
|
+
* Includes Gmail-specific features:
|
|
7
|
+
* - fuzzyPhrase: Approximate phrase matching (Gmail's quoted string behavior with relevance ranking)
|
|
8
|
+
* - categories: Gmail system categories (primary, social, promotions, updates, forums)
|
|
9
|
+
* - label: User-created Gmail labels (case-sensitive, discovered via gmail-labels-list)
|
|
10
|
+
* - rawGmailQuery: Escape hatch for advanced Gmail query syntax
|
|
11
|
+
*
|
|
12
|
+
* Plus all base fields from baseEmailQueryFields:
|
|
13
|
+
* - Email addresses: from, to, cc, bcc (support string or field operators)
|
|
14
|
+
* - Content: subject, body, text
|
|
15
|
+
* - Flags: hasAttachment, isRead
|
|
16
|
+
* - Date range: date { $gte, $lt }
|
|
17
|
+
* - Logical operators: $and, $or, $not (recursive)
|
|
18
|
+
*
|
|
19
|
+
* Note: Cast through unknown to work around Zod's lazy schema type inference issue
|
|
20
|
+
* with exactOptionalPropertyTypes. The runtime schema is correct; this cast ensures
|
|
21
|
+
* TypeScript sees the strict GmailQuery type everywhere the schema is used.
|
|
22
|
+
*/ export const GmailQuerySchema = z.lazy(()=>z.object({
|
|
23
|
+
// Logical operators for combining conditions (recursive)
|
|
24
|
+
$and: z.array(GmailQuerySchema).optional().describe('Array of conditions that must ALL match'),
|
|
25
|
+
$or: z.array(GmailQuerySchema).optional().describe('Array of conditions where ANY must match'),
|
|
26
|
+
$not: GmailQuerySchema.optional().describe('Nested condition that must NOT match'),
|
|
27
|
+
// Spread base email query fields (from, to, subject, body, etc.)
|
|
28
|
+
...baseEmailQueryFields,
|
|
29
|
+
// Gmail-specific features
|
|
30
|
+
// Fuzzy phrase matching - Gmail's approximate search using quoted strings
|
|
31
|
+
fuzzyPhrase: z.string().min(1).optional().describe('Fuzzy phrase matching - words should appear together (approximate matching). Gmail uses relevance-based matching.'),
|
|
32
|
+
// Gmail system categories with field operator support
|
|
33
|
+
categories: z.union([
|
|
34
|
+
z.enum([
|
|
35
|
+
'primary',
|
|
36
|
+
'social',
|
|
37
|
+
'promotions',
|
|
38
|
+
'updates',
|
|
39
|
+
'forums'
|
|
40
|
+
]),
|
|
41
|
+
z.object({
|
|
42
|
+
$any: z.array(z.enum([
|
|
43
|
+
'primary',
|
|
44
|
+
'social',
|
|
45
|
+
'promotions',
|
|
46
|
+
'updates',
|
|
47
|
+
'forums'
|
|
48
|
+
])).optional(),
|
|
49
|
+
$all: z.array(z.enum([
|
|
50
|
+
'primary',
|
|
51
|
+
'social',
|
|
52
|
+
'promotions',
|
|
53
|
+
'updates',
|
|
54
|
+
'forums'
|
|
55
|
+
])).optional(),
|
|
56
|
+
$none: z.array(z.enum([
|
|
57
|
+
'primary',
|
|
58
|
+
'social',
|
|
59
|
+
'promotions',
|
|
60
|
+
'updates',
|
|
61
|
+
'forums'
|
|
62
|
+
])).optional()
|
|
63
|
+
}).strict()
|
|
64
|
+
]).optional().describe('Filter by Gmail system categories (primary, social, promotions, updates, forums)'),
|
|
65
|
+
// User-created labels
|
|
66
|
+
label: z.union([
|
|
67
|
+
z.string().min(1),
|
|
68
|
+
FieldOperatorSchema
|
|
69
|
+
]).optional().describe('Filter by user-created labels (case-sensitive). Use gmail-labels-list to see available labels'),
|
|
70
|
+
// Raw Gmail query string - escape hatch for advanced syntax
|
|
71
|
+
rawGmailQuery: z.string().min(1).optional().describe('Raw Gmail query syntax for advanced use cases. Bypasses schema validation - use sparingly.')
|
|
72
|
+
}).strict());
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/schemas/gmail-query-schema.ts"],"sourcesContent":["import { type BaseEmailQueryFields, baseEmailQueryFields, type FieldOperator, FieldOperatorSchema } from '@mcp-z/email';\nimport { z } from 'zod';\n\n/**\n * Gmail-specific query schema with recursive operators and Gmail features.\n *\n * Includes Gmail-specific features:\n * - fuzzyPhrase: Approximate phrase matching (Gmail's quoted string behavior with relevance ranking)\n * - categories: Gmail system categories (primary, social, promotions, updates, forums)\n * - label: User-created Gmail labels (case-sensitive, discovered via gmail-labels-list)\n * - rawGmailQuery: Escape hatch for advanced Gmail query syntax\n *\n * Plus all base fields from baseEmailQueryFields:\n * - Email addresses: from, to, cc, bcc (support string or field operators)\n * - Content: subject, body, text\n * - Flags: hasAttachment, isRead\n * - Date range: date { $gte, $lt }\n * - Logical operators: $and, $or, $not (recursive)\n *\n * Note: Cast through unknown to work around Zod's lazy schema type inference issue\n * with exactOptionalPropertyTypes. The runtime schema is correct; this cast ensures\n * TypeScript sees the strict GmailQuery type everywhere the schema is used.\n */\nexport const GmailQuerySchema = z.lazy(() =>\n z\n .object({\n // Logical operators for combining conditions (recursive)\n $and: z.array(GmailQuerySchema).optional().describe('Array of conditions that must ALL match'),\n $or: z.array(GmailQuerySchema).optional().describe('Array of conditions where ANY must match'),\n $not: GmailQuerySchema.optional().describe('Nested condition that must NOT match'),\n\n // Spread base email query fields (from, to, subject, body, etc.)\n ...baseEmailQueryFields,\n\n // Gmail-specific features\n\n // Fuzzy phrase matching - Gmail's approximate search using quoted strings\n fuzzyPhrase: z.string().min(1).optional().describe('Fuzzy phrase matching - words should appear together (approximate matching). Gmail uses relevance-based matching.'),\n\n // Gmail system categories with field operator support\n categories: z\n .union([\n z.enum(['primary', 'social', 'promotions', 'updates', 'forums']),\n z\n .object({\n $any: z.array(z.enum(['primary', 'social', 'promotions', 'updates', 'forums'])).optional(),\n $all: z.array(z.enum(['primary', 'social', 'promotions', 'updates', 'forums'])).optional(),\n $none: z.array(z.enum(['primary', 'social', 'promotions', 'updates', 'forums'])).optional(),\n })\n .strict(),\n ])\n .optional()\n .describe('Filter by Gmail system categories (primary, social, promotions, updates, forums)'),\n\n // User-created labels\n label: z\n .union([z.string().min(1), FieldOperatorSchema])\n .optional()\n .describe('Filter by user-created labels (case-sensitive). Use gmail-labels-list to see available labels'),\n\n // Raw Gmail query string - escape hatch for advanced syntax\n rawGmailQuery: z.string().min(1).optional().describe('Raw Gmail query syntax for advanced use cases. Bypasses schema validation - use sparingly.'),\n })\n .strict()\n) as unknown as z.ZodType<GmailQuery>;\n\nexport type GmailQuery = BaseEmailQueryFields & {\n $and?: GmailQuery[];\n $or?: GmailQuery[];\n $not?: GmailQuery;\n fuzzyPhrase?: string;\n categories?:\n | 'primary'\n | 'social'\n | 'promotions'\n | 'updates'\n | 'forums'\n | {\n $any?: ('primary' | 'social' | 'promotions' | 'updates' | 'forums')[];\n $all?: ('primary' | 'social' | 'promotions' | 'updates' | 'forums')[];\n $none?: ('primary' | 'social' | 'promotions' | 'updates' | 'forums')[];\n };\n label?: string | FieldOperator;\n rawGmailQuery?: string;\n};\n"],"names":["baseEmailQueryFields","FieldOperatorSchema","z","GmailQuerySchema","lazy","object","$and","array","optional","describe","$or","$not","fuzzyPhrase","string","min","categories","union","enum","$any","$all","$none","strict","label","rawGmailQuery"],"mappings":"AAAA,SAAoCA,oBAAoB,EAAsBC,mBAAmB,QAAQ,eAAe;AACxH,SAASC,CAAC,QAAQ,MAAM;AAExB;;;;;;;;;;;;;;;;;;;CAmBC,GACD,OAAO,MAAMC,mBAAmBD,EAAEE,IAAI,CAAC,IACrCF,EACGG,MAAM,CAAC;QACN,yDAAyD;QACzDC,MAAMJ,EAAEK,KAAK,CAACJ,kBAAkBK,QAAQ,GAAGC,QAAQ,CAAC;QACpDC,KAAKR,EAAEK,KAAK,CAACJ,kBAAkBK,QAAQ,GAAGC,QAAQ,CAAC;QACnDE,MAAMR,iBAAiBK,QAAQ,GAAGC,QAAQ,CAAC;QAE3C,iEAAiE;QACjE,GAAGT,oBAAoB;QAEvB,0BAA0B;QAE1B,0EAA0E;QAC1EY,aAAaV,EAAEW,MAAM,GAAGC,GAAG,CAAC,GAAGN,QAAQ,GAAGC,QAAQ,CAAC;QAEnD,sDAAsD;QACtDM,YAAYb,EACTc,KAAK,CAAC;YACLd,EAAEe,IAAI,CAAC;gBAAC;gBAAW;gBAAU;gBAAc;gBAAW;aAAS;YAC/Df,EACGG,MAAM,CAAC;gBACNa,MAAMhB,EAAEK,KAAK,CAACL,EAAEe,IAAI,CAAC;oBAAC;oBAAW;oBAAU;oBAAc;oBAAW;iBAAS,GAAGT,QAAQ;gBACxFW,MAAMjB,EAAEK,KAAK,CAACL,EAAEe,IAAI,CAAC;oBAAC;oBAAW;oBAAU;oBAAc;oBAAW;iBAAS,GAAGT,QAAQ;gBACxFY,OAAOlB,EAAEK,KAAK,CAACL,EAAEe,IAAI,CAAC;oBAAC;oBAAW;oBAAU;oBAAc;oBAAW;iBAAS,GAAGT,QAAQ;YAC3F,GACCa,MAAM;SACV,EACAb,QAAQ,GACRC,QAAQ,CAAC;QAEZ,sBAAsB;QACtBa,OAAOpB,EACJc,KAAK,CAAC;YAACd,EAAEW,MAAM,GAAGC,GAAG,CAAC;YAAIb;SAAoB,EAC9CO,QAAQ,GACRC,QAAQ,CAAC;QAEZ,4DAA4D;QAC5Dc,eAAerB,EAAEW,MAAM,GAAGC,GAAG,CAAC,GAAGN,QAAQ,GAAGC,QAAQ,CAAC;IACvD,GACCY,MAAM,IAC2B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './gmail-query-schema.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './gmail-query-schema.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/schemas/index.ts"],"sourcesContent":["export * from './gmail-query-schema.js';\n"],"names":[],"mappings":"AAAA,cAAc,0BAA0B"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ServerConfig } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Handle --version and --help flags before config parsing.
|
|
4
|
+
* These should work without requiring any configuration.
|
|
5
|
+
*/
|
|
6
|
+
export declare function handleVersionHelp(args: string[]): {
|
|
7
|
+
handled: boolean;
|
|
8
|
+
output?: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Parse Gmail server configuration from CLI arguments and environment.
|
|
12
|
+
*
|
|
13
|
+
* CLI Arguments (all optional):
|
|
14
|
+
* - --auth=<mode> Authentication mode (default: loopback-oauth)
|
|
15
|
+
* Modes: loopback-oauth, service-account, dcr
|
|
16
|
+
* - --headless Disable browser auto-open, return auth URL instead
|
|
17
|
+
* - --redirect-uri=<uri> OAuth redirect URI (default: ephemeral loopback)
|
|
18
|
+
* - --dcr-mode=<mode> DCR mode (self-hosted or external, default: self-hosted)
|
|
19
|
+
* - --dcr-verify-url=<url> External verification endpoint (required for external mode)
|
|
20
|
+
* - --dcr-store-uri=<uri> DCR client storage URI (required for self-hosted mode)
|
|
21
|
+
* - --port=<port> Enable HTTP transport on specified port
|
|
22
|
+
* - --stdio Enable stdio transport (default if no port)
|
|
23
|
+
* - --log-level=<level> Logging level (default: info)
|
|
24
|
+
* - --storage-dir=<path> Directory for CSV file storage (default: .mcp-z/files)
|
|
25
|
+
* - --base-url=<url> Base URL for HTTP file serving (optional)
|
|
26
|
+
*
|
|
27
|
+
* Environment Variables:
|
|
28
|
+
* - GOOGLE_CLIENT_ID OAuth client ID (REQUIRED)
|
|
29
|
+
* - GOOGLE_CLIENT_SECRET OAuth client secret (optional)
|
|
30
|
+
* - AUTH_MODE Default authentication mode (optional)
|
|
31
|
+
* - HEADLESS Disable browser auto-open (optional)
|
|
32
|
+
* - DCR_MODE DCR mode (optional, same format as --dcr-mode)
|
|
33
|
+
* - DCR_VERIFY_URL External verification URL (optional, same as --dcr-verify-url)
|
|
34
|
+
* - DCR_STORE_URI DCR storage URI (optional, same as --dcr-store-uri)
|
|
35
|
+
* - PORT Default HTTP port (optional)
|
|
36
|
+
* - LOG_LEVEL Default logging level (optional)
|
|
37
|
+
* - STORAGE_DIR Default storage directory (optional)
|
|
38
|
+
* - BASE_URL Default base URL for file serving (optional)
|
|
39
|
+
*
|
|
40
|
+
* OAuth Scopes (from constants.ts):
|
|
41
|
+
* openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://mail.google.com/
|
|
42
|
+
*/
|
|
43
|
+
export declare function parseConfig(args: string[], env: Record<string, string | undefined>): ServerConfig;
|
|
44
|
+
/**
|
|
45
|
+
* Build production configuration from process globals.
|
|
46
|
+
* Entry point for production server.
|
|
47
|
+
*/
|
|
48
|
+
export declare function createConfig(): ServerConfig;
|