@mcp-z/mcp-gmail 2.0.0 → 2.1.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 (91) hide show
  1. package/dist/cjs/email/messages/fetch-message.d.cts +1 -1
  2. package/dist/cjs/email/messages/fetch-message.d.ts +1 -1
  3. package/dist/cjs/email/messages/fetch-message.js.map +1 -1
  4. package/dist/cjs/email/messages/messages.d.cts +1 -1
  5. package/dist/cjs/email/messages/messages.d.ts +1 -1
  6. package/dist/cjs/email/messages/messages.js.map +1 -1
  7. package/dist/cjs/email/parsing/html-processing.d.cts +1 -1
  8. package/dist/cjs/email/parsing/html-processing.d.ts +1 -1
  9. package/dist/cjs/email/parsing/html-processing.js.map +1 -1
  10. package/dist/cjs/email/querying/execute-query.d.cts +1 -1
  11. package/dist/cjs/email/querying/execute-query.d.ts +1 -1
  12. package/dist/cjs/email/querying/execute-query.js.map +1 -1
  13. package/dist/cjs/email/querying/pagination.d.cts +1 -1
  14. package/dist/cjs/email/querying/pagination.d.ts +1 -1
  15. package/dist/cjs/email/querying/pagination.js.map +1 -1
  16. package/dist/cjs/email/querying/search-execution.d.cts +1 -1
  17. package/dist/cjs/email/querying/search-execution.d.ts +1 -1
  18. package/dist/cjs/email/querying/search-execution.js.map +1 -1
  19. package/dist/cjs/labels/gmail-labels.d.cts +1 -1
  20. package/dist/cjs/labels/gmail-labels.d.ts +1 -1
  21. package/dist/cjs/labels/gmail-labels.js.map +1 -1
  22. package/dist/cjs/lib/google-auth.d.cts +9 -0
  23. package/dist/cjs/lib/google-auth.d.ts +9 -0
  24. package/dist/cjs/lib/google-auth.js +16 -0
  25. package/dist/cjs/lib/google-auth.js.map +1 -0
  26. package/dist/cjs/mcp/resources/email.js +4 -3
  27. package/dist/cjs/mcp/resources/email.js.map +1 -1
  28. package/dist/cjs/mcp/tools/categories-list.js +4 -3
  29. package/dist/cjs/mcp/tools/categories-list.js.map +1 -1
  30. package/dist/cjs/mcp/tools/label-add.js +4 -3
  31. package/dist/cjs/mcp/tools/label-add.js.map +1 -1
  32. package/dist/cjs/mcp/tools/label-delete.js +4 -3
  33. package/dist/cjs/mcp/tools/label-delete.js.map +1 -1
  34. package/dist/cjs/mcp/tools/labels-list.js +4 -3
  35. package/dist/cjs/mcp/tools/labels-list.js.map +1 -1
  36. package/dist/cjs/mcp/tools/message-get.js +4 -3
  37. package/dist/cjs/mcp/tools/message-get.js.map +1 -1
  38. package/dist/cjs/mcp/tools/message-mark-read.js +4 -3
  39. package/dist/cjs/mcp/tools/message-mark-read.js.map +1 -1
  40. package/dist/cjs/mcp/tools/message-move-to-trash.js +4 -3
  41. package/dist/cjs/mcp/tools/message-move-to-trash.js.map +1 -1
  42. package/dist/cjs/mcp/tools/message-respond.js +4 -3
  43. package/dist/cjs/mcp/tools/message-respond.js.map +1 -1
  44. package/dist/cjs/mcp/tools/message-search.js +4 -3
  45. package/dist/cjs/mcp/tools/message-search.js.map +1 -1
  46. package/dist/cjs/mcp/tools/message-send.js +4 -3
  47. package/dist/cjs/mcp/tools/message-send.js.map +1 -1
  48. package/dist/cjs/mcp/tools/messages-export-csv.js +4 -3
  49. package/dist/cjs/mcp/tools/messages-export-csv.js.map +1 -1
  50. package/dist/esm/email/messages/fetch-message.d.ts +1 -1
  51. package/dist/esm/email/messages/fetch-message.js.map +1 -1
  52. package/dist/esm/email/messages/messages.d.ts +1 -1
  53. package/dist/esm/email/messages/messages.js.map +1 -1
  54. package/dist/esm/email/parsing/html-processing.d.ts +1 -1
  55. package/dist/esm/email/parsing/html-processing.js.map +1 -1
  56. package/dist/esm/email/querying/execute-query.d.ts +1 -1
  57. package/dist/esm/email/querying/execute-query.js.map +1 -1
  58. package/dist/esm/email/querying/pagination.d.ts +1 -1
  59. package/dist/esm/email/querying/pagination.js.map +1 -1
  60. package/dist/esm/email/querying/search-execution.d.ts +1 -1
  61. package/dist/esm/email/querying/search-execution.js.map +1 -1
  62. package/dist/esm/labels/gmail-labels.d.ts +1 -1
  63. package/dist/esm/labels/gmail-labels.js.map +1 -1
  64. package/dist/esm/lib/google-auth.d.ts +9 -0
  65. package/dist/esm/lib/google-auth.js +11 -0
  66. package/dist/esm/lib/google-auth.js.map +1 -0
  67. package/dist/esm/mcp/resources/email.js +4 -3
  68. package/dist/esm/mcp/resources/email.js.map +1 -1
  69. package/dist/esm/mcp/tools/categories-list.js +4 -3
  70. package/dist/esm/mcp/tools/categories-list.js.map +1 -1
  71. package/dist/esm/mcp/tools/label-add.js +4 -3
  72. package/dist/esm/mcp/tools/label-add.js.map +1 -1
  73. package/dist/esm/mcp/tools/label-delete.js +4 -3
  74. package/dist/esm/mcp/tools/label-delete.js.map +1 -1
  75. package/dist/esm/mcp/tools/labels-list.js +4 -3
  76. package/dist/esm/mcp/tools/labels-list.js.map +1 -1
  77. package/dist/esm/mcp/tools/message-get.js +4 -3
  78. package/dist/esm/mcp/tools/message-get.js.map +1 -1
  79. package/dist/esm/mcp/tools/message-mark-read.js +4 -3
  80. package/dist/esm/mcp/tools/message-mark-read.js.map +1 -1
  81. package/dist/esm/mcp/tools/message-move-to-trash.js +4 -3
  82. package/dist/esm/mcp/tools/message-move-to-trash.js.map +1 -1
  83. package/dist/esm/mcp/tools/message-respond.js +4 -3
  84. package/dist/esm/mcp/tools/message-respond.js.map +1 -1
  85. package/dist/esm/mcp/tools/message-search.js +4 -3
  86. package/dist/esm/mcp/tools/message-search.js.map +1 -1
  87. package/dist/esm/mcp/tools/message-send.js +4 -3
  88. package/dist/esm/mcp/tools/message-send.js.map +1 -1
  89. package/dist/esm/mcp/tools/messages-export-csv.js +4 -3
  90. package/dist/esm/mcp/tools/messages-export-csv.js.map +1 -1
  91. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/mcp/tools/message-search.ts"],"sourcesContent":["import { ProtocolError, ProtocolErrorCode } from '@mcp-z/server';\n/** Gmail message search using middleware-based auth pattern */\n\nimport { EMAIL_COMMON_PATTERNS, EMAIL_FIELD_DESCRIPTIONS, EMAIL_FIELDS, EmailContentTypeSchema, type EmailDetail, EmailDetailSchema, ExcludeThreadHistorySchema } from '@mcp-z/email';\nimport type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport { schemas } from '@mcp-z/oauth-google';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport { createFieldsSchema, createPaginationSchema, createShapeSchema, filterFields, parseFields, type ToolModule, toColumnarFormat } from '@mcp-z/server';\nimport { type gmail_v1, google } from 'googleapis';\nimport { z } from 'zod';\nimport { DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE } from '../../constants.ts';\nimport { extractBodyFromPayload } from '../../email/parsing/html-processing.ts';\nimport { executeQuery as executeGmailQuery } from '../../email/querying/execute-query.ts';\nimport { GmailQueryParameterSchema, parseGmailQueryParameter } from '../../schemas/gmail-query-schema.ts';\n\nconst inputSchema = z.object({\n query: GmailQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and rawGmailQuery for Gmail syntax.'),\n fields: createFieldsSchema({\n availableFields: EMAIL_FIELDS,\n fieldDescriptions: EMAIL_FIELD_DESCRIPTIONS,\n commonPatterns: EMAIL_COMMON_PATTERNS,\n resourceName: 'email message',\n }),\n ...createPaginationSchema({ defaultPageSize: DEFAULT_PAGE_SIZE, maxPageSize: MAX_PAGE_SIZE, provider: 'gmail' }).shape,\n shape: createShapeSchema(),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schemas for different shapes\nconst successObjectsBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('objects'),\n items: z.array(EmailDetailSchema).describe('Matching email messages'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\nconst successArraysBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('arrays'),\n columns: z.array(z.string()).describe('Column names in canonical order'),\n rows: z.array(z.array(z.unknown())).describe('Row data matching column order'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\n// Output schema with auth_required support\n// Using z.union instead of discriminatedUnion since we have two success branches with different shapes\nconst outputSchema = z.union([successObjectsBranchSchema, successArraysBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Search Gmail messages using structured query objects with flexible field selection.',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\nasync function handler({ query, pageSize = DEFAULT_PAGE_SIZE, pageToken, fields, shape = 'arrays', contentType = 'text', excludeThreadHistory = false }: Input, extra: EnrichedExtra) {\n const logger = extra.logger;\n\n try {\n const parsedQuery = parseGmailQueryParameter(query);\n const requestedFields = parseFields(fields, EMAIL_FIELDS);\n const includeBody = requestedFields === 'all' || requestedFields.has('body');\n\n logger.info('gmail.message.search called', {\n query: parsedQuery,\n pageSize,\n pageToken: pageToken ? '[provided]' : undefined,\n fields,\n includeBody,\n accountId: extra.authContext.accountId, // Available from middleware\n });\n\n const gmail = google.gmail({ version: 'v1', auth: extra.authContext.auth });\n\n const started = Date.now();\n\n const exec = await executeGmailQuery(\n parsedQuery,\n {\n client: gmail,\n logger,\n pageSize,\n ...(pageToken !== undefined && { pageToken }),\n includeBody,\n },\n (full: unknown) => {\n // Type-safe property access with guards\n const fullData = full as gmail_v1.Schema$Message;\n\n const headersArray = Array.isArray(fullData?.payload?.headers) ? fullData.payload.headers : [];\n const headers = Object.fromEntries(\n headersArray.map((h: unknown) => {\n const header = h as gmail_v1.Schema$MessagePartHeader;\n return [String(header.name ?? ''), String(header.value ?? '')];\n })\n );\n\n const mapped: Partial<EmailDetail> = {\n id: String(fullData?.id ?? ''),\n threadId: fullData?.threadId ? String(fullData.threadId) : undefined,\n from: headers?.From,\n to: headers?.To,\n subject: headers?.Subject,\n date: headers?.Date,\n snippet: fullData?.snippet ? String(fullData.snippet) : undefined,\n };\n\n if (includeBody) {\n const payload = fullData?.payload;\n // Cast to Schema$MessagePart for extractBodyFromPayload\n const body = payload ? extractBodyFromPayload(payload as gmail_v1.Schema$MessagePart, { contentType, excludeThreadHistory }) : '';\n if (body) {\n mapped.body = body;\n mapped.bodyContentType = contentType;\n }\n }\n return mapped;\n }\n );\n\n const items = exec.items;\n const metadata = exec.metadata;\n const durationMs = Date.now() - started;\n\n // Type-safe field filtering\n const filteredItems = items.map((item) => filterFields(item, requestedFields));\n\n logger.info('gmail.message.search results', { query, pageSize, resultCount: filteredItems.length, fields: fields || 'all' });\n logger.info('gmail.message.search metrics', { durationMs, metadata });\n\n // Type-safe metadata access\n const metadataObj = metadata as { nextPageToken?: string } | undefined;\n\n // Build result based on shape\n const result: Output =\n shape === 'arrays'\n ? {\n type: 'success' as const,\n shape: 'arrays' as const,\n ...toColumnarFormat(filteredItems, requestedFields, EMAIL_FIELDS),\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\n }\n : {\n type: 'success' as const,\n shape: 'objects' as const,\n items: filteredItems,\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\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.message.search error', { error: message });\n\n throw new ProtocolError(ProtocolErrorCode.InternalError, `Error searching messages: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-search',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["createTool","AuthRequiredBranchSchema","schemas","inputSchema","z","object","query","GmailQueryParameterSchema","optional","describe","fields","createFieldsSchema","availableFields","EMAIL_FIELDS","fieldDescriptions","EMAIL_FIELD_DESCRIPTIONS","commonPatterns","EMAIL_COMMON_PATTERNS","resourceName","createPaginationSchema","defaultPageSize","DEFAULT_PAGE_SIZE","maxPageSize","MAX_PAGE_SIZE","provider","shape","createShapeSchema","contentType","EmailContentTypeSchema","excludeThreadHistory","ExcludeThreadHistorySchema","successObjectsBranchSchema","type","literal","items","array","EmailDetailSchema","nextPageToken","string","successArraysBranchSchema","columns","rows","unknown","outputSchema","union","config","description","result","handler","extra","pageSize","pageToken","logger","parsedQuery","requestedFields","includeBody","gmail","started","exec","metadata","durationMs","filteredItems","metadataObj","error","message","parseGmailQueryParameter","parseFields","has","info","undefined","accountId","authContext","google","version","auth","Date","now","executeGmailQuery","client","full","fullData","headersArray","Array","isArray","payload","headers","Object","fromEntries","map","h","header","String","name","value","mapped","id","threadId","from","From","to","To","subject","Subject","date","snippet","body","extractBodyFromPayload","bodyContentType","item","filterFields","resultCount","length","toColumnarFormat","content","text","JSON","stringify","structuredContent","Error","ProtocolError","ProtocolErrorCode","InternalError","stack"],"mappings":";;;;+BA+KA;;;eAAwBA;;;sBA/KyB;qBAGsH;2BAE/I;0BAKc;mBACpB;2BAC+B;gCACV;8BACW;kCACkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AARpE,IAAM,AAAEC,2BAA6BC,oBAAO,CAApCD;AAUR,IAAME,cAAcC,MAAC,CAACC,MAAM,CAAC;IAC3BC,OAAOC,6CAAyB,CAACC,QAAQ,GAAGC,QAAQ,CAAC;IACrDC,QAAQC,IAAAA,0BAAkB,EAAC;QACzBC,iBAAiBC,mBAAY;QAC7BC,mBAAmBC,+BAAwB;QAC3CC,gBAAgBC,4BAAqB;QACrCC,cAAc;IAChB;GACGC,IAAAA,8BAAsB,EAAC;IAAEC,iBAAiBC,8BAAiB;IAAEC,aAAaC,0BAAa;IAAEC,UAAU;AAAQ,GAAGC,KAAK;IACtHA,OAAOC,IAAAA,yBAAiB;IACxBC,aAAaC,6BAAsB;IACnCC,sBAAsBC,iCAA0B;;AAGlD,8CAA8C;AAC9C,IAAMC,6BAA6B3B,MAAC,CAACC,MAAM,CAAC;IAC1C2B,MAAM5B,MAAC,CAAC6B,OAAO,CAAC;IAChBR,OAAOrB,MAAC,CAAC6B,OAAO,CAAC;IACjBC,OAAO9B,MAAC,CAAC+B,KAAK,CAACC,wBAAiB,EAAE3B,QAAQ,CAAC;IAC3C4B,eAAejC,MAAC,CAACkC,MAAM,GAAG9B,QAAQ,GAAGC,QAAQ,CAAC;AAChD;AAEA,IAAM8B,4BAA4BnC,MAAC,CAACC,MAAM,CAAC;IACzC2B,MAAM5B,MAAC,CAAC6B,OAAO,CAAC;IAChBR,OAAOrB,MAAC,CAAC6B,OAAO,CAAC;IACjBO,SAASpC,MAAC,CAAC+B,KAAK,CAAC/B,MAAC,CAACkC,MAAM,IAAI7B,QAAQ,CAAC;IACtCgC,MAAMrC,MAAC,CAAC+B,KAAK,CAAC/B,MAAC,CAAC+B,KAAK,CAAC/B,MAAC,CAACsC,OAAO,KAAKjC,QAAQ,CAAC;IAC7C4B,eAAejC,MAAC,CAACkC,MAAM,GAAG9B,QAAQ,GAAGC,QAAQ,CAAC;AAChD;AAEA,2CAA2C;AAC3C,uGAAuG;AACvG,IAAMkC,eAAevC,MAAC,CAACwC,KAAK,CAAC;IAACb;IAA4BQ;IAA2BtC;CAAyB;AAE9G,IAAM4C,SAAS;IACbC,aAAa;IACb3C,aAAaA;IACbwC,cAAcvC,MAAC,CAACC,MAAM,CAAC;QACrB0C,QAAQJ;IACV;AACF;AAKA,SAAeK;wCAAQ,KAAuI,EAAEC,KAAoB;YAA3J3C,wBAAO4C,UAA8BC,WAAWzC,sBAAQe,2BAAkBE,0CAAsBE,sBACjHuB,QAGEC,aACAC,iBACAC,aAWAC,OAEAC,SAEAC,MA4CAxB,OACAyB,UACAC,YAGAC,eAMAC,aAGAf,QAwBCgB,OACDC;;;;oBAxGe1D,QAAF,MAAEA,yBAAF,MAAS4C,UAAAA,wCAAW7B,8BAAiB,oBAAE8B,YAAvC,MAAuCA,WAAWzC,SAAlD,MAAkDA,uBAAlD,MAA0De,OAAAA,kCAAQ,8CAAlE,MAA4EE,aAAAA,8CAAc,2DAA1F,MAAkGE,sBAAAA,gEAAuB;oBACxIuB,SAASH,MAAMG,MAAM;;;;;;;;;oBAGnBC,cAAcY,IAAAA,4CAAwB,EAAC3D;oBACvCgD,kBAAkBY,IAAAA,mBAAW,EAACxD,QAAQG,mBAAY;oBAClD0C,cAAcD,oBAAoB,SAASA,gBAAgBa,GAAG,CAAC;oBAErEf,OAAOgB,IAAI,CAAC,+BAA+B;wBACzC9D,OAAO+C;wBACPH,UAAAA;wBACAC,WAAWA,YAAY,eAAekB;wBACtC3D,QAAAA;wBACA6C,aAAAA;wBACAe,WAAWrB,MAAMsB,WAAW,CAACD,SAAS;oBACxC;oBAEMd,QAAQgB,kBAAM,CAAChB,KAAK,CAAC;wBAAEiB,SAAS;wBAAMC,MAAMzB,MAAMsB,WAAW,CAACG,IAAI;oBAAC;oBAEnEjB,UAAUkB,KAAKC,GAAG;oBAEX;;wBAAMC,IAAAA,4BAAiB,EAClCxB,aACA;4BACEyB,QAAQtB;4BACRJ,QAAAA;4BACAF,UAAAA;2BACIC,cAAckB,aAAa;4BAAElB,WAAAA;wBAAU;4BAC3CI,aAAAA;4BAEF,SAACwB;;gCAIoCC;4BAHnC,wCAAwC;4BACxC,IAAMA,WAAWD;4BAEjB,IAAME,eAAeC,MAAMC,OAAO,CAACH,qBAAAA,gCAAAA,oBAAAA,SAAUI,OAAO,cAAjBJ,wCAAAA,kBAAmBK,OAAO,IAAIL,SAASI,OAAO,CAACC,OAAO,GAAG,EAAE;4BAC9F,IAAMA,UAAUC,OAAOC,WAAW,CAChCN,aAAaO,GAAG,CAAC,SAACC;oCAEDC,cAA2BA;gCAD1C,IAAMA,SAASD;gCACf,OAAO;oCAACE,QAAOD,eAAAA,OAAOE,IAAI,cAAXF,0BAAAA,eAAe;oCAAKC,QAAOD,gBAAAA,OAAOG,KAAK,cAAZH,2BAAAA,gBAAgB;iCAAI;4BAChE;4BAGF,IAAMI,SAA+B;gCACnCC,IAAIJ,eAAOX,qBAAAA,+BAAAA,SAAUe,EAAE,uCAAI;gCAC3BC,UAAUhB,CAAAA,qBAAAA,+BAAAA,SAAUgB,QAAQ,IAAGL,OAAOX,SAASgB,QAAQ,IAAI3B;gCAC3D4B,IAAI,EAAEZ,oBAAAA,8BAAAA,QAASa,IAAI;gCACnBC,EAAE,EAAEd,oBAAAA,8BAAAA,QAASe,EAAE;gCACfC,OAAO,EAAEhB,oBAAAA,8BAAAA,QAASiB,OAAO;gCACzBC,IAAI,EAAElB,oBAAAA,8BAAAA,QAASV,IAAI;gCACnB6B,SAASxB,CAAAA,qBAAAA,+BAAAA,SAAUwB,OAAO,IAAGb,OAAOX,SAASwB,OAAO,IAAInC;4BAC1D;4BAEA,IAAId,aAAa;gCACf,IAAM6B,UAAUJ,qBAAAA,+BAAAA,SAAUI,OAAO;gCACjC,wDAAwD;gCACxD,IAAMqB,OAAOrB,UAAUsB,IAAAA,wCAAsB,EAACtB,SAAwC;oCAAEzD,aAAAA;oCAAaE,sBAAAA;gCAAqB,KAAK;gCAC/H,IAAI4E,MAAM;oCACRX,OAAOW,IAAI,GAAGA;oCACdX,OAAOa,eAAe,GAAGhF;gCAC3B;4BACF;4BACA,OAAOmE;wBACT;;;oBAzCIpC,OAAO;oBA4CPxB,QAAQwB,KAAKxB,KAAK;oBAClByB,WAAWD,KAAKC,QAAQ;oBACxBC,aAAae,KAAKC,GAAG,KAAKnB;oBAEhC,4BAA4B;oBACtBI,gBAAgB3B,MAAMsD,GAAG,CAAC,SAACoB;+BAASC,IAAAA,oBAAY,EAACD,MAAMtD;;oBAE7DF,OAAOgB,IAAI,CAAC,gCAAgC;wBAAE9D,OAAAA;wBAAO4C,UAAAA;wBAAU4D,aAAajD,cAAckD,MAAM;wBAAErG,QAAQA,UAAU;oBAAM;oBAC1H0C,OAAOgB,IAAI,CAAC,gCAAgC;wBAAER,YAAAA;wBAAYD,UAAAA;oBAAS;oBAEnE,4BAA4B;oBACtBG,cAAcH;oBAEpB,8BAA8B;oBACxBZ,SACJtB,UAAU,WACN;wBACEO,MAAM;wBACNP,OAAO;uBACJuF,IAAAA,wBAAgB,EAACnD,eAAeP,iBAAiBzC,mBAAY,GAC5DiD,CAAAA,wBAAAA,kCAAAA,YAAazB,aAAa,KAAI;wBAAEA,eAAeyB,YAAYzB,aAAa;oBAAC,KAE/E;wBACEL,MAAM;wBACNP,OAAO;wBACPS,OAAO2B;uBACHC,CAAAA,wBAAAA,kCAAAA,YAAazB,aAAa,KAAI;wBAAEA,eAAeyB,YAAYzB,aAAa;oBAAC;oBAGrF;;wBAAO;4BACL4E,OAAO;gCACL;oCACEjF,MAAM;oCACNkF,MAAMC,KAAKC,SAAS,CAACrE;gCACvB;;4BAEFsE,mBAAmB;gCAAEtE,QAAAA;4BAAO;wBAC9B;;;oBACOgB;oBACDC,UAAUD,AAAK,YAALA,OAAiBuD,SAAQvD,MAAMC,OAAO,GAAG2B,OAAO5B;oBAChEX,OAAOW,KAAK,CAAC,8BAA8B;wBAAEA,OAAOC;oBAAQ;oBAE5D,MAAM,IAAIuD,qBAAa,CAACC,yBAAiB,CAACC,aAAa,EAAE,AAAC,6BAAoC,OAARzD,UAAW;wBAC/F0D,OAAO3D,AAAK,YAALA,OAAiBuD,SAAQvD,MAAM2D,KAAK,GAAGrD;oBAChD;;;;;;;IAEJ;;AAEe,SAASrE;IACtB,OAAO;QACL4F,MAAM;QACN/C,QAAAA;QACAG,SAAAA;IACF;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/mcp/tools/message-search.ts"],"sourcesContent":["import { type gmail_v1, gmail as gmailApi } from '@googleapis/gmail';\nimport { ProtocolError, ProtocolErrorCode } from '@mcp-z/server';\n/** Gmail message search using middleware-based auth pattern */\n\nimport { EMAIL_COMMON_PATTERNS, EMAIL_FIELD_DESCRIPTIONS, EMAIL_FIELDS, EmailContentTypeSchema, type EmailDetail, EmailDetailSchema, ExcludeThreadHistorySchema } from '@mcp-z/email';\nimport type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport { schemas } from '@mcp-z/oauth-google';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport { createFieldsSchema, createPaginationSchema, createShapeSchema, filterFields, parseFields, type ToolModule, toColumnarFormat } from '@mcp-z/server';\nimport { z } from 'zod';\nimport { DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE } from '../../constants.ts';\nimport { extractBodyFromPayload } from '../../email/parsing/html-processing.ts';\nimport { executeQuery as executeGmailQuery } from '../../email/querying/execute-query.ts';\nimport { googleAuth } from '../../lib/google-auth.ts';\nimport { GmailQueryParameterSchema, parseGmailQueryParameter } from '../../schemas/gmail-query-schema.ts';\n\nconst inputSchema = z.object({\n query: GmailQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and rawGmailQuery for Gmail syntax.'),\n fields: createFieldsSchema({\n availableFields: EMAIL_FIELDS,\n fieldDescriptions: EMAIL_FIELD_DESCRIPTIONS,\n commonPatterns: EMAIL_COMMON_PATTERNS,\n resourceName: 'email message',\n }),\n ...createPaginationSchema({ defaultPageSize: DEFAULT_PAGE_SIZE, maxPageSize: MAX_PAGE_SIZE, provider: 'gmail' }).shape,\n shape: createShapeSchema(),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schemas for different shapes\nconst successObjectsBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('objects'),\n items: z.array(EmailDetailSchema).describe('Matching email messages'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\nconst successArraysBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('arrays'),\n columns: z.array(z.string()).describe('Column names in canonical order'),\n rows: z.array(z.array(z.unknown())).describe('Row data matching column order'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\n// Output schema with auth_required support\n// Using z.union instead of discriminatedUnion since we have two success branches with different shapes\nconst outputSchema = z.union([successObjectsBranchSchema, successArraysBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Search Gmail messages using structured query objects with flexible field selection.',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\nasync function handler({ query, pageSize = DEFAULT_PAGE_SIZE, pageToken, fields, shape = 'arrays', contentType = 'text', excludeThreadHistory = false }: Input, extra: EnrichedExtra) {\n const logger = extra.logger;\n\n try {\n const parsedQuery = parseGmailQueryParameter(query);\n const requestedFields = parseFields(fields, EMAIL_FIELDS);\n const includeBody = requestedFields === 'all' || requestedFields.has('body');\n\n logger.info('gmail.message.search called', {\n query: parsedQuery,\n pageSize,\n pageToken: pageToken ? '[provided]' : undefined,\n fields,\n includeBody,\n accountId: extra.authContext.accountId, // Available from middleware\n });\n\n const gmail = gmailApi({ version: 'v1', auth: googleAuth(extra.authContext.auth) });\n\n const started = Date.now();\n\n const exec = await executeGmailQuery(\n parsedQuery,\n {\n client: gmail,\n logger,\n pageSize,\n ...(pageToken !== undefined && { pageToken }),\n includeBody,\n },\n (full: unknown) => {\n // Type-safe property access with guards\n const fullData = full as gmail_v1.Schema$Message;\n\n const headersArray = Array.isArray(fullData?.payload?.headers) ? fullData.payload.headers : [];\n const headers = Object.fromEntries(\n headersArray.map((h: unknown) => {\n const header = h as gmail_v1.Schema$MessagePartHeader;\n return [String(header.name ?? ''), String(header.value ?? '')];\n })\n );\n\n const mapped: Partial<EmailDetail> = {\n id: String(fullData?.id ?? ''),\n threadId: fullData?.threadId ? String(fullData.threadId) : undefined,\n from: headers?.From,\n to: headers?.To,\n subject: headers?.Subject,\n date: headers?.Date,\n snippet: fullData?.snippet ? String(fullData.snippet) : undefined,\n };\n\n if (includeBody) {\n const payload = fullData?.payload;\n // Cast to Schema$MessagePart for extractBodyFromPayload\n const body = payload ? extractBodyFromPayload(payload as gmail_v1.Schema$MessagePart, { contentType, excludeThreadHistory }) : '';\n if (body) {\n mapped.body = body;\n mapped.bodyContentType = contentType;\n }\n }\n return mapped;\n }\n );\n\n const items = exec.items;\n const metadata = exec.metadata;\n const durationMs = Date.now() - started;\n\n // Type-safe field filtering\n const filteredItems = items.map((item) => filterFields(item, requestedFields));\n\n logger.info('gmail.message.search results', { query, pageSize, resultCount: filteredItems.length, fields: fields || 'all' });\n logger.info('gmail.message.search metrics', { durationMs, metadata });\n\n // Type-safe metadata access\n const metadataObj = metadata as { nextPageToken?: string } | undefined;\n\n // Build result based on shape\n const result: Output =\n shape === 'arrays'\n ? {\n type: 'success' as const,\n shape: 'arrays' as const,\n ...toColumnarFormat(filteredItems, requestedFields, EMAIL_FIELDS),\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\n }\n : {\n type: 'success' as const,\n shape: 'objects' as const,\n items: filteredItems,\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\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.message.search error', { error: message });\n\n throw new ProtocolError(ProtocolErrorCode.InternalError, `Error searching messages: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-search',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["createTool","AuthRequiredBranchSchema","schemas","inputSchema","z","object","query","GmailQueryParameterSchema","optional","describe","fields","createFieldsSchema","availableFields","EMAIL_FIELDS","fieldDescriptions","EMAIL_FIELD_DESCRIPTIONS","commonPatterns","EMAIL_COMMON_PATTERNS","resourceName","createPaginationSchema","defaultPageSize","DEFAULT_PAGE_SIZE","maxPageSize","MAX_PAGE_SIZE","provider","shape","createShapeSchema","contentType","EmailContentTypeSchema","excludeThreadHistory","ExcludeThreadHistorySchema","successObjectsBranchSchema","type","literal","items","array","EmailDetailSchema","nextPageToken","string","successArraysBranchSchema","columns","rows","unknown","outputSchema","union","config","description","result","handler","extra","pageSize","pageToken","logger","parsedQuery","requestedFields","includeBody","gmail","started","exec","metadata","durationMs","filteredItems","metadataObj","error","message","parseGmailQueryParameter","parseFields","has","info","undefined","accountId","authContext","gmailApi","version","auth","googleAuth","Date","now","executeGmailQuery","client","full","fullData","headersArray","Array","isArray","payload","headers","Object","fromEntries","map","h","header","String","name","value","mapped","id","threadId","from","From","to","To","subject","Subject","date","snippet","body","extractBodyFromPayload","bodyContentType","item","filterFields","resultCount","length","toColumnarFormat","content","text","JSON","stringify","structuredContent","Error","ProtocolError","ProtocolErrorCode","InternalError","stack"],"mappings":"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"}
@@ -8,13 +8,14 @@ Object.defineProperty(exports, "default", {
8
8
  return createTool;
9
9
  }
10
10
  });
11
+ var _gmail = require("@googleapis/gmail");
11
12
  var _email = require("@mcp-z/email");
12
13
  var _oauthgoogle = require("@mcp-z/oauth-google");
13
14
  var _server = require("@mcp-z/server");
14
- var _googleapis = require("googleapis");
15
15
  var _zod = require("zod");
16
16
  var _rfc822builderts = require("../../email/composition/rfc822-builder.js");
17
17
  var _base64encodingts = require("../../lib/base64-encoding.js");
18
+ var _googleauthts = require("../../lib/google-auth.js");
18
19
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
19
20
  try {
20
21
  var info = gen[key](arg);
@@ -208,9 +209,9 @@ function handler(params, extra) {
208
209
  if (subject !== undefined) msgArgs.subject = subject;
209
210
  raw = (0, _rfc822builderts.buildRfc822FromArgs)(msgArgs);
210
211
  encodedMessage = (0, _base64encodingts.b64url)(raw);
211
- gmail = _googleapis.google.gmail({
212
+ gmail = (0, _gmail.gmail)({
212
213
  version: 'v1',
213
- auth: extra.authContext.auth
214
+ auth: (0, _googleauthts.googleAuth)(extra.authContext.auth)
214
215
  });
215
216
  return [
216
217
  4,
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/mcp/tools/message-send.ts"],"sourcesContent":["import { ComposeContentTypeSchema, createEmailRecipientsSchema, createMessageResultSchema } from '@mcp-z/email';\nimport type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport { schemas } from '@mcp-z/oauth-google';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport type { ToolModule } from '@mcp-z/server';\nimport { ProtocolError, ProtocolErrorCode } from '@mcp-z/server';\nimport { google } from 'googleapis';\nimport { z } from 'zod';\nimport { buildRfc822FromArgs } from '../../email/composition/rfc822-builder.ts';\nimport { b64url } from '../../lib/base64-encoding.ts';\n\nconst inputSchema = z.object({\n to: createEmailRecipientsSchema('to', true),\n cc: createEmailRecipientsSchema('cc', false),\n bcc: createEmailRecipientsSchema('bcc', false),\n subject: z.string().describe('Message subject').default(''),\n body: z.string().trim().min(1).describe('Email body content (plain text or HTML)'),\n contentType: ComposeContentTypeSchema,\n});\n\n// Success branch schema\nconst successBranchSchema = z.object({\n type: z.literal('success'),\n item: createMessageResultSchema('gmail'),\n});\n\n// Output schema with auth_required support\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Send an email message through Gmail',\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(params: Input, extra: EnrichedExtra) {\n const { to, cc, bcc, subject, body, contentType } = params;\n const logger = extra.logger;\n logger.info('gmail.message.send called', { to, subject, contentType });\n\n if (!to) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Missing required field: to');\n }\n\n try {\n // Build RFC822 message - only include optional headers when defined to satisfy\n // exactOptionalPropertyTypes (avoid passing `undefined` into optional props)\n const msgArgs: { to: string; cc?: string; bcc?: string; subject?: string; body: string; contentType: 'text' | 'html' } = { to, body, contentType };\n if (cc !== undefined) msgArgs.cc = cc;\n if (bcc !== undefined) msgArgs.bcc = bcc;\n if (subject !== undefined) msgArgs.subject = subject;\n\n const raw = buildRfc822FromArgs(msgArgs);\n const encodedMessage = b64url(raw);\n\n const gmail = google.gmail({ version: 'v1', auth: extra.authContext.auth });\n\n const sendRes = await gmail.users.messages.send({\n userId: 'me',\n requestBody: { raw: encodedMessage },\n });\n const sendData = sendRes.data;\n const messageId = sendData.id || 'unknown';\n logger.info('Gmail: sent message successfully', { id: messageId });\n logger.info('gmail.message.send result (typed)', { to, subject, messageId });\n\n const totalRecipients = (Array.isArray(to) ? to.length : 1) + (cc ? (Array.isArray(cc) ? cc.length : 1) : 0) + (bcc ? (Array.isArray(bcc) ? bcc.length : 1) : 0);\n const result: Output = {\n type: 'success' as const,\n item: {\n id: messageId,\n sentAt: new Date().toISOString(),\n recipientCount: totalRecipients,\n webLink: `https://mail.google.com/mail/u/0/#sent/${messageId}`,\n },\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result),\n },\n ],\n structuredContent: { result },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error('gmail.message.send error', { error: message });\n\n throw new ProtocolError(ProtocolErrorCode.InternalError, `Error sending message: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-send',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["createTool","AuthRequiredBranchSchema","schemas","inputSchema","z","object","to","createEmailRecipientsSchema","cc","bcc","subject","string","describe","default","body","trim","min","contentType","ComposeContentTypeSchema","successBranchSchema","type","literal","item","createMessageResultSchema","outputSchema","discriminatedUnion","config","description","result","handler","params","extra","logger","msgArgs","raw","encodedMessage","gmail","sendRes","sendData","messageId","totalRecipients","error","message","info","ProtocolError","ProtocolErrorCode","InvalidParams","undefined","buildRfc822FromArgs","b64url","google","version","auth","authContext","users","messages","send","userId","requestBody","data","id","Array","isArray","length","sentAt","Date","toISOString","recipientCount","webLink","content","text","JSON","stringify","structuredContent","Error","String","InternalError","stack","name"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/mcp/tools/message-send.ts"],"sourcesContent":["import { gmail as gmailApi } from '@googleapis/gmail';\nimport { ComposeContentTypeSchema, createEmailRecipientsSchema, createMessageResultSchema } from '@mcp-z/email';\nimport type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport { schemas } from '@mcp-z/oauth-google';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport type { ToolModule } from '@mcp-z/server';\nimport { ProtocolError, ProtocolErrorCode } from '@mcp-z/server';\nimport { z } from 'zod';\nimport { buildRfc822FromArgs } from '../../email/composition/rfc822-builder.ts';\nimport { b64url } from '../../lib/base64-encoding.ts';\nimport { googleAuth } from '../../lib/google-auth.ts';\n\nconst inputSchema = z.object({\n to: createEmailRecipientsSchema('to', true),\n cc: createEmailRecipientsSchema('cc', false),\n bcc: createEmailRecipientsSchema('bcc', false),\n subject: z.string().describe('Message subject').default(''),\n body: z.string().trim().min(1).describe('Email body content (plain text or HTML)'),\n contentType: ComposeContentTypeSchema,\n});\n\n// Success branch schema\nconst successBranchSchema = z.object({\n type: z.literal('success'),\n item: createMessageResultSchema('gmail'),\n});\n\n// Output schema with auth_required support\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Send an email message through Gmail',\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(params: Input, extra: EnrichedExtra) {\n const { to, cc, bcc, subject, body, contentType } = params;\n const logger = extra.logger;\n logger.info('gmail.message.send called', { to, subject, contentType });\n\n if (!to) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Missing required field: to');\n }\n\n try {\n // Build RFC822 message - only include optional headers when defined to satisfy\n // exactOptionalPropertyTypes (avoid passing `undefined` into optional props)\n const msgArgs: { to: string; cc?: string; bcc?: string; subject?: string; body: string; contentType: 'text' | 'html' } = { to, body, contentType };\n if (cc !== undefined) msgArgs.cc = cc;\n if (bcc !== undefined) msgArgs.bcc = bcc;\n if (subject !== undefined) msgArgs.subject = subject;\n\n const raw = buildRfc822FromArgs(msgArgs);\n const encodedMessage = b64url(raw);\n\n const gmail = gmailApi({ version: 'v1', auth: googleAuth(extra.authContext.auth) });\n\n const sendRes = await gmail.users.messages.send({\n userId: 'me',\n requestBody: { raw: encodedMessage },\n });\n const sendData = sendRes.data;\n const messageId = sendData.id || 'unknown';\n logger.info('Gmail: sent message successfully', { id: messageId });\n logger.info('gmail.message.send result (typed)', { to, subject, messageId });\n\n const totalRecipients = (Array.isArray(to) ? to.length : 1) + (cc ? (Array.isArray(cc) ? cc.length : 1) : 0) + (bcc ? (Array.isArray(bcc) ? bcc.length : 1) : 0);\n const result: Output = {\n type: 'success' as const,\n item: {\n id: messageId,\n sentAt: new Date().toISOString(),\n recipientCount: totalRecipients,\n webLink: `https://mail.google.com/mail/u/0/#sent/${messageId}`,\n },\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result),\n },\n ],\n structuredContent: { result },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error('gmail.message.send error', { error: message });\n\n throw new ProtocolError(ProtocolErrorCode.InternalError, `Error sending message: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-send',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["createTool","AuthRequiredBranchSchema","schemas","inputSchema","z","object","to","createEmailRecipientsSchema","cc","bcc","subject","string","describe","default","body","trim","min","contentType","ComposeContentTypeSchema","successBranchSchema","type","literal","item","createMessageResultSchema","outputSchema","discriminatedUnion","config","description","result","handler","params","extra","logger","msgArgs","raw","encodedMessage","gmail","sendRes","sendData","messageId","totalRecipients","error","message","info","ProtocolError","ProtocolErrorCode","InvalidParams","undefined","buildRfc822FromArgs","b64url","gmailApi","version","auth","googleAuth","authContext","users","messages","send","userId","requestBody","data","id","Array","isArray","length","sentAt","Date","toISOString","recipientCount","webLink","content","text","JSON","stringify","structuredContent","Error","String","InternalError","stack","name"],"mappings":";;;;+BAwGA;;;eAAwBA;;;qBAxGU;qBAC+D;2BAEzE;sBAKyB;mBAC/B;+BACkB;gCACb;4BACI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAP3B,IAAM,AAAEC,2BAA6BC,oBAAO,CAApCD;AASR,IAAME,cAAcC,MAAC,CAACC,MAAM,CAAC;IAC3BC,IAAIC,IAAAA,kCAA2B,EAAC,MAAM;IACtCC,IAAID,IAAAA,kCAA2B,EAAC,MAAM;IACtCE,KAAKF,IAAAA,kCAA2B,EAAC,OAAO;IACxCG,SAASN,MAAC,CAACO,MAAM,GAAGC,QAAQ,CAAC,mBAAmBC,OAAO,CAAC;IACxDC,MAAMV,MAAC,CAACO,MAAM,GAAGI,IAAI,GAAGC,GAAG,CAAC,GAAGJ,QAAQ,CAAC;IACxCK,aAAaC,+BAAwB;AACvC;AAEA,wBAAwB;AACxB,IAAMC,sBAAsBf,MAAC,CAACC,MAAM,CAAC;IACnCe,MAAMhB,MAAC,CAACiB,OAAO,CAAC;IAChBC,MAAMC,IAAAA,gCAAyB,EAAC;AAClC;AAEA,2CAA2C;AAC3C,IAAMC,eAAepB,MAAC,CAACqB,kBAAkB,CAAC,QAAQ;IAACN;IAAqBlB;CAAyB;AAEjG,IAAMyB,SAAS;IACbC,aAAa;IACbxB,aAAaA;IACbqB,cAAcpB,MAAC,CAACC,MAAM,CAAC;QACrBuB,QAAQJ;IACV;AACF;AAKA,SAAeK,QAAQC,MAAa,EAAEC,KAAoB;;YAChDzB,IAAIE,IAAIC,KAAKC,SAASI,MAAMG,aAC9Be,QAUEC,SAKAC,KACAC,gBAEAC,OAEAC,SAIAC,UACAC,WAIAC,iBACAZ,QAmBCa,OACDC;;;;oBAnDApC,KAA4CwB,OAA5CxB,IAAIE,KAAwCsB,OAAxCtB,IAAIC,MAAoCqB,OAApCrB,KAAKC,UAA+BoB,OAA/BpB,SAASI,OAAsBgB,OAAtBhB,MAAMG,cAAgBa,OAAhBb;oBAC9Be,SAASD,MAAMC,MAAM;oBAC3BA,OAAOW,IAAI,CAAC,6BAA6B;wBAAErC,IAAAA;wBAAII,SAAAA;wBAASO,aAAAA;oBAAY;oBAEpE,IAAI,CAACX,IAAI;wBACP,MAAM,IAAIsC,qBAAa,CAACC,yBAAiB,CAACC,aAAa,EAAE;oBAC3D;;;;;;;;;oBAGE,+EAA+E;oBAC/E,6EAA6E;oBACvEb,UAAmH;wBAAE3B,IAAAA;wBAAIQ,MAAAA;wBAAMG,aAAAA;oBAAY;oBACjJ,IAAIT,OAAOuC,WAAWd,QAAQzB,EAAE,GAAGA;oBACnC,IAAIC,QAAQsC,WAAWd,QAAQxB,GAAG,GAAGA;oBACrC,IAAIC,YAAYqC,WAAWd,QAAQvB,OAAO,GAAGA;oBAEvCwB,MAAMc,IAAAA,oCAAmB,EAACf;oBAC1BE,iBAAiBc,IAAAA,wBAAM,EAACf;oBAExBE,QAAQc,IAAAA,YAAQ,EAAC;wBAAEC,SAAS;wBAAMC,MAAMC,IAAAA,wBAAU,EAACtB,MAAMuB,WAAW,CAACF,IAAI;oBAAE;oBAEjE;;wBAAMhB,MAAMmB,KAAK,CAACC,QAAQ,CAACC,IAAI,CAAC;4BAC9CC,QAAQ;4BACRC,aAAa;gCAAEzB,KAAKC;4BAAe;wBACrC;;;oBAHME,UAAU;oBAIVC,WAAWD,QAAQuB,IAAI;oBACvBrB,YAAYD,SAASuB,EAAE,IAAI;oBACjC7B,OAAOW,IAAI,CAAC,oCAAoC;wBAAEkB,IAAItB;oBAAU;oBAChEP,OAAOW,IAAI,CAAC,qCAAqC;wBAAErC,IAAAA;wBAAII,SAAAA;wBAAS6B,WAAAA;oBAAU;oBAEpEC,kBAAkB,AAACsB,CAAAA,MAAMC,OAAO,CAACzD,MAAMA,GAAG0D,MAAM,GAAG,CAAA,IAAMxD,CAAAA,KAAMsD,MAAMC,OAAO,CAACvD,MAAMA,GAAGwD,MAAM,GAAG,IAAK,CAAA,IAAMvD,CAAAA,MAAOqD,MAAMC,OAAO,CAACtD,OAAOA,IAAIuD,MAAM,GAAG,IAAK,CAAA;oBACxJpC,SAAiB;wBACrBR,MAAM;wBACNE,MAAM;4BACJuC,IAAItB;4BACJ0B,QAAQ,IAAIC,OAAOC,WAAW;4BAC9BC,gBAAgB5B;4BAChB6B,SAAS,AAAC,0CAAmD,OAAV9B;wBACrD;oBACF;oBAEA;;wBAAO;4BACL+B,OAAO;gCACL;oCACElD,MAAM;oCACNmD,MAAMC,KAAKC,SAAS,CAAC7C;gCACvB;;4BAEF8C,mBAAmB;gCAAE9C,QAAAA;4BAAO;wBAC9B;;;oBACOa;oBACDC,UAAUD,AAAK,YAALA,OAAiBkC,SAAQlC,MAAMC,OAAO,GAAGkC,OAAOnC;oBAChET,OAAOS,KAAK,CAAC,4BAA4B;wBAAEA,OAAOC;oBAAQ;oBAE1D,MAAM,IAAIE,qBAAa,CAACC,yBAAiB,CAACgC,aAAa,EAAE,AAAC,0BAAiC,OAARnC,UAAW;wBAC5FoC,OAAOrC,AAAK,YAALA,OAAiBkC,SAAQlC,MAAMqC,KAAK,GAAG/B;oBAChD;;;;;;;IAEJ;;AAEe,SAAS/C;IACtB,OAAO;QACL+E,MAAM;QACNrD,QAAAA;QACAG,SAAAA;IACF;AACF"}
@@ -8,17 +8,18 @@ Object.defineProperty(exports, "default", {
8
8
  return createTool;
9
9
  }
10
10
  });
11
+ var _gmail = require("@googleapis/gmail");
11
12
  var _email = require("@mcp-z/email");
12
13
  var _oauthgoogle = require("@mcp-z/oauth-google");
13
14
  var _server = require("@mcp-z/server");
14
15
  var _sync = require("csv-stringify/sync");
15
16
  var _fs = require("fs");
16
17
  var _promises = require("fs/promises");
17
- var _googleapis = require("googleapis");
18
18
  var _zod = require("zod");
19
19
  var _constantsts = require("../../constants.js");
20
20
  var _htmlprocessingts = require("../../email/parsing/html-processing.js");
21
21
  var _executequeryts = require("../../email/querying/execute-query.js");
22
+ var _googleauthts = require("../../lib/google-auth.js");
22
23
  var _gmailqueryschemats = require("../../schemas/gmail-query-schema.js");
23
24
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
24
25
  try {
@@ -275,9 +276,9 @@ var config = {
275
276
  filename: filename,
276
277
  accountId: extra.authContext.accountId
277
278
  });
278
- gmail = _googleapis.google.gmail({
279
+ gmail = (0, _gmail.gmail)({
279
280
  version: 'v1',
280
- auth: extra.authContext.auth
281
+ auth: (0, _googleauthts.googleAuth)(extra.authContext.auth)
281
282
  });
282
283
  // Create CSV headers (all email fields)
283
284
  csvHeaders = [
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/mcp/tools/messages-export-csv.ts"],"sourcesContent":["import { EmailContentTypeSchema, ExcludeThreadHistorySchema } from '@mcp-z/email';\nimport type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport { schemas } from '@mcp-z/oauth-google';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport { getFileUri, ProtocolError, ProtocolErrorCode, reserveFile, type ToolModule } from '@mcp-z/server';\n\nimport { stringify } from 'csv-stringify/sync';\nimport { createWriteStream } from 'fs';\nimport { unlink } from 'fs/promises';\nimport { type gmail_v1, google } from 'googleapis';\nimport { z } from 'zod';\nimport { DEFAULT_PAGE_SIZE } from '../../constants.ts';\nimport { extractBodyFromPayload } from '../../email/parsing/html-processing.ts';\nimport { executeQuery as executeGmailQuery } from '../../email/querying/execute-query.ts';\nimport { GmailQueryParameterSchema, parseGmailQueryParameter } from '../../schemas/gmail-query-schema.ts';\nimport type { StorageExtra } from '../../types.ts';\n\nconst DEFAULT_MAX_ITEMS = 10000;\nconst MAX_EXPORT_ITEMS = 50000;\n\n/**\n * CSV row format based on EmailDetail\n * All fields are strings (empty string instead of undefined)\n * Includes additional CSV-specific fields: provider and labels\n */\ninterface CsvRow {\n id: string;\n threadId: string;\n from: string;\n to: string;\n cc: string;\n bcc: string;\n subject: string;\n date: string;\n snippet: string;\n body: string;\n provider: string;\n labels: string;\n}\n\nconst inputSchema = z.object({\n query: GmailQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and rawGmailQuery for Gmail syntax.'),\n maxItems: z.number().int().positive().max(MAX_EXPORT_ITEMS).default(DEFAULT_MAX_ITEMS).describe(`Maximum messages to export (default: ${DEFAULT_MAX_ITEMS}, max: ${MAX_EXPORT_ITEMS})`),\n filename: z.string().trim().min(1).default('gmail-messages.csv').describe('Output filename (default: gmail-messages.csv)'),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\nconst successBranchSchema = z.object({\n type: z.literal('success'),\n uri: z.string().describe('File URI (file:// or http://)'),\n filename: z.string().describe('Stored filename'),\n rowCount: z.number().describe('Number of messages exported'),\n truncated: z.boolean().describe('Whether export was truncated at maxItems'),\n});\n\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Export Gmail messages to CSV with streaming pagination. Returns file URI. Use query-syntax prompt for query reference.',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\n/**\n * Handler for gmail-messages-export-csv tool\n *\n * CRITICAL: Streaming implementation per user requirements\n * - Generate UUID upfront\n * - Write CSV header immediately\n * - Append rows as batches arrive\n * - Delete partial file on error\n * - NO RETRIES (fail fast on error)\n */\nasync function handler({ query, maxItems, filename, contentType, excludeThreadHistory }: Input, extra: EnrichedExtra & StorageExtra) {\n const logger = extra.logger;\n const { storageContext } = extra;\n const { transport, resourceStoreUri, baseUrl } = storageContext;\n\n // Reserve file location for streaming write (creates directory, generates ID, formats filename)\n const reservation = await reserveFile(filename, {\n resourceStoreUri,\n });\n const { storedName, fullPath } = reservation;\n\n logger.info('gmail.messages.export-csv starting streaming export', { path: fullPath, maxItems });\n\n try {\n const parsedQuery = parseGmailQueryParameter(query);\n\n logger.info('gmail.messages.export-csv called', {\n query: parsedQuery,\n maxItems,\n filename,\n accountId: extra.authContext.accountId,\n });\n\n const gmail = google.gmail({ version: 'v1', auth: extra.authContext.auth });\n\n // Create CSV headers (all email fields)\n const csvHeaders = ['id', 'threadId', 'from', 'to', 'cc', 'bcc', 'subject', 'date', 'snippet', 'body', 'provider', 'labels'];\n\n // Create write stream and write headers immediately\n const writeStream = createWriteStream(fullPath, { encoding: 'utf-8' });\n const headerLine = stringify([csvHeaders], { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(headerLine);\n\n // Internal pagination loop - append to CSV with each batch\n // NO RETRIES: If any error occurs, fail the whole operation and clean up\n let totalRows = 0;\n let nextPageToken: string | undefined;\n const started = Date.now();\n\n while (totalRows < maxItems) {\n const remainingItems = maxItems - totalRows;\n const pageSize = Math.min(remainingItems, DEFAULT_PAGE_SIZE);\n\n const exec: {\n items: CsvRow[];\n metadata?: { nextPageToken?: string };\n } = await executeGmailQuery(\n parsedQuery,\n {\n client: gmail,\n logger,\n pageSize,\n ...(nextPageToken !== undefined && { pageToken: nextPageToken }),\n includeBody: true, // Always include body for CSV export\n },\n (full: unknown): CsvRow => {\n // Type-safe property access with guards\n const fullData = full as {\n id?: unknown;\n threadId?: unknown;\n snippet?: unknown;\n labelIds?: unknown[];\n payload?: { headers?: unknown[] };\n };\n\n const headersArray = Array.isArray(fullData?.payload?.headers) ? fullData.payload.headers : [];\n const headers = Object.fromEntries(\n headersArray.map((h: unknown) => {\n const header = h as { name?: unknown; value?: unknown };\n return [String(header.name ?? ''), String(header.value ?? '')];\n })\n );\n\n const payload = fullData?.payload;\n // Cast to Schema$MessagePart for extractBodyFromPayload\n const body = payload ? extractBodyFromPayload(payload as gmail_v1.Schema$MessagePart, { contentType, excludeThreadHistory }) : '';\n\n const labelIds = Array.isArray(fullData?.labelIds) ? fullData.labelIds.map((id) => String(id ?? '')) : [];\n\n return {\n id: String(fullData?.id ?? ''),\n threadId: fullData?.threadId ? String(fullData.threadId) : '',\n from: headers?.From || '',\n to: headers?.To || '',\n cc: headers?.Cc || '',\n bcc: headers?.Bcc || '',\n subject: headers?.Subject || '',\n date: headers?.Date || '',\n snippet: fullData?.snippet ? String(fullData.snippet) : '',\n body,\n provider: 'gmail',\n labels: labelIds.join(';'),\n };\n }\n );\n\n // Type-safe CSV row mapping\n const csvRows = exec.items.map((row) => {\n return [row.id, row.threadId, row.from, row.to, row.cc, row.bcc, row.subject, row.date, row.snippet, row.body, row.provider, row.labels];\n });\n\n // Append rows to CSV file immediately\n if (csvRows.length > 0) {\n const rowsContent = stringify(csvRows, { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(rowsContent);\n }\n\n totalRows += exec.items.length;\n nextPageToken = exec.metadata?.nextPageToken;\n\n logger.info('gmail.messages.export-csv batch written', {\n batchSize: exec.items.length,\n totalRows,\n hasMore: Boolean(nextPageToken),\n });\n\n // Exit if no more results or reached maxItems\n if (!nextPageToken || exec.items.length === 0) {\n break;\n }\n }\n\n // Close write stream\n await new Promise<void>((resolve, reject) => {\n writeStream.end(() => resolve());\n writeStream.on('error', reject);\n });\n\n const durationMs = Date.now() - started;\n const truncated = totalRows >= maxItems && Boolean(nextPageToken);\n\n logger.info('gmail.messages.export-csv completed', {\n rowCount: totalRows,\n truncated,\n durationMs,\n filename: storedName,\n });\n\n // Generate URI based on transport type (stdio: file://, HTTP: http://)\n const uri = getFileUri(storedName, transport, {\n resourceStoreUri,\n ...(baseUrl && { baseUrl }),\n endpoint: '/files',\n });\n\n const result: Output = {\n type: 'success' as const,\n uri,\n filename: storedName,\n rowCount: totalRows,\n truncated,\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result),\n },\n ],\n structuredContent: { result },\n };\n } catch (error) {\n // CRITICAL: Clean up partial CSV file on error\n try {\n await unlink(fullPath);\n logger.debug('Cleaned up partial CSV file after error', { path: fullPath });\n } catch (_cleanupError) {\n logger.debug('Could not clean up CSV file (may not exist)', { path: fullPath });\n }\n\n const message = error instanceof Error ? error.message : String(error);\n logger.error('gmail.messages.export-csv error', { error: message });\n\n throw new ProtocolError(ProtocolErrorCode.InternalError, `Error exporting messages to CSV: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'messages-export-csv',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["createTool","AuthRequiredBranchSchema","schemas","DEFAULT_MAX_ITEMS","MAX_EXPORT_ITEMS","inputSchema","z","object","query","GmailQueryParameterSchema","optional","describe","maxItems","number","int","positive","max","default","filename","string","trim","min","contentType","EmailContentTypeSchema","excludeThreadHistory","ExcludeThreadHistorySchema","successBranchSchema","type","literal","uri","rowCount","truncated","boolean","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","storageContext","transport","resourceStoreUri","baseUrl","reservation","storedName","fullPath","parsedQuery","gmail","csvHeaders","writeStream","headerLine","totalRows","nextPageToken","started","exec","remainingItems","pageSize","csvRows","rowsContent","durationMs","error","_cleanupError","message","reserveFile","info","path","parseGmailQueryParameter","accountId","authContext","google","version","auth","createWriteStream","encoding","stringify","header","quoted","quote","escape","write","Date","now","Math","DEFAULT_PAGE_SIZE","executeGmailQuery","client","undefined","pageToken","includeBody","full","fullData","headersArray","Array","isArray","payload","headers","Object","fromEntries","map","h","String","name","value","body","extractBodyFromPayload","labelIds","id","threadId","from","From","to","To","cc","Cc","bcc","Bcc","subject","Subject","date","snippet","provider","labels","join","items","row","length","metadata","batchSize","hasMore","Boolean","Promise","resolve","reject","end","on","getFileUri","endpoint","content","text","JSON","structuredContent","unlink","debug","Error","ProtocolError","ProtocolErrorCode","InternalError","stack"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/mcp/tools/messages-export-csv.ts"],"sourcesContent":["import { type gmail_v1, gmail as gmailApi } from '@googleapis/gmail';\nimport { EmailContentTypeSchema, ExcludeThreadHistorySchema } from '@mcp-z/email';\nimport type { EnrichedExtra } from '@mcp-z/oauth-google';\nimport { schemas } from '@mcp-z/oauth-google';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport { getFileUri, ProtocolError, ProtocolErrorCode, reserveFile, type ToolModule } from '@mcp-z/server';\n\nimport { stringify } from 'csv-stringify/sync';\nimport { createWriteStream } from 'fs';\nimport { unlink } from 'fs/promises';\nimport { z } from 'zod';\nimport { DEFAULT_PAGE_SIZE } from '../../constants.ts';\nimport { extractBodyFromPayload } from '../../email/parsing/html-processing.ts';\nimport { executeQuery as executeGmailQuery } from '../../email/querying/execute-query.ts';\nimport { googleAuth } from '../../lib/google-auth.ts';\nimport { GmailQueryParameterSchema, parseGmailQueryParameter } from '../../schemas/gmail-query-schema.ts';\nimport type { StorageExtra } from '../../types.ts';\n\nconst DEFAULT_MAX_ITEMS = 10000;\nconst MAX_EXPORT_ITEMS = 50000;\n\n/**\n * CSV row format based on EmailDetail\n * All fields are strings (empty string instead of undefined)\n * Includes additional CSV-specific fields: provider and labels\n */\ninterface CsvRow {\n id: string;\n threadId: string;\n from: string;\n to: string;\n cc: string;\n bcc: string;\n subject: string;\n date: string;\n snippet: string;\n body: string;\n provider: string;\n labels: string;\n}\n\nconst inputSchema = z.object({\n query: GmailQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and rawGmailQuery for Gmail syntax.'),\n maxItems: z.number().int().positive().max(MAX_EXPORT_ITEMS).default(DEFAULT_MAX_ITEMS).describe(`Maximum messages to export (default: ${DEFAULT_MAX_ITEMS}, max: ${MAX_EXPORT_ITEMS})`),\n filename: z.string().trim().min(1).default('gmail-messages.csv').describe('Output filename (default: gmail-messages.csv)'),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\nconst successBranchSchema = z.object({\n type: z.literal('success'),\n uri: z.string().describe('File URI (file:// or http://)'),\n filename: z.string().describe('Stored filename'),\n rowCount: z.number().describe('Number of messages exported'),\n truncated: z.boolean().describe('Whether export was truncated at maxItems'),\n});\n\nconst outputSchema = z.discriminatedUnion('type', [successBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Export Gmail messages to CSV with streaming pagination. Returns file URI. Use query-syntax prompt for query reference.',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\n/**\n * Handler for gmail-messages-export-csv tool\n *\n * CRITICAL: Streaming implementation per user requirements\n * - Generate UUID upfront\n * - Write CSV header immediately\n * - Append rows as batches arrive\n * - Delete partial file on error\n * - NO RETRIES (fail fast on error)\n */\nasync function handler({ query, maxItems, filename, contentType, excludeThreadHistory }: Input, extra: EnrichedExtra & StorageExtra) {\n const logger = extra.logger;\n const { storageContext } = extra;\n const { transport, resourceStoreUri, baseUrl } = storageContext;\n\n // Reserve file location for streaming write (creates directory, generates ID, formats filename)\n const reservation = await reserveFile(filename, {\n resourceStoreUri,\n });\n const { storedName, fullPath } = reservation;\n\n logger.info('gmail.messages.export-csv starting streaming export', { path: fullPath, maxItems });\n\n try {\n const parsedQuery = parseGmailQueryParameter(query);\n\n logger.info('gmail.messages.export-csv called', {\n query: parsedQuery,\n maxItems,\n filename,\n accountId: extra.authContext.accountId,\n });\n\n const gmail = gmailApi({ version: 'v1', auth: googleAuth(extra.authContext.auth) });\n\n // Create CSV headers (all email fields)\n const csvHeaders = ['id', 'threadId', 'from', 'to', 'cc', 'bcc', 'subject', 'date', 'snippet', 'body', 'provider', 'labels'];\n\n // Create write stream and write headers immediately\n const writeStream = createWriteStream(fullPath, { encoding: 'utf-8' });\n const headerLine = stringify([csvHeaders], { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(headerLine);\n\n // Internal pagination loop - append to CSV with each batch\n // NO RETRIES: If any error occurs, fail the whole operation and clean up\n let totalRows = 0;\n let nextPageToken: string | undefined;\n const started = Date.now();\n\n while (totalRows < maxItems) {\n const remainingItems = maxItems - totalRows;\n const pageSize = Math.min(remainingItems, DEFAULT_PAGE_SIZE);\n\n const exec: {\n items: CsvRow[];\n metadata?: { nextPageToken?: string };\n } = await executeGmailQuery(\n parsedQuery,\n {\n client: gmail,\n logger,\n pageSize,\n ...(nextPageToken !== undefined && { pageToken: nextPageToken }),\n includeBody: true, // Always include body for CSV export\n },\n (full: unknown): CsvRow => {\n // Type-safe property access with guards\n const fullData = full as {\n id?: unknown;\n threadId?: unknown;\n snippet?: unknown;\n labelIds?: unknown[];\n payload?: { headers?: unknown[] };\n };\n\n const headersArray = Array.isArray(fullData?.payload?.headers) ? fullData.payload.headers : [];\n const headers = Object.fromEntries(\n headersArray.map((h: unknown) => {\n const header = h as { name?: unknown; value?: unknown };\n return [String(header.name ?? ''), String(header.value ?? '')];\n })\n );\n\n const payload = fullData?.payload;\n // Cast to Schema$MessagePart for extractBodyFromPayload\n const body = payload ? extractBodyFromPayload(payload as gmail_v1.Schema$MessagePart, { contentType, excludeThreadHistory }) : '';\n\n const labelIds = Array.isArray(fullData?.labelIds) ? fullData.labelIds.map((id) => String(id ?? '')) : [];\n\n return {\n id: String(fullData?.id ?? ''),\n threadId: fullData?.threadId ? String(fullData.threadId) : '',\n from: headers?.From || '',\n to: headers?.To || '',\n cc: headers?.Cc || '',\n bcc: headers?.Bcc || '',\n subject: headers?.Subject || '',\n date: headers?.Date || '',\n snippet: fullData?.snippet ? String(fullData.snippet) : '',\n body,\n provider: 'gmail',\n labels: labelIds.join(';'),\n };\n }\n );\n\n // Type-safe CSV row mapping\n const csvRows = exec.items.map((row) => {\n return [row.id, row.threadId, row.from, row.to, row.cc, row.bcc, row.subject, row.date, row.snippet, row.body, row.provider, row.labels];\n });\n\n // Append rows to CSV file immediately\n if (csvRows.length > 0) {\n const rowsContent = stringify(csvRows, { header: false, quoted: true, quote: '\"', escape: '\"' });\n writeStream.write(rowsContent);\n }\n\n totalRows += exec.items.length;\n nextPageToken = exec.metadata?.nextPageToken;\n\n logger.info('gmail.messages.export-csv batch written', {\n batchSize: exec.items.length,\n totalRows,\n hasMore: Boolean(nextPageToken),\n });\n\n // Exit if no more results or reached maxItems\n if (!nextPageToken || exec.items.length === 0) {\n break;\n }\n }\n\n // Close write stream\n await new Promise<void>((resolve, reject) => {\n writeStream.end(() => resolve());\n writeStream.on('error', reject);\n });\n\n const durationMs = Date.now() - started;\n const truncated = totalRows >= maxItems && Boolean(nextPageToken);\n\n logger.info('gmail.messages.export-csv completed', {\n rowCount: totalRows,\n truncated,\n durationMs,\n filename: storedName,\n });\n\n // Generate URI based on transport type (stdio: file://, HTTP: http://)\n const uri = getFileUri(storedName, transport, {\n resourceStoreUri,\n ...(baseUrl && { baseUrl }),\n endpoint: '/files',\n });\n\n const result: Output = {\n type: 'success' as const,\n uri,\n filename: storedName,\n rowCount: totalRows,\n truncated,\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result),\n },\n ],\n structuredContent: { result },\n };\n } catch (error) {\n // CRITICAL: Clean up partial CSV file on error\n try {\n await unlink(fullPath);\n logger.debug('Cleaned up partial CSV file after error', { path: fullPath });\n } catch (_cleanupError) {\n logger.debug('Could not clean up CSV file (may not exist)', { path: fullPath });\n }\n\n const message = error instanceof Error ? error.message : String(error);\n logger.error('gmail.messages.export-csv error', { error: message });\n\n throw new ProtocolError(ProtocolErrorCode.InternalError, `Error exporting messages to CSV: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'messages-export-csv',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["createTool","AuthRequiredBranchSchema","schemas","DEFAULT_MAX_ITEMS","MAX_EXPORT_ITEMS","inputSchema","z","object","query","GmailQueryParameterSchema","optional","describe","maxItems","number","int","positive","max","default","filename","string","trim","min","contentType","EmailContentTypeSchema","excludeThreadHistory","ExcludeThreadHistorySchema","successBranchSchema","type","literal","uri","rowCount","truncated","boolean","outputSchema","discriminatedUnion","config","description","result","handler","extra","logger","storageContext","transport","resourceStoreUri","baseUrl","reservation","storedName","fullPath","parsedQuery","gmail","csvHeaders","writeStream","headerLine","totalRows","nextPageToken","started","exec","remainingItems","pageSize","csvRows","rowsContent","durationMs","error","_cleanupError","message","reserveFile","info","path","parseGmailQueryParameter","accountId","authContext","gmailApi","version","auth","googleAuth","createWriteStream","encoding","stringify","header","quoted","quote","escape","write","Date","now","Math","DEFAULT_PAGE_SIZE","executeGmailQuery","client","undefined","pageToken","includeBody","full","fullData","headersArray","Array","isArray","payload","headers","Object","fromEntries","map","h","String","name","value","body","extractBodyFromPayload","labelIds","id","threadId","from","From","to","To","cc","Cc","bcc","Bcc","subject","Subject","date","snippet","provider","labels","join","items","row","length","metadata","batchSize","hasMore","Boolean","Promise","resolve","reject","end","on","getFileUri","endpoint","content","text","JSON","structuredContent","unlink","debug","Error","ProtocolError","ProtocolErrorCode","InternalError","stack"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { gmail_v1 } from 'googleapis';
1
+ import type { gmail_v1 } from '@googleapis/gmail';
2
2
  export type FetchMode = 'metadata' | 'full';
3
3
  export interface NormalizedAddress {
4
4
  address?: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/email/messages/fetch-message.ts"],"sourcesContent":["import type { gmail_v1 } from 'googleapis';\nimport { toIsoUtc } from '../../lib/date-conversion.ts';\nimport { extractEmails, extractFrom } from '../parsing/headers-utils.ts';\n\nexport type FetchMode = 'metadata' | 'full';\n\nexport interface NormalizedAddress {\n address?: string | undefined;\n name?: string | undefined;\n}\nexport interface NormalizedMessage {\n id: string;\n threadId?: string | undefined;\n date?: string | undefined;\n subject?: string | undefined;\n from?: NormalizedAddress | undefined;\n to?: string[] | undefined;\n cc?: string[] | undefined;\n bcc?: string[] | undefined;\n snippet?: string | undefined;\n labels?: string[] | undefined;\n body?: string | undefined;\n}\n\nexport interface GmailDeps {\n /** googleapis Gmail client created via createGmailClient(provider). */\n gmail: gmail_v1.Gmail;\n}\n\nfunction extractHeader(headers: Array<{ name?: string; value?: string }> | undefined, key: string): string | undefined {\n const h = headers?.find((x) => (x.name ?? '').toLowerCase() === key.toLowerCase());\n return h?.value ?? undefined;\n}\n\nfunction base64UrlDecode(input: string): string {\n let s = String(input).replace(/-/g, '+').replace(/_/g, '/');\n while (s.length % 4 !== 0) s += '=';\n try {\n return Buffer.from(s, 'base64').toString('utf8');\n } catch {\n return '';\n }\n}\n\nfunction extractBody(payload: unknown): string | undefined {\n const find = (parts: unknown[] | undefined, mime: string): string | undefined => {\n for (const p of parts ?? []) {\n if (p && typeof p === 'object' && 'mimeType' in p && 'body' in p) {\n if (p.mimeType === mime && p.body && typeof p.body === 'object' && 'data' in p.body) {\n return base64UrlDecode(p.body.data as string);\n }\n }\n if (p && typeof p === 'object' && 'parts' in p) {\n const nested = find(p.parts as unknown[], mime);\n if (nested) return nested;\n }\n }\n return undefined;\n };\n if (payload && typeof payload === 'object' && 'parts' in payload) {\n return find(payload.parts as unknown[], 'text/plain') ?? find(payload.parts as unknown[], 'text/html')?.replace(/\\r\\n?/g, '\\n');\n }\n return undefined;\n}\n\nexport async function fetchMessage(deps: GmailDeps, id: string, mode: FetchMode): Promise<NormalizedMessage> {\n const { gmail } = deps;\n // When only metadata is requested, ask Gmail for a reduced payload with just the headers we care about.\n const metadataHeaders = ['Date', 'Subject', 'From', 'To', 'Cc', 'Bcc'];\n const format = mode === 'full' ? 'full' : 'metadata';\n const baseParams = { userId: 'me' as const, id, format };\n const resp = format === 'metadata' ? await gmail.users.messages.get({ ...baseParams, metadataHeaders }) : await gmail.users.messages.get(baseParams);\n const data = resp?.data as unknown;\n const headers = data && typeof data === 'object' && 'payload' in data && data.payload && typeof data.payload === 'object' && 'headers' in data.payload ? (data.payload.headers as Array<{ name?: string; value?: string }> | undefined) : undefined;\n const dateRaw = extractHeader(headers, 'Date');\n const fromRaw = extractHeader(headers, 'From');\n const toRaw = extractHeader(headers, 'To');\n const ccRaw = extractHeader(headers, 'Cc');\n const bccRaw = extractHeader(headers, 'Bcc');\n\n const fromObj = (fromRaw ? (extractFrom(fromRaw) as NormalizedAddress) : undefined) ?? undefined;\n const toArr = toRaw ? extractEmails(toRaw) : [];\n const ccArr = ccRaw ? extractEmails(ccRaw) : [];\n const bccArr = bccRaw ? extractEmails(bccRaw) : [];\n\n const getId = (): string => {\n if (data && typeof data === 'object' && 'id' in data) {\n return String(data.id ?? id);\n }\n return id;\n };\n\n const getThreadId = (): string | undefined => {\n if (data && typeof data === 'object' && 'threadId' in data && data.threadId) {\n return String(data.threadId);\n }\n return undefined;\n };\n\n const getSnippet = (): string | undefined => {\n if (data && typeof data === 'object' && 'snippet' in data && data.snippet) {\n return String(data.snippet);\n }\n return undefined;\n };\n\n const getLabelIds = (): string[] | undefined => {\n if (data && typeof data === 'object' && 'labelIds' in data && Array.isArray(data.labelIds)) {\n return data.labelIds.map(String);\n }\n return undefined;\n };\n\n const getPayload = (): unknown => {\n if (data && typeof data === 'object' && 'payload' in data) {\n return data.payload;\n }\n return undefined;\n };\n\n const msg: NormalizedMessage = {\n id: getId(),\n threadId: getThreadId(),\n date: dateRaw ? (toIsoUtc(dateRaw) ?? dateRaw) : undefined,\n subject: extractHeader(headers, 'Subject'),\n from: fromObj,\n to: toArr.length ? toArr : undefined,\n cc: ccArr.length ? ccArr : undefined,\n bcc: bccArr.length ? bccArr : undefined,\n snippet: getSnippet(),\n labels: getLabelIds(),\n };\n if (mode === 'full') {\n const body = extractBody(getPayload());\n if (body) msg.body = body;\n }\n return msg;\n}\n"],"names":["toIsoUtc","extractEmails","extractFrom","extractHeader","headers","key","h","find","x","name","toLowerCase","value","undefined","base64UrlDecode","input","s","String","replace","length","Buffer","from","toString","extractBody","payload","parts","mime","p","mimeType","body","data","nested","fetchMessage","deps","id","mode","fromRaw","gmail","metadataHeaders","format","baseParams","userId","resp","users","messages","get","dateRaw","toRaw","ccRaw","bccRaw","fromObj","toArr","ccArr","bccArr","getId","getThreadId","threadId","getSnippet","snippet","getLabelIds","Array","isArray","labelIds","map","getPayload","msg","date","subject","to","cc","bcc","labels"],"mappings":"AACA,SAASA,QAAQ,QAAQ,+BAA+B;AACxD,SAASC,aAAa,EAAEC,WAAW,QAAQ,8BAA8B;AA2BzE,SAASC,cAAcC,OAA6D,EAAEC,GAAW;;IAC/F,MAAMC,IAAIF,oBAAAA,8BAAAA,QAASG,IAAI,CAAC,CAACC;YAAOA;eAAD,EAACA,UAAAA,EAAEC,IAAI,cAAND,qBAAAA,UAAU,IAAIE,WAAW,OAAOL,IAAIK,WAAW;;IAC/E,eAAOJ,cAAAA,wBAAAA,EAAGK,KAAK,uCAAIC;AACrB;AAEA,SAASC,gBAAgBC,KAAa;IACpC,IAAIC,IAAIC,OAAOF,OAAOG,OAAO,CAAC,MAAM,KAAKA,OAAO,CAAC,MAAM;IACvD,MAAOF,EAAEG,MAAM,GAAG,MAAM,EAAGH,KAAK;IAChC,IAAI;QACF,OAAOI,OAAOC,IAAI,CAACL,GAAG,UAAUM,QAAQ,CAAC;IAC3C,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,SAASC,YAAYC,OAAgB;IACnC,MAAMhB,OAAO,CAACiB,OAA8BC;QAC1C,KAAK,MAAMC,KAAKF,kBAAAA,mBAAAA,QAAS,EAAE,CAAE;YAC3B,IAAIE,KAAK,OAAOA,MAAM,YAAY,cAAcA,KAAK,UAAUA,GAAG;gBAChE,IAAIA,EAAEC,QAAQ,KAAKF,QAAQC,EAAEE,IAAI,IAAI,OAAOF,EAAEE,IAAI,KAAK,YAAY,UAAUF,EAAEE,IAAI,EAAE;oBACnF,OAAOf,gBAAgBa,EAAEE,IAAI,CAACC,IAAI;gBACpC;YACF;YACA,IAAIH,KAAK,OAAOA,MAAM,YAAY,WAAWA,GAAG;gBAC9C,MAAMI,SAASvB,KAAKmB,EAAEF,KAAK,EAAeC;gBAC1C,IAAIK,QAAQ,OAAOA;YACrB;QACF;QACA,OAAOlB;IACT;IACA,IAAIW,WAAW,OAAOA,YAAY,YAAY,WAAWA,SAAS;YACzDhB;YAAkDA;QAAzD,QAAOA,QAAAA,KAAKgB,QAAQC,KAAK,EAAe,2BAAjCjB,mBAAAA,SAAkDA,SAAAA,KAAKgB,QAAQC,KAAK,EAAe,0BAAjCjB,6BAAAA,OAA+CU,OAAO,CAAC,UAAU;IAC5H;IACA,OAAOL;AACT;AAEA,OAAO,eAAemB,aAAaC,IAAe,EAAEC,EAAU,EAAEC,IAAe;QAe5DC,MA2CEnC;IAzDnB,MAAM,EAAEoC,KAAK,EAAE,GAAGJ;IAClB,wGAAwG;IACxG,MAAMK,kBAAkB;QAAC;QAAQ;QAAW;QAAQ;QAAM;QAAM;KAAM;IACtE,MAAMC,SAASJ,SAAS,SAAS,SAAS;IAC1C,MAAMK,aAAa;QAAEC,QAAQ;QAAeP;QAAIK;IAAO;IACvD,MAAMG,OAAOH,WAAW,aAAa,MAAMF,MAAMM,KAAK,CAACC,QAAQ,CAACC,GAAG,CAAC;QAAE,GAAGL,UAAU;QAAEF;IAAgB,KAAK,MAAMD,MAAMM,KAAK,CAACC,QAAQ,CAACC,GAAG,CAACL;IACzI,MAAMV,OAAOY,iBAAAA,2BAAAA,KAAMZ,IAAI;IACvB,MAAMzB,UAAUyB,QAAQ,OAAOA,SAAS,YAAY,aAAaA,QAAQA,KAAKN,OAAO,IAAI,OAAOM,KAAKN,OAAO,KAAK,YAAY,aAAaM,KAAKN,OAAO,GAAIM,KAAKN,OAAO,CAACnB,OAAO,GAA4DQ;IAC1O,MAAMiC,UAAU1C,cAAcC,SAAS;IACvC,MAAM+B,UAAUhC,cAAcC,SAAS;IACvC,MAAM0C,QAAQ3C,cAAcC,SAAS;IACrC,MAAM2C,QAAQ5C,cAAcC,SAAS;IACrC,MAAM4C,SAAS7C,cAAcC,SAAS;IAEtC,MAAM6C,WAAWd,OAAAA,UAAWjC,YAAYiC,WAAiCvB,uBAAxDuB,kBAAAA,OAAsEvB;IACvF,MAAMsC,QAAQJ,QAAQ7C,cAAc6C,SAAS,EAAE;IAC/C,MAAMK,QAAQJ,QAAQ9C,cAAc8C,SAAS,EAAE;IAC/C,MAAMK,SAASJ,SAAS/C,cAAc+C,UAAU,EAAE;IAElD,MAAMK,QAAQ;QACZ,IAAIxB,QAAQ,OAAOA,SAAS,YAAY,QAAQA,MAAM;gBACtCA;YAAd,OAAOb,QAAOa,WAAAA,KAAKI,EAAE,cAAPJ,sBAAAA,WAAWI;QAC3B;QACA,OAAOA;IACT;IAEA,MAAMqB,cAAc;QAClB,IAAIzB,QAAQ,OAAOA,SAAS,YAAY,cAAcA,QAAQA,KAAK0B,QAAQ,EAAE;YAC3E,OAAOvC,OAAOa,KAAK0B,QAAQ;QAC7B;QACA,OAAO3C;IACT;IAEA,MAAM4C,aAAa;QACjB,IAAI3B,QAAQ,OAAOA,SAAS,YAAY,aAAaA,QAAQA,KAAK4B,OAAO,EAAE;YACzE,OAAOzC,OAAOa,KAAK4B,OAAO;QAC5B;QACA,OAAO7C;IACT;IAEA,MAAM8C,cAAc;QAClB,IAAI7B,QAAQ,OAAOA,SAAS,YAAY,cAAcA,QAAQ8B,MAAMC,OAAO,CAAC/B,KAAKgC,QAAQ,GAAG;YAC1F,OAAOhC,KAAKgC,QAAQ,CAACC,GAAG,CAAC9C;QAC3B;QACA,OAAOJ;IACT;IAEA,MAAMmD,aAAa;QACjB,IAAIlC,QAAQ,OAAOA,SAAS,YAAY,aAAaA,MAAM;YACzD,OAAOA,KAAKN,OAAO;QACrB;QACA,OAAOX;IACT;IAEA,MAAMoD,MAAyB;QAC7B/B,IAAIoB;QACJE,UAAUD;QACVW,MAAMpB,WAAW7C,YAAAA,SAAS6C,sBAAT7C,uBAAAA,YAAqB6C,UAAWjC;QACjDsD,SAAS/D,cAAcC,SAAS;QAChCgB,MAAM6B;QACNkB,IAAIjB,MAAMhC,MAAM,GAAGgC,QAAQtC;QAC3BwD,IAAIjB,MAAMjC,MAAM,GAAGiC,QAAQvC;QAC3ByD,KAAKjB,OAAOlC,MAAM,GAAGkC,SAASxC;QAC9B6C,SAASD;QACTc,QAAQZ;IACV;IACA,IAAIxB,SAAS,QAAQ;QACnB,MAAMN,OAAON,YAAYyC;QACzB,IAAInC,MAAMoC,IAAIpC,IAAI,GAAGA;IACvB;IACA,OAAOoC;AACT"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/email/messages/fetch-message.ts"],"sourcesContent":["import type { gmail_v1 } from '@googleapis/gmail';\nimport { toIsoUtc } from '../../lib/date-conversion.ts';\nimport { extractEmails, extractFrom } from '../parsing/headers-utils.ts';\n\nexport type FetchMode = 'metadata' | 'full';\n\nexport interface NormalizedAddress {\n address?: string | undefined;\n name?: string | undefined;\n}\nexport interface NormalizedMessage {\n id: string;\n threadId?: string | undefined;\n date?: string | undefined;\n subject?: string | undefined;\n from?: NormalizedAddress | undefined;\n to?: string[] | undefined;\n cc?: string[] | undefined;\n bcc?: string[] | undefined;\n snippet?: string | undefined;\n labels?: string[] | undefined;\n body?: string | undefined;\n}\n\nexport interface GmailDeps {\n /** googleapis Gmail client created via createGmailClient(provider). */\n gmail: gmail_v1.Gmail;\n}\n\nfunction extractHeader(headers: Array<{ name?: string; value?: string }> | undefined, key: string): string | undefined {\n const h = headers?.find((x) => (x.name ?? '').toLowerCase() === key.toLowerCase());\n return h?.value ?? undefined;\n}\n\nfunction base64UrlDecode(input: string): string {\n let s = String(input).replace(/-/g, '+').replace(/_/g, '/');\n while (s.length % 4 !== 0) s += '=';\n try {\n return Buffer.from(s, 'base64').toString('utf8');\n } catch {\n return '';\n }\n}\n\nfunction extractBody(payload: unknown): string | undefined {\n const find = (parts: unknown[] | undefined, mime: string): string | undefined => {\n for (const p of parts ?? []) {\n if (p && typeof p === 'object' && 'mimeType' in p && 'body' in p) {\n if (p.mimeType === mime && p.body && typeof p.body === 'object' && 'data' in p.body) {\n return base64UrlDecode(p.body.data as string);\n }\n }\n if (p && typeof p === 'object' && 'parts' in p) {\n const nested = find(p.parts as unknown[], mime);\n if (nested) return nested;\n }\n }\n return undefined;\n };\n if (payload && typeof payload === 'object' && 'parts' in payload) {\n return find(payload.parts as unknown[], 'text/plain') ?? find(payload.parts as unknown[], 'text/html')?.replace(/\\r\\n?/g, '\\n');\n }\n return undefined;\n}\n\nexport async function fetchMessage(deps: GmailDeps, id: string, mode: FetchMode): Promise<NormalizedMessage> {\n const { gmail } = deps;\n // When only metadata is requested, ask Gmail for a reduced payload with just the headers we care about.\n const metadataHeaders = ['Date', 'Subject', 'From', 'To', 'Cc', 'Bcc'];\n const format = mode === 'full' ? 'full' : 'metadata';\n const baseParams = { userId: 'me' as const, id, format };\n const resp = format === 'metadata' ? await gmail.users.messages.get({ ...baseParams, metadataHeaders }) : await gmail.users.messages.get(baseParams);\n const data = resp?.data as unknown;\n const headers = data && typeof data === 'object' && 'payload' in data && data.payload && typeof data.payload === 'object' && 'headers' in data.payload ? (data.payload.headers as Array<{ name?: string; value?: string }> | undefined) : undefined;\n const dateRaw = extractHeader(headers, 'Date');\n const fromRaw = extractHeader(headers, 'From');\n const toRaw = extractHeader(headers, 'To');\n const ccRaw = extractHeader(headers, 'Cc');\n const bccRaw = extractHeader(headers, 'Bcc');\n\n const fromObj = (fromRaw ? (extractFrom(fromRaw) as NormalizedAddress) : undefined) ?? undefined;\n const toArr = toRaw ? extractEmails(toRaw) : [];\n const ccArr = ccRaw ? extractEmails(ccRaw) : [];\n const bccArr = bccRaw ? extractEmails(bccRaw) : [];\n\n const getId = (): string => {\n if (data && typeof data === 'object' && 'id' in data) {\n return String(data.id ?? id);\n }\n return id;\n };\n\n const getThreadId = (): string | undefined => {\n if (data && typeof data === 'object' && 'threadId' in data && data.threadId) {\n return String(data.threadId);\n }\n return undefined;\n };\n\n const getSnippet = (): string | undefined => {\n if (data && typeof data === 'object' && 'snippet' in data && data.snippet) {\n return String(data.snippet);\n }\n return undefined;\n };\n\n const getLabelIds = (): string[] | undefined => {\n if (data && typeof data === 'object' && 'labelIds' in data && Array.isArray(data.labelIds)) {\n return data.labelIds.map(String);\n }\n return undefined;\n };\n\n const getPayload = (): unknown => {\n if (data && typeof data === 'object' && 'payload' in data) {\n return data.payload;\n }\n return undefined;\n };\n\n const msg: NormalizedMessage = {\n id: getId(),\n threadId: getThreadId(),\n date: dateRaw ? (toIsoUtc(dateRaw) ?? dateRaw) : undefined,\n subject: extractHeader(headers, 'Subject'),\n from: fromObj,\n to: toArr.length ? toArr : undefined,\n cc: ccArr.length ? ccArr : undefined,\n bcc: bccArr.length ? bccArr : undefined,\n snippet: getSnippet(),\n labels: getLabelIds(),\n };\n if (mode === 'full') {\n const body = extractBody(getPayload());\n if (body) msg.body = body;\n }\n return msg;\n}\n"],"names":["toIsoUtc","extractEmails","extractFrom","extractHeader","headers","key","h","find","x","name","toLowerCase","value","undefined","base64UrlDecode","input","s","String","replace","length","Buffer","from","toString","extractBody","payload","parts","mime","p","mimeType","body","data","nested","fetchMessage","deps","id","mode","fromRaw","gmail","metadataHeaders","format","baseParams","userId","resp","users","messages","get","dateRaw","toRaw","ccRaw","bccRaw","fromObj","toArr","ccArr","bccArr","getId","getThreadId","threadId","getSnippet","snippet","getLabelIds","Array","isArray","labelIds","map","getPayload","msg","date","subject","to","cc","bcc","labels"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
+ import type { gmail_v1 } from '@googleapis/gmail';
1
2
  import { buildContentForItems } from '@mcp-z/email';
2
- import type { gmail_v1 } from 'googleapis';
3
3
  export { buildContentForItems };
4
4
  export declare function toRowFromGmail(msg?: gmail_v1.Schema$Message, opts?: {
5
5
  body?: boolean;
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/email/messages/messages.ts"],"sourcesContent":["import { buildContentForItems } from '@mcp-z/email';\nimport type { gmail_v1 } from 'googleapis';\nimport { safeBase64Decode } from '../../lib/base64-encoding.ts';\nimport { toIsoUtc } from '../../lib/date-conversion.ts';\nimport { extractEmails, extractFrom } from '../parsing/headers-utils.ts';\n\nexport { buildContentForItems };\n\n// Convert a Gmail messages.get() response into canonical row shape used by sheets writer\n// [id, provider, threadId, to, from, cc, bcc, date, subject, labels, snippet, body]\nexport function toRowFromGmail(msg: gmail_v1.Schema$Message = {}, opts: { body?: boolean; addressFormat?: 'email' | string } = { body: false, addressFormat: 'email' }) {\n const headers = msg?.payload?.headers || [];\n const headerObj: Record<string, string> = Object.fromEntries((headers || []).map((h) => [String(h?.name ?? ''), String(h?.value ?? '')]));\n const id = msg?.id ?? '';\n const provider = 'gmail';\n const threadId = msg?.threadId ?? '';\n const to = extractEmails(headerObj.To ?? '').join(', ');\n const fromInfo = extractFrom(headerObj.From ?? '');\n const from = ((fromInfo && fromInfo.address) || headerObj.From) ?? '';\n const cc = extractEmails(headerObj.Cc ?? '').join(', ');\n const bcc = extractEmails(headerObj.Bcc ?? '').join(', ');\n const date = (toIsoUtc(headerObj.Date) || headerObj.Date) ?? '';\n const subject = headerObj.Subject ?? '';\n const labelIds = Array.isArray(msg?.labelIds) ? (msg.labelIds as string[]) : [];\n const labels = labelIds.join(';');\n const snippet = msg?.snippet ?? '';\n\n let bodyFull = '';\n if (opts?.body) {\n const parts = msg?.payload?.parts || [];\n const findText = (partsArr: unknown[]): string | null => {\n for (const p of partsArr || []) {\n if (p && typeof p === 'object' && 'mimeType' in p && 'body' in p) {\n if (p.mimeType === 'text/plain' && p.body && typeof p.body === 'object' && 'data' in p.body) {\n return p.body.data as string;\n }\n }\n if (p && typeof p === 'object' && 'parts' in p) {\n const nested = findText(p.parts as unknown[]);\n if (nested) return nested;\n }\n }\n return null;\n };\n const raw = findText(parts as unknown[]) || (msg?.payload?.body && typeof msg.payload.body === 'object' && 'data' in msg.payload.body ? msg.payload.body.data : null) || null;\n if (raw) {\n bodyFull = safeBase64Decode(raw as string);\n } else {\n const findHtml = (partsArr: unknown[]): string | null => {\n for (const p of partsArr || []) {\n if (p && typeof p === 'object' && 'mimeType' in p && 'body' in p) {\n if (p.mimeType === 'text/html' && p.body && typeof p.body === 'object' && 'data' in p.body) {\n return p.body.data as string;\n }\n }\n if (p && typeof p === 'object' && 'parts' in p) {\n const nested = findHtml(p.parts as unknown[]);\n if (nested) return nested;\n }\n }\n return null;\n };\n const htmlPart = findHtml(parts as unknown[]);\n if (htmlPart) {\n bodyFull = safeBase64Decode(htmlPart).replace(/\\r\\n?/g, '\\n');\n }\n }\n }\n return [id, provider, threadId, to, from, cc, bcc, date, subject, labels, snippet, bodyFull];\n}\n"],"names":["buildContentForItems","safeBase64Decode","toIsoUtc","extractEmails","extractFrom","toRowFromGmail","msg","opts","body","addressFormat","headerObj","headers","payload","Object","fromEntries","map","h","String","name","value","id","provider","threadId","to","To","join","fromInfo","From","from","address","cc","Cc","bcc","Bcc","date","Date","subject","Subject","labelIds","Array","isArray","labels","snippet","bodyFull","parts","findText","partsArr","p","mimeType","data","nested","raw","findHtml","htmlPart","replace"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/email/messages/messages.ts"],"sourcesContent":["import type { gmail_v1 } from '@googleapis/gmail';\nimport { buildContentForItems } from '@mcp-z/email';\nimport { safeBase64Decode } from '../../lib/base64-encoding.ts';\nimport { toIsoUtc } from '../../lib/date-conversion.ts';\nimport { extractEmails, extractFrom } from '../parsing/headers-utils.ts';\n\nexport { buildContentForItems };\n\n// Convert a Gmail messages.get() response into canonical row shape used by sheets writer\n// [id, provider, threadId, to, from, cc, bcc, date, subject, labels, snippet, body]\nexport function toRowFromGmail(msg: gmail_v1.Schema$Message = {}, opts: { body?: boolean; addressFormat?: 'email' | string } = { body: false, addressFormat: 'email' }) {\n const headers = msg?.payload?.headers || [];\n const headerObj: Record<string, string> = Object.fromEntries((headers || []).map((h) => [String(h?.name ?? ''), String(h?.value ?? '')]));\n const id = msg?.id ?? '';\n const provider = 'gmail';\n const threadId = msg?.threadId ?? '';\n const to = extractEmails(headerObj.To ?? '').join(', ');\n const fromInfo = extractFrom(headerObj.From ?? '');\n const from = ((fromInfo && fromInfo.address) || headerObj.From) ?? '';\n const cc = extractEmails(headerObj.Cc ?? '').join(', ');\n const bcc = extractEmails(headerObj.Bcc ?? '').join(', ');\n const date = (toIsoUtc(headerObj.Date) || headerObj.Date) ?? '';\n const subject = headerObj.Subject ?? '';\n const labelIds = Array.isArray(msg?.labelIds) ? (msg.labelIds as string[]) : [];\n const labels = labelIds.join(';');\n const snippet = msg?.snippet ?? '';\n\n let bodyFull = '';\n if (opts?.body) {\n const parts = msg?.payload?.parts || [];\n const findText = (partsArr: unknown[]): string | null => {\n for (const p of partsArr || []) {\n if (p && typeof p === 'object' && 'mimeType' in p && 'body' in p) {\n if (p.mimeType === 'text/plain' && p.body && typeof p.body === 'object' && 'data' in p.body) {\n return p.body.data as string;\n }\n }\n if (p && typeof p === 'object' && 'parts' in p) {\n const nested = findText(p.parts as unknown[]);\n if (nested) return nested;\n }\n }\n return null;\n };\n const raw = findText(parts as unknown[]) || (msg?.payload?.body && typeof msg.payload.body === 'object' && 'data' in msg.payload.body ? msg.payload.body.data : null) || null;\n if (raw) {\n bodyFull = safeBase64Decode(raw as string);\n } else {\n const findHtml = (partsArr: unknown[]): string | null => {\n for (const p of partsArr || []) {\n if (p && typeof p === 'object' && 'mimeType' in p && 'body' in p) {\n if (p.mimeType === 'text/html' && p.body && typeof p.body === 'object' && 'data' in p.body) {\n return p.body.data as string;\n }\n }\n if (p && typeof p === 'object' && 'parts' in p) {\n const nested = findHtml(p.parts as unknown[]);\n if (nested) return nested;\n }\n }\n return null;\n };\n const htmlPart = findHtml(parts as unknown[]);\n if (htmlPart) {\n bodyFull = safeBase64Decode(htmlPart).replace(/\\r\\n?/g, '\\n');\n }\n }\n }\n return [id, provider, threadId, to, from, cc, bcc, date, subject, labels, snippet, bodyFull];\n}\n"],"names":["buildContentForItems","safeBase64Decode","toIsoUtc","extractEmails","extractFrom","toRowFromGmail","msg","opts","body","addressFormat","headerObj","headers","payload","Object","fromEntries","map","h","String","name","value","id","provider","threadId","to","To","join","fromInfo","From","from","address","cc","Cc","bcc","Bcc","date","Date","subject","Subject","labelIds","Array","isArray","labels","snippet","bodyFull","parts","findText","partsArr","p","mimeType","data","nested","raw","findHtml","htmlPart","replace"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { gmail_v1 } from 'googleapis';
1
+ import type { gmail_v1 } from '@googleapis/gmail';
2
2
  export interface BodyExtractionOptions {
3
3
  /** Format to return: 'text' extracts plain text, 'html' preserves HTML structure */
4
4
  contentType?: 'text' | 'html';
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/email/parsing/html-processing.ts"],"sourcesContent":["import { extractCurrentMessageFromHtml } from '@mcp-z/email';\nimport type { gmail_v1 } from 'googleapis';\nimport { parse } from 'node-html-parser';\n\nexport interface BodyExtractionOptions {\n /** Format to return: 'text' extracts plain text, 'html' preserves HTML structure */\n contentType?: 'text' | 'html';\n /** When true, removes quoted thread history from HTML content */\n excludeThreadHistory?: boolean;\n}\n\nexport function extractBodyFromPayload(payload: gmail_v1.Schema$MessagePart, options: BodyExtractionOptions = {}): string {\n const { contentType = 'text', excludeThreadHistory = false } = options;\n if (!payload) return '';\n\n // If there's a direct body with data\n if (payload.body?.data) {\n return Buffer.from(payload.body.data, 'base64').toString('utf-8');\n }\n\n // If there are parts, look for text/plain or text/html\n if (payload.parts && Array.isArray(payload.parts)) {\n for (const part of payload.parts) {\n if (part.mimeType === 'text/plain' && part.body?.data) {\n return Buffer.from(part.body.data, 'base64').toString('utf-8');\n }\n if (part.mimeType === 'text/html' && part.body?.data) {\n let html = Buffer.from(part.body.data, 'base64').toString('utf-8');\n\n // Remove thread history if requested\n if (excludeThreadHistory) {\n html = extractCurrentMessageFromHtml(html);\n }\n\n // Return HTML directly if requested\n if (contentType === 'html') {\n return html;\n }\n\n // Otherwise extract plain text from HTML\n const doc = parse(html);\n const docUnknown = doc as unknown;\n if (docUnknown && typeof docUnknown === 'object' && 'text' in docUnknown) {\n return docUnknown.text as string;\n }\n return '';\n }\n }\n }\n\n return '';\n}\n"],"names":["extractCurrentMessageFromHtml","parse","extractBodyFromPayload","payload","options","contentType","excludeThreadHistory","body","data","Buffer","from","toString","parts","Array","isArray","part","mimeType","html","doc","docUnknown","text"],"mappings":"AAAA,SAASA,6BAA6B,QAAQ,eAAe;AAE7D,SAASC,KAAK,QAAQ,mBAAmB;AASzC,OAAO,SAASC,uBAAuBC,OAAoC,EAAEC,UAAiC,CAAC,CAAC;QAK1GD;IAJJ,MAAM,EAAEE,cAAc,MAAM,EAAEC,uBAAuB,KAAK,EAAE,GAAGF;IAC/D,IAAI,CAACD,SAAS,OAAO;IAErB,qCAAqC;IACrC,KAAIA,gBAAAA,QAAQI,IAAI,cAAZJ,oCAAAA,cAAcK,IAAI,EAAE;QACtB,OAAOC,OAAOC,IAAI,CAACP,QAAQI,IAAI,CAACC,IAAI,EAAE,UAAUG,QAAQ,CAAC;IAC3D;IAEA,uDAAuD;IACvD,IAAIR,QAAQS,KAAK,IAAIC,MAAMC,OAAO,CAACX,QAAQS,KAAK,GAAG;QACjD,KAAK,MAAMG,QAAQZ,QAAQS,KAAK,CAAE;gBACMG,YAGDA;YAHrC,IAAIA,KAAKC,QAAQ,KAAK,kBAAgBD,aAAAA,KAAKR,IAAI,cAATQ,iCAAAA,WAAWP,IAAI,GAAE;gBACrD,OAAOC,OAAOC,IAAI,CAACK,KAAKR,IAAI,CAACC,IAAI,EAAE,UAAUG,QAAQ,CAAC;YACxD;YACA,IAAII,KAAKC,QAAQ,KAAK,iBAAeD,cAAAA,KAAKR,IAAI,cAATQ,kCAAAA,YAAWP,IAAI,GAAE;gBACpD,IAAIS,OAAOR,OAAOC,IAAI,CAACK,KAAKR,IAAI,CAACC,IAAI,EAAE,UAAUG,QAAQ,CAAC;gBAE1D,qCAAqC;gBACrC,IAAIL,sBAAsB;oBACxBW,OAAOjB,8BAA8BiB;gBACvC;gBAEA,oCAAoC;gBACpC,IAAIZ,gBAAgB,QAAQ;oBAC1B,OAAOY;gBACT;gBAEA,yCAAyC;gBACzC,MAAMC,MAAMjB,MAAMgB;gBAClB,MAAME,aAAaD;gBACnB,IAAIC,cAAc,OAAOA,eAAe,YAAY,UAAUA,YAAY;oBACxE,OAAOA,WAAWC,IAAI;gBACxB;gBACA,OAAO;YACT;QACF;IACF;IAEA,OAAO;AACT"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/email/parsing/html-processing.ts"],"sourcesContent":["import type { gmail_v1 } from '@googleapis/gmail';\nimport { extractCurrentMessageFromHtml } from '@mcp-z/email';\nimport { parse } from 'node-html-parser';\n\nexport interface BodyExtractionOptions {\n /** Format to return: 'text' extracts plain text, 'html' preserves HTML structure */\n contentType?: 'text' | 'html';\n /** When true, removes quoted thread history from HTML content */\n excludeThreadHistory?: boolean;\n}\n\nexport function extractBodyFromPayload(payload: gmail_v1.Schema$MessagePart, options: BodyExtractionOptions = {}): string {\n const { contentType = 'text', excludeThreadHistory = false } = options;\n if (!payload) return '';\n\n // If there's a direct body with data\n if (payload.body?.data) {\n return Buffer.from(payload.body.data, 'base64').toString('utf-8');\n }\n\n // If there are parts, look for text/plain or text/html\n if (payload.parts && Array.isArray(payload.parts)) {\n for (const part of payload.parts) {\n if (part.mimeType === 'text/plain' && part.body?.data) {\n return Buffer.from(part.body.data, 'base64').toString('utf-8');\n }\n if (part.mimeType === 'text/html' && part.body?.data) {\n let html = Buffer.from(part.body.data, 'base64').toString('utf-8');\n\n // Remove thread history if requested\n if (excludeThreadHistory) {\n html = extractCurrentMessageFromHtml(html);\n }\n\n // Return HTML directly if requested\n if (contentType === 'html') {\n return html;\n }\n\n // Otherwise extract plain text from HTML\n const doc = parse(html);\n const docUnknown = doc as unknown;\n if (docUnknown && typeof docUnknown === 'object' && 'text' in docUnknown) {\n return docUnknown.text as string;\n }\n return '';\n }\n }\n }\n\n return '';\n}\n"],"names":["extractCurrentMessageFromHtml","parse","extractBodyFromPayload","payload","options","contentType","excludeThreadHistory","body","data","Buffer","from","toString","parts","Array","isArray","part","mimeType","html","doc","docUnknown","text"],"mappings":"AACA,SAASA,6BAA6B,QAAQ,eAAe;AAC7D,SAASC,KAAK,QAAQ,mBAAmB;AASzC,OAAO,SAASC,uBAAuBC,OAAoC,EAAEC,UAAiC,CAAC,CAAC;QAK1GD;IAJJ,MAAM,EAAEE,cAAc,MAAM,EAAEC,uBAAuB,KAAK,EAAE,GAAGF;IAC/D,IAAI,CAACD,SAAS,OAAO;IAErB,qCAAqC;IACrC,KAAIA,gBAAAA,QAAQI,IAAI,cAAZJ,oCAAAA,cAAcK,IAAI,EAAE;QACtB,OAAOC,OAAOC,IAAI,CAACP,QAAQI,IAAI,CAACC,IAAI,EAAE,UAAUG,QAAQ,CAAC;IAC3D;IAEA,uDAAuD;IACvD,IAAIR,QAAQS,KAAK,IAAIC,MAAMC,OAAO,CAACX,QAAQS,KAAK,GAAG;QACjD,KAAK,MAAMG,QAAQZ,QAAQS,KAAK,CAAE;gBACMG,YAGDA;YAHrC,IAAIA,KAAKC,QAAQ,KAAK,kBAAgBD,aAAAA,KAAKR,IAAI,cAATQ,iCAAAA,WAAWP,IAAI,GAAE;gBACrD,OAAOC,OAAOC,IAAI,CAACK,KAAKR,IAAI,CAACC,IAAI,EAAE,UAAUG,QAAQ,CAAC;YACxD;YACA,IAAII,KAAKC,QAAQ,KAAK,iBAAeD,cAAAA,KAAKR,IAAI,cAATQ,kCAAAA,YAAWP,IAAI,GAAE;gBACpD,IAAIS,OAAOR,OAAOC,IAAI,CAACK,KAAKR,IAAI,CAACC,IAAI,EAAE,UAAUG,QAAQ,CAAC;gBAE1D,qCAAqC;gBACrC,IAAIL,sBAAsB;oBACxBW,OAAOjB,8BAA8BiB;gBACvC;gBAEA,oCAAoC;gBACpC,IAAIZ,gBAAgB,QAAQ;oBAC1B,OAAOY;gBACT;gBAEA,yCAAyC;gBACzC,MAAMC,MAAMjB,MAAMgB;gBAClB,MAAME,aAAaD;gBACnB,IAAIC,cAAc,OAAOA,eAAe,YAAY,UAAUA,YAAY;oBACxE,OAAOA,WAAWC,IAAI;gBACxB;gBACA,OAAO;YACT;QACF;IACF;IAEA,OAAO;AACT"}
@@ -1,5 +1,5 @@
1
+ import type { gmail_v1 } from '@googleapis/gmail';
1
2
  import type { ExecutionResult } from '@mcp-z/email';
2
- import type { gmail_v1 } from 'googleapis';
3
3
  import type { GmailQuery as QueryNode } from '../../schemas/gmail-query-schema.js';
4
4
  import type { Logger } from '../../types.js';
5
5
  export interface ExecuteQueryOptions {
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/email/querying/execute-query.ts"],"sourcesContent":["import type { ExecutionResult } from '@mcp-z/email';\nimport type { gmail_v1 } from 'googleapis';\nimport { MAX_PAGE_SIZE } from '../../constants.ts';\nimport type { GmailQuery as QueryNode } from '../../schemas/gmail-query-schema.ts';\nimport type { Logger } from '../../types.ts';\nimport { searchMessages } from './search-execution.ts';\n\nexport interface ExecuteQueryOptions {\n client: gmail_v1.Gmail;\n logger: Logger;\n pageSize?: number;\n pageToken?: string;\n includeBody?: boolean;\n}\n\n/**\n * Execute a Gmail query with direct, single-attempt execution.\n * No planning, no fallbacks, no retries.\n * Provider errors are returned directly to the caller for actionable feedback.\n */\nexport async function executeQuery<T>(query: QueryNode | undefined, options: ExecuteQueryOptions, transform: (item: unknown) => T): Promise<ExecutionResult<T>> {\n const { client, logger, pageSize, pageToken, includeBody } = options;\n\n // Validate pagination parameters\n if (pageSize !== undefined && (pageSize < 1 || pageSize > MAX_PAGE_SIZE)) {\n throw new Error(`pageSize must be between 1 and ${MAX_PAGE_SIZE}`);\n }\n\n if (pageToken !== undefined && typeof pageToken === 'string' && pageToken.trim().length === 0) {\n logger.info('Empty pageToken provided, ignoring');\n }\n\n // Single execution - direct query to Gmail API\n logger.info('executeQuery: executing direct Gmail query');\n\n try {\n const result = await searchMessages(client, {\n ...(query !== undefined && { query }),\n pageSize: pageSize ?? 50,\n pageToken: pageToken && pageToken.trim().length > 0 ? pageToken : undefined,\n includeBody: includeBody ?? false,\n logger,\n });\n\n // Transform results\n const transformedResults = result.messages.map(transform);\n\n logger.info(`executeQuery: succeeded with ${transformedResults.length} results`);\n\n return {\n success: true,\n items: transformedResults,\n metadata: {\n nextPageToken: result.nextPageToken,\n },\n };\n } catch (error) {\n // Re-throw errors directly - no fallback logic\n logger.error('executeQuery: failed', { error: error instanceof Error ? error.message : String(error) });\n throw error;\n }\n}\n"],"names":["MAX_PAGE_SIZE","searchMessages","executeQuery","query","options","transform","client","logger","pageSize","pageToken","includeBody","undefined","Error","trim","length","info","result","transformedResults","messages","map","success","items","metadata","nextPageToken","error","message","String"],"mappings":"AAEA,SAASA,aAAa,QAAQ,qBAAqB;AAGnD,SAASC,cAAc,QAAQ,wBAAwB;AAUvD;;;;CAIC,GACD,OAAO,eAAeC,aAAgBC,KAA4B,EAAEC,OAA4B,EAAEC,SAA+B;IAC/H,MAAM,EAAEC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,WAAW,EAAE,GAAGN;IAE7D,iCAAiC;IACjC,IAAII,aAAaG,aAAcH,CAAAA,WAAW,KAAKA,WAAWR,aAAY,GAAI;QACxE,MAAM,IAAIY,MAAM,CAAC,+BAA+B,EAAEZ,eAAe;IACnE;IAEA,IAAIS,cAAcE,aAAa,OAAOF,cAAc,YAAYA,UAAUI,IAAI,GAAGC,MAAM,KAAK,GAAG;QAC7FP,OAAOQ,IAAI,CAAC;IACd;IAEA,+CAA+C;IAC/CR,OAAOQ,IAAI,CAAC;IAEZ,IAAI;QACF,MAAMC,SAAS,MAAMf,eAAeK,QAAQ;YAC1C,GAAIH,UAAUQ,aAAa;gBAAER;YAAM,CAAC;YACpCK,QAAQ,EAAEA,qBAAAA,sBAAAA,WAAY;YACtBC,WAAWA,aAAaA,UAAUI,IAAI,GAAGC,MAAM,GAAG,IAAIL,YAAYE;YAClED,WAAW,EAAEA,wBAAAA,yBAAAA,cAAe;YAC5BH;QACF;QAEA,oBAAoB;QACpB,MAAMU,qBAAqBD,OAAOE,QAAQ,CAACC,GAAG,CAACd;QAE/CE,OAAOQ,IAAI,CAAC,CAAC,6BAA6B,EAAEE,mBAAmBH,MAAM,CAAC,QAAQ,CAAC;QAE/E,OAAO;YACLM,SAAS;YACTC,OAAOJ;YACPK,UAAU;gBACRC,eAAeP,OAAOO,aAAa;YACrC;QACF;IACF,EAAE,OAAOC,OAAO;QACd,+CAA+C;QAC/CjB,OAAOiB,KAAK,CAAC,wBAAwB;YAAEA,OAAOA,iBAAiBZ,QAAQY,MAAMC,OAAO,GAAGC,OAAOF;QAAO;QACrG,MAAMA;IACR;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/email/querying/execute-query.ts"],"sourcesContent":["import type { gmail_v1 } from '@googleapis/gmail';\nimport type { ExecutionResult } from '@mcp-z/email';\nimport { MAX_PAGE_SIZE } from '../../constants.ts';\nimport type { GmailQuery as QueryNode } from '../../schemas/gmail-query-schema.ts';\nimport type { Logger } from '../../types.ts';\nimport { searchMessages } from './search-execution.ts';\n\nexport interface ExecuteQueryOptions {\n client: gmail_v1.Gmail;\n logger: Logger;\n pageSize?: number;\n pageToken?: string;\n includeBody?: boolean;\n}\n\n/**\n * Execute a Gmail query with direct, single-attempt execution.\n * No planning, no fallbacks, no retries.\n * Provider errors are returned directly to the caller for actionable feedback.\n */\nexport async function executeQuery<T>(query: QueryNode | undefined, options: ExecuteQueryOptions, transform: (item: unknown) => T): Promise<ExecutionResult<T>> {\n const { client, logger, pageSize, pageToken, includeBody } = options;\n\n // Validate pagination parameters\n if (pageSize !== undefined && (pageSize < 1 || pageSize > MAX_PAGE_SIZE)) {\n throw new Error(`pageSize must be between 1 and ${MAX_PAGE_SIZE}`);\n }\n\n if (pageToken !== undefined && typeof pageToken === 'string' && pageToken.trim().length === 0) {\n logger.info('Empty pageToken provided, ignoring');\n }\n\n // Single execution - direct query to Gmail API\n logger.info('executeQuery: executing direct Gmail query');\n\n try {\n const result = await searchMessages(client, {\n ...(query !== undefined && { query }),\n pageSize: pageSize ?? 50,\n pageToken: pageToken && pageToken.trim().length > 0 ? pageToken : undefined,\n includeBody: includeBody ?? false,\n logger,\n });\n\n // Transform results\n const transformedResults = result.messages.map(transform);\n\n logger.info(`executeQuery: succeeded with ${transformedResults.length} results`);\n\n return {\n success: true,\n items: transformedResults,\n metadata: {\n nextPageToken: result.nextPageToken,\n },\n };\n } catch (error) {\n // Re-throw errors directly - no fallback logic\n logger.error('executeQuery: failed', { error: error instanceof Error ? error.message : String(error) });\n throw error;\n }\n}\n"],"names":["MAX_PAGE_SIZE","searchMessages","executeQuery","query","options","transform","client","logger","pageSize","pageToken","includeBody","undefined","Error","trim","length","info","result","transformedResults","messages","map","success","items","metadata","nextPageToken","error","message","String"],"mappings":"AAEA,SAASA,aAAa,QAAQ,qBAAqB;AAGnD,SAASC,cAAc,QAAQ,wBAAwB;AAUvD;;;;CAIC,GACD,OAAO,eAAeC,aAAgBC,KAA4B,EAAEC,OAA4B,EAAEC,SAA+B;IAC/H,MAAM,EAAEC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,WAAW,EAAE,GAAGN;IAE7D,iCAAiC;IACjC,IAAII,aAAaG,aAAcH,CAAAA,WAAW,KAAKA,WAAWR,aAAY,GAAI;QACxE,MAAM,IAAIY,MAAM,CAAC,+BAA+B,EAAEZ,eAAe;IACnE;IAEA,IAAIS,cAAcE,aAAa,OAAOF,cAAc,YAAYA,UAAUI,IAAI,GAAGC,MAAM,KAAK,GAAG;QAC7FP,OAAOQ,IAAI,CAAC;IACd;IAEA,+CAA+C;IAC/CR,OAAOQ,IAAI,CAAC;IAEZ,IAAI;QACF,MAAMC,SAAS,MAAMf,eAAeK,QAAQ;YAC1C,GAAIH,UAAUQ,aAAa;gBAAER;YAAM,CAAC;YACpCK,QAAQ,EAAEA,qBAAAA,sBAAAA,WAAY;YACtBC,WAAWA,aAAaA,UAAUI,IAAI,GAAGC,MAAM,GAAG,IAAIL,YAAYE;YAClED,WAAW,EAAEA,wBAAAA,yBAAAA,cAAe;YAC5BH;QACF;QAEA,oBAAoB;QACpB,MAAMU,qBAAqBD,OAAOE,QAAQ,CAACC,GAAG,CAACd;QAE/CE,OAAOQ,IAAI,CAAC,CAAC,6BAA6B,EAAEE,mBAAmBH,MAAM,CAAC,QAAQ,CAAC;QAE/E,OAAO;YACLM,SAAS;YACTC,OAAOJ;YACPK,UAAU;gBACRC,eAAeP,OAAOO,aAAa;YACrC;QACF;IACF,EAAE,OAAOC,OAAO;QACd,+CAA+C;QAC/CjB,OAAOiB,KAAK,CAAC,wBAAwB;YAAEA,OAAOA,iBAAiBZ,QAAQY,MAAMC,OAAO,GAAGC,OAAOF;QAAO;QACrG,MAAMA;IACR;AACF"}
@@ -1,5 +1,5 @@
1
1
  /** Gmail pagination helpers for single-page operations. */
2
- import type { gmail_v1 } from 'googleapis';
2
+ import type { gmail_v1 } from '@googleapis/gmail';
3
3
  import type { Logger } from '../../types.js';
4
4
  export interface SinglePageResult {
5
5
  readonly messages: gmail_v1.Schema$Message[];
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/email/querying/pagination.ts"],"sourcesContent":["/** Gmail pagination helpers for single-page operations. */\n\nimport type { gmail_v1 } from 'googleapis';\nimport type { Logger } from '../../types.ts';\n\nexport interface SinglePageResult {\n readonly messages: gmail_v1.Schema$Message[];\n readonly nextPageToken: string | undefined;\n}\n\n/**\n * Fetch a single page of messages from Gmail\n */\nexport interface FetchMessagesPageParams {\n readonly gmailQ: string;\n readonly pageSize?: number;\n readonly pageToken: string | undefined;\n readonly body?: boolean;\n readonly logger: Logger;\n readonly metadataHeaders?: readonly string[];\n}\n\nexport async function fetchMessagesPage(gmail: gmail_v1.Gmail, params: FetchMessagesPageParams): Promise<SinglePageResult> {\n const { gmailQ, pageSize = 50, pageToken, body = false, logger, metadataHeaders } = params;\n\n // Secure resource bounds checking - prevent security bypasses\n const maxPageSize = 500; // Gmail API maximum - enforced for security\n const minPageSize = 1; // Minimum valid page size\n\n // Validate input is a positive number to prevent bypass attempts\n if (!Number.isInteger(pageSize) || pageSize < 0) {\n throw new Error(`Invalid pageSize: must be a positive integer, got ${pageSize}`);\n }\n\n const safePageSize = Math.min(Math.max(minPageSize, pageSize), maxPageSize);\n\n if (pageSize !== safePageSize && logger) {\n logger.info('Page size bounded for API safety', { requested: pageSize, applied: safePageSize });\n // No fallback to console - would corrupt MCP stdio communication\n }\n\n try {\n const listParams = {\n userId: 'me',\n q: gmailQ,\n maxResults: safePageSize,\n };\n const listResponse = pageToken && pageToken.trim().length > 0 ? await gmail.users.messages.list({ ...listParams, pageToken }) : await gmail.users.messages.list(listParams);\n const response = listResponse.data;\n const messages = response.messages || [];\n\n if (messages.length === 0) {\n if (logger) logger.info('No messages found on page');\n return { messages: [], nextPageToken: undefined };\n }\n\n const items = messages.map((m: gmail_v1.Schema$Message) => m.id).filter(Boolean) as string[];\n if (items.length === 0) {\n if (logger) logger.info('No valid message ids on page');\n return { messages: [], nextPageToken: response.nextPageToken && response.nextPageToken.trim().length > 0 ? response.nextPageToken : undefined };\n }\n\n const concurrentArgs: FetchMessagesConcurrentlyParams = {\n items,\n concurrency: 5,\n body,\n ...(logger && { logger }),\n ...(metadataHeaders && { metadataHeaders }),\n };\n const detailedMessages = await fetchMessagesConcurrently(gmail, concurrentArgs);\n\n if (logger) logger.info(`Fetched page with ${detailedMessages.length} messages`);\n return {\n messages: detailedMessages,\n nextPageToken: response.nextPageToken && response.nextPageToken.trim().length > 0 ? response.nextPageToken : undefined,\n };\n } catch (error) {\n // Standardized error handling for pagination pipeline\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (logger)\n logger.error('Gmail pagination: single page fetch failed', {\n error: errorMessage,\n query: gmailQ,\n pageSize: safePageSize,\n hasPageToken: !!pageToken,\n });\n\n // Preserve original error type for upstream handling\n if (error instanceof Error) {\n // Enhance error with pagination context\n error.message = `Gmail pagination fetch failed: ${error.message}`;\n throw error;\n }\n\n // Convert non-Error objects to proper Error instances\n throw new Error(`Gmail pagination fetch failed: ${errorMessage}`);\n }\n}\n\nexport interface FetchMessagesConcurrentlyParams {\n readonly items: readonly string[];\n readonly concurrency?: number;\n readonly body?: boolean;\n readonly logger: Logger;\n readonly metadataHeaders?: readonly string[];\n}\n\nexport async function fetchMessagesConcurrently(gmail: gmail_v1.Gmail, params: FetchMessagesConcurrentlyParams): Promise<gmail_v1.Schema$Message[]> {\n const { items, concurrency = 2, body = false, logger, metadataHeaders } = params;\n\n // Secure resource bounds checking for concurrent operations\n const maxConcurrency = 10; // Conservative limit to prevent rate limiting and resource exhaustion\n const minConcurrency = 1; // Minimum valid concurrency\n\n // Validate input is a positive number to prevent bypass attempts\n if (!Number.isInteger(concurrency) || concurrency < 0) {\n throw new Error(`Invalid concurrency: must be a positive integer, got ${concurrency}`);\n }\n\n const safeConcurrency = Math.min(Math.max(minConcurrency, concurrency), maxConcurrency);\n\n if (concurrency !== safeConcurrency && logger) {\n logger.info('Concurrency bounded for API safety', { requested: concurrency, applied: safeConcurrency });\n // No fallback to console - would corrupt MCP stdio communication\n }\n\n if (items.length === 0) return [];\n\n const results: (gmail_v1.Schema$Message | null)[] = new Array(items.length);\n const format = body ? 'full' : 'metadata';\n // Always pass metadataHeaders if provided - body doesn't replace headers, it's additional content\n const metadataHeadersForRequest = metadataHeaders;\n\n // Pre-build request parameters to avoid repeated object creation\n const requestParams = items.map((id) => {\n const baseParams = {\n userId: 'me' as const,\n id,\n format,\n };\n // Only include metadataHeaders if defined (exactOptionalPropertyTypes compliance)\n return metadataHeadersForRequest ? { ...baseParams, metadataHeaders: [...metadataHeadersForRequest] } : baseParams;\n });\n\n // Optimize concurrent processing using batching\n const batchSize = safeConcurrency;\n const batches: (typeof requestParams)[] = [];\n for (let i = 0; i < requestParams.length; i += batchSize) {\n batches.push(requestParams.slice(i, i + batchSize));\n }\n\n let processedCount = 0;\n for (const batch of batches) {\n const batchPromises = batch.map(async (params, batchIndex) => {\n try {\n const messageResponse = await gmail.users.messages.get(params);\n const globalIndex = processedCount + batchIndex;\n results[globalIndex] = messageResponse.data;\n return messageResponse.data;\n } catch (error) {\n // Log individual message fetch failures but continue processing\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (logger)\n logger.info('Gmail pagination: individual message fetch failed, continuing', {\n error: errorMessage,\n messageId: params.id,\n globalIndex: processedCount + batchIndex,\n });\n return null; // Mark as failed but continue\n }\n });\n\n await Promise.all(batchPromises);\n processedCount += batch.length;\n\n // Progress logging for large batches\n if (items.length > 20) {\n if (logger) logger.info(`Gmail pagination: processed ${processedCount}/${items.length} messages`);\n }\n }\n\n // Filter out any null results from failed individual fetches\n return results.filter((result) => result !== null && result !== undefined);\n}\n"],"names":["fetchMessagesPage","gmail","params","gmailQ","pageSize","pageToken","body","logger","metadataHeaders","maxPageSize","minPageSize","Number","isInteger","Error","safePageSize","Math","min","max","info","requested","applied","listParams","userId","q","maxResults","listResponse","trim","length","users","messages","list","response","data","nextPageToken","undefined","items","map","m","id","filter","Boolean","concurrentArgs","concurrency","detailedMessages","fetchMessagesConcurrently","error","errorMessage","message","String","query","hasPageToken","maxConcurrency","minConcurrency","safeConcurrency","results","Array","format","metadataHeadersForRequest","requestParams","baseParams","batchSize","batches","i","push","slice","processedCount","batch","batchPromises","batchIndex","messageResponse","get","globalIndex","messageId","Promise","all","result"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/email/querying/pagination.ts"],"sourcesContent":["/** Gmail pagination helpers for single-page operations. */\n\nimport type { gmail_v1 } from '@googleapis/gmail';\nimport type { Logger } from '../../types.ts';\n\nexport interface SinglePageResult {\n readonly messages: gmail_v1.Schema$Message[];\n readonly nextPageToken: string | undefined;\n}\n\n/**\n * Fetch a single page of messages from Gmail\n */\nexport interface FetchMessagesPageParams {\n readonly gmailQ: string;\n readonly pageSize?: number;\n readonly pageToken: string | undefined;\n readonly body?: boolean;\n readonly logger: Logger;\n readonly metadataHeaders?: readonly string[];\n}\n\nexport async function fetchMessagesPage(gmail: gmail_v1.Gmail, params: FetchMessagesPageParams): Promise<SinglePageResult> {\n const { gmailQ, pageSize = 50, pageToken, body = false, logger, metadataHeaders } = params;\n\n // Secure resource bounds checking - prevent security bypasses\n const maxPageSize = 500; // Gmail API maximum - enforced for security\n const minPageSize = 1; // Minimum valid page size\n\n // Validate input is a positive number to prevent bypass attempts\n if (!Number.isInteger(pageSize) || pageSize < 0) {\n throw new Error(`Invalid pageSize: must be a positive integer, got ${pageSize}`);\n }\n\n const safePageSize = Math.min(Math.max(minPageSize, pageSize), maxPageSize);\n\n if (pageSize !== safePageSize && logger) {\n logger.info('Page size bounded for API safety', { requested: pageSize, applied: safePageSize });\n // No fallback to console - would corrupt MCP stdio communication\n }\n\n try {\n const listParams = {\n userId: 'me',\n q: gmailQ,\n maxResults: safePageSize,\n };\n const listResponse = pageToken && pageToken.trim().length > 0 ? await gmail.users.messages.list({ ...listParams, pageToken }) : await gmail.users.messages.list(listParams);\n const response = listResponse.data;\n const messages = response.messages || [];\n\n if (messages.length === 0) {\n if (logger) logger.info('No messages found on page');\n return { messages: [], nextPageToken: undefined };\n }\n\n const items = messages.map((m: gmail_v1.Schema$Message) => m.id).filter(Boolean) as string[];\n if (items.length === 0) {\n if (logger) logger.info('No valid message ids on page');\n return { messages: [], nextPageToken: response.nextPageToken && response.nextPageToken.trim().length > 0 ? response.nextPageToken : undefined };\n }\n\n const concurrentArgs: FetchMessagesConcurrentlyParams = {\n items,\n concurrency: 5,\n body,\n ...(logger && { logger }),\n ...(metadataHeaders && { metadataHeaders }),\n };\n const detailedMessages = await fetchMessagesConcurrently(gmail, concurrentArgs);\n\n if (logger) logger.info(`Fetched page with ${detailedMessages.length} messages`);\n return {\n messages: detailedMessages,\n nextPageToken: response.nextPageToken && response.nextPageToken.trim().length > 0 ? response.nextPageToken : undefined,\n };\n } catch (error) {\n // Standardized error handling for pagination pipeline\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (logger)\n logger.error('Gmail pagination: single page fetch failed', {\n error: errorMessage,\n query: gmailQ,\n pageSize: safePageSize,\n hasPageToken: !!pageToken,\n });\n\n // Preserve original error type for upstream handling\n if (error instanceof Error) {\n // Enhance error with pagination context\n error.message = `Gmail pagination fetch failed: ${error.message}`;\n throw error;\n }\n\n // Convert non-Error objects to proper Error instances\n throw new Error(`Gmail pagination fetch failed: ${errorMessage}`);\n }\n}\n\nexport interface FetchMessagesConcurrentlyParams {\n readonly items: readonly string[];\n readonly concurrency?: number;\n readonly body?: boolean;\n readonly logger: Logger;\n readonly metadataHeaders?: readonly string[];\n}\n\nexport async function fetchMessagesConcurrently(gmail: gmail_v1.Gmail, params: FetchMessagesConcurrentlyParams): Promise<gmail_v1.Schema$Message[]> {\n const { items, concurrency = 2, body = false, logger, metadataHeaders } = params;\n\n // Secure resource bounds checking for concurrent operations\n const maxConcurrency = 10; // Conservative limit to prevent rate limiting and resource exhaustion\n const minConcurrency = 1; // Minimum valid concurrency\n\n // Validate input is a positive number to prevent bypass attempts\n if (!Number.isInteger(concurrency) || concurrency < 0) {\n throw new Error(`Invalid concurrency: must be a positive integer, got ${concurrency}`);\n }\n\n const safeConcurrency = Math.min(Math.max(minConcurrency, concurrency), maxConcurrency);\n\n if (concurrency !== safeConcurrency && logger) {\n logger.info('Concurrency bounded for API safety', { requested: concurrency, applied: safeConcurrency });\n // No fallback to console - would corrupt MCP stdio communication\n }\n\n if (items.length === 0) return [];\n\n const results: (gmail_v1.Schema$Message | null)[] = new Array(items.length);\n const format = body ? 'full' : 'metadata';\n // Always pass metadataHeaders if provided - body doesn't replace headers, it's additional content\n const metadataHeadersForRequest = metadataHeaders;\n\n // Pre-build request parameters to avoid repeated object creation\n const requestParams = items.map((id) => {\n const baseParams = {\n userId: 'me' as const,\n id,\n format,\n };\n // Only include metadataHeaders if defined (exactOptionalPropertyTypes compliance)\n return metadataHeadersForRequest ? { ...baseParams, metadataHeaders: [...metadataHeadersForRequest] } : baseParams;\n });\n\n // Optimize concurrent processing using batching\n const batchSize = safeConcurrency;\n const batches: (typeof requestParams)[] = [];\n for (let i = 0; i < requestParams.length; i += batchSize) {\n batches.push(requestParams.slice(i, i + batchSize));\n }\n\n let processedCount = 0;\n for (const batch of batches) {\n const batchPromises = batch.map(async (params, batchIndex) => {\n try {\n const messageResponse = await gmail.users.messages.get(params);\n const globalIndex = processedCount + batchIndex;\n results[globalIndex] = messageResponse.data;\n return messageResponse.data;\n } catch (error) {\n // Log individual message fetch failures but continue processing\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (logger)\n logger.info('Gmail pagination: individual message fetch failed, continuing', {\n error: errorMessage,\n messageId: params.id,\n globalIndex: processedCount + batchIndex,\n });\n return null; // Mark as failed but continue\n }\n });\n\n await Promise.all(batchPromises);\n processedCount += batch.length;\n\n // Progress logging for large batches\n if (items.length > 20) {\n if (logger) logger.info(`Gmail pagination: processed ${processedCount}/${items.length} messages`);\n }\n }\n\n // Filter out any null results from failed individual fetches\n return results.filter((result) => result !== null && result !== undefined);\n}\n"],"names":["fetchMessagesPage","gmail","params","gmailQ","pageSize","pageToken","body","logger","metadataHeaders","maxPageSize","minPageSize","Number","isInteger","Error","safePageSize","Math","min","max","info","requested","applied","listParams","userId","q","maxResults","listResponse","trim","length","users","messages","list","response","data","nextPageToken","undefined","items","map","m","id","filter","Boolean","concurrentArgs","concurrency","detailedMessages","fetchMessagesConcurrently","error","errorMessage","message","String","query","hasPageToken","maxConcurrency","minConcurrency","safeConcurrency","results","Array","format","metadataHeadersForRequest","requestParams","baseParams","batchSize","batches","i","push","slice","processedCount","batch","batchPromises","batchIndex","messageResponse","get","globalIndex","messageId","Promise","all","result"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { gmail_v1 } from 'googleapis';
1
+ import type { gmail_v1 } from '@googleapis/gmail';
2
2
  import type { GmailQuery as QueryNode } from '../../schemas/gmail-query-schema.js';
3
3
  import type { Logger } from '../../types.js';
4
4
  export interface GmailSearchOptions {
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/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
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/email/querying/search-execution.ts"],"sourcesContent":["import type { gmail_v1 } from '@googleapis/gmail';\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,2 +1,2 @@
1
- import type { gmail_v1 } from 'googleapis';
1
+ import type { gmail_v1 } from '@googleapis/gmail';
2
2
  export declare function ensureLabelId(gmail: gmail_v1.Gmail, userId: string, labelName: string): Promise<string>;
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/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
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-gmail/src/labels/gmail-labels.ts"],"sourcesContent":["import type { gmail_v1 } from '@googleapis/gmail';\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"}