@mcp-z/mcp-gmail 1.0.0 → 1.0.1

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.
Files changed (122) hide show
  1. package/README.md +33 -3
  2. package/bin/server.js +1 -1
  3. package/dist/cjs/constants.js.map +1 -1
  4. package/dist/cjs/email/composition/rfc822-builder.js.map +1 -1
  5. package/dist/cjs/email/messages/fetch-message.js +7 -7
  6. package/dist/cjs/email/messages/fetch-message.js.map +1 -1
  7. package/dist/cjs/email/messages/messages.js +10 -10
  8. package/dist/cjs/email/messages/messages.js.map +1 -1
  9. package/dist/cjs/email/parsing/header-parsing.js +3 -3
  10. package/dist/cjs/email/parsing/header-parsing.js.map +1 -1
  11. package/dist/cjs/email/parsing/headers-utils.js.map +1 -1
  12. package/dist/cjs/email/parsing/html-processing.js.map +1 -1
  13. package/dist/cjs/email/parsing/message-extraction.js +5 -5
  14. package/dist/cjs/email/parsing/message-extraction.js.map +1 -1
  15. package/dist/cjs/email/querying/execute-query.js +2 -2
  16. package/dist/cjs/email/querying/execute-query.js.map +1 -1
  17. package/dist/cjs/email/querying/pagination.js.map +1 -1
  18. package/dist/cjs/email/querying/query-builder.js.map +1 -1
  19. package/dist/cjs/email/querying/search-execution.js +4 -4
  20. package/dist/cjs/email/querying/search-execution.js.map +1 -1
  21. package/dist/cjs/index.js +13 -13
  22. package/dist/cjs/index.js.map +1 -1
  23. package/dist/cjs/labels/gmail-labels.js.map +1 -1
  24. package/dist/cjs/lib/base64-encoding.js.map +1 -1
  25. package/dist/cjs/lib/create-store.js.map +1 -1
  26. package/dist/cjs/lib/date-conversion.js.map +1 -1
  27. package/dist/cjs/lib/messages-to-row.js.map +1 -1
  28. package/dist/cjs/mcp/index.js +6 -6
  29. package/dist/cjs/mcp/index.js.map +1 -1
  30. package/dist/cjs/mcp/prompts/draft-email.js.map +1 -1
  31. package/dist/cjs/mcp/prompts/index.js +4 -4
  32. package/dist/cjs/mcp/prompts/index.js.map +1 -1
  33. package/dist/cjs/mcp/prompts/query-syntax.js.map +1 -1
  34. package/dist/cjs/mcp/resources/email.js +5 -5
  35. package/dist/cjs/mcp/resources/email.js.map +1 -1
  36. package/dist/cjs/mcp/resources/index.js +2 -2
  37. package/dist/cjs/mcp/resources/index.js.map +1 -1
  38. package/dist/cjs/mcp/tools/categories-list.js.map +1 -1
  39. package/dist/cjs/mcp/tools/index.js +22 -22
  40. package/dist/cjs/mcp/tools/index.js.map +1 -1
  41. package/dist/cjs/mcp/tools/label-add.js +2 -2
  42. package/dist/cjs/mcp/tools/label-add.js.map +1 -1
  43. package/dist/cjs/mcp/tools/label-delete.js.map +1 -1
  44. package/dist/cjs/mcp/tools/labels-list.js.map +1 -1
  45. package/dist/cjs/mcp/tools/message-get.js +8 -8
  46. package/dist/cjs/mcp/tools/message-get.js.map +1 -1
  47. package/dist/cjs/mcp/tools/message-mark-read.js.map +1 -1
  48. package/dist/cjs/mcp/tools/message-move-to-trash.js.map +1 -1
  49. package/dist/cjs/mcp/tools/message-respond.js +4 -4
  50. package/dist/cjs/mcp/tools/message-respond.js.map +1 -1
  51. package/dist/cjs/mcp/tools/message-search.js +6 -6
  52. package/dist/cjs/mcp/tools/message-search.js.map +1 -1
  53. package/dist/cjs/mcp/tools/message-send.js +4 -4
  54. package/dist/cjs/mcp/tools/message-send.js.map +1 -1
  55. package/dist/cjs/mcp/tools/messages-export-csv.js +6 -6
  56. package/dist/cjs/mcp/tools/messages-export-csv.js.map +1 -1
  57. package/dist/cjs/schemas/gmail-query-schema.js.map +1 -1
  58. package/dist/cjs/schemas/index.js.map +1 -1
  59. package/dist/cjs/setup/config.js +11 -1
  60. package/dist/cjs/setup/config.js.map +1 -1
  61. package/dist/cjs/setup/http.js +6 -2
  62. package/dist/cjs/setup/http.js.map +1 -1
  63. package/dist/cjs/setup/index.js +9 -9
  64. package/dist/cjs/setup/index.js.map +1 -1
  65. package/dist/cjs/setup/oauth-google.d.cts +3 -2
  66. package/dist/cjs/setup/oauth-google.d.ts +3 -2
  67. package/dist/cjs/setup/oauth-google.js +15 -12
  68. package/dist/cjs/setup/oauth-google.js.map +1 -1
  69. package/dist/cjs/setup/runtime.js +9 -9
  70. package/dist/cjs/setup/runtime.js.map +1 -1
  71. package/dist/cjs/setup/stdio.js +2 -2
  72. package/dist/cjs/setup/stdio.js.map +1 -1
  73. package/dist/esm/constants.js.map +1 -1
  74. package/dist/esm/email/composition/rfc822-builder.js.map +1 -1
  75. package/dist/esm/email/messages/fetch-message.js.map +1 -1
  76. package/dist/esm/email/messages/messages.js.map +1 -1
  77. package/dist/esm/email/parsing/header-parsing.js.map +1 -1
  78. package/dist/esm/email/parsing/headers-utils.js.map +1 -1
  79. package/dist/esm/email/parsing/html-processing.js.map +1 -1
  80. package/dist/esm/email/parsing/message-extraction.js.map +1 -1
  81. package/dist/esm/email/querying/execute-query.js.map +1 -1
  82. package/dist/esm/email/querying/pagination.js.map +1 -1
  83. package/dist/esm/email/querying/query-builder.js.map +1 -1
  84. package/dist/esm/email/querying/search-execution.js.map +1 -1
  85. package/dist/esm/index.js.map +1 -1
  86. package/dist/esm/labels/gmail-labels.js.map +1 -1
  87. package/dist/esm/lib/base64-encoding.js.map +1 -1
  88. package/dist/esm/lib/create-store.js.map +1 -1
  89. package/dist/esm/lib/date-conversion.js.map +1 -1
  90. package/dist/esm/lib/messages-to-row.js.map +1 -1
  91. package/dist/esm/mcp/index.js.map +1 -1
  92. package/dist/esm/mcp/prompts/draft-email.js.map +1 -1
  93. package/dist/esm/mcp/prompts/index.js.map +1 -1
  94. package/dist/esm/mcp/prompts/query-syntax.js.map +1 -1
  95. package/dist/esm/mcp/resources/email.js.map +1 -1
  96. package/dist/esm/mcp/resources/index.js.map +1 -1
  97. package/dist/esm/mcp/tools/categories-list.js.map +1 -1
  98. package/dist/esm/mcp/tools/index.js.map +1 -1
  99. package/dist/esm/mcp/tools/label-add.js.map +1 -1
  100. package/dist/esm/mcp/tools/label-delete.js.map +1 -1
  101. package/dist/esm/mcp/tools/labels-list.js.map +1 -1
  102. package/dist/esm/mcp/tools/message-get.js.map +1 -1
  103. package/dist/esm/mcp/tools/message-mark-read.js.map +1 -1
  104. package/dist/esm/mcp/tools/message-move-to-trash.js.map +1 -1
  105. package/dist/esm/mcp/tools/message-respond.js.map +1 -1
  106. package/dist/esm/mcp/tools/message-search.js.map +1 -1
  107. package/dist/esm/mcp/tools/message-send.js.map +1 -1
  108. package/dist/esm/mcp/tools/messages-export-csv.js.map +1 -1
  109. package/dist/esm/schemas/gmail-query-schema.js.map +1 -1
  110. package/dist/esm/schemas/index.js.map +1 -1
  111. package/dist/esm/setup/config.js +12 -2
  112. package/dist/esm/setup/config.js.map +1 -1
  113. package/dist/esm/setup/http.js +4 -0
  114. package/dist/esm/setup/http.js.map +1 -1
  115. package/dist/esm/setup/index.js.map +1 -1
  116. package/dist/esm/setup/oauth-google.d.ts +3 -2
  117. package/dist/esm/setup/oauth-google.js +8 -11
  118. package/dist/esm/setup/oauth-google.js.map +1 -1
  119. package/dist/esm/setup/runtime.js.map +1 -1
  120. package/dist/esm/setup/stdio.js.map +1 -1
  121. package/dist/esm/types.js.map +1 -1
  122. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/email/querying/query-builder.ts"],"sourcesContent":["import type { GmailQuery as QueryNode } from '../../schemas/gmail-query-schema.js';\n\n/**\n * Field operator interface for query filters\n */\nexport interface FieldOperator {\n $any?: string[];\n $all?: string[];\n $none?: string[];\n}\n\n/**\n * Field query interface with support for all email fields including categories and labels\n */\nexport interface FieldQuery {\n from?: FieldOperator | string;\n to?: FieldOperator | string;\n cc?: FieldOperator | string;\n bcc?: FieldOperator | string;\n subject?: FieldOperator | string;\n text?: FieldOperator | string;\n body?: FieldOperator | string;\n categories?: FieldOperator | string;\n label?: FieldOperator | string;\n}\n\n/**\n * Filter extraction result with all collected values from a query\n */\nexport interface Filters {\n subjectIncludes?: string[];\n bodyIncludes?: string[];\n textIncludes?: string[];\n fromIncludes?: string[];\n toIncludes?: string[];\n ccIncludes?: string[];\n bccIncludes?: string[];\n categoriesIncludes?: string[];\n labelIncludes?: string[];\n hasAttachment?: boolean;\n since?: string;\n before?: string;\n}\n\n/**\n * Gmail category mappings - case insensitive input to exact system labels\n */\nconst GMAIL_CATEGORIES = {\n primary: 'CATEGORY_PERSONAL',\n social: 'CATEGORY_SOCIAL',\n promotions: 'CATEGORY_PROMOTIONS',\n updates: 'CATEGORY_UPDATES',\n forums: 'CATEGORY_FORUMS',\n} as const;\n\n/**\n * Validate and map category name to Gmail system label\n * Throws error for invalid categories (fail fast principle)\n */\nfunction mapCategoryToLabel(category: string): string {\n // Input validation - fail fast on invalid input\n if (!category || typeof category !== 'string') {\n throw new Error(`Invalid category: expected non-empty string, got ${typeof category}`);\n }\n\n const trimmed = category.trim();\n if (trimmed === '') {\n throw new Error('Invalid category: empty string after trimming');\n }\n\n // Fail fast on unknown categories\n const normalizedCategory = trimmed.toLowerCase();\n const systemLabel = GMAIL_CATEGORIES[normalizedCategory as keyof typeof GMAIL_CATEGORIES];\n\n if (!systemLabel) {\n throw new Error(`Invalid Gmail category: \"${category}\". Valid categories: ${Object.keys(GMAIL_CATEGORIES).join(', ')}`);\n }\n\n return systemLabel;\n}\n\nexport function toGmailQuery(query: QueryNode, options: { dateSlash?: boolean } = {}) {\n const slashDates = options.dateSlash !== false;\n const subjectIncludes: string[] = [];\n const bodyIncludes: string[] = [];\n const textIncludes: string[] = [];\n const fromIncludes: string[] = [];\n const toIncludes: string[] = [];\n const ccIncludes: string[] = [];\n const bccIncludes: string[] = [];\n const categoriesIncludes: string[] = [];\n const labelIncludes: string[] = [];\n let hasAttachment: boolean | undefined;\n\n function p(s: unknown) {\n return `(${String(s ?? '')})`;\n }\n function fmt(d: unknown) {\n const str = String(d ?? '');\n return slashDates ? str.replace(/-/g, '/') : str;\n }\n\n function fv(field: string, raw?: unknown) {\n const rawVal = String(raw ?? '');\n if (rawVal.trim() === '') {\n throw new Error(`Invalid ${field} value: empty string`);\n }\n const v = quote(rawVal);\n if (field === 'subject') subjectIncludes.push(rawVal);\n if (field === 'body') bodyIncludes.push(rawVal);\n if (field === 'text') {\n textIncludes.push(rawVal);\n bodyIncludes.push(rawVal);\n }\n if (field === 'from') fromIncludes.push(rawVal);\n if (field === 'to') toIncludes.push(rawVal);\n if (field === 'cc') ccIncludes.push(rawVal);\n if (field === 'bcc') bccIncludes.push(rawVal);\n if (field === 'categories') {\n const systemLabel = mapCategoryToLabel(rawVal);\n categoriesIncludes.push(rawVal);\n return `label:${systemLabel}`;\n }\n if (field === 'label') {\n // Direct passthrough to Gmail's label syntax (case-sensitive)\n labelIncludes.push(rawVal);\n return `label:${quote(rawVal)}`;\n }\n if (field === 'text' || field === 'body') return p(`subject:${v} OR ${v}`);\n return `${field}:${v}`;\n }\n\n function chain(op: 'AND' | 'OR', arr: string[]) {\n if (arr.length === 0) throw new Error(`chain: empty array for ${op} operation`);\n if (arr.length === 1) {\n const first = arr[0] ?? '';\n return first;\n }\n return p(arr.join(` ${op} `));\n }\n\n function fieldExpr(field: string, op: FieldOperator) {\n if (op.$any) {\n const results = op.$any.map((v: string) => fv(field, String(v ?? '')));\n return chain('OR', results);\n }\n if (op.$all) {\n const results = op.$all.map((v: string) => fv(field, String(v ?? '')));\n return chain('AND', results);\n }\n if (op.$none) {\n const results = op.$none.map((v: string) => fv(field, String(v ?? '')));\n return `NOT ${p(chain('OR', results))}`;\n }\n throw new Error(`Unknown field operator ${JSON.stringify(op)}`);\n }\n\n function dateExpr(d: unknown) {\n const parts: string[] = [];\n if (d && typeof d === 'object' && '$gte' in d) {\n parts.push(`after:${fmt(d.$gte)}`);\n }\n if (d && typeof d === 'object' && '$lt' in d) {\n parts.push(`before:${fmt(d.$lt)}`);\n }\n return parts.length > 1 ? p(parts.join(' AND ')) : (parts[0] ?? '');\n }\n\n function fieldKeys() {\n return ['from', 'to', 'cc', 'bcc', 'subject', 'text', 'body', 'categories', 'label'];\n }\n\n function quote(s?: unknown) {\n const str = String(s ?? '');\n return /[\\s\"()]/.test(str) ? `\"${str.replace(/[\"\\\\]/g, (m) => `\\\\${m}`)}\"` : str;\n }\n\n function emit(n: unknown): string {\n if (!n || typeof n !== 'object') return '';\n\n if ('$and' in n && Array.isArray(n.$and)) {\n return p(n.$and.map(emit).join(' AND '));\n }\n if ('$or' in n && Array.isArray(n.$or)) {\n return p(n.$or.map(emit).join(' OR '));\n }\n if ('$not' in n) {\n return `NOT ${emit(n.$not)}`;\n }\n if ('hasAttachment' in n) {\n hasAttachment = true;\n return 'has:attachment';\n }\n if ('fuzzyPhrase' in n) {\n // Gmail fuzzy phrase matching using quoted strings\n // Example: { fuzzyPhrase: \"quarterly report\" } -> \"quarterly report\"\n return quote(n.fuzzyPhrase);\n }\n if ('date' in n) {\n return dateExpr(n.date);\n }\n\n // Handle empty objects\n const keys = Object.keys(n);\n if (keys.length === 0) return '';\n\n if (keys.length === 1) {\n const k = String(keys[0] ?? '');\n if (fieldKeys().includes(k)) {\n const op = (n as Record<string, unknown>)[k];\n // Handle string-only category queries properly (C2 fix)\n const normalizedOp: FieldOperator = typeof op === 'string' ? { $any: [op] } : (op ?? {});\n return fieldExpr(k, normalizedOp);\n }\n }\n throw new Error(`Unknown node: ${JSON.stringify(n)}`);\n }\n\n function emitTop(n: unknown): string {\n if (!n || typeof n !== 'object') return '';\n\n // Handle empty objects\n if (Object.keys(n).length === 0) return '';\n\n if ('$and' in n && Array.isArray(n.$and)) {\n return n.$and.map(emit).join(' ');\n }\n if ('$or' in n && Array.isArray(n.$or)) {\n return n.$or.map(emit).join(' OR ');\n }\n if ('$not' in n) {\n return `NOT ${emit(n.$not)}`;\n }\n if ('hasAttachment' in n) {\n hasAttachment = true;\n return 'has:attachment';\n }\n if ('fuzzyPhrase' in n) {\n // Gmail fuzzy phrase matching using quoted strings\n return quote(n.fuzzyPhrase);\n }\n if ('date' in n) {\n return dateExpr(n.date);\n }\n return emit(n);\n }\n\n const q = emitTop(query);\n const filters: Record<string, unknown> = {};\n if (subjectIncludes.length) filters.subjectIncludes = subjectIncludes;\n if (bodyIncludes.length) filters.bodyIncludes = bodyIncludes;\n if (textIncludes.length) filters.textIncludes = textIncludes;\n if (fromIncludes.length) filters.fromIncludes = fromIncludes;\n if (toIncludes.length) filters.toIncludes = toIncludes;\n if (ccIncludes.length) filters.ccIncludes = ccIncludes;\n if (bccIncludes.length) filters.bccIncludes = bccIncludes;\n if (categoriesIncludes.length) filters.categoriesIncludes = categoriesIncludes;\n if (labelIncludes.length) filters.labelIncludes = labelIncludes;\n if (typeof hasAttachment === 'boolean') filters.hasAttachment = hasAttachment;\n return { q: q ?? '', filters };\n}\n\nexport function extractFiltersFromParsed(parsed: QueryNode): Filters {\n const filters: Filters = {\n subjectIncludes: [],\n bodyIncludes: [],\n textIncludes: [],\n categoriesIncludes: [],\n labelIncludes: [],\n };\n\n function walk(node: unknown): void {\n if (!node || typeof node !== 'object') return;\n\n if ('$and' in node && Array.isArray(node.$and)) {\n node.$and.forEach(walk);\n return;\n }\n if ('$or' in node && Array.isArray(node.$or)) {\n node.$or.forEach(walk);\n return;\n }\n if ('$not' in node) {\n walk(node.$not);\n return;\n }\n if ('hasAttachment' in node) {\n filters.hasAttachment = node.hasAttachment === true;\n return;\n }\n if ('date' in node) {\n const dateObj = node.date;\n if (dateObj && typeof dateObj === 'object') {\n if ('$gte' in dateObj) {\n filters.since = String(dateObj.$gte);\n }\n if ('$lt' in dateObj) {\n filters.before = String(dateObj.$lt);\n }\n }\n return;\n }\n\n const keys = Object.keys(node || {});\n for (const k of keys) {\n const v = (node as Record<string, unknown>)[k];\n if (!v || typeof v !== 'object') continue;\n\n if (k === 'subject') {\n if ('$any' in v && Array.isArray(v.$any)) filters.subjectIncludes?.push(...v.$any);\n if ('$all' in v && Array.isArray(v.$all)) filters.subjectIncludes?.push(...v.$all);\n if ('$none' in v && Array.isArray(v.$none)) filters.subjectIncludes?.push(...v.$none);\n } else if (k === 'body') {\n if ('$any' in v && Array.isArray(v.$any)) filters.bodyIncludes?.push(...v.$any);\n if ('$all' in v && Array.isArray(v.$all)) filters.bodyIncludes?.push(...v.$all);\n if ('$none' in v && Array.isArray(v.$none)) filters.bodyIncludes?.push(...v.$none);\n } else if (k === 'text') {\n if ('$any' in v && Array.isArray(v.$any)) filters.textIncludes?.push(...v.$any);\n if ('$all' in v && Array.isArray(v.$all)) filters.textIncludes?.push(...v.$all);\n if ('$none' in v && Array.isArray(v.$none)) filters.textIncludes?.push(...v.$none);\n } else if (k === 'categories') {\n // Validate all categories (will throw on invalid)\n if ('$any' in v && Array.isArray(v.$any)) {\n v.$any.forEach((cat: unknown) => {\n mapCategoryToLabel(String(cat));\n });\n filters.categoriesIncludes?.push(...v.$any.map(String));\n }\n if ('$all' in v && Array.isArray(v.$all)) {\n v.$all.forEach((cat: unknown) => {\n mapCategoryToLabel(String(cat));\n });\n filters.categoriesIncludes?.push(...v.$all.map(String));\n }\n if ('$none' in v && Array.isArray(v.$none)) {\n v.$none.forEach((cat: unknown) => {\n mapCategoryToLabel(String(cat));\n });\n filters.categoriesIncludes?.push(...v.$none.map(String));\n }\n } else if (k === 'label') {\n // Direct passthrough for labels (case-sensitive)\n if ('$any' in v && Array.isArray(v.$any)) filters.labelIncludes?.push(...v.$any.map(String));\n if ('$all' in v && Array.isArray(v.$all)) filters.labelIncludes?.push(...v.$all.map(String));\n if ('$none' in v && Array.isArray(v.$none)) filters.labelIncludes?.push(...v.$none.map(String));\n }\n }\n }\n walk(parsed);\n return filters;\n}\n"],"names":["GMAIL_CATEGORIES","primary","social","promotions","updates","forums","mapCategoryToLabel","category","Error","trimmed","trim","normalizedCategory","toLowerCase","systemLabel","Object","keys","join","toGmailQuery","query","options","slashDates","dateSlash","subjectIncludes","bodyIncludes","textIncludes","fromIncludes","toIncludes","ccIncludes","bccIncludes","categoriesIncludes","labelIncludes","hasAttachment","p","s","String","fmt","d","str","replace","fv","field","raw","rawVal","v","quote","push","chain","op","arr","length","first","fieldExpr","$any","results","map","$all","$none","JSON","stringify","dateExpr","parts","$gte","$lt","fieldKeys","test","m","emit","n","Array","isArray","$and","$or","$not","fuzzyPhrase","date","k","includes","normalizedOp","emitTop","q","filters","extractFiltersFromParsed","parsed","walk","node","forEach","dateObj","since","before","cat"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/email/querying/query-builder.ts"],"sourcesContent":["import type { GmailQuery as QueryNode } from '../../schemas/gmail-query-schema.ts';\n\n/**\n * Field operator interface for query filters\n */\nexport interface FieldOperator {\n $any?: string[];\n $all?: string[];\n $none?: string[];\n}\n\n/**\n * Field query interface with support for all email fields including categories and labels\n */\nexport interface FieldQuery {\n from?: FieldOperator | string;\n to?: FieldOperator | string;\n cc?: FieldOperator | string;\n bcc?: FieldOperator | string;\n subject?: FieldOperator | string;\n text?: FieldOperator | string;\n body?: FieldOperator | string;\n categories?: FieldOperator | string;\n label?: FieldOperator | string;\n}\n\n/**\n * Filter extraction result with all collected values from a query\n */\nexport interface Filters {\n subjectIncludes?: string[];\n bodyIncludes?: string[];\n textIncludes?: string[];\n fromIncludes?: string[];\n toIncludes?: string[];\n ccIncludes?: string[];\n bccIncludes?: string[];\n categoriesIncludes?: string[];\n labelIncludes?: string[];\n hasAttachment?: boolean;\n since?: string;\n before?: string;\n}\n\n/**\n * Gmail category mappings - case insensitive input to exact system labels\n */\nconst GMAIL_CATEGORIES = {\n primary: 'CATEGORY_PERSONAL',\n social: 'CATEGORY_SOCIAL',\n promotions: 'CATEGORY_PROMOTIONS',\n updates: 'CATEGORY_UPDATES',\n forums: 'CATEGORY_FORUMS',\n} as const;\n\n/**\n * Validate and map category name to Gmail system label\n * Throws error for invalid categories (fail fast principle)\n */\nfunction mapCategoryToLabel(category: string): string {\n // Input validation - fail fast on invalid input\n if (!category || typeof category !== 'string') {\n throw new Error(`Invalid category: expected non-empty string, got ${typeof category}`);\n }\n\n const trimmed = category.trim();\n if (trimmed === '') {\n throw new Error('Invalid category: empty string after trimming');\n }\n\n // Fail fast on unknown categories\n const normalizedCategory = trimmed.toLowerCase();\n const systemLabel = GMAIL_CATEGORIES[normalizedCategory as keyof typeof GMAIL_CATEGORIES];\n\n if (!systemLabel) {\n throw new Error(`Invalid Gmail category: \"${category}\". Valid categories: ${Object.keys(GMAIL_CATEGORIES).join(', ')}`);\n }\n\n return systemLabel;\n}\n\nexport function toGmailQuery(query: QueryNode, options: { dateSlash?: boolean } = {}) {\n const slashDates = options.dateSlash !== false;\n const subjectIncludes: string[] = [];\n const bodyIncludes: string[] = [];\n const textIncludes: string[] = [];\n const fromIncludes: string[] = [];\n const toIncludes: string[] = [];\n const ccIncludes: string[] = [];\n const bccIncludes: string[] = [];\n const categoriesIncludes: string[] = [];\n const labelIncludes: string[] = [];\n let hasAttachment: boolean | undefined;\n\n function p(s: unknown) {\n return `(${String(s ?? '')})`;\n }\n function fmt(d: unknown) {\n const str = String(d ?? '');\n return slashDates ? str.replace(/-/g, '/') : str;\n }\n\n function fv(field: string, raw?: unknown) {\n const rawVal = String(raw ?? '');\n if (rawVal.trim() === '') {\n throw new Error(`Invalid ${field} value: empty string`);\n }\n const v = quote(rawVal);\n if (field === 'subject') subjectIncludes.push(rawVal);\n if (field === 'body') bodyIncludes.push(rawVal);\n if (field === 'text') {\n textIncludes.push(rawVal);\n bodyIncludes.push(rawVal);\n }\n if (field === 'from') fromIncludes.push(rawVal);\n if (field === 'to') toIncludes.push(rawVal);\n if (field === 'cc') ccIncludes.push(rawVal);\n if (field === 'bcc') bccIncludes.push(rawVal);\n if (field === 'categories') {\n const systemLabel = mapCategoryToLabel(rawVal);\n categoriesIncludes.push(rawVal);\n return `label:${systemLabel}`;\n }\n if (field === 'label') {\n // Direct passthrough to Gmail's label syntax (case-sensitive)\n labelIncludes.push(rawVal);\n return `label:${quote(rawVal)}`;\n }\n if (field === 'text' || field === 'body') return p(`subject:${v} OR ${v}`);\n return `${field}:${v}`;\n }\n\n function chain(op: 'AND' | 'OR', arr: string[]) {\n if (arr.length === 0) throw new Error(`chain: empty array for ${op} operation`);\n if (arr.length === 1) {\n const first = arr[0] ?? '';\n return first;\n }\n return p(arr.join(` ${op} `));\n }\n\n function fieldExpr(field: string, op: FieldOperator) {\n if (op.$any) {\n const results = op.$any.map((v: string) => fv(field, String(v ?? '')));\n return chain('OR', results);\n }\n if (op.$all) {\n const results = op.$all.map((v: string) => fv(field, String(v ?? '')));\n return chain('AND', results);\n }\n if (op.$none) {\n const results = op.$none.map((v: string) => fv(field, String(v ?? '')));\n return `NOT ${p(chain('OR', results))}`;\n }\n throw new Error(`Unknown field operator ${JSON.stringify(op)}`);\n }\n\n function dateExpr(d: unknown) {\n const parts: string[] = [];\n if (d && typeof d === 'object' && '$gte' in d) {\n parts.push(`after:${fmt(d.$gte)}`);\n }\n if (d && typeof d === 'object' && '$lt' in d) {\n parts.push(`before:${fmt(d.$lt)}`);\n }\n return parts.length > 1 ? p(parts.join(' AND ')) : (parts[0] ?? '');\n }\n\n function fieldKeys() {\n return ['from', 'to', 'cc', 'bcc', 'subject', 'text', 'body', 'categories', 'label'];\n }\n\n function quote(s?: unknown) {\n const str = String(s ?? '');\n return /[\\s\"()]/.test(str) ? `\"${str.replace(/[\"\\\\]/g, (m) => `\\\\${m}`)}\"` : str;\n }\n\n function emit(n: unknown): string {\n if (!n || typeof n !== 'object') return '';\n\n if ('$and' in n && Array.isArray(n.$and)) {\n return p(n.$and.map(emit).join(' AND '));\n }\n if ('$or' in n && Array.isArray(n.$or)) {\n return p(n.$or.map(emit).join(' OR '));\n }\n if ('$not' in n) {\n return `NOT ${emit(n.$not)}`;\n }\n if ('hasAttachment' in n) {\n hasAttachment = true;\n return 'has:attachment';\n }\n if ('fuzzyPhrase' in n) {\n // Gmail fuzzy phrase matching using quoted strings\n // Example: { fuzzyPhrase: \"quarterly report\" } -> \"quarterly report\"\n return quote(n.fuzzyPhrase);\n }\n if ('date' in n) {\n return dateExpr(n.date);\n }\n\n // Handle empty objects\n const keys = Object.keys(n);\n if (keys.length === 0) return '';\n\n if (keys.length === 1) {\n const k = String(keys[0] ?? '');\n if (fieldKeys().includes(k)) {\n const op = (n as Record<string, unknown>)[k];\n // Handle string-only category queries properly (C2 fix)\n const normalizedOp: FieldOperator = typeof op === 'string' ? { $any: [op] } : (op ?? {});\n return fieldExpr(k, normalizedOp);\n }\n }\n throw new Error(`Unknown node: ${JSON.stringify(n)}`);\n }\n\n function emitTop(n: unknown): string {\n if (!n || typeof n !== 'object') return '';\n\n // Handle empty objects\n if (Object.keys(n).length === 0) return '';\n\n if ('$and' in n && Array.isArray(n.$and)) {\n return n.$and.map(emit).join(' ');\n }\n if ('$or' in n && Array.isArray(n.$or)) {\n return n.$or.map(emit).join(' OR ');\n }\n if ('$not' in n) {\n return `NOT ${emit(n.$not)}`;\n }\n if ('hasAttachment' in n) {\n hasAttachment = true;\n return 'has:attachment';\n }\n if ('fuzzyPhrase' in n) {\n // Gmail fuzzy phrase matching using quoted strings\n return quote(n.fuzzyPhrase);\n }\n if ('date' in n) {\n return dateExpr(n.date);\n }\n return emit(n);\n }\n\n const q = emitTop(query);\n const filters: Record<string, unknown> = {};\n if (subjectIncludes.length) filters.subjectIncludes = subjectIncludes;\n if (bodyIncludes.length) filters.bodyIncludes = bodyIncludes;\n if (textIncludes.length) filters.textIncludes = textIncludes;\n if (fromIncludes.length) filters.fromIncludes = fromIncludes;\n if (toIncludes.length) filters.toIncludes = toIncludes;\n if (ccIncludes.length) filters.ccIncludes = ccIncludes;\n if (bccIncludes.length) filters.bccIncludes = bccIncludes;\n if (categoriesIncludes.length) filters.categoriesIncludes = categoriesIncludes;\n if (labelIncludes.length) filters.labelIncludes = labelIncludes;\n if (typeof hasAttachment === 'boolean') filters.hasAttachment = hasAttachment;\n return { q: q ?? '', filters };\n}\n\nexport function extractFiltersFromParsed(parsed: QueryNode): Filters {\n const filters: Filters = {\n subjectIncludes: [],\n bodyIncludes: [],\n textIncludes: [],\n categoriesIncludes: [],\n labelIncludes: [],\n };\n\n function walk(node: unknown): void {\n if (!node || typeof node !== 'object') return;\n\n if ('$and' in node && Array.isArray(node.$and)) {\n node.$and.forEach(walk);\n return;\n }\n if ('$or' in node && Array.isArray(node.$or)) {\n node.$or.forEach(walk);\n return;\n }\n if ('$not' in node) {\n walk(node.$not);\n return;\n }\n if ('hasAttachment' in node) {\n filters.hasAttachment = node.hasAttachment === true;\n return;\n }\n if ('date' in node) {\n const dateObj = node.date;\n if (dateObj && typeof dateObj === 'object') {\n if ('$gte' in dateObj) {\n filters.since = String(dateObj.$gte);\n }\n if ('$lt' in dateObj) {\n filters.before = String(dateObj.$lt);\n }\n }\n return;\n }\n\n const keys = Object.keys(node || {});\n for (const k of keys) {\n const v = (node as Record<string, unknown>)[k];\n if (!v || typeof v !== 'object') continue;\n\n if (k === 'subject') {\n if ('$any' in v && Array.isArray(v.$any)) filters.subjectIncludes?.push(...v.$any);\n if ('$all' in v && Array.isArray(v.$all)) filters.subjectIncludes?.push(...v.$all);\n if ('$none' in v && Array.isArray(v.$none)) filters.subjectIncludes?.push(...v.$none);\n } else if (k === 'body') {\n if ('$any' in v && Array.isArray(v.$any)) filters.bodyIncludes?.push(...v.$any);\n if ('$all' in v && Array.isArray(v.$all)) filters.bodyIncludes?.push(...v.$all);\n if ('$none' in v && Array.isArray(v.$none)) filters.bodyIncludes?.push(...v.$none);\n } else if (k === 'text') {\n if ('$any' in v && Array.isArray(v.$any)) filters.textIncludes?.push(...v.$any);\n if ('$all' in v && Array.isArray(v.$all)) filters.textIncludes?.push(...v.$all);\n if ('$none' in v && Array.isArray(v.$none)) filters.textIncludes?.push(...v.$none);\n } else if (k === 'categories') {\n // Validate all categories (will throw on invalid)\n if ('$any' in v && Array.isArray(v.$any)) {\n v.$any.forEach((cat: unknown) => {\n mapCategoryToLabel(String(cat));\n });\n filters.categoriesIncludes?.push(...v.$any.map(String));\n }\n if ('$all' in v && Array.isArray(v.$all)) {\n v.$all.forEach((cat: unknown) => {\n mapCategoryToLabel(String(cat));\n });\n filters.categoriesIncludes?.push(...v.$all.map(String));\n }\n if ('$none' in v && Array.isArray(v.$none)) {\n v.$none.forEach((cat: unknown) => {\n mapCategoryToLabel(String(cat));\n });\n filters.categoriesIncludes?.push(...v.$none.map(String));\n }\n } else if (k === 'label') {\n // Direct passthrough for labels (case-sensitive)\n if ('$any' in v && Array.isArray(v.$any)) filters.labelIncludes?.push(...v.$any.map(String));\n if ('$all' in v && Array.isArray(v.$all)) filters.labelIncludes?.push(...v.$all.map(String));\n if ('$none' in v && Array.isArray(v.$none)) filters.labelIncludes?.push(...v.$none.map(String));\n }\n }\n }\n walk(parsed);\n return filters;\n}\n"],"names":["GMAIL_CATEGORIES","primary","social","promotions","updates","forums","mapCategoryToLabel","category","Error","trimmed","trim","normalizedCategory","toLowerCase","systemLabel","Object","keys","join","toGmailQuery","query","options","slashDates","dateSlash","subjectIncludes","bodyIncludes","textIncludes","fromIncludes","toIncludes","ccIncludes","bccIncludes","categoriesIncludes","labelIncludes","hasAttachment","p","s","String","fmt","d","str","replace","fv","field","raw","rawVal","v","quote","push","chain","op","arr","length","first","fieldExpr","$any","results","map","$all","$none","JSON","stringify","dateExpr","parts","$gte","$lt","fieldKeys","test","m","emit","n","Array","isArray","$and","$or","$not","fuzzyPhrase","date","k","includes","normalizedOp","emitTop","q","filters","extractFiltersFromParsed","parsed","walk","node","forEach","dateObj","since","before","cat"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/email/querying/search-execution.ts"],"sourcesContent":["import type { gmail_v1 } from 'googleapis';\nimport type { GmailQuery as QueryNode } from '../../schemas/gmail-query-schema.js';\nimport type { Logger } from '../../types.js';\nimport { type FetchMessagesPageParams, fetchMessagesPage } from './pagination.js';\nimport { toGmailQuery } from './query-builder.js';\n\nexport interface GmailSearchOptions {\n readonly query?: QueryNode;\n readonly pageSize?: number;\n readonly includeBody?: boolean;\n readonly pageToken: string | undefined; // For pagination support - explicit undefined allowed\n readonly logger: Logger;\n}\n\nexport interface GmailEmailSummary {\n readonly id: string;\n readonly provider: 'gmail';\n readonly threadId?: string;\n readonly date?: string;\n readonly from?: string;\n readonly fromName?: string;\n readonly to?: string;\n readonly cc?: string;\n readonly bcc?: string;\n readonly subject?: string;\n readonly snippet?: string;\n readonly body?: string;\n}\n\nfunction buildGmailQ(query: QueryNode | undefined): string {\n if (!query) return '';\n const emitted = toGmailQuery(query);\n return emitted?.q ?? '';\n}\n\nexport interface GmailSearchResult {\n readonly messages: gmail_v1.Schema$Message[]; // Raw Gmail API messages for transformation by caller\n readonly nextPageToken: string | undefined;\n}\n\nexport async function searchMessages(gmail: gmail_v1.Gmail, opts: GmailSearchOptions): Promise<GmailSearchResult> {\n const { query, pageSize = 50, includeBody = false, pageToken, logger } = opts;\n const gmailQ = buildGmailQ(query);\n const metadataHeaders = ['Date', 'Subject', 'From', 'To', 'Cc', 'Bcc'];\n // Always fetch metadata headers - body is additional content, not a replacement for headers\n const pageParams: FetchMessagesPageParams = {\n gmailQ,\n pageSize,\n body: includeBody,\n metadataHeaders,\n pageToken,\n logger,\n };\n const result = await fetchMessagesPage(gmail, pageParams);\n\n // Return raw Gmail messages - transformation happens in caller\n return {\n messages: result.messages,\n nextPageToken: result.nextPageToken,\n };\n}\n"],"names":["fetchMessagesPage","toGmailQuery","buildGmailQ","query","emitted","q","searchMessages","gmail","opts","pageSize","includeBody","pageToken","logger","gmailQ","metadataHeaders","pageParams","body","result","messages","nextPageToken"],"mappings":"AAGA,SAAuCA,iBAAiB,QAAQ,kBAAkB;AAClF,SAASC,YAAY,QAAQ,qBAAqB;AAyBlD,SAASC,YAAYC,KAA4B;;IAC/C,IAAI,CAACA,OAAO,OAAO;IACnB,MAAMC,UAAUH,aAAaE;IAC7B,eAAOC,oBAAAA,8BAAAA,QAASC,CAAC,uCAAI;AACvB;AAOA,OAAO,eAAeC,eAAeC,KAAqB,EAAEC,IAAwB;IAClF,MAAM,EAAEL,KAAK,EAAEM,WAAW,EAAE,EAAEC,cAAc,KAAK,EAAEC,SAAS,EAAEC,MAAM,EAAE,GAAGJ;IACzE,MAAMK,SAASX,YAAYC;IAC3B,MAAMW,kBAAkB;QAAC;QAAQ;QAAW;QAAQ;QAAM;QAAM;KAAM;IACtE,4FAA4F;IAC5F,MAAMC,aAAsC;QAC1CF;QACAJ;QACAO,MAAMN;QACNI;QACAH;QACAC;IACF;IACA,MAAMK,SAAS,MAAMjB,kBAAkBO,OAAOQ;IAE9C,+DAA+D;IAC/D,OAAO;QACLG,UAAUD,OAAOC,QAAQ;QACzBC,eAAeF,OAAOE,aAAa;IACrC;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/email/querying/search-execution.ts"],"sourcesContent":["import type { gmail_v1 } from 'googleapis';\nimport type { GmailQuery as QueryNode } from '../../schemas/gmail-query-schema.ts';\nimport type { Logger } from '../../types.ts';\nimport { type FetchMessagesPageParams, fetchMessagesPage } from './pagination.ts';\nimport { toGmailQuery } from './query-builder.ts';\n\nexport interface GmailSearchOptions {\n readonly query?: QueryNode;\n readonly pageSize?: number;\n readonly includeBody?: boolean;\n readonly pageToken: string | undefined; // For pagination support - explicit undefined allowed\n readonly logger: Logger;\n}\n\nexport interface GmailEmailSummary {\n readonly id: string;\n readonly provider: 'gmail';\n readonly threadId?: string;\n readonly date?: string;\n readonly from?: string;\n readonly fromName?: string;\n readonly to?: string;\n readonly cc?: string;\n readonly bcc?: string;\n readonly subject?: string;\n readonly snippet?: string;\n readonly body?: string;\n}\n\nfunction buildGmailQ(query: QueryNode | undefined): string {\n if (!query) return '';\n const emitted = toGmailQuery(query);\n return emitted?.q ?? '';\n}\n\nexport interface GmailSearchResult {\n readonly messages: gmail_v1.Schema$Message[]; // Raw Gmail API messages for transformation by caller\n readonly nextPageToken: string | undefined;\n}\n\nexport async function searchMessages(gmail: gmail_v1.Gmail, opts: GmailSearchOptions): Promise<GmailSearchResult> {\n const { query, pageSize = 50, includeBody = false, pageToken, logger } = opts;\n const gmailQ = buildGmailQ(query);\n const metadataHeaders = ['Date', 'Subject', 'From', 'To', 'Cc', 'Bcc'];\n // Always fetch metadata headers - body is additional content, not a replacement for headers\n const pageParams: FetchMessagesPageParams = {\n gmailQ,\n pageSize,\n body: includeBody,\n metadataHeaders,\n pageToken,\n logger,\n };\n const result = await fetchMessagesPage(gmail, pageParams);\n\n // Return raw Gmail messages - transformation happens in caller\n return {\n messages: result.messages,\n nextPageToken: result.nextPageToken,\n };\n}\n"],"names":["fetchMessagesPage","toGmailQuery","buildGmailQ","query","emitted","q","searchMessages","gmail","opts","pageSize","includeBody","pageToken","logger","gmailQ","metadataHeaders","pageParams","body","result","messages","nextPageToken"],"mappings":"AAGA,SAAuCA,iBAAiB,QAAQ,kBAAkB;AAClF,SAASC,YAAY,QAAQ,qBAAqB;AAyBlD,SAASC,YAAYC,KAA4B;;IAC/C,IAAI,CAACA,OAAO,OAAO;IACnB,MAAMC,UAAUH,aAAaE;IAC7B,eAAOC,oBAAAA,8BAAAA,QAASC,CAAC,uCAAI;AACvB;AAOA,OAAO,eAAeC,eAAeC,KAAqB,EAAEC,IAAwB;IAClF,MAAM,EAAEL,KAAK,EAAEM,WAAW,EAAE,EAAEC,cAAc,KAAK,EAAEC,SAAS,EAAEC,MAAM,EAAE,GAAGJ;IACzE,MAAMK,SAASX,YAAYC;IAC3B,MAAMW,kBAAkB;QAAC;QAAQ;QAAW;QAAQ;QAAM;QAAM;KAAM;IACtE,4FAA4F;IAC5F,MAAMC,aAAsC;QAC1CF;QACAJ;QACAO,MAAMN;QACNI;QACAH;QACAC;IACF;IACA,MAAMK,SAAS,MAAMjB,kBAAkBO,OAAOQ;IAE9C,+DAA+D;IAC/D,OAAO;QACLG,UAAUD,OAAOC,QAAQ;QACzBC,eAAeF,OAAOE,aAAa;IACrC;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/index.ts"],"sourcesContent":["import { createConfig, handleVersionHelp } from './setup/config.js';\nimport { createHTTPServer } from './setup/http.js';\nimport { createStdioServer } from './setup/stdio.js';\nimport type { ServerConfig } from './types.js';\n\nexport { GOOGLE_SCOPE } from './constants.ts';\nexport * as mcp from './mcp/index.js';\nexport * as schemas from './schemas/index.js';\nexport * as setup from './setup/index.js';\nexport * from './types.js';\n\nexport async function startServer(config: ServerConfig): Promise<void> {\n const { logger, close } = config.transport.type === 'stdio' ? await createStdioServer(config) : await createHTTPServer(config);\n\n process.on('SIGINT', async () => {\n await close();\n process.exit(0);\n });\n\n logger.info(`Server started with ${config.transport.type} transport`);\n await new Promise(() => {});\n}\n\nexport default async function main(): Promise<void> {\n // Check for help/version flags FIRST, before config parsing\n const versionHelpResult = handleVersionHelp(process.argv);\n if (versionHelpResult.handled) {\n console.log(versionHelpResult.output);\n process.exit(0);\n }\n\n // Only parse config if no help/version flags\n const config = createConfig();\n await startServer(config);\n}\n\nif (process.argv[1] === new URL(import.meta.url).pathname) {\n main();\n}\n"],"names":["createConfig","handleVersionHelp","createHTTPServer","createStdioServer","GOOGLE_SCOPE","mcp","schemas","setup","startServer","config","logger","close","transport","type","process","on","exit","info","Promise","main","versionHelpResult","argv","handled","console","log","output","URL","url","pathname"],"mappings":"AAAA,SAASA,YAAY,EAAEC,iBAAiB,QAAQ,oBAAoB;AACpE,SAASC,gBAAgB,QAAQ,kBAAkB;AACnD,SAASC,iBAAiB,QAAQ,mBAAmB;AAGrD,SAASC,YAAY,QAAQ,iBAAiB;AAC9C,sBAAqB,iBAAiB;AAAtC,SAAO,QAAKC,GAAG,GAAuB;AACtC,0BAAyB,qBAAqB;AAA9C,SAAO,YAAKC,OAAO,GAA2B;AAC9C,wBAAuB,mBAAmB;AAA1C,SAAO,UAAKC,KAAK,GAAyB;AAC1C,cAAc,aAAa;AAE3B,OAAO,eAAeC,YAAYC,MAAoB;IACpD,MAAM,EAAEC,MAAM,EAAEC,KAAK,EAAE,GAAGF,OAAOG,SAAS,CAACC,IAAI,KAAK,UAAU,MAAMV,kBAAkBM,UAAU,MAAMP,iBAAiBO;IAEvHK,QAAQC,EAAE,CAAC,UAAU;QACnB,MAAMJ;QACNG,QAAQE,IAAI,CAAC;IACf;IAEAN,OAAOO,IAAI,CAAC,CAAC,oBAAoB,EAAER,OAAOG,SAAS,CAACC,IAAI,CAAC,UAAU,CAAC;IACpE,MAAM,IAAIK,QAAQ,KAAO;AAC3B;AAEA,eAAe,eAAeC;IAC5B,4DAA4D;IAC5D,MAAMC,oBAAoBnB,kBAAkBa,QAAQO,IAAI;IACxD,IAAID,kBAAkBE,OAAO,EAAE;QAC7BC,QAAQC,GAAG,CAACJ,kBAAkBK,MAAM;QACpCX,QAAQE,IAAI,CAAC;IACf;IAEA,6CAA6C;IAC7C,MAAMP,SAAST;IACf,MAAMQ,YAAYC;AACpB;AAEA,IAAIK,QAAQO,IAAI,CAAC,EAAE,KAAK,IAAIK,IAAI,YAAYC,GAAG,EAAEC,QAAQ,EAAE;IACzDT;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/index.ts"],"sourcesContent":["import { createConfig, handleVersionHelp } from './setup/config.ts';\nimport { createHTTPServer } from './setup/http.ts';\nimport { createStdioServer } from './setup/stdio.ts';\nimport type { ServerConfig } from './types.ts';\n\nexport { GOOGLE_SCOPE } from './constants.ts';\nexport * as mcp from './mcp/index.ts';\nexport * as schemas from './schemas/index.ts';\nexport * as setup from './setup/index.ts';\nexport * from './types.ts';\n\nexport async function startServer(config: ServerConfig): Promise<void> {\n const { logger, close } = config.transport.type === 'stdio' ? await createStdioServer(config) : await createHTTPServer(config);\n\n process.on('SIGINT', async () => {\n await close();\n process.exit(0);\n });\n\n logger.info(`Server started with ${config.transport.type} transport`);\n await new Promise(() => {});\n}\n\nexport default async function main(): Promise<void> {\n // Check for help/version flags FIRST, before config parsing\n const versionHelpResult = handleVersionHelp(process.argv);\n if (versionHelpResult.handled) {\n console.log(versionHelpResult.output);\n process.exit(0);\n }\n\n // Only parse config if no help/version flags\n const config = createConfig();\n await startServer(config);\n}\n\nif (process.argv[1] === new URL(import.meta.url).pathname) {\n main();\n}\n"],"names":["createConfig","handleVersionHelp","createHTTPServer","createStdioServer","GOOGLE_SCOPE","mcp","schemas","setup","startServer","config","logger","close","transport","type","process","on","exit","info","Promise","main","versionHelpResult","argv","handled","console","log","output","URL","url","pathname"],"mappings":"AAAA,SAASA,YAAY,EAAEC,iBAAiB,QAAQ,oBAAoB;AACpE,SAASC,gBAAgB,QAAQ,kBAAkB;AACnD,SAASC,iBAAiB,QAAQ,mBAAmB;AAGrD,SAASC,YAAY,QAAQ,iBAAiB;AAC9C,sBAAqB,iBAAiB;AAAtC,SAAO,QAAKC,GAAG,GAAuB;AACtC,0BAAyB,qBAAqB;AAA9C,SAAO,YAAKC,OAAO,GAA2B;AAC9C,wBAAuB,mBAAmB;AAA1C,SAAO,UAAKC,KAAK,GAAyB;AAC1C,cAAc,aAAa;AAE3B,OAAO,eAAeC,YAAYC,MAAoB;IACpD,MAAM,EAAEC,MAAM,EAAEC,KAAK,EAAE,GAAGF,OAAOG,SAAS,CAACC,IAAI,KAAK,UAAU,MAAMV,kBAAkBM,UAAU,MAAMP,iBAAiBO;IAEvHK,QAAQC,EAAE,CAAC,UAAU;QACnB,MAAMJ;QACNG,QAAQE,IAAI,CAAC;IACf;IAEAN,OAAOO,IAAI,CAAC,CAAC,oBAAoB,EAAER,OAAOG,SAAS,CAACC,IAAI,CAAC,UAAU,CAAC;IACpE,MAAM,IAAIK,QAAQ,KAAO;AAC3B;AAEA,eAAe,eAAeC;IAC5B,4DAA4D;IAC5D,MAAMC,oBAAoBnB,kBAAkBa,QAAQO,IAAI;IACxD,IAAID,kBAAkBE,OAAO,EAAE;QAC7BC,QAAQC,GAAG,CAACJ,kBAAkBK,MAAM;QACpCX,QAAQE,IAAI,CAAC;IACf;IAEA,6CAA6C;IAC7C,MAAMP,SAAST;IACf,MAAMQ,YAAYC;AACpB;AAEA,IAAIK,QAAQO,IAAI,CAAC,EAAE,KAAK,IAAIK,IAAI,YAAYC,GAAG,EAAEC,QAAQ,EAAE;IACzDT;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/labels/gmail-labels.ts"],"sourcesContent":["import type { gmail_v1 } from 'googleapis';\n\nexport async function ensureLabelId(gmail: gmail_v1.Gmail, userId: string, labelName: string): Promise<string> {\n // Built-in system labels: pass through by name\n const builtInLabels: Record<string, string> = {\n INBOX: 'INBOX',\n SPAM: 'SPAM',\n TRASH: 'TRASH',\n UNREAD: 'UNREAD',\n STARRED: 'STARRED',\n IMPORTANT: 'IMPORTANT',\n SENT: 'SENT',\n DRAFT: 'DRAFT',\n CATEGORY_PERSONAL: 'CATEGORY_PERSONAL',\n CATEGORY_SOCIAL: 'CATEGORY_SOCIAL',\n CATEGORY_PROMOTIONS: 'CATEGORY_PROMOTIONS',\n CATEGORY_UPDATES: 'CATEGORY_UPDATES',\n CATEGORY_FORUMS: 'CATEGORY_FORUMS',\n };\n\n const upper = labelName.toUpperCase();\n if (builtInLabels[upper]) return builtInLabels[upper];\n\n // Try to find an existing user label by name\n const listed = await gmail.users.labels.list({ userId });\n const labels = Array.isArray(listed?.data?.labels) ? listed.data.labels : [];\n const existing = labels.find((l: unknown) => {\n const label = l as { name?: unknown; id?: unknown };\n return label?.name === labelName;\n });\n const existingTyped = existing as { id?: unknown } | undefined;\n if (existingTyped?.id) return String(existingTyped.id);\n\n // Create the label if it doesn't exist\n const created = await gmail.users.labels.create({\n userId,\n requestBody: {\n name: labelName,\n labelListVisibility: 'labelShow',\n messageListVisibility: 'show',\n },\n });\n if (!created?.data?.id) throw new Error('Failed to create label');\n return created.data.id as string;\n}\n"],"names":["ensureLabelId","gmail","userId","labelName","listed","created","builtInLabels","INBOX","SPAM","TRASH","UNREAD","STARRED","IMPORTANT","SENT","DRAFT","CATEGORY_PERSONAL","CATEGORY_SOCIAL","CATEGORY_PROMOTIONS","CATEGORY_UPDATES","CATEGORY_FORUMS","upper","toUpperCase","users","labels","list","Array","isArray","data","existing","find","l","label","name","existingTyped","id","String","create","requestBody","labelListVisibility","messageListVisibility","Error"],"mappings":"AAEA,OAAO,eAAeA,cAAcC,KAAqB,EAAEC,MAAc,EAAEC,SAAiB;QAuB7DC,cAiBxBC;IAvCL,+CAA+C;IAC/C,MAAMC,gBAAwC;QAC5CC,OAAO;QACPC,MAAM;QACNC,OAAO;QACPC,QAAQ;QACRC,SAAS;QACTC,WAAW;QACXC,MAAM;QACNC,OAAO;QACPC,mBAAmB;QACnBC,iBAAiB;QACjBC,qBAAqB;QACrBC,kBAAkB;QAClBC,iBAAiB;IACnB;IAEA,MAAMC,QAAQjB,UAAUkB,WAAW;IACnC,IAAIf,aAAa,CAACc,MAAM,EAAE,OAAOd,aAAa,CAACc,MAAM;IAErD,6CAA6C;IAC7C,MAAMhB,SAAS,MAAMH,MAAMqB,KAAK,CAACC,MAAM,CAACC,IAAI,CAAC;QAAEtB;IAAO;IACtD,MAAMqB,SAASE,MAAMC,OAAO,CAACtB,mBAAAA,8BAAAA,eAAAA,OAAQuB,IAAI,cAAZvB,mCAAAA,aAAcmB,MAAM,IAAInB,OAAOuB,IAAI,CAACJ,MAAM,GAAG,EAAE;IAC5E,MAAMK,WAAWL,OAAOM,IAAI,CAAC,CAACC;QAC5B,MAAMC,QAAQD;QACd,OAAOC,CAAAA,kBAAAA,4BAAAA,MAAOC,IAAI,MAAK7B;IACzB;IACA,MAAM8B,gBAAgBL;IACtB,IAAIK,0BAAAA,oCAAAA,cAAeC,EAAE,EAAE,OAAOC,OAAOF,cAAcC,EAAE;IAErD,uCAAuC;IACvC,MAAM7B,UAAU,MAAMJ,MAAMqB,KAAK,CAACC,MAAM,CAACa,MAAM,CAAC;QAC9ClC;QACAmC,aAAa;YACXL,MAAM7B;YACNmC,qBAAqB;YACrBC,uBAAuB;QACzB;IACF;IACA,IAAI,EAAClC,oBAAAA,+BAAAA,gBAAAA,QAASsB,IAAI,cAAbtB,oCAAAA,cAAe6B,EAAE,GAAE,MAAM,IAAIM,MAAM;IACxC,OAAOnC,QAAQsB,IAAI,CAACO,EAAE;AACxB"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/labels/gmail-labels.ts"],"sourcesContent":["import type { gmail_v1 } from 'googleapis';\n\nexport async function ensureLabelId(gmail: gmail_v1.Gmail, userId: string, labelName: string): Promise<string> {\n // Built-in system labels: pass through by name\n const builtInLabels: Record<string, string> = {\n INBOX: 'INBOX',\n SPAM: 'SPAM',\n TRASH: 'TRASH',\n UNREAD: 'UNREAD',\n STARRED: 'STARRED',\n IMPORTANT: 'IMPORTANT',\n SENT: 'SENT',\n DRAFT: 'DRAFT',\n CATEGORY_PERSONAL: 'CATEGORY_PERSONAL',\n CATEGORY_SOCIAL: 'CATEGORY_SOCIAL',\n CATEGORY_PROMOTIONS: 'CATEGORY_PROMOTIONS',\n CATEGORY_UPDATES: 'CATEGORY_UPDATES',\n CATEGORY_FORUMS: 'CATEGORY_FORUMS',\n };\n\n const upper = labelName.toUpperCase();\n if (builtInLabels[upper]) return builtInLabels[upper];\n\n // Try to find an existing user label by name\n const listed = await gmail.users.labels.list({ userId });\n const labels = Array.isArray(listed?.data?.labels) ? listed.data.labels : [];\n const existing = labels.find((l: unknown) => {\n const label = l as { name?: unknown; id?: unknown };\n return label?.name === labelName;\n });\n const existingTyped = existing as { id?: unknown } | undefined;\n if (existingTyped?.id) return String(existingTyped.id);\n\n // Create the label if it doesn't exist\n const created = await gmail.users.labels.create({\n userId,\n requestBody: {\n name: labelName,\n labelListVisibility: 'labelShow',\n messageListVisibility: 'show',\n },\n });\n if (!created?.data?.id) throw new Error('Failed to create label');\n return created.data.id as string;\n}\n"],"names":["ensureLabelId","gmail","userId","labelName","listed","created","builtInLabels","INBOX","SPAM","TRASH","UNREAD","STARRED","IMPORTANT","SENT","DRAFT","CATEGORY_PERSONAL","CATEGORY_SOCIAL","CATEGORY_PROMOTIONS","CATEGORY_UPDATES","CATEGORY_FORUMS","upper","toUpperCase","users","labels","list","Array","isArray","data","existing","find","l","label","name","existingTyped","id","String","create","requestBody","labelListVisibility","messageListVisibility","Error"],"mappings":"AAEA,OAAO,eAAeA,cAAcC,KAAqB,EAAEC,MAAc,EAAEC,SAAiB;QAuB7DC,cAiBxBC;IAvCL,+CAA+C;IAC/C,MAAMC,gBAAwC;QAC5CC,OAAO;QACPC,MAAM;QACNC,OAAO;QACPC,QAAQ;QACRC,SAAS;QACTC,WAAW;QACXC,MAAM;QACNC,OAAO;QACPC,mBAAmB;QACnBC,iBAAiB;QACjBC,qBAAqB;QACrBC,kBAAkB;QAClBC,iBAAiB;IACnB;IAEA,MAAMC,QAAQjB,UAAUkB,WAAW;IACnC,IAAIf,aAAa,CAACc,MAAM,EAAE,OAAOd,aAAa,CAACc,MAAM;IAErD,6CAA6C;IAC7C,MAAMhB,SAAS,MAAMH,MAAMqB,KAAK,CAACC,MAAM,CAACC,IAAI,CAAC;QAAEtB;IAAO;IACtD,MAAMqB,SAASE,MAAMC,OAAO,CAACtB,mBAAAA,8BAAAA,eAAAA,OAAQuB,IAAI,cAAZvB,mCAAAA,aAAcmB,MAAM,IAAInB,OAAOuB,IAAI,CAACJ,MAAM,GAAG,EAAE;IAC5E,MAAMK,WAAWL,OAAOM,IAAI,CAAC,CAACC;QAC5B,MAAMC,QAAQD;QACd,OAAOC,CAAAA,kBAAAA,4BAAAA,MAAOC,IAAI,MAAK7B;IACzB;IACA,MAAM8B,gBAAgBL;IACtB,IAAIK,0BAAAA,oCAAAA,cAAeC,EAAE,EAAE,OAAOC,OAAOF,cAAcC,EAAE;IAErD,uCAAuC;IACvC,MAAM7B,UAAU,MAAMJ,MAAMqB,KAAK,CAACC,MAAM,CAACa,MAAM,CAAC;QAC9ClC;QACAmC,aAAa;YACXL,MAAM7B;YACNmC,qBAAqB;YACrBC,uBAAuB;QACzB;IACF;IACA,IAAI,EAAClC,oBAAAA,+BAAAA,gBAAAA,QAASsB,IAAI,cAAbtB,oCAAAA,cAAe6B,EAAE,GAAE,MAAM,IAAIM,MAAM;IACxC,OAAOnC,QAAQsB,IAAI,CAACO,EAAE;AACxB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/lib/base64-encoding.ts"],"sourcesContent":["import { safeBase64UrlDecode } from '@mcp-z/email';\n\nexport function safeBase64Decode(raw?: string): string {\n if (!raw) return '';\n try {\n return safeBase64UrlDecode(raw);\n } catch {\n // Fallback to original input if decoding fails\n return String(raw);\n }\n}\n\nexport function b64url(input: string): string {\n return Buffer.from(input).toString('base64').replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n"],"names":["safeBase64UrlDecode","safeBase64Decode","raw","String","b64url","input","Buffer","from","toString","replace"],"mappings":"AAAA,SAASA,mBAAmB,QAAQ,eAAe;AAEnD,OAAO,SAASC,iBAAiBC,GAAY;IAC3C,IAAI,CAACA,KAAK,OAAO;IACjB,IAAI;QACF,OAAOF,oBAAoBE;IAC7B,EAAE,OAAM;QACN,+CAA+C;QAC/C,OAAOC,OAAOD;IAChB;AACF;AAEA,OAAO,SAASE,OAAOC,KAAa;IAClC,OAAOC,OAAOC,IAAI,CAACF,OAAOG,QAAQ,CAAC,UAAUC,OAAO,CAAC,OAAO,KAAKA,OAAO,CAAC,OAAO,KAAKA,OAAO,CAAC,OAAO;AACtG"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/lib/base64-encoding.ts"],"sourcesContent":["import { safeBase64UrlDecode } from '@mcp-z/email';\n\nexport function safeBase64Decode(raw?: string): string {\n if (!raw) return '';\n try {\n return safeBase64UrlDecode(raw);\n } catch {\n // Fallback to original input if decoding fails\n return String(raw);\n }\n}\n\nexport function b64url(input: string): string {\n return Buffer.from(input).toString('base64').replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n"],"names":["safeBase64UrlDecode","safeBase64Decode","raw","String","b64url","input","Buffer","from","toString","replace"],"mappings":"AAAA,SAASA,mBAAmB,QAAQ,eAAe;AAEnD,OAAO,SAASC,iBAAiBC,GAAY;IAC3C,IAAI,CAACA,KAAK,OAAO;IACjB,IAAI;QACF,OAAOF,oBAAoBE;IAC7B,EAAE,OAAM;QACN,+CAA+C;QAC/C,OAAOC,OAAOD;IAChB;AACF;AAEA,OAAO,SAASE,OAAOC,KAAa;IAClC,OAAOC,OAAOC,IAAI,CAACF,OAAOG,QAAQ,CAAC,UAAUC,OAAO,CAAC,OAAO,KAAKA,OAAO,CAAC,OAAO,KAAKA,OAAO,CAAC,OAAO;AACtG"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/lib/create-store.ts"],"sourcesContent":["import type Keyv from 'keyv';\nimport keyvRegistry from 'keyv-registry';\n\nexport default async function createStore<T>(uri: string): Promise<Keyv<T>> {\n const store = await keyvRegistry<T>(uri);\n if (!store) throw new Error(`Failed to create store for URI: ${uri}`);\n return store;\n}\n"],"names":["keyvRegistry","createStore","uri","store","Error"],"mappings":"AACA,OAAOA,kBAAkB,gBAAgB;AAEzC,eAAe,eAAeC,YAAeC,GAAW;IACtD,MAAMC,QAAQ,MAAMH,aAAgBE;IACpC,IAAI,CAACC,OAAO,MAAM,IAAIC,MAAM,CAAC,gCAAgC,EAAEF,KAAK;IACpE,OAAOC;AACT"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/lib/create-store.ts"],"sourcesContent":["import type Keyv from 'keyv';\nimport keyvRegistry from 'keyv-registry';\n\nexport default async function createStore<T>(uri: string): Promise<Keyv<T>> {\n const store = await keyvRegistry<T>(uri);\n if (!store) throw new Error(`Failed to create store for URI: ${uri}`);\n return store;\n}\n"],"names":["keyvRegistry","createStore","uri","store","Error"],"mappings":"AACA,OAAOA,kBAAkB,gBAAgB;AAEzC,eAAe,eAAeC,YAAeC,GAAW;IACtD,MAAMC,QAAQ,MAAMH,aAAgBE;IACpC,IAAI,CAACC,OAAO,MAAM,IAAIC,MAAM,CAAC,gCAAgC,EAAEF,KAAK;IACpE,OAAOC;AACT"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/lib/date-conversion.ts"],"sourcesContent":["export function toIsoUtc(dateStr?: string): string | undefined {\n if (!dateStr) return undefined;\n const d = new Date(dateStr);\n return Number.isNaN(d.getTime()) ? undefined : d.toISOString();\n}\n"],"names":["toIsoUtc","dateStr","undefined","d","Date","Number","isNaN","getTime","toISOString"],"mappings":"AAAA,OAAO,SAASA,SAASC,OAAgB;IACvC,IAAI,CAACA,SAAS,OAAOC;IACrB,MAAMC,IAAI,IAAIC,KAAKH;IACnB,OAAOI,OAAOC,KAAK,CAACH,EAAEI,OAAO,MAAML,YAAYC,EAAEK,WAAW;AAC9D"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/lib/date-conversion.ts"],"sourcesContent":["export function toIsoUtc(dateStr?: string): string | undefined {\n if (!dateStr) return undefined;\n const d = new Date(dateStr);\n return Number.isNaN(d.getTime()) ? undefined : d.toISOString();\n}\n"],"names":["toIsoUtc","dateStr","undefined","d","Date","Number","isNaN","getTime","toISOString"],"mappings":"AAAA,OAAO,SAASA,SAASC,OAAgB;IACvC,IAAI,CAACA,SAAS,OAAOC;IACrB,MAAMC,IAAI,IAAIC,KAAKH;IACnB,OAAOI,OAAOC,KAAK,CAACH,EAAEI,OAAO,MAAML,YAAYC,EAAEK,WAAW;AAC9D"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/lib/messages-to-row.ts"],"sourcesContent":["import { extractCurrentMessageFromHtmlToText, extractCurrentMessageFromText, formatAddresses, normalizeDateToISO } from '@mcp-z/email';\n\nexport interface GmailMessage {\n id?: string;\n threadId?: string;\n labelIds?: string[];\n snippet?: string;\n payload?: {\n headers?: Array<{ name: string; value: string }>;\n body?: {\n data?: string;\n };\n parts?: Array<{\n mimeType: string;\n body?: {\n data?: string;\n };\n }>;\n };\n}\n\ninterface GmailEmailSummary {\n id: string;\n provider: 'gmail';\n threadId?: string | undefined;\n date?: string | undefined;\n from?: string | undefined;\n fromName?: string | undefined;\n to?: string | undefined;\n cc?: string | undefined;\n bcc?: string | undefined;\n subject?: string | undefined;\n snippet?: string | undefined;\n body?: string | undefined;\n}\n\ninterface FormatOptions {\n body?: boolean;\n addressFormat?: 'raw' | 'name' | 'email';\n}\n\nfunction getHeader(headers: Array<{ name: string; value: string }> | undefined, name: string): string {\n if (!headers || !Array.isArray(headers)) return '';\n const header = headers.find((h) => h.name.toLowerCase() === name.toLowerCase());\n return header ? header.value : '';\n}\n\ninterface AddressToken {\n name?: string | undefined;\n email: string;\n}\n\nfunction parseEmailHeader(headerValue: string): AddressToken[] {\n if (!headerValue) return [];\n\n const parts: string[] = [];\n let current = '';\n let inQuotes = false;\n\n for (let i = 0; i < headerValue.length; i++) {\n const char = headerValue[i];\n if (char === '\"') {\n inQuotes = !inQuotes;\n current += char;\n } else if (char === ',' && !inQuotes) {\n parts.push(current.trim());\n current = '';\n } else {\n current += char;\n }\n }\n\n if (current) parts.push(current.trim());\n\n return parts\n .map((part): AddressToken => {\n const match = part.match(/^(?:\"?([^\"]*)\"? <([^>]+)>|([^,]+))$/);\n if (match) {\n if (match[2]) {\n return { name: match[1] || undefined, email: match[2] };\n }\n return { email: match[3] || '' };\n }\n return { email: part.trim() };\n })\n .filter((token) => !!token.email); // Type guard to ensure email is always present\n}\n\nfunction formatRecipientHeader(headerValue: string, mode: 'raw' | 'name' | 'email' = 'email'): string {\n const addresses = parseEmailHeader(headerValue);\n return formatAddresses(addresses, mode);\n}\n\n/**\n * Sanitizes email body text for Google Sheets export by enforcing cell character limits.\n * Google Sheets API limits cells to 50,000 characters - this prevents API errors during export.\n */\nfunction sanitizeForSheetsExport(text: string): string {\n // Google Sheets has a 50,000 character limit per cell\n // Leave some buffer for safety\n const GOOGLE_SHEETS_CELL_LIMIT = 49000;\n\n if (text.length <= GOOGLE_SHEETS_CELL_LIMIT) return text;\n\n // Truncate and add indication that it was truncated\n const truncated = text.substring(0, GOOGLE_SHEETS_CELL_LIMIT - 100);\n return `${truncated}\\n\\n[...content truncated to fit Google Sheets cell limit...]`;\n}\n\nexport function toRowFromGmail(msg: GmailMessage = {}, opts: FormatOptions = { body: false, addressFormat: 'email' }) {\n const id = msg.id ?? '';\n const provider = 'gmail';\n const threadId = msg.threadId ?? '';\n const fmt = opts.addressFormat || 'email';\n\n const headers = msg.payload?.headers || [];\n const toHeader = getHeader(headers, 'To');\n const fromHeader = getHeader(headers, 'From');\n const ccHeader = getHeader(headers, 'Cc');\n const bccHeader = getHeader(headers, 'Bcc');\n const dateHeader = getHeader(headers, 'Date');\n const subjectHeader = getHeader(headers, 'Subject');\n\n const to = formatRecipientHeader(toHeader, fmt);\n const from = formatRecipientHeader(fromHeader, fmt);\n const cc = formatRecipientHeader(ccHeader, fmt);\n const bcc = formatRecipientHeader(bccHeader, fmt);\n const date = normalizeDateToISO(dateHeader) ?? '';\n const subject = subjectHeader ?? '';\n\n const labels = (msg.labelIds || []).join(', ');\n const snippet = msg.snippet ?? '';\n\n let bodyFull = '';\n if (opts.body) {\n if (msg.payload) {\n if (msg.payload.body?.data) {\n const rawBody = Buffer.from(msg.payload.body.data, 'base64').toString('utf-8');\n bodyFull = extractCurrentMessageFromText(rawBody);\n } else if (msg.payload.parts && Array.isArray(msg.payload.parts)) {\n for (const part of msg.payload.parts) {\n if (part.body?.data) {\n const rawBody = Buffer.from(part.body.data, 'base64').toString('utf-8');\n if (part.mimeType === 'text/plain') {\n bodyFull = extractCurrentMessageFromText(rawBody);\n break;\n }\n if (part.mimeType === 'text/html') {\n bodyFull = extractCurrentMessageFromHtmlToText(rawBody);\n break;\n }\n }\n }\n }\n }\n }\n\n return [id, provider, threadId, to, from, cc, bcc, date, subject, labels, snippet, sanitizeForSheetsExport(bodyFull)];\n}\n\nexport function toRowFromGmailSummary(msg: GmailEmailSummary, opts: FormatOptions = { body: false, addressFormat: 'email' }) {\n const id = msg.id ?? '';\n const provider = msg.provider || 'gmail';\n const threadId = msg.threadId ?? '';\n const fmt = opts.addressFormat || 'email';\n\n const to = formatRecipientHeader(msg.to ?? '', fmt);\n const from = formatRecipientHeader(msg.from ?? '', fmt);\n const cc = formatRecipientHeader(msg.cc ?? '', fmt);\n const bcc = formatRecipientHeader(msg.bcc ?? '', fmt);\n const date = normalizeDateToISO(msg.date) ?? '';\n const subject = msg.subject ?? '';\n const labels = '';\n const snippet = msg.snippet ?? '';\n\n let bodyFull = '';\n if (opts.body && msg.body) {\n bodyFull = extractCurrentMessageFromText(msg.body);\n }\n\n return [id, provider, threadId, to, from, cc, bcc, date, subject, labels, snippet, sanitizeForSheetsExport(bodyFull)];\n}\n\ninterface ClientSideFilters {\n subjectIncludes?: string[];\n bodyIncludes?: string[];\n textIncludes?: string[];\n fromIncludes?: string[];\n toIncludes?: string[];\n ccIncludes?: string[];\n bccIncludes?: string[];\n}\n\ninterface FilterContent {\n subject?: string;\n snippetOrPreview?: string;\n fullBody?: string;\n from?: string;\n to?: string;\n cc?: string;\n bcc?: string;\n}\n\nexport function filterClientSide(filters: ClientSideFilters, { subject = '', snippetOrPreview = '', fullBody = '', from = '', to = '', cc = '', bcc = '' }: FilterContent = {}) {\n const lower = (a: string[]) => a.map((t) => String(t).toLowerCase());\n const subjectTokens = lower(filters.subjectIncludes || []);\n const bodyTokens = lower(filters.bodyIncludes || []);\n const textTokens = lower(filters.textIncludes || []);\n const fromTokens = lower(filters.fromIncludes || []);\n const toCredentials = lower(filters.toIncludes || []);\n const ccTokens = lower(filters.ccIncludes || []);\n const bccTokens = lower(filters.bccIncludes || []);\n\n const s = String(subject ?? '').toLowerCase();\n const b = String((fullBody || snippetOrPreview) ?? '').toLowerCase();\n const f = String(from ?? '').toLowerCase();\n const t = String(to ?? '').toLowerCase();\n const c = String(cc ?? '').toLowerCase();\n const bc = String(bcc ?? '').toLowerCase();\n\n const anyIncludes = (val: string, tokens: string[]) => (tokens.length === 1 ? val.includes(tokens[0] ?? '') : tokens.some((token) => val.includes(token)));\n const subjectOk = subjectTokens.length ? anyIncludes(s, subjectTokens) : true;\n const bodyOk = bodyTokens.length ? anyIncludes(b, bodyTokens) : true;\n const textOk = textTokens.length ? textTokens.some((token) => s.includes(token) || b.includes(token)) : true;\n const fromOk = fromTokens.length ? anyIncludes(f, fromTokens) : true;\n const toOk = toCredentials.length ? anyIncludes(t, toCredentials) : true;\n const ccOk = ccTokens.length ? anyIncludes(c, ccTokens) : true;\n const bccOk = bccTokens.length ? anyIncludes(bc, bccTokens) : true;\n\n return subjectOk && bodyOk && textOk && fromOk && toOk && ccOk && bccOk;\n}\n"],"names":["extractCurrentMessageFromHtmlToText","extractCurrentMessageFromText","formatAddresses","normalizeDateToISO","getHeader","headers","name","Array","isArray","header","find","h","toLowerCase","value","parseEmailHeader","headerValue","parts","current","inQuotes","i","length","char","push","trim","map","part","match","undefined","email","filter","token","formatRecipientHeader","mode","addresses","sanitizeForSheetsExport","text","GOOGLE_SHEETS_CELL_LIMIT","truncated","substring","toRowFromGmail","msg","opts","body","addressFormat","id","provider","threadId","fmt","payload","toHeader","fromHeader","ccHeader","bccHeader","dateHeader","subjectHeader","to","from","cc","bcc","date","subject","labels","labelIds","join","snippet","bodyFull","data","rawBody","Buffer","toString","mimeType","toRowFromGmailSummary","filterClientSide","filters","snippetOrPreview","fullBody","lower","a","t","String","subjectTokens","subjectIncludes","bodyTokens","bodyIncludes","textTokens","textIncludes","fromTokens","fromIncludes","toCredentials","toIncludes","ccTokens","ccIncludes","bccTokens","bccIncludes","s","b","f","c","bc","anyIncludes","val","tokens","includes","some","subjectOk","bodyOk","textOk","fromOk","toOk","ccOk","bccOk"],"mappings":"AAAA,SAASA,mCAAmC,EAAEC,6BAA6B,EAAEC,eAAe,EAAEC,kBAAkB,QAAQ,eAAe;AAyCvI,SAASC,UAAUC,OAA2D,EAAEC,IAAY;IAC1F,IAAI,CAACD,WAAW,CAACE,MAAMC,OAAO,CAACH,UAAU,OAAO;IAChD,MAAMI,SAASJ,QAAQK,IAAI,CAAC,CAACC,IAAMA,EAAEL,IAAI,CAACM,WAAW,OAAON,KAAKM,WAAW;IAC5E,OAAOH,SAASA,OAAOI,KAAK,GAAG;AACjC;AAOA,SAASC,iBAAiBC,WAAmB;IAC3C,IAAI,CAACA,aAAa,OAAO,EAAE;IAE3B,MAAMC,QAAkB,EAAE;IAC1B,IAAIC,UAAU;IACd,IAAIC,WAAW;IAEf,IAAK,IAAIC,IAAI,GAAGA,IAAIJ,YAAYK,MAAM,EAAED,IAAK;QAC3C,MAAME,OAAON,WAAW,CAACI,EAAE;QAC3B,IAAIE,SAAS,KAAK;YAChBH,WAAW,CAACA;YACZD,WAAWI;QACb,OAAO,IAAIA,SAAS,OAAO,CAACH,UAAU;YACpCF,MAAMM,IAAI,CAACL,QAAQM,IAAI;YACvBN,UAAU;QACZ,OAAO;YACLA,WAAWI;QACb;IACF;IAEA,IAAIJ,SAASD,MAAMM,IAAI,CAACL,QAAQM,IAAI;IAEpC,OAAOP,MACJQ,GAAG,CAAC,CAACC;QACJ,MAAMC,QAAQD,KAAKC,KAAK,CAAC;QACzB,IAAIA,OAAO;YACT,IAAIA,KAAK,CAAC,EAAE,EAAE;gBACZ,OAAO;oBAAEpB,MAAMoB,KAAK,CAAC,EAAE,IAAIC;oBAAWC,OAAOF,KAAK,CAAC,EAAE;gBAAC;YACxD;YACA,OAAO;gBAAEE,OAAOF,KAAK,CAAC,EAAE,IAAI;YAAG;QACjC;QACA,OAAO;YAAEE,OAAOH,KAAKF,IAAI;QAAG;IAC9B,GACCM,MAAM,CAAC,CAACC,QAAU,CAAC,CAACA,MAAMF,KAAK,GAAG,+CAA+C;AACtF;AAEA,SAASG,sBAAsBhB,WAAmB,EAAEiB,OAAiC,OAAO;IAC1F,MAAMC,YAAYnB,iBAAiBC;IACnC,OAAOb,gBAAgB+B,WAAWD;AACpC;AAEA;;;CAGC,GACD,SAASE,wBAAwBC,IAAY;IAC3C,sDAAsD;IACtD,+BAA+B;IAC/B,MAAMC,2BAA2B;IAEjC,IAAID,KAAKf,MAAM,IAAIgB,0BAA0B,OAAOD;IAEpD,oDAAoD;IACpD,MAAME,YAAYF,KAAKG,SAAS,CAAC,GAAGF,2BAA2B;IAC/D,OAAO,GAAGC,UAAU,6DAA6D,CAAC;AACpF;AAEA,OAAO,SAASE,eAAeC,MAAoB,CAAC,CAAC,EAAEC,OAAsB;IAAEC,MAAM;IAAOC,eAAe;AAAQ,CAAC;QACvGH,SAEMA,eAeJrC,qBAIGqC;QAhBAA;IALhB,MAAMI,MAAKJ,UAAAA,IAAII,EAAE,cAANJ,qBAAAA,UAAU;IACrB,MAAMK,WAAW;IACjB,MAAMC,YAAWN,gBAAAA,IAAIM,QAAQ,cAAZN,2BAAAA,gBAAgB;IACjC,MAAMO,MAAMN,KAAKE,aAAa,IAAI;IAElC,MAAMtC,UAAUmC,EAAAA,eAAAA,IAAIQ,OAAO,cAAXR,mCAAAA,aAAanC,OAAO,KAAI,EAAE;IAC1C,MAAM4C,WAAW7C,UAAUC,SAAS;IACpC,MAAM6C,aAAa9C,UAAUC,SAAS;IACtC,MAAM8C,WAAW/C,UAAUC,SAAS;IACpC,MAAM+C,YAAYhD,UAAUC,SAAS;IACrC,MAAMgD,aAAajD,UAAUC,SAAS;IACtC,MAAMiD,gBAAgBlD,UAAUC,SAAS;IAEzC,MAAMkD,KAAKxB,sBAAsBkB,UAAUF;IAC3C,MAAMS,OAAOzB,sBAAsBmB,YAAYH;IAC/C,MAAMU,KAAK1B,sBAAsBoB,UAAUJ;IAC3C,MAAMW,MAAM3B,sBAAsBqB,WAAWL;IAC7C,MAAMY,QAAOxD,sBAAAA,mBAAmBkD,yBAAnBlD,iCAAAA,sBAAkC;IAC/C,MAAMyD,UAAUN,0BAAAA,2BAAAA,gBAAiB;IAEjC,MAAMO,SAAS,AAACrB,CAAAA,IAAIsB,QAAQ,IAAI,EAAE,AAAD,EAAGC,IAAI,CAAC;IACzC,MAAMC,WAAUxB,eAAAA,IAAIwB,OAAO,cAAXxB,0BAAAA,eAAe;IAE/B,IAAIyB,WAAW;IACf,IAAIxB,KAAKC,IAAI,EAAE;QACb,IAAIF,IAAIQ,OAAO,EAAE;gBACXR;YAAJ,KAAIA,oBAAAA,IAAIQ,OAAO,CAACN,IAAI,cAAhBF,wCAAAA,kBAAkB0B,IAAI,EAAE;gBAC1B,MAAMC,UAAUC,OAAOZ,IAAI,CAAChB,IAAIQ,OAAO,CAACN,IAAI,CAACwB,IAAI,EAAE,UAAUG,QAAQ,CAAC;gBACtEJ,WAAWhE,8BAA8BkE;YAC3C,OAAO,IAAI3B,IAAIQ,OAAO,CAAChC,KAAK,IAAIT,MAAMC,OAAO,CAACgC,IAAIQ,OAAO,CAAChC,KAAK,GAAG;gBAChE,KAAK,MAAMS,QAAQe,IAAIQ,OAAO,CAAChC,KAAK,CAAE;wBAChCS;oBAAJ,KAAIA,aAAAA,KAAKiB,IAAI,cAATjB,iCAAAA,WAAWyC,IAAI,EAAE;wBACnB,MAAMC,UAAUC,OAAOZ,IAAI,CAAC/B,KAAKiB,IAAI,CAACwB,IAAI,EAAE,UAAUG,QAAQ,CAAC;wBAC/D,IAAI5C,KAAK6C,QAAQ,KAAK,cAAc;4BAClCL,WAAWhE,8BAA8BkE;4BACzC;wBACF;wBACA,IAAI1C,KAAK6C,QAAQ,KAAK,aAAa;4BACjCL,WAAWjE,oCAAoCmE;4BAC/C;wBACF;oBACF;gBACF;YACF;QACF;IACF;IAEA,OAAO;QAACvB;QAAIC;QAAUC;QAAUS;QAAIC;QAAMC;QAAIC;QAAKC;QAAMC;QAASC;QAAQG;QAAS9B,wBAAwB+B;KAAU;AACvH;AAEA,OAAO,SAASM,sBAAsB/B,GAAsB,EAAEC,OAAsB;IAAEC,MAAM;IAAOC,eAAe;AAAQ,CAAC;QAC9GH,SAEMA,eAGgBA,SACEA,WACFA,SACCA,UACrBrC,qBACGqC,cAEAA;IAZhB,MAAMI,MAAKJ,UAAAA,IAAII,EAAE,cAANJ,qBAAAA,UAAU;IACrB,MAAMK,WAAWL,IAAIK,QAAQ,IAAI;IACjC,MAAMC,YAAWN,gBAAAA,IAAIM,QAAQ,cAAZN,2BAAAA,gBAAgB;IACjC,MAAMO,MAAMN,KAAKE,aAAa,IAAI;IAElC,MAAMY,KAAKxB,uBAAsBS,UAAAA,IAAIe,EAAE,cAANf,qBAAAA,UAAU,IAAIO;IAC/C,MAAMS,OAAOzB,uBAAsBS,YAAAA,IAAIgB,IAAI,cAARhB,uBAAAA,YAAY,IAAIO;IACnD,MAAMU,KAAK1B,uBAAsBS,UAAAA,IAAIiB,EAAE,cAANjB,qBAAAA,UAAU,IAAIO;IAC/C,MAAMW,MAAM3B,uBAAsBS,WAAAA,IAAIkB,GAAG,cAAPlB,sBAAAA,WAAW,IAAIO;IACjD,MAAMY,QAAOxD,sBAAAA,mBAAmBqC,IAAImB,IAAI,eAA3BxD,iCAAAA,sBAAgC;IAC7C,MAAMyD,WAAUpB,eAAAA,IAAIoB,OAAO,cAAXpB,0BAAAA,eAAe;IAC/B,MAAMqB,SAAS;IACf,MAAMG,WAAUxB,eAAAA,IAAIwB,OAAO,cAAXxB,0BAAAA,eAAe;IAE/B,IAAIyB,WAAW;IACf,IAAIxB,KAAKC,IAAI,IAAIF,IAAIE,IAAI,EAAE;QACzBuB,WAAWhE,8BAA8BuC,IAAIE,IAAI;IACnD;IAEA,OAAO;QAACE;QAAIC;QAAUC;QAAUS;QAAIC;QAAMC;QAAIC;QAAKC;QAAMC;QAASC;QAAQG;QAAS9B,wBAAwB+B;KAAU;AACvH;AAsBA,OAAO,SAASO,iBAAiBC,OAA0B,EAAE,EAAEb,UAAU,EAAE,EAAEc,mBAAmB,EAAE,EAAEC,WAAW,EAAE,EAAEnB,OAAO,EAAE,EAAED,KAAK,EAAE,EAAEE,KAAK,EAAE,EAAEC,MAAM,EAAE,EAAiB,GAAG,CAAC,CAAC;QAW1JiB;IAVlB,MAAMC,QAAQ,CAACC,IAAgBA,EAAErD,GAAG,CAAC,CAACsD,IAAMC,OAAOD,GAAGlE,WAAW;IACjE,MAAMoE,gBAAgBJ,MAAMH,QAAQQ,eAAe,IAAI,EAAE;IACzD,MAAMC,aAAaN,MAAMH,QAAQU,YAAY,IAAI,EAAE;IACnD,MAAMC,aAAaR,MAAMH,QAAQY,YAAY,IAAI,EAAE;IACnD,MAAMC,aAAaV,MAAMH,QAAQc,YAAY,IAAI,EAAE;IACnD,MAAMC,gBAAgBZ,MAAMH,QAAQgB,UAAU,IAAI,EAAE;IACpD,MAAMC,WAAWd,MAAMH,QAAQkB,UAAU,IAAI,EAAE;IAC/C,MAAMC,YAAYhB,MAAMH,QAAQoB,WAAW,IAAI,EAAE;IAEjD,MAAMC,IAAIf,OAAOnB,oBAAAA,qBAAAA,UAAW,IAAIhD,WAAW;IAC3C,MAAMmF,IAAIhB,QAAQJ,OAAAA,YAAYD,8BAAZC,kBAAAA,OAAiC,IAAI/D,WAAW;IAClE,MAAMoF,IAAIjB,OAAOvB,iBAAAA,kBAAAA,OAAQ,IAAI5C,WAAW;IACxC,MAAMkE,IAAIC,OAAOxB,eAAAA,gBAAAA,KAAM,IAAI3C,WAAW;IACtC,MAAMqF,IAAIlB,OAAOtB,eAAAA,gBAAAA,KAAM,IAAI7C,WAAW;IACtC,MAAMsF,KAAKnB,OAAOrB,gBAAAA,iBAAAA,MAAO,IAAI9C,WAAW;IAExC,MAAMuF,cAAc,CAACC,KAAaC;YAAyDA;eAAnCA,OAAOjF,MAAM,KAAK,IAAIgF,IAAIE,QAAQ,EAACD,WAAAA,MAAM,CAAC,EAAE,cAATA,sBAAAA,WAAa,MAAMA,OAAOE,IAAI,CAAC,CAACzE,QAAUsE,IAAIE,QAAQ,CAACxE;;IAClJ,MAAM0E,YAAYxB,cAAc5D,MAAM,GAAG+E,YAAYL,GAAGd,iBAAiB;IACzE,MAAMyB,SAASvB,WAAW9D,MAAM,GAAG+E,YAAYJ,GAAGb,cAAc;IAChE,MAAMwB,SAAStB,WAAWhE,MAAM,GAAGgE,WAAWmB,IAAI,CAAC,CAACzE,QAAUgE,EAAEQ,QAAQ,CAACxE,UAAUiE,EAAEO,QAAQ,CAACxE,UAAU;IACxG,MAAM6E,SAASrB,WAAWlE,MAAM,GAAG+E,YAAYH,GAAGV,cAAc;IAChE,MAAMsB,OAAOpB,cAAcpE,MAAM,GAAG+E,YAAYrB,GAAGU,iBAAiB;IACpE,MAAMqB,OAAOnB,SAAStE,MAAM,GAAG+E,YAAYF,GAAGP,YAAY;IAC1D,MAAMoB,QAAQlB,UAAUxE,MAAM,GAAG+E,YAAYD,IAAIN,aAAa;IAE9D,OAAOY,aAAaC,UAAUC,UAAUC,UAAUC,QAAQC,QAAQC;AACpE"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/lib/messages-to-row.ts"],"sourcesContent":["import { extractCurrentMessageFromHtmlToText, extractCurrentMessageFromText, formatAddresses, normalizeDateToISO } from '@mcp-z/email';\n\nexport interface GmailMessage {\n id?: string;\n threadId?: string;\n labelIds?: string[];\n snippet?: string;\n payload?: {\n headers?: Array<{ name: string; value: string }>;\n body?: {\n data?: string;\n };\n parts?: Array<{\n mimeType: string;\n body?: {\n data?: string;\n };\n }>;\n };\n}\n\ninterface GmailEmailSummary {\n id: string;\n provider: 'gmail';\n threadId?: string | undefined;\n date?: string | undefined;\n from?: string | undefined;\n fromName?: string | undefined;\n to?: string | undefined;\n cc?: string | undefined;\n bcc?: string | undefined;\n subject?: string | undefined;\n snippet?: string | undefined;\n body?: string | undefined;\n}\n\ninterface FormatOptions {\n body?: boolean;\n addressFormat?: 'raw' | 'name' | 'email';\n}\n\nfunction getHeader(headers: Array<{ name: string; value: string }> | undefined, name: string): string {\n if (!headers || !Array.isArray(headers)) return '';\n const header = headers.find((h) => h.name.toLowerCase() === name.toLowerCase());\n return header ? header.value : '';\n}\n\ninterface AddressToken {\n name?: string | undefined;\n email: string;\n}\n\nfunction parseEmailHeader(headerValue: string): AddressToken[] {\n if (!headerValue) return [];\n\n const parts: string[] = [];\n let current = '';\n let inQuotes = false;\n\n for (let i = 0; i < headerValue.length; i++) {\n const char = headerValue[i];\n if (char === '\"') {\n inQuotes = !inQuotes;\n current += char;\n } else if (char === ',' && !inQuotes) {\n parts.push(current.trim());\n current = '';\n } else {\n current += char;\n }\n }\n\n if (current) parts.push(current.trim());\n\n return parts\n .map((part): AddressToken => {\n const match = part.match(/^(?:\"?([^\"]*)\"? <([^>]+)>|([^,]+))$/);\n if (match) {\n if (match[2]) {\n return { name: match[1] || undefined, email: match[2] };\n }\n return { email: match[3] || '' };\n }\n return { email: part.trim() };\n })\n .filter((token) => !!token.email); // Type guard to ensure email is always present\n}\n\nfunction formatRecipientHeader(headerValue: string, mode: 'raw' | 'name' | 'email' = 'email'): string {\n const addresses = parseEmailHeader(headerValue);\n return formatAddresses(addresses, mode);\n}\n\n/**\n * Sanitizes email body text for Google Sheets export by enforcing cell character limits.\n * Google Sheets API limits cells to 50,000 characters - this prevents API errors during export.\n */\nfunction sanitizeForSheetsExport(text: string): string {\n // Google Sheets has a 50,000 character limit per cell\n // Leave some buffer for safety\n const GOOGLE_SHEETS_CELL_LIMIT = 49000;\n\n if (text.length <= GOOGLE_SHEETS_CELL_LIMIT) return text;\n\n // Truncate and add indication that it was truncated\n const truncated = text.substring(0, GOOGLE_SHEETS_CELL_LIMIT - 100);\n return `${truncated}\\n\\n[...content truncated to fit Google Sheets cell limit...]`;\n}\n\nexport function toRowFromGmail(msg: GmailMessage = {}, opts: FormatOptions = { body: false, addressFormat: 'email' }) {\n const id = msg.id ?? '';\n const provider = 'gmail';\n const threadId = msg.threadId ?? '';\n const fmt = opts.addressFormat || 'email';\n\n const headers = msg.payload?.headers || [];\n const toHeader = getHeader(headers, 'To');\n const fromHeader = getHeader(headers, 'From');\n const ccHeader = getHeader(headers, 'Cc');\n const bccHeader = getHeader(headers, 'Bcc');\n const dateHeader = getHeader(headers, 'Date');\n const subjectHeader = getHeader(headers, 'Subject');\n\n const to = formatRecipientHeader(toHeader, fmt);\n const from = formatRecipientHeader(fromHeader, fmt);\n const cc = formatRecipientHeader(ccHeader, fmt);\n const bcc = formatRecipientHeader(bccHeader, fmt);\n const date = normalizeDateToISO(dateHeader) ?? '';\n const subject = subjectHeader ?? '';\n\n const labels = (msg.labelIds || []).join(', ');\n const snippet = msg.snippet ?? '';\n\n let bodyFull = '';\n if (opts.body) {\n if (msg.payload) {\n if (msg.payload.body?.data) {\n const rawBody = Buffer.from(msg.payload.body.data, 'base64').toString('utf-8');\n bodyFull = extractCurrentMessageFromText(rawBody);\n } else if (msg.payload.parts && Array.isArray(msg.payload.parts)) {\n for (const part of msg.payload.parts) {\n if (part.body?.data) {\n const rawBody = Buffer.from(part.body.data, 'base64').toString('utf-8');\n if (part.mimeType === 'text/plain') {\n bodyFull = extractCurrentMessageFromText(rawBody);\n break;\n }\n if (part.mimeType === 'text/html') {\n bodyFull = extractCurrentMessageFromHtmlToText(rawBody);\n break;\n }\n }\n }\n }\n }\n }\n\n return [id, provider, threadId, to, from, cc, bcc, date, subject, labels, snippet, sanitizeForSheetsExport(bodyFull)];\n}\n\nexport function toRowFromGmailSummary(msg: GmailEmailSummary, opts: FormatOptions = { body: false, addressFormat: 'email' }) {\n const id = msg.id ?? '';\n const provider = msg.provider || 'gmail';\n const threadId = msg.threadId ?? '';\n const fmt = opts.addressFormat || 'email';\n\n const to = formatRecipientHeader(msg.to ?? '', fmt);\n const from = formatRecipientHeader(msg.from ?? '', fmt);\n const cc = formatRecipientHeader(msg.cc ?? '', fmt);\n const bcc = formatRecipientHeader(msg.bcc ?? '', fmt);\n const date = normalizeDateToISO(msg.date) ?? '';\n const subject = msg.subject ?? '';\n const labels = '';\n const snippet = msg.snippet ?? '';\n\n let bodyFull = '';\n if (opts.body && msg.body) {\n bodyFull = extractCurrentMessageFromText(msg.body);\n }\n\n return [id, provider, threadId, to, from, cc, bcc, date, subject, labels, snippet, sanitizeForSheetsExport(bodyFull)];\n}\n\ninterface ClientSideFilters {\n subjectIncludes?: string[];\n bodyIncludes?: string[];\n textIncludes?: string[];\n fromIncludes?: string[];\n toIncludes?: string[];\n ccIncludes?: string[];\n bccIncludes?: string[];\n}\n\ninterface FilterContent {\n subject?: string;\n snippetOrPreview?: string;\n fullBody?: string;\n from?: string;\n to?: string;\n cc?: string;\n bcc?: string;\n}\n\nexport function filterClientSide(filters: ClientSideFilters, { subject = '', snippetOrPreview = '', fullBody = '', from = '', to = '', cc = '', bcc = '' }: FilterContent = {}) {\n const lower = (a: string[]) => a.map((t) => String(t).toLowerCase());\n const subjectTokens = lower(filters.subjectIncludes || []);\n const bodyTokens = lower(filters.bodyIncludes || []);\n const textTokens = lower(filters.textIncludes || []);\n const fromTokens = lower(filters.fromIncludes || []);\n const toCredentials = lower(filters.toIncludes || []);\n const ccTokens = lower(filters.ccIncludes || []);\n const bccTokens = lower(filters.bccIncludes || []);\n\n const s = String(subject ?? '').toLowerCase();\n const b = String((fullBody || snippetOrPreview) ?? '').toLowerCase();\n const f = String(from ?? '').toLowerCase();\n const t = String(to ?? '').toLowerCase();\n const c = String(cc ?? '').toLowerCase();\n const bc = String(bcc ?? '').toLowerCase();\n\n const anyIncludes = (val: string, tokens: string[]) => (tokens.length === 1 ? val.includes(tokens[0] ?? '') : tokens.some((token) => val.includes(token)));\n const subjectOk = subjectTokens.length ? anyIncludes(s, subjectTokens) : true;\n const bodyOk = bodyTokens.length ? anyIncludes(b, bodyTokens) : true;\n const textOk = textTokens.length ? textTokens.some((token) => s.includes(token) || b.includes(token)) : true;\n const fromOk = fromTokens.length ? anyIncludes(f, fromTokens) : true;\n const toOk = toCredentials.length ? anyIncludes(t, toCredentials) : true;\n const ccOk = ccTokens.length ? anyIncludes(c, ccTokens) : true;\n const bccOk = bccTokens.length ? anyIncludes(bc, bccTokens) : true;\n\n return subjectOk && bodyOk && textOk && fromOk && toOk && ccOk && bccOk;\n}\n"],"names":["extractCurrentMessageFromHtmlToText","extractCurrentMessageFromText","formatAddresses","normalizeDateToISO","getHeader","headers","name","Array","isArray","header","find","h","toLowerCase","value","parseEmailHeader","headerValue","parts","current","inQuotes","i","length","char","push","trim","map","part","match","undefined","email","filter","token","formatRecipientHeader","mode","addresses","sanitizeForSheetsExport","text","GOOGLE_SHEETS_CELL_LIMIT","truncated","substring","toRowFromGmail","msg","opts","body","addressFormat","id","provider","threadId","fmt","payload","toHeader","fromHeader","ccHeader","bccHeader","dateHeader","subjectHeader","to","from","cc","bcc","date","subject","labels","labelIds","join","snippet","bodyFull","data","rawBody","Buffer","toString","mimeType","toRowFromGmailSummary","filterClientSide","filters","snippetOrPreview","fullBody","lower","a","t","String","subjectTokens","subjectIncludes","bodyTokens","bodyIncludes","textTokens","textIncludes","fromTokens","fromIncludes","toCredentials","toIncludes","ccTokens","ccIncludes","bccTokens","bccIncludes","s","b","f","c","bc","anyIncludes","val","tokens","includes","some","subjectOk","bodyOk","textOk","fromOk","toOk","ccOk","bccOk"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/mcp/index.ts"],"sourcesContent":["export * as promptFactories from './prompts/index.js';\nexport * as resourceFactories from './resources/index.js';\nexport * as toolFactories from './tools/index.js';\n"],"names":["promptFactories","resourceFactories","toolFactories"],"mappings":"AAAA,kCAAiC,qBAAqB;AAAtD,SAAO,oBAAKA,eAAe,GAA2B;AACtD,oCAAmC,uBAAuB;AAA1D,SAAO,sBAAKC,iBAAiB,GAA6B;AAC1D,gCAA+B,mBAAmB;AAAlD,SAAO,kBAAKC,aAAa,GAAyB"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/mcp/index.ts"],"sourcesContent":["export * as promptFactories from './prompts/index.ts';\nexport * as resourceFactories from './resources/index.ts';\nexport * as toolFactories from './tools/index.ts';\n"],"names":["promptFactories","resourceFactories","toolFactories"],"mappings":"AAAA,kCAAiC,qBAAqB;AAAtD,SAAO,oBAAKA,eAAe,GAA2B;AACtD,oCAAmC,uBAAuB;AAA1D,SAAO,sBAAKC,iBAAiB,GAA6B;AAC1D,gCAA+B,mBAAmB;AAAlD,SAAO,kBAAKC,aAAa,GAAyB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/mcp/prompts/draft-email.ts"],"sourcesContent":["import type { PromptModule } from '@mcp-z/server';\nimport type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport type { ServerNotification, ServerRequest } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\n\nexport default function createPrompt() {\n const argsSchema = z.object({\n context: z.string().min(1).describe('Email context to draft response for'),\n tone: z.string().optional().describe('Email tone (default: professional)'),\n });\n\n const config = {\n description: 'Draft an email response',\n argsSchema: argsSchema.shape,\n };\n\n const handler = async (args: { [x: string]: unknown }, _extra: RequestHandlerExtra<ServerRequest, ServerNotification>) => {\n const { context, tone } = argsSchema.parse(args);\n return {\n messages: [\n { role: 'system' as const, content: { type: 'text' as const, text: 'You are an expert email assistant.' } },\n { role: 'user' as const, content: { type: 'text' as const, text: `Draft a ${tone || 'professional'} email:\\n\\n${context}` } },\n ],\n };\n };\n\n return {\n name: 'draft-email',\n config,\n handler,\n } satisfies PromptModule;\n}\n"],"names":["z","createPrompt","argsSchema","object","context","string","min","describe","tone","optional","config","description","shape","handler","args","_extra","parse","messages","role","content","type","text","name"],"mappings":"AAGA,SAASA,CAAC,QAAQ,MAAM;AAExB,eAAe,SAASC;IACtB,MAAMC,aAAaF,EAAEG,MAAM,CAAC;QAC1BC,SAASJ,EAAEK,MAAM,GAAGC,GAAG,CAAC,GAAGC,QAAQ,CAAC;QACpCC,MAAMR,EAAEK,MAAM,GAAGI,QAAQ,GAAGF,QAAQ,CAAC;IACvC;IAEA,MAAMG,SAAS;QACbC,aAAa;QACbT,YAAYA,WAAWU,KAAK;IAC9B;IAEA,MAAMC,UAAU,OAAOC,MAAgCC;QACrD,MAAM,EAAEX,OAAO,EAAEI,IAAI,EAAE,GAAGN,WAAWc,KAAK,CAACF;QAC3C,OAAO;YACLG,UAAU;gBACR;oBAAEC,MAAM;oBAAmBC,SAAS;wBAAEC,MAAM;wBAAiBC,MAAM;oBAAqC;gBAAE;gBAC1G;oBAAEH,MAAM;oBAAiBC,SAAS;wBAAEC,MAAM;wBAAiBC,MAAM,CAAC,QAAQ,EAAEb,QAAQ,eAAe,WAAW,EAAEJ,SAAS;oBAAC;gBAAE;aAC7H;QACH;IACF;IAEA,OAAO;QACLkB,MAAM;QACNZ;QACAG;IACF;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/mcp/prompts/draft-email.ts"],"sourcesContent":["import type { PromptModule } from '@mcp-z/server';\nimport type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport type { ServerNotification, ServerRequest } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\n\nexport default function createPrompt() {\n const argsSchema = z.object({\n context: z.string().min(1).describe('Email context to draft response for'),\n tone: z.string().optional().describe('Email tone (default: professional)'),\n });\n\n const config = {\n description: 'Draft an email response',\n argsSchema: argsSchema.shape,\n };\n\n const handler = async (args: { [x: string]: unknown }, _extra: RequestHandlerExtra<ServerRequest, ServerNotification>) => {\n const { context, tone } = argsSchema.parse(args);\n return {\n messages: [\n { role: 'system' as const, content: { type: 'text' as const, text: 'You are an expert email assistant.' } },\n { role: 'user' as const, content: { type: 'text' as const, text: `Draft a ${tone || 'professional'} email:\\n\\n${context}` } },\n ],\n };\n };\n\n return {\n name: 'draft-email',\n config,\n handler,\n } satisfies PromptModule;\n}\n"],"names":["z","createPrompt","argsSchema","object","context","string","min","describe","tone","optional","config","description","shape","handler","args","_extra","parse","messages","role","content","type","text","name"],"mappings":"AAGA,SAASA,CAAC,QAAQ,MAAM;AAExB,eAAe,SAASC;IACtB,MAAMC,aAAaF,EAAEG,MAAM,CAAC;QAC1BC,SAASJ,EAAEK,MAAM,GAAGC,GAAG,CAAC,GAAGC,QAAQ,CAAC;QACpCC,MAAMR,EAAEK,MAAM,GAAGI,QAAQ,GAAGF,QAAQ,CAAC;IACvC;IAEA,MAAMG,SAAS;QACbC,aAAa;QACbT,YAAYA,WAAWU,KAAK;IAC9B;IAEA,MAAMC,UAAU,OAAOC,MAAgCC;QACrD,MAAM,EAAEX,OAAO,EAAEI,IAAI,EAAE,GAAGN,WAAWc,KAAK,CAACF;QAC3C,OAAO;YACLG,UAAU;gBACR;oBAAEC,MAAM;oBAAmBC,SAAS;wBAAEC,MAAM;wBAAiBC,MAAM;oBAAqC;gBAAE;gBAC1G;oBAAEH,MAAM;oBAAiBC,SAAS;wBAAEC,MAAM;wBAAiBC,MAAM,CAAC,QAAQ,EAAEb,QAAQ,eAAe,WAAW,EAAEJ,SAAS;oBAAC;gBAAE;aAC7H;QACH;IACF;IAEA,OAAO;QACLkB,MAAM;QACNZ;QACAG;IACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/mcp/prompts/index.ts"],"sourcesContent":["export { default as draftEmail } from './draft-email.js';\nexport { default as querySyntax } from './query-syntax.js';\n"],"names":["default","draftEmail","querySyntax"],"mappings":"AAAA,SAASA,WAAWC,UAAU,QAAQ,mBAAmB;AACzD,SAASD,WAAWE,WAAW,QAAQ,oBAAoB"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/mcp/prompts/index.ts"],"sourcesContent":["export { default as draftEmail } from './draft-email.ts';\nexport { default as querySyntax } from './query-syntax.ts';\n"],"names":["default","draftEmail","querySyntax"],"mappings":"AAAA,SAASA,WAAWC,UAAU,QAAQ,mBAAmB;AACzD,SAASD,WAAWE,WAAW,QAAQ,oBAAoB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/mcp/prompts/query-syntax.ts"],"sourcesContent":["import type { PromptModule } from '@mcp-z/server';\nimport type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport type { ServerNotification, ServerRequest } from '@modelcontextprotocol/sdk/types.js';\n\nexport default function createPrompt() {\n const config = {\n description: 'Reference guide for Gmail query syntax',\n };\n\n const handler = async (_args: { [x: string]: unknown }, _extra: RequestHandlerExtra<ServerRequest, ServerNotification>) => {\n return {\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: `# Gmail Query Syntax Reference\n\n## Logical Operators\n- \\`$and\\`: Array of conditions that ALL must match\n- \\`$or\\`: Array of conditions where ANY must match\n- \\`$not\\`: Condition that must NOT match\n\n## Email Address Fields\n- \\`from\\`, \\`to\\`, \\`cc\\`, \\`bcc\\`: String or field operators\n\n## Content Fields\n- \\`subject\\`: Search subject line\n- \\`body\\`: Search message body\n- \\`text\\`: Search all text content\n- \\`fuzzyPhrase\\`: Approximate phrase matching (words appear together)\n\n## Boolean Flags\n- \\`hasAttachment\\`: true/false\n- \\`isRead\\`: true/false\n\n## Date Range\n\\`\\`\\`json\n{ \"date\": { \"$gte\": \"2024-01-01\", \"$lt\": \"2024-12-31\" } }\n\\`\\`\\`\n\n## Gmail-Specific\n- \\`categories\\`: primary, social, promotions, updates, forums\n- \\`label\\`: User labels (case-sensitive, use gmail-labels-list to discover)\n- \\`rawGmailQuery\\`: Escape hatch for advanced Gmail syntax\n\n## Field Operators (for multi-value fields)\n- \\`$any\\`: OR - matches if ANY value matches\n- \\`$all\\`: AND - matches if ALL values match\n- \\`$none\\`: NOT - matches if NONE match\n\n## Example Queries\n\\`\\`\\`json\n// Unread from specific sender\n{ \"from\": \"boss@company.com\", \"isRead\": false }\n\n// Recent with attachment\n{ \"hasAttachment\": true, \"date\": { \"$gte\": \"2024-01-01\" } }\n\n// Multiple senders\n{ \"from\": { \"$any\": [\"alice@example.com\", \"bob@example.com\"] } }\n\n// Complex: promotions OR social, unread\n{ \"$and\": [\n { \"categories\": { \"$any\": [\"promotions\", \"social\"] } },\n { \"isRead\": false }\n]}\n\\`\\`\\``,\n },\n },\n ],\n };\n };\n\n return {\n name: 'query-syntax',\n config,\n handler,\n } satisfies PromptModule;\n}\n"],"names":["createPrompt","config","description","handler","_args","_extra","messages","role","content","type","text","name"],"mappings":"AAIA,eAAe,SAASA;IACtB,MAAMC,SAAS;QACbC,aAAa;IACf;IAEA,MAAMC,UAAU,OAAOC,OAAiCC;QACtD,OAAO;YACLC,UAAU;gBACR;oBACEC,MAAM;oBACNC,SAAS;wBACPC,MAAM;wBACNC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAmDb,CAAC;oBACG;gBACF;aACD;QACH;IACF;IAEA,OAAO;QACLC,MAAM;QACNV;QACAE;IACF;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/mcp/prompts/query-syntax.ts"],"sourcesContent":["import type { PromptModule } from '@mcp-z/server';\nimport type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport type { ServerNotification, ServerRequest } from '@modelcontextprotocol/sdk/types.js';\n\nexport default function createPrompt() {\n const config = {\n description: 'Reference guide for Gmail query syntax',\n };\n\n const handler = async (_args: { [x: string]: unknown }, _extra: RequestHandlerExtra<ServerRequest, ServerNotification>) => {\n return {\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: `# Gmail Query Syntax Reference\n\n## Logical Operators\n- \\`$and\\`: Array of conditions that ALL must match\n- \\`$or\\`: Array of conditions where ANY must match\n- \\`$not\\`: Condition that must NOT match\n\n## Email Address Fields\n- \\`from\\`, \\`to\\`, \\`cc\\`, \\`bcc\\`: String or field operators\n\n## Content Fields\n- \\`subject\\`: Search subject line\n- \\`body\\`: Search message body\n- \\`text\\`: Search all text content\n- \\`fuzzyPhrase\\`: Approximate phrase matching (words appear together)\n\n## Boolean Flags\n- \\`hasAttachment\\`: true/false\n- \\`isRead\\`: true/false\n\n## Date Range\n\\`\\`\\`json\n{ \"date\": { \"$gte\": \"2024-01-01\", \"$lt\": \"2024-12-31\" } }\n\\`\\`\\`\n\n## Gmail-Specific\n- \\`categories\\`: primary, social, promotions, updates, forums\n- \\`label\\`: User labels (case-sensitive, use gmail-labels-list to discover)\n- \\`rawGmailQuery\\`: Escape hatch for advanced Gmail syntax\n\n## Field Operators (for multi-value fields)\n- \\`$any\\`: OR - matches if ANY value matches\n- \\`$all\\`: AND - matches if ALL values match\n- \\`$none\\`: NOT - matches if NONE match\n\n## Example Queries\n\\`\\`\\`json\n// Unread from specific sender\n{ \"from\": \"boss@company.com\", \"isRead\": false }\n\n// Recent with attachment\n{ \"hasAttachment\": true, \"date\": { \"$gte\": \"2024-01-01\" } }\n\n// Multiple senders\n{ \"from\": { \"$any\": [\"alice@example.com\", \"bob@example.com\"] } }\n\n// Complex: promotions OR social, unread\n{ \"$and\": [\n { \"categories\": { \"$any\": [\"promotions\", \"social\"] } },\n { \"isRead\": false }\n]}\n\\`\\`\\``,\n },\n },\n ],\n };\n };\n\n return {\n name: 'query-syntax',\n config,\n handler,\n } satisfies PromptModule;\n}\n"],"names":["createPrompt","config","description","handler","_args","_extra","messages","role","content","type","text","name"],"mappings":"AAIA,eAAe,SAASA;IACtB,MAAMC,SAAS;QACbC,aAAa;IACf;IAEA,MAAMC,UAAU,OAAOC,OAAiCC;QACtD,OAAO;YACLC,UAAU;gBACR;oBACEC,MAAM;oBACNC,SAAS;wBACPC,MAAM;wBACNC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAmDb,CAAC;oBACG;gBACF;aACD;QACH;IACF;IAEA,OAAO;QACLC,MAAM;QACNV;QACAE;IACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/mcp/resources/email.ts"],"sourcesContent":["import type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport type { ResourceConfig, ResourceModule } from '@mcp-z/server';\nimport { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport type { ReadResourceResult, ServerNotification, ServerRequest } from '@modelcontextprotocol/sdk/types.js';\nimport { type gmail_v1, google } from 'googleapis';\nimport { extractEmails, extractFrom } from '../../email/parsing/message-extraction.js';\nimport { toIsoUtc } from '../../lib/date-conversion.js';\n\nexport default function createResource() {\n const template = new ResourceTemplate('gmail://messages/{id}', {\n list: undefined,\n });\n const config: ResourceConfig = {\n description: 'Gmail message metadata (lightweight: id, subject, from, to, date)',\n mimeType: 'application/json',\n };\n\n const handler = async (uri: URL, variables: { id: string }, extra: RequestHandlerExtra<ServerRequest, ServerNotification>): Promise<ReadResourceResult> => {\n try {\n const { logger, authContext } = extra as unknown as EnrichedExtra;\n\n logger.info(variables, 'gmail-email resource fetch');\n\n const gmail = google.gmail({ version: 'v1', auth: authContext.auth });\n const response = await gmail.users.messages.get({\n userId: 'me',\n id: variables.id,\n format: 'metadata',\n metadataHeaders: ['From', 'To', 'Subject', 'Date'],\n });\n\n const fullData = response.data;\n if (!fullData) {\n throw new Error('Message not found');\n }\n\n // Extract headers\n const headers = fullData?.payload?.headers;\n const headersArray = Array.isArray(headers) ? headers : [];\n const headersMap: Record<string, string> = Object.fromEntries(\n headersArray.map((h: unknown) => {\n const header = h as gmail_v1.Schema$MessagePartHeader;\n return [String(header.name ?? ''), String(header.value ?? '')];\n })\n );\n\n const fromInfo = extractFrom(headersMap.From);\n const toStr = extractEmails(headersMap.To).join(', ');\n\n // Return lightweight metadata only (no body/snippet)\n const metadata = {\n id: fullData.id ?? variables.id,\n subject: headersMap.Subject ?? '',\n from: fromInfo?.address || headersMap.From,\n to: toStr,\n date: toIsoUtc(headersMap.Date) || headersMap.Date,\n };\n\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(metadata),\n },\n ],\n };\n } catch (e) {\n const { logger } = extra as unknown as EnrichedExtra;\n logger.error(e as Record<string, unknown>, 'gmail-email resource fetch failed');\n const error = e as { message?: unknown };\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify({ error: String(error?.message ?? e) }),\n },\n ],\n };\n }\n };\n\n return {\n name: 'email',\n template,\n config,\n handler,\n } satisfies ResourceModule;\n}\n"],"names":["ResourceTemplate","google","extractEmails","extractFrom","toIsoUtc","createResource","template","list","undefined","config","description","mimeType","handler","uri","variables","extra","fullData","headersMap","logger","authContext","info","gmail","version","auth","response","users","messages","get","userId","id","format","metadataHeaders","data","Error","headers","payload","headersArray","Array","isArray","Object","fromEntries","map","h","header","String","name","value","fromInfo","From","toStr","To","join","metadata","subject","Subject","from","address","to","date","Date","contents","href","text","JSON","stringify","e","error","message"],"mappings":"AAEA,SAASA,gBAAgB,QAAQ,0CAA0C;AAG3E,SAAwBC,MAAM,QAAQ,aAAa;AACnD,SAASC,aAAa,EAAEC,WAAW,QAAQ,4CAA4C;AACvF,SAASC,QAAQ,QAAQ,+BAA+B;AAExD,eAAe,SAASC;IACtB,MAAMC,WAAW,IAAIN,iBAAiB,yBAAyB;QAC7DO,MAAMC;IACR;IACA,MAAMC,SAAyB;QAC7BC,aAAa;QACbC,UAAU;IACZ;IAEA,MAAMC,UAAU,OAAOC,KAAUC,WAA2BC;QAC1D,IAAI;gBAiCIC,cACKC;gBAfKD;YAlBhB,MAAM,EAAEE,MAAM,EAAEC,WAAW,EAAE,GAAGJ;YAEhCG,OAAOE,IAAI,CAACN,WAAW;YAEvB,MAAMO,QAAQpB,OAAOoB,KAAK,CAAC;gBAAEC,SAAS;gBAAMC,MAAMJ,YAAYI,IAAI;YAAC;YACnE,MAAMC,WAAW,MAAMH,MAAMI,KAAK,CAACC,QAAQ,CAACC,GAAG,CAAC;gBAC9CC,QAAQ;gBACRC,IAAIf,UAAUe,EAAE;gBAChBC,QAAQ;gBACRC,iBAAiB;oBAAC;oBAAQ;oBAAM;oBAAW;iBAAO;YACpD;YAEA,MAAMf,WAAWQ,SAASQ,IAAI;YAC9B,IAAI,CAAChB,UAAU;gBACb,MAAM,IAAIiB,MAAM;YAClB;YAEA,kBAAkB;YAClB,MAAMC,UAAUlB,qBAAAA,gCAAAA,oBAAAA,SAAUmB,OAAO,cAAjBnB,wCAAAA,kBAAmBkB,OAAO;YAC1C,MAAME,eAAeC,MAAMC,OAAO,CAACJ,WAAWA,UAAU,EAAE;YAC1D,MAAMjB,aAAqCsB,OAAOC,WAAW,CAC3DJ,aAAaK,GAAG,CAAC,CAACC;oBAEDC,cAA2BA;gBAD1C,MAAMA,SAASD;gBACf,OAAO;oBAACE,QAAOD,eAAAA,OAAOE,IAAI,cAAXF,0BAAAA,eAAe;oBAAKC,QAAOD,gBAAAA,OAAOG,KAAK,cAAZH,2BAAAA,gBAAgB;iBAAI;YAChE;YAGF,MAAMI,WAAW5C,YAAYc,WAAW+B,IAAI;YAC5C,MAAMC,QAAQ/C,cAAce,WAAWiC,EAAE,EAAEC,IAAI,CAAC;YAEhD,qDAAqD;YACrD,MAAMC,WAAW;gBACfvB,EAAE,GAAEb,eAAAA,SAASa,EAAE,cAAXb,0BAAAA,eAAeF,UAAUe,EAAE;gBAC/BwB,OAAO,GAAEpC,sBAAAA,WAAWqC,OAAO,cAAlBrC,iCAAAA,sBAAsB;gBAC/BsC,MAAMR,CAAAA,qBAAAA,+BAAAA,SAAUS,OAAO,KAAIvC,WAAW+B,IAAI;gBAC1CS,IAAIR;gBACJS,MAAMtD,SAASa,WAAW0C,IAAI,KAAK1C,WAAW0C,IAAI;YACpD;YAEA,OAAO;gBACLC,UAAU;oBACR;wBACE/C,KAAKA,IAAIgD,IAAI;wBACblD,UAAU;wBACVmD,MAAMC,KAAKC,SAAS,CAACZ;oBACvB;iBACD;YACH;QACF,EAAE,OAAOa,GAAG;;YACV,MAAM,EAAE/C,MAAM,EAAE,GAAGH;YACnBG,OAAOgD,KAAK,CAACD,GAA8B;YAC3C,MAAMC,QAAQD;YACd,OAAO;gBACLL,UAAU;oBACR;wBACE/C,KAAKA,IAAIgD,IAAI;wBACblD,UAAU;wBACVmD,MAAMC,KAAKC,SAAS,CAAC;4BAAEE,OAAOtB,eAAOsB,kBAAAA,4BAAAA,MAAOC,OAAO,uCAAIF;wBAAG;oBAC5D;iBACD;YACH;QACF;IACF;IAEA,OAAO;QACLpB,MAAM;QACNvC;QACAG;QACAG;IACF;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/mcp/resources/email.ts"],"sourcesContent":["import type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport type { ResourceConfig, ResourceModule } from '@mcp-z/server';\nimport { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport type { ReadResourceResult, ServerNotification, ServerRequest } from '@modelcontextprotocol/sdk/types.js';\nimport { type gmail_v1, google } from 'googleapis';\nimport { extractEmails, extractFrom } from '../../email/parsing/message-extraction.ts';\nimport { toIsoUtc } from '../../lib/date-conversion.ts';\n\nexport default function createResource() {\n const template = new ResourceTemplate('gmail://messages/{id}', {\n list: undefined,\n });\n const config: ResourceConfig = {\n description: 'Gmail message metadata (lightweight: id, subject, from, to, date)',\n mimeType: 'application/json',\n };\n\n const handler = async (uri: URL, variables: { id: string }, extra: RequestHandlerExtra<ServerRequest, ServerNotification>): Promise<ReadResourceResult> => {\n try {\n const { logger, authContext } = extra as unknown as EnrichedExtra;\n\n logger.info(variables, 'gmail-email resource fetch');\n\n const gmail = google.gmail({ version: 'v1', auth: authContext.auth });\n const response = await gmail.users.messages.get({\n userId: 'me',\n id: variables.id,\n format: 'metadata',\n metadataHeaders: ['From', 'To', 'Subject', 'Date'],\n });\n\n const fullData = response.data;\n if (!fullData) {\n throw new Error('Message not found');\n }\n\n // Extract headers\n const headers = fullData?.payload?.headers;\n const headersArray = Array.isArray(headers) ? headers : [];\n const headersMap: Record<string, string> = Object.fromEntries(\n headersArray.map((h: unknown) => {\n const header = h as gmail_v1.Schema$MessagePartHeader;\n return [String(header.name ?? ''), String(header.value ?? '')];\n })\n );\n\n const fromInfo = extractFrom(headersMap.From);\n const toStr = extractEmails(headersMap.To).join(', ');\n\n // Return lightweight metadata only (no body/snippet)\n const metadata = {\n id: fullData.id ?? variables.id,\n subject: headersMap.Subject ?? '',\n from: fromInfo?.address || headersMap.From,\n to: toStr,\n date: toIsoUtc(headersMap.Date) || headersMap.Date,\n };\n\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(metadata),\n },\n ],\n };\n } catch (e) {\n const { logger } = extra as unknown as EnrichedExtra;\n logger.error(e as Record<string, unknown>, 'gmail-email resource fetch failed');\n const error = e as { message?: unknown };\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify({ error: String(error?.message ?? e) }),\n },\n ],\n };\n }\n };\n\n return {\n name: 'email',\n template,\n config,\n handler,\n } satisfies ResourceModule;\n}\n"],"names":["ResourceTemplate","google","extractEmails","extractFrom","toIsoUtc","createResource","template","list","undefined","config","description","mimeType","handler","uri","variables","extra","fullData","headersMap","logger","authContext","info","gmail","version","auth","response","users","messages","get","userId","id","format","metadataHeaders","data","Error","headers","payload","headersArray","Array","isArray","Object","fromEntries","map","h","header","String","name","value","fromInfo","From","toStr","To","join","metadata","subject","Subject","from","address","to","date","Date","contents","href","text","JSON","stringify","e","error","message"],"mappings":"AAEA,SAASA,gBAAgB,QAAQ,0CAA0C;AAG3E,SAAwBC,MAAM,QAAQ,aAAa;AACnD,SAASC,aAAa,EAAEC,WAAW,QAAQ,4CAA4C;AACvF,SAASC,QAAQ,QAAQ,+BAA+B;AAExD,eAAe,SAASC;IACtB,MAAMC,WAAW,IAAIN,iBAAiB,yBAAyB;QAC7DO,MAAMC;IACR;IACA,MAAMC,SAAyB;QAC7BC,aAAa;QACbC,UAAU;IACZ;IAEA,MAAMC,UAAU,OAAOC,KAAUC,WAA2BC;QAC1D,IAAI;gBAiCIC,cACKC;gBAfKD;YAlBhB,MAAM,EAAEE,MAAM,EAAEC,WAAW,EAAE,GAAGJ;YAEhCG,OAAOE,IAAI,CAACN,WAAW;YAEvB,MAAMO,QAAQpB,OAAOoB,KAAK,CAAC;gBAAEC,SAAS;gBAAMC,MAAMJ,YAAYI,IAAI;YAAC;YACnE,MAAMC,WAAW,MAAMH,MAAMI,KAAK,CAACC,QAAQ,CAACC,GAAG,CAAC;gBAC9CC,QAAQ;gBACRC,IAAIf,UAAUe,EAAE;gBAChBC,QAAQ;gBACRC,iBAAiB;oBAAC;oBAAQ;oBAAM;oBAAW;iBAAO;YACpD;YAEA,MAAMf,WAAWQ,SAASQ,IAAI;YAC9B,IAAI,CAAChB,UAAU;gBACb,MAAM,IAAIiB,MAAM;YAClB;YAEA,kBAAkB;YAClB,MAAMC,UAAUlB,qBAAAA,gCAAAA,oBAAAA,SAAUmB,OAAO,cAAjBnB,wCAAAA,kBAAmBkB,OAAO;YAC1C,MAAME,eAAeC,MAAMC,OAAO,CAACJ,WAAWA,UAAU,EAAE;YAC1D,MAAMjB,aAAqCsB,OAAOC,WAAW,CAC3DJ,aAAaK,GAAG,CAAC,CAACC;oBAEDC,cAA2BA;gBAD1C,MAAMA,SAASD;gBACf,OAAO;oBAACE,QAAOD,eAAAA,OAAOE,IAAI,cAAXF,0BAAAA,eAAe;oBAAKC,QAAOD,gBAAAA,OAAOG,KAAK,cAAZH,2BAAAA,gBAAgB;iBAAI;YAChE;YAGF,MAAMI,WAAW5C,YAAYc,WAAW+B,IAAI;YAC5C,MAAMC,QAAQ/C,cAAce,WAAWiC,EAAE,EAAEC,IAAI,CAAC;YAEhD,qDAAqD;YACrD,MAAMC,WAAW;gBACfvB,EAAE,GAAEb,eAAAA,SAASa,EAAE,cAAXb,0BAAAA,eAAeF,UAAUe,EAAE;gBAC/BwB,OAAO,GAAEpC,sBAAAA,WAAWqC,OAAO,cAAlBrC,iCAAAA,sBAAsB;gBAC/BsC,MAAMR,CAAAA,qBAAAA,+BAAAA,SAAUS,OAAO,KAAIvC,WAAW+B,IAAI;gBAC1CS,IAAIR;gBACJS,MAAMtD,SAASa,WAAW0C,IAAI,KAAK1C,WAAW0C,IAAI;YACpD;YAEA,OAAO;gBACLC,UAAU;oBACR;wBACE/C,KAAKA,IAAIgD,IAAI;wBACblD,UAAU;wBACVmD,MAAMC,KAAKC,SAAS,CAACZ;oBACvB;iBACD;YACH;QACF,EAAE,OAAOa,GAAG;;YACV,MAAM,EAAE/C,MAAM,EAAE,GAAGH;YACnBG,OAAOgD,KAAK,CAACD,GAA8B;YAC3C,MAAMC,QAAQD;YACd,OAAO;gBACLL,UAAU;oBACR;wBACE/C,KAAKA,IAAIgD,IAAI;wBACblD,UAAU;wBACVmD,MAAMC,KAAKC,SAAS,CAAC;4BAAEE,OAAOtB,eAAOsB,kBAAAA,4BAAAA,MAAOC,OAAO,uCAAIF;wBAAG;oBAC5D;iBACD;YACH;QACF;IACF;IAEA,OAAO;QACLpB,MAAM;QACNvC;QACAG;QACAG;IACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/mcp/resources/index.ts"],"sourcesContent":["export { default as email } from './email.js';\n"],"names":["default","email"],"mappings":"AAAA,SAASA,WAAWC,KAAK,QAAQ,aAAa"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/mcp/resources/index.ts"],"sourcesContent":["export { default as email } from './email.ts';\n"],"names":["default","email"],"mappings":"AAAA,SAASA,WAAWC,KAAK,QAAQ,aAAa"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/mcp/tools/categories-list.ts"],"sourcesContent":["import type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport { schemas } from '@mcp-z/oauth-google';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport type { ToolModule } from '@mcp-z/server';\nimport { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { google } from 'googleapis';\nimport { z } from 'zod';\n\n// Schema for individual category items\nconst CategorySchema = z.object({\n id: z.string().describe('Gmail category ID (e.g., CATEGORY_PERSONAL)'),\n name: z.string().describe('Human-readable category name'),\n description: z.string().describe('Description of what emails belong in this category'),\n});\n\nconst inputSchema = z.object({});\n\n// Success branch schema\nconst successBranchSchema = z.object({\n type: z.literal('success'),\n items: z.array(CategorySchema),\n});\n\n// Output schema with auth_required support\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'List Gmail category labels (CATEGORY_*) with IDs and descriptions.',\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(_args: Input, extra: EnrichedExtra) {\n const logger = extra.logger;\n logger.info('gmail.categories.list called');\n\n try {\n const gmail = google.gmail({ version: 'v1', auth: extra.authContext.auth });\n const started = Date.now();\n\n // Fetch all labels from Gmail API\n const response = await gmail.users.labels.list({ userId: 'me' });\n const labels = response.data.labels || [];\n\n // Filter for CATEGORY_* system labels and map to our schema\n const categories = labels\n .filter((label) => label.id?.startsWith('CATEGORY_'))\n .map((label) => {\n const id = label.id as string;\n let name = label.name || id;\n let description = '';\n\n // Map known category types to user-friendly names and descriptions\n switch (id) {\n case 'CATEGORY_PERSONAL':\n name = 'Primary';\n description = 'Important emails from people you know';\n break;\n case 'CATEGORY_SOCIAL':\n name = 'Social';\n description = 'Social networks and social websites';\n break;\n case 'CATEGORY_PROMOTIONS':\n name = 'Promotions';\n description = 'Deals, offers, and marketing emails';\n break;\n case 'CATEGORY_UPDATES':\n name = 'Updates';\n description = 'Confirmations, receipts, bills, and statements';\n break;\n case 'CATEGORY_FORUMS':\n name = 'Forums';\n description = 'Online groups, discussion boards, mailing lists';\n break;\n default:\n // For any unknown CATEGORY_* labels, use the label name as-is\n name = label.name || id.replace('CATEGORY_', '');\n description = `Gmail category: ${name}`;\n }\n\n return {\n id,\n name,\n description,\n };\n })\n .sort((a, b) => a.name.localeCompare(b.name)); // Sort alphabetically by name\n\n const durationMs = Date.now() - started;\n\n logger.info('gmail.categories.list results', { categoryCount: categories.length, totalLabels: labels.length });\n logger.info('gmail.categories.list metrics', { durationMs });\n\n const result: Output = {\n type: 'success' as const,\n items: categories,\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('gmail.categories.list error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error listing categories: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'categories-list',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["schemas","AuthRequiredBranchSchema","ErrorCode","McpError","google","z","CategorySchema","object","id","string","describe","name","description","inputSchema","successBranchSchema","type","literal","items","array","outputSchema","discriminatedUnion","config","result","handler","_args","extra","logger","info","gmail","version","auth","authContext","started","Date","now","response","users","labels","list","userId","data","categories","filter","label","startsWith","map","replace","sort","a","b","localeCompare","durationMs","categoryCount","length","totalLabels","content","text","JSON","stringify","structuredContent","error","message","Error","String","InternalError","stack","undefined","createTool"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/mcp/tools/categories-list.ts"],"sourcesContent":["import type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport { schemas } from '@mcp-z/oauth-google';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport type { ToolModule } from '@mcp-z/server';\nimport { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { google } from 'googleapis';\nimport { z } from 'zod';\n\n// Schema for individual category items\nconst CategorySchema = z.object({\n id: z.string().describe('Gmail category ID (e.g., CATEGORY_PERSONAL)'),\n name: z.string().describe('Human-readable category name'),\n description: z.string().describe('Description of what emails belong in this category'),\n});\n\nconst inputSchema = z.object({});\n\n// Success branch schema\nconst successBranchSchema = z.object({\n type: z.literal('success'),\n items: z.array(CategorySchema),\n});\n\n// Output schema with auth_required support\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'List Gmail category labels (CATEGORY_*) with IDs and descriptions.',\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(_args: Input, extra: EnrichedExtra) {\n const logger = extra.logger;\n logger.info('gmail.categories.list called');\n\n try {\n const gmail = google.gmail({ version: 'v1', auth: extra.authContext.auth });\n const started = Date.now();\n\n // Fetch all labels from Gmail API\n const response = await gmail.users.labels.list({ userId: 'me' });\n const labels = response.data.labels || [];\n\n // Filter for CATEGORY_* system labels and map to our schema\n const categories = labels\n .filter((label) => label.id?.startsWith('CATEGORY_'))\n .map((label) => {\n const id = label.id as string;\n let name = label.name || id;\n let description = '';\n\n // Map known category types to user-friendly names and descriptions\n switch (id) {\n case 'CATEGORY_PERSONAL':\n name = 'Primary';\n description = 'Important emails from people you know';\n break;\n case 'CATEGORY_SOCIAL':\n name = 'Social';\n description = 'Social networks and social websites';\n break;\n case 'CATEGORY_PROMOTIONS':\n name = 'Promotions';\n description = 'Deals, offers, and marketing emails';\n break;\n case 'CATEGORY_UPDATES':\n name = 'Updates';\n description = 'Confirmations, receipts, bills, and statements';\n break;\n case 'CATEGORY_FORUMS':\n name = 'Forums';\n description = 'Online groups, discussion boards, mailing lists';\n break;\n default:\n // For any unknown CATEGORY_* labels, use the label name as-is\n name = label.name || id.replace('CATEGORY_', '');\n description = `Gmail category: ${name}`;\n }\n\n return {\n id,\n name,\n description,\n };\n })\n .sort((a, b) => a.name.localeCompare(b.name)); // Sort alphabetically by name\n\n const durationMs = Date.now() - started;\n\n logger.info('gmail.categories.list results', { categoryCount: categories.length, totalLabels: labels.length });\n logger.info('gmail.categories.list metrics', { durationMs });\n\n const result: Output = {\n type: 'success' as const,\n items: categories,\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('gmail.categories.list error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error listing categories: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'categories-list',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["schemas","AuthRequiredBranchSchema","ErrorCode","McpError","google","z","CategorySchema","object","id","string","describe","name","description","inputSchema","successBranchSchema","type","literal","items","array","outputSchema","discriminatedUnion","config","result","handler","_args","extra","logger","info","gmail","version","auth","authContext","started","Date","now","response","users","labels","list","userId","data","categories","filter","label","startsWith","map","replace","sort","a","b","localeCompare","durationMs","categoryCount","length","totalLabels","content","text","JSON","stringify","structuredContent","error","message","Error","String","InternalError","stack","undefined","createTool"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/mcp/tools/index.ts"],"sourcesContent":["export { default as categoriesList } from './categories-list.js';\nexport { default as labelAdd } from './label-add.js';\nexport { default as labelDelete } from './label-delete.js';\nexport { default as labelsList } from './labels-list.js';\nexport { default as messageGet } from './message-get.js';\nexport { default as messageMarkRead } from './message-mark-read.js';\nexport { default as messageMoveToTrash } from './message-move-to-trash.js';\nexport { default as messageRespond } from './message-respond.js';\nexport { default as messageSearch } from './message-search.js';\nexport { default as messageSend } from './message-send.js';\nexport { default as messagesExportCsv } from './messages-export-csv.js';\n"],"names":["default","categoriesList","labelAdd","labelDelete","labelsList","messageGet","messageMarkRead","messageMoveToTrash","messageRespond","messageSearch","messageSend","messagesExportCsv"],"mappings":"AAAA,SAASA,WAAWC,cAAc,QAAQ,uBAAuB;AACjE,SAASD,WAAWE,QAAQ,QAAQ,iBAAiB;AACrD,SAASF,WAAWG,WAAW,QAAQ,oBAAoB;AAC3D,SAASH,WAAWI,UAAU,QAAQ,mBAAmB;AACzD,SAASJ,WAAWK,UAAU,QAAQ,mBAAmB;AACzD,SAASL,WAAWM,eAAe,QAAQ,yBAAyB;AACpE,SAASN,WAAWO,kBAAkB,QAAQ,6BAA6B;AAC3E,SAASP,WAAWQ,cAAc,QAAQ,uBAAuB;AACjE,SAASR,WAAWS,aAAa,QAAQ,sBAAsB;AAC/D,SAAST,WAAWU,WAAW,QAAQ,oBAAoB;AAC3D,SAASV,WAAWW,iBAAiB,QAAQ,2BAA2B"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/mcp/tools/index.ts"],"sourcesContent":["export { default as categoriesList } from './categories-list.ts';\nexport { default as labelAdd } from './label-add.ts';\nexport { default as labelDelete } from './label-delete.ts';\nexport { default as labelsList } from './labels-list.ts';\nexport { default as messageGet } from './message-get.ts';\nexport { default as messageMarkRead } from './message-mark-read.ts';\nexport { default as messageMoveToTrash } from './message-move-to-trash.ts';\nexport { default as messageRespond } from './message-respond.ts';\nexport { default as messageSearch } from './message-search.ts';\nexport { default as messageSend } from './message-send.ts';\nexport { default as messagesExportCsv } from './messages-export-csv.ts';\n"],"names":["default","categoriesList","labelAdd","labelDelete","labelsList","messageGet","messageMarkRead","messageMoveToTrash","messageRespond","messageSearch","messageSend","messagesExportCsv"],"mappings":"AAAA,SAASA,WAAWC,cAAc,QAAQ,uBAAuB;AACjE,SAASD,WAAWE,QAAQ,QAAQ,iBAAiB;AACrD,SAASF,WAAWG,WAAW,QAAQ,oBAAoB;AAC3D,SAASH,WAAWI,UAAU,QAAQ,mBAAmB;AACzD,SAASJ,WAAWK,UAAU,QAAQ,mBAAmB;AACzD,SAASL,WAAWM,eAAe,QAAQ,yBAAyB;AACpE,SAASN,WAAWO,kBAAkB,QAAQ,6BAA6B;AAC3E,SAASP,WAAWQ,cAAc,QAAQ,uBAAuB;AACjE,SAASR,WAAWS,aAAa,QAAQ,sBAAsB;AAC/D,SAAST,WAAWU,WAAW,QAAQ,oBAAoB;AAC3D,SAASV,WAAWW,iBAAiB,QAAQ,2BAA2B"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/mcp/tools/label-add.ts"],"sourcesContent":["import type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport { schemas } from '@mcp-z/oauth-google';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport type { ToolModule } from '@mcp-z/server';\nimport { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { google } from 'googleapis';\nimport { z } from 'zod';\nimport { ensureLabelId } from '../../labels/gmail-labels.js';\n\nconst inputSchema = z.object({\n id: z.coerce.string().trim().min(1).describe('Gmail message ID to add label to'),\n label: z.coerce.string().trim().min(1).describe('Label name or ID (use gmail-labels-list to discover available labels)'),\n});\n\n// Success branch schema\nconst successBranchSchema = z.object({\n type: z.literal('success'),\n item: z.object({\n id: z.string().describe('Message ID the label was added to'),\n label: z.string().describe('Label that was added'),\n }),\n});\n\n// Output schema with auth_required support\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Add a label to a Gmail message',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\nasync function handler({ id, label }: Input, extra: EnrichedExtra) {\n const logger = extra.logger;\n logger.info('gmail.label.add called', { id, label });\n\n if (!id || !label) {\n logger.info('gmail.label.add missing parameters', { id, label });\n throw new McpError(ErrorCode.InvalidParams, 'Missing id or label');\n }\n\n try {\n const gmail = google.gmail({ version: 'v1', auth: extra.authContext.auth });\n\n const labelId = await ensureLabelId(gmail, 'me', label);\n await gmail.users.messages.modify({\n userId: 'me',\n id: id,\n requestBody: {\n addLabelIds: [labelId],\n },\n });\n\n logger.info('gmail.label.add success', { id, label });\n logger.info('gmail.label.add result (typed)', { id, label });\n\n const result: Output = {\n type: 'success' as const,\n item: { id, label },\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('gmail.label.add error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error adding label to message: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'label-add',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["schemas","AuthRequiredBranchSchema","ErrorCode","McpError","google","z","ensureLabelId","inputSchema","object","id","coerce","string","trim","min","describe","label","successBranchSchema","type","literal","item","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","info","InvalidParams","gmail","version","auth","authContext","labelId","users","messages","modify","userId","requestBody","addLabelIds","content","text","JSON","stringify","structuredContent","error","message","Error","String","InternalError","stack","undefined","createTool","name"],"mappings":"AACA,SAASA,OAAO,QAAQ,sBAAsB;AAE9C,MAAM,EAAEC,wBAAwB,EAAE,GAAGD;AAGrC,SAASE,SAAS,EAAEC,QAAQ,QAAQ,qCAAqC;AACzE,SAASC,MAAM,QAAQ,aAAa;AACpC,SAASC,CAAC,QAAQ,MAAM;AACxB,SAASC,aAAa,QAAQ,+BAA+B;AAE7D,MAAMC,cAAcF,EAAEG,MAAM,CAAC;IAC3BC,IAAIJ,EAAEK,MAAM,CAACC,MAAM,GAAGC,IAAI,GAAGC,GAAG,CAAC,GAAGC,QAAQ,CAAC;IAC7CC,OAAOV,EAAEK,MAAM,CAACC,MAAM,GAAGC,IAAI,GAAGC,GAAG,CAAC,GAAGC,QAAQ,CAAC;AAClD;AAEA,wBAAwB;AACxB,MAAME,sBAAsBX,EAAEG,MAAM,CAAC;IACnCS,MAAMZ,EAAEa,OAAO,CAAC;IAChBC,MAAMd,EAAEG,MAAM,CAAC;QACbC,IAAIJ,EAAEM,MAAM,GAAGG,QAAQ,CAAC;QACxBC,OAAOV,EAAEM,MAAM,GAAGG,QAAQ,CAAC;IAC7B;AACF;AAEA,2CAA2C;AAC3C,MAAMM,eAAef,EAAEgB,kBAAkB,CAAC,QAAQ;IAACL;IAAqBf;CAAyB;AAEjG,MAAMqB,SAAS;IACbC,aAAa;IACbhB,aAAaA;IACba,cAAcf,EAAEG,MAAM,CAAC;QACrBgB,QAAQJ;IACV;AACF;AAKA,eAAeK,QAAQ,EAAEhB,EAAE,EAAEM,KAAK,EAAS,EAAEW,KAAoB;IAC/D,MAAMC,SAASD,MAAMC,MAAM;IAC3BA,OAAOC,IAAI,CAAC,0BAA0B;QAAEnB;QAAIM;IAAM;IAElD,IAAI,CAACN,MAAM,CAACM,OAAO;QACjBY,OAAOC,IAAI,CAAC,sCAAsC;YAAEnB;YAAIM;QAAM;QAC9D,MAAM,IAAIZ,SAASD,UAAU2B,aAAa,EAAE;IAC9C;IAEA,IAAI;QACF,MAAMC,QAAQ1B,OAAO0B,KAAK,CAAC;YAAEC,SAAS;YAAMC,MAAMN,MAAMO,WAAW,CAACD,IAAI;QAAC;QAEzE,MAAME,UAAU,MAAM5B,cAAcwB,OAAO,MAAMf;QACjD,MAAMe,MAAMK,KAAK,CAACC,QAAQ,CAACC,MAAM,CAAC;YAChCC,QAAQ;YACR7B,IAAIA;YACJ8B,aAAa;gBACXC,aAAa;oBAACN;iBAAQ;YACxB;QACF;QAEAP,OAAOC,IAAI,CAAC,2BAA2B;YAAEnB;YAAIM;QAAM;QACnDY,OAAOC,IAAI,CAAC,kCAAkC;YAAEnB;YAAIM;QAAM;QAE1D,MAAMS,SAAiB;YACrBP,MAAM;YACNE,MAAM;gBAAEV;gBAAIM;YAAM;QACpB;QAEA,OAAO;YACL0B,SAAS;gBACP;oBACExB,MAAM;oBACNyB,MAAMC,KAAKC,SAAS,CAACpB;gBACvB;aACD;YACDqB,mBAAmB;gBAAErB;YAAO;QAC9B;IACF,EAAE,OAAOsB,OAAO;QACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,OAAO,GAAGE,OAAOH;QAChEnB,OAAOmB,KAAK,CAAC,yBAAyB;YAAEA,OAAOC;QAAQ;QAEvD,MAAM,IAAI5C,SAASD,UAAUgD,aAAa,EAAE,CAAC,+BAA+B,EAAEH,SAAS,EAAE;YACvFI,OAAOL,iBAAiBE,QAAQF,MAAMK,KAAK,GAAGC;QAChD;IACF;AACF;AAEA,eAAe,SAASC;IACtB,OAAO;QACLC,MAAM;QACNhC;QACAG;IACF;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/mcp/tools/label-add.ts"],"sourcesContent":["import type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport { schemas } from '@mcp-z/oauth-google';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport type { ToolModule } from '@mcp-z/server';\nimport { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { google } from 'googleapis';\nimport { z } from 'zod';\nimport { ensureLabelId } from '../../labels/gmail-labels.ts';\n\nconst inputSchema = z.object({\n id: z.coerce.string().trim().min(1).describe('Gmail message ID to add label to'),\n label: z.coerce.string().trim().min(1).describe('Label name or ID (use gmail-labels-list to discover available labels)'),\n});\n\n// Success branch schema\nconst successBranchSchema = z.object({\n type: z.literal('success'),\n item: z.object({\n id: z.string().describe('Message ID the label was added to'),\n label: z.string().describe('Label that was added'),\n }),\n});\n\n// Output schema with auth_required support\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Add a label to a Gmail message',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\nasync function handler({ id, label }: Input, extra: EnrichedExtra) {\n const logger = extra.logger;\n logger.info('gmail.label.add called', { id, label });\n\n if (!id || !label) {\n logger.info('gmail.label.add missing parameters', { id, label });\n throw new McpError(ErrorCode.InvalidParams, 'Missing id or label');\n }\n\n try {\n const gmail = google.gmail({ version: 'v1', auth: extra.authContext.auth });\n\n const labelId = await ensureLabelId(gmail, 'me', label);\n await gmail.users.messages.modify({\n userId: 'me',\n id: id,\n requestBody: {\n addLabelIds: [labelId],\n },\n });\n\n logger.info('gmail.label.add success', { id, label });\n logger.info('gmail.label.add result (typed)', { id, label });\n\n const result: Output = {\n type: 'success' as const,\n item: { id, label },\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('gmail.label.add error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error adding label to message: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'label-add',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["schemas","AuthRequiredBranchSchema","ErrorCode","McpError","google","z","ensureLabelId","inputSchema","object","id","coerce","string","trim","min","describe","label","successBranchSchema","type","literal","item","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","info","InvalidParams","gmail","version","auth","authContext","labelId","users","messages","modify","userId","requestBody","addLabelIds","content","text","JSON","stringify","structuredContent","error","message","Error","String","InternalError","stack","undefined","createTool","name"],"mappings":"AACA,SAASA,OAAO,QAAQ,sBAAsB;AAE9C,MAAM,EAAEC,wBAAwB,EAAE,GAAGD;AAGrC,SAASE,SAAS,EAAEC,QAAQ,QAAQ,qCAAqC;AACzE,SAASC,MAAM,QAAQ,aAAa;AACpC,SAASC,CAAC,QAAQ,MAAM;AACxB,SAASC,aAAa,QAAQ,+BAA+B;AAE7D,MAAMC,cAAcF,EAAEG,MAAM,CAAC;IAC3BC,IAAIJ,EAAEK,MAAM,CAACC,MAAM,GAAGC,IAAI,GAAGC,GAAG,CAAC,GAAGC,QAAQ,CAAC;IAC7CC,OAAOV,EAAEK,MAAM,CAACC,MAAM,GAAGC,IAAI,GAAGC,GAAG,CAAC,GAAGC,QAAQ,CAAC;AAClD;AAEA,wBAAwB;AACxB,MAAME,sBAAsBX,EAAEG,MAAM,CAAC;IACnCS,MAAMZ,EAAEa,OAAO,CAAC;IAChBC,MAAMd,EAAEG,MAAM,CAAC;QACbC,IAAIJ,EAAEM,MAAM,GAAGG,QAAQ,CAAC;QACxBC,OAAOV,EAAEM,MAAM,GAAGG,QAAQ,CAAC;IAC7B;AACF;AAEA,2CAA2C;AAC3C,MAAMM,eAAef,EAAEgB,kBAAkB,CAAC,QAAQ;IAACL;IAAqBf;CAAyB;AAEjG,MAAMqB,SAAS;IACbC,aAAa;IACbhB,aAAaA;IACba,cAAcf,EAAEG,MAAM,CAAC;QACrBgB,QAAQJ;IACV;AACF;AAKA,eAAeK,QAAQ,EAAEhB,EAAE,EAAEM,KAAK,EAAS,EAAEW,KAAoB;IAC/D,MAAMC,SAASD,MAAMC,MAAM;IAC3BA,OAAOC,IAAI,CAAC,0BAA0B;QAAEnB;QAAIM;IAAM;IAElD,IAAI,CAACN,MAAM,CAACM,OAAO;QACjBY,OAAOC,IAAI,CAAC,sCAAsC;YAAEnB;YAAIM;QAAM;QAC9D,MAAM,IAAIZ,SAASD,UAAU2B,aAAa,EAAE;IAC9C;IAEA,IAAI;QACF,MAAMC,QAAQ1B,OAAO0B,KAAK,CAAC;YAAEC,SAAS;YAAMC,MAAMN,MAAMO,WAAW,CAACD,IAAI;QAAC;QAEzE,MAAME,UAAU,MAAM5B,cAAcwB,OAAO,MAAMf;QACjD,MAAMe,MAAMK,KAAK,CAACC,QAAQ,CAACC,MAAM,CAAC;YAChCC,QAAQ;YACR7B,IAAIA;YACJ8B,aAAa;gBACXC,aAAa;oBAACN;iBAAQ;YACxB;QACF;QAEAP,OAAOC,IAAI,CAAC,2BAA2B;YAAEnB;YAAIM;QAAM;QACnDY,OAAOC,IAAI,CAAC,kCAAkC;YAAEnB;YAAIM;QAAM;QAE1D,MAAMS,SAAiB;YACrBP,MAAM;YACNE,MAAM;gBAAEV;gBAAIM;YAAM;QACpB;QAEA,OAAO;YACL0B,SAAS;gBACP;oBACExB,MAAM;oBACNyB,MAAMC,KAAKC,SAAS,CAACpB;gBACvB;aACD;YACDqB,mBAAmB;gBAAErB;YAAO;QAC9B;IACF,EAAE,OAAOsB,OAAO;QACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,OAAO,GAAGE,OAAOH;QAChEnB,OAAOmB,KAAK,CAAC,yBAAyB;YAAEA,OAAOC;QAAQ;QAEvD,MAAM,IAAI5C,SAASD,UAAUgD,aAAa,EAAE,CAAC,+BAA+B,EAAEH,SAAS,EAAE;YACvFI,OAAOL,iBAAiBE,QAAQF,MAAMK,KAAK,GAAGC;QAChD;IACF;AACF;AAEA,eAAe,SAASC;IACtB,OAAO;QACLC,MAAM;QACNhC;QACAG;IACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/servers/mcp-gmail/src/mcp/tools/label-delete.ts"],"sourcesContent":["import type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport { schemas } from '@mcp-z/oauth-google';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport type { ToolModule } from '@mcp-z/server';\nimport { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { google } from 'googleapis';\nimport { z } from 'zod';\nimport { CHUNK_SIZE, MAX_BATCH_SIZE } from '../../constants.ts';\n\nconst inputSchema = z.object({\n ids: z.array(z.coerce.string().trim().min(1)).min(1).describe('Gmail label IDs to delete'),\n});\n\nconst successBranchSchema = z.object({\n type: z.literal('success'),\n totalRequested: z.number().describe('Total number of labels requested to delete'),\n successCount: z.number().describe('Number of labels successfully deleted'),\n failureCount: z.number().describe('Number of labels that failed to delete'),\n results: z\n .array(\n z.object({\n id: z.string().describe('Label 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 label'),\n});\n\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Delete Gmail labels permanently (irreversible). System labels (INBOX, SENT, etc.) cannot be deleted.',\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) {\n const logger = extra.logger;\n logger.info('gmail-label-delete called', { count: ids.length });\n\n if (!ids || ids.length === 0) {\n throw new McpError(ErrorCode.InvalidParams, 'Missing ids');\n }\n\n // Validate batch size to prevent memory exhaustion\n if (ids.length > MAX_BATCH_SIZE) {\n throw new McpError(ErrorCode.InvalidParams, `Batch size ${ids.length} exceeds maximum allowed size of ${MAX_BATCH_SIZE}`);\n }\n\n // Validate and sanitize IDs\n const validatedIds: string[] = [];\n const invalidIds: string[] = [];\n\n for (const id of ids) {\n const trimmedId = id.trim();\n if (!trimmedId) {\n invalidIds.push(id);\n continue;\n }\n // Basic Gmail label ID validation - should not contain certain characters\n if (trimmedId.includes('/') || trimmedId.includes('\\\\') || trimmedId.includes('<') || trimmedId.includes('>')) {\n invalidIds.push(id);\n continue;\n }\n validatedIds.push(trimmedId);\n }\n\n if (invalidIds.length > 0) {\n throw new McpError(ErrorCode.InvalidParams, `Found ${invalidIds.length} invalid IDs: ${invalidIds.join(', ')}`);\n }\n\n if (validatedIds.length === 0) {\n throw new McpError(ErrorCode.InvalidParams, 'No valid IDs found after validation');\n }\n\n try {\n const gmail = google.gmail({ version: 'v1', auth: extra.authContext.auth });\n // Get all labels first to check for system labels\n const labelsResponse = await gmail.users.labels.list({ userId: 'me' });\n const allLabels = labelsResponse.data.labels || [];\n const labelMap = new Map(allLabels.map((label) => [label.id || '', label]));\n\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 < validatedIds.length; i += CHUNK_SIZE) {\n const chunk = validatedIds.slice(i, i + CHUNK_SIZE);\n logger.info('Processing chunk', { chunkIndex: i / CHUNK_SIZE + 1, chunkSize: chunk.length, totalChunks: Math.ceil(validatedIds.length / CHUNK_SIZE) });\n\n const chunkResults = await Promise.allSettled(\n chunk.map(async (id) => {\n const label = labelMap.get(id);\n\n // Check if label exists\n if (!label) {\n throw new Error(`Label not found: ${id}`);\n }\n\n // Check if it's a system label\n if (label.type === 'system') {\n throw new Error(`Cannot delete system label: ${label.name} (${id})`);\n }\n\n // Delete the label\n await gmail.users.labels.delete({\n userId: 'me',\n id: id,\n });\n return { id, success: true };\n })\n );\n\n // Process chunk results\n const processedChunkResults = chunkResults.map((result, chunkIndex) => {\n const id = chunk[chunkIndex];\n if (!id) {\n throw new Error(`Chunk index ${chunkIndex} is out of bounds for chunk of size ${chunk.length}`);\n }\n if (result.status === 'fulfilled') {\n return { id, success: true };\n }\n\n // Extract error message more robustly\n let errorMessage = 'Unknown error';\n if (result.reason) {\n if (typeof result.reason === 'string') {\n errorMessage = result.reason;\n } else if (result.reason instanceof Error) {\n errorMessage = result.reason.message;\n } else if (result.reason && typeof result.reason === 'object' && 'message' in result.reason) {\n errorMessage = String(result.reason.message);\n } else if (result.reason && typeof result.reason === 'object' && 'error' in result.reason) {\n errorMessage = String(result.reason.error);\n } else {\n errorMessage = String(result.reason);\n }\n }\n\n return { id, success: false, error: errorMessage };\n });\n\n allResults.push(...processedChunkResults);\n }\n\n const successCount = allResults.filter((r) => r.success).length;\n const failureCount = allResults.filter((r) => !r.success).length;\n\n logger.info('gmail-label-delete completed', {\n totalRequested: validatedIds.length,\n successCount,\n failureCount,\n chunksProcessed: Math.ceil(validatedIds.length / CHUNK_SIZE),\n });\n\n const result: Output = {\n type: 'success' as const,\n totalRequested: validatedIds.length,\n successCount,\n failureCount,\n results: allResults,\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('gmail-label-delete error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error deleting labels: ${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","ErrorCode","McpError","google","z","CHUNK_SIZE","MAX_BATCH_SIZE","inputSchema","object","ids","array","coerce","string","trim","min","describe","successBranchSchema","type","literal","totalRequested","number","successCount","failureCount","results","id","success","boolean","error","optional","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","info","count","length","InvalidParams","validatedIds","invalidIds","trimmedId","push","includes","join","gmail","version","auth","authContext","labelsResponse","users","labels","list","userId","allLabels","data","labelMap","Map","map","label","allResults","i","chunk","slice","chunkIndex","chunkSize","totalChunks","Math","ceil","chunkResults","Promise","allSettled","get","Error","name","delete","processedChunkResults","status","errorMessage","reason","message","String","filter","r","chunksProcessed","content","text","JSON","stringify","structuredContent","InternalError","stack","undefined","createTool"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-gmail/src/mcp/tools/label-delete.ts"],"sourcesContent":["import type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport { schemas } from '@mcp-z/oauth-google';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport type { ToolModule } from '@mcp-z/server';\nimport { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { google } from 'googleapis';\nimport { z } from 'zod';\nimport { CHUNK_SIZE, MAX_BATCH_SIZE } from '../../constants.ts';\n\nconst inputSchema = z.object({\n ids: z.array(z.coerce.string().trim().min(1)).min(1).describe('Gmail label IDs to delete'),\n});\n\nconst successBranchSchema = z.object({\n type: z.literal('success'),\n totalRequested: z.number().describe('Total number of labels requested to delete'),\n successCount: z.number().describe('Number of labels successfully deleted'),\n failureCount: z.number().describe('Number of labels that failed to delete'),\n results: z\n .array(\n z.object({\n id: z.string().describe('Label 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 label'),\n});\n\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Delete Gmail labels permanently (irreversible). System labels (INBOX, SENT, etc.) cannot be deleted.',\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) {\n const logger = extra.logger;\n logger.info('gmail-label-delete called', { count: ids.length });\n\n if (!ids || ids.length === 0) {\n throw new McpError(ErrorCode.InvalidParams, 'Missing ids');\n }\n\n // Validate batch size to prevent memory exhaustion\n if (ids.length > MAX_BATCH_SIZE) {\n throw new McpError(ErrorCode.InvalidParams, `Batch size ${ids.length} exceeds maximum allowed size of ${MAX_BATCH_SIZE}`);\n }\n\n // Validate and sanitize IDs\n const validatedIds: string[] = [];\n const invalidIds: string[] = [];\n\n for (const id of ids) {\n const trimmedId = id.trim();\n if (!trimmedId) {\n invalidIds.push(id);\n continue;\n }\n // Basic Gmail label ID validation - should not contain certain characters\n if (trimmedId.includes('/') || trimmedId.includes('\\\\') || trimmedId.includes('<') || trimmedId.includes('>')) {\n invalidIds.push(id);\n continue;\n }\n validatedIds.push(trimmedId);\n }\n\n if (invalidIds.length > 0) {\n throw new McpError(ErrorCode.InvalidParams, `Found ${invalidIds.length} invalid IDs: ${invalidIds.join(', ')}`);\n }\n\n if (validatedIds.length === 0) {\n throw new McpError(ErrorCode.InvalidParams, 'No valid IDs found after validation');\n }\n\n try {\n const gmail = google.gmail({ version: 'v1', auth: extra.authContext.auth });\n // Get all labels first to check for system labels\n const labelsResponse = await gmail.users.labels.list({ userId: 'me' });\n const allLabels = labelsResponse.data.labels || [];\n const labelMap = new Map(allLabels.map((label) => [label.id || '', label]));\n\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 < validatedIds.length; i += CHUNK_SIZE) {\n const chunk = validatedIds.slice(i, i + CHUNK_SIZE);\n logger.info('Processing chunk', { chunkIndex: i / CHUNK_SIZE + 1, chunkSize: chunk.length, totalChunks: Math.ceil(validatedIds.length / CHUNK_SIZE) });\n\n const chunkResults = await Promise.allSettled(\n chunk.map(async (id) => {\n const label = labelMap.get(id);\n\n // Check if label exists\n if (!label) {\n throw new Error(`Label not found: ${id}`);\n }\n\n // Check if it's a system label\n if (label.type === 'system') {\n throw new Error(`Cannot delete system label: ${label.name} (${id})`);\n }\n\n // Delete the label\n await gmail.users.labels.delete({\n userId: 'me',\n id: id,\n });\n return { id, success: true };\n })\n );\n\n // Process chunk results\n const processedChunkResults = chunkResults.map((result, chunkIndex) => {\n const id = chunk[chunkIndex];\n if (!id) {\n throw new Error(`Chunk index ${chunkIndex} is out of bounds for chunk of size ${chunk.length}`);\n }\n if (result.status === 'fulfilled') {\n return { id, success: true };\n }\n\n // Extract error message more robustly\n let errorMessage = 'Unknown error';\n if (result.reason) {\n if (typeof result.reason === 'string') {\n errorMessage = result.reason;\n } else if (result.reason instanceof Error) {\n errorMessage = result.reason.message;\n } else if (result.reason && typeof result.reason === 'object' && 'message' in result.reason) {\n errorMessage = String(result.reason.message);\n } else if (result.reason && typeof result.reason === 'object' && 'error' in result.reason) {\n errorMessage = String(result.reason.error);\n } else {\n errorMessage = String(result.reason);\n }\n }\n\n return { id, success: false, error: errorMessage };\n });\n\n allResults.push(...processedChunkResults);\n }\n\n const successCount = allResults.filter((r) => r.success).length;\n const failureCount = allResults.filter((r) => !r.success).length;\n\n logger.info('gmail-label-delete completed', {\n totalRequested: validatedIds.length,\n successCount,\n failureCount,\n chunksProcessed: Math.ceil(validatedIds.length / CHUNK_SIZE),\n });\n\n const result: Output = {\n type: 'success' as const,\n totalRequested: validatedIds.length,\n successCount,\n failureCount,\n results: allResults,\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('gmail-label-delete error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error deleting labels: ${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","ErrorCode","McpError","google","z","CHUNK_SIZE","MAX_BATCH_SIZE","inputSchema","object","ids","array","coerce","string","trim","min","describe","successBranchSchema","type","literal","totalRequested","number","successCount","failureCount","results","id","success","boolean","error","optional","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","info","count","length","InvalidParams","validatedIds","invalidIds","trimmedId","push","includes","join","gmail","version","auth","authContext","labelsResponse","users","labels","list","userId","allLabels","data","labelMap","Map","map","label","allResults","i","chunk","slice","chunkIndex","chunkSize","totalChunks","Math","ceil","chunkResults","Promise","allSettled","get","Error","name","delete","processedChunkResults","status","errorMessage","reason","message","String","filter","r","chunksProcessed","content","text","JSON","stringify","structuredContent","InternalError","stack","undefined","createTool"],"mappings":"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"}