@yoryoboy/bi-mcp 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/README.md +346 -0
  2. package/bin/bi-mcp.js +2 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/index.js +768 -0
  5. package/dist/index.js.map +7 -0
  6. package/dist/mcp-use.json +7 -0
  7. package/dist/public/favicon.ico +0 -0
  8. package/dist/public/icon.svg +6 -0
  9. package/dist/src/analytics/ga4-channel-groups.js +20 -0
  10. package/dist/src/analytics/ga4-channel-groups.js.map +7 -0
  11. package/dist/src/analytics/ga4-report-utils.js +117 -0
  12. package/dist/src/analytics/ga4-report-utils.js.map +7 -0
  13. package/dist/src/config/benchmarks.js +128 -0
  14. package/dist/src/config/benchmarks.js.map +7 -0
  15. package/dist/src/config/google.js +41 -0
  16. package/dist/src/config/google.js.map +7 -0
  17. package/dist/src/config/vtex.js +26 -0
  18. package/dist/src/config/vtex.js.map +7 -0
  19. package/dist/src/google-ads/report-utils.js +78 -0
  20. package/dist/src/google-ads/report-utils.js.map +7 -0
  21. package/dist/src/prompts/reporte-ventas.js +75 -0
  22. package/dist/src/prompts/reporte-ventas.js.map +7 -0
  23. package/dist/src/search-console/search-console-utils.js +275 -0
  24. package/dist/src/search-console/search-console-utils.js.map +7 -0
  25. package/dist/src/services/analytics/ga4-client.js +69 -0
  26. package/dist/src/services/analytics/ga4-client.js.map +7 -0
  27. package/dist/src/services/analytics/oauth.js +30 -0
  28. package/dist/src/services/analytics/oauth.js.map +7 -0
  29. package/dist/src/services/google-ads/google-ads-client.js +54 -0
  30. package/dist/src/services/google-ads/google-ads-client.js.map +7 -0
  31. package/dist/src/services/search-console/search-console-client.js +45 -0
  32. package/dist/src/services/search-console/search-console-client.js.map +7 -0
  33. package/dist/src/services/vtex/vtex-api.js +51 -0
  34. package/dist/src/services/vtex/vtex-api.js.map +7 -0
  35. package/dist/src/services/vtex/vtex-catalog.js +18 -0
  36. package/dist/src/services/vtex/vtex-catalog.js.map +7 -0
  37. package/dist/src/services/vtex/vtex-logistics.js +151 -0
  38. package/dist/src/services/vtex/vtex-logistics.js.map +7 -0
  39. package/dist/src/services/vtex/vtex-orders.js +143 -0
  40. package/dist/src/services/vtex/vtex-orders.js.map +7 -0
  41. package/dist/src/services/vtex/vtex-pricing.js +17 -0
  42. package/dist/src/services/vtex/vtex-pricing.js.map +7 -0
  43. package/dist/src/tools/analytics/attribution-gaps.js +109 -0
  44. package/dist/src/tools/analytics/attribution-gaps.js.map +7 -0
  45. package/dist/src/tools/analytics/channel-mix.js +74 -0
  46. package/dist/src/tools/analytics/channel-mix.js.map +7 -0
  47. package/dist/src/tools/analytics/ecommerce-tracking-health.js +89 -0
  48. package/dist/src/tools/analytics/ecommerce-tracking-health.js.map +7 -0
  49. package/dist/src/tools/analytics/engagement-overview.js +71 -0
  50. package/dist/src/tools/analytics/engagement-overview.js.map +7 -0
  51. package/dist/src/tools/analytics/index.js +12 -0
  52. package/dist/src/tools/analytics/index.js.map +7 -0
  53. package/dist/src/tools/analytics/list-accessible-properties.js +46 -0
  54. package/dist/src/tools/analytics/list-accessible-properties.js.map +7 -0
  55. package/dist/src/tools/analytics/property-info.js +54 -0
  56. package/dist/src/tools/analytics/property-info.js.map +7 -0
  57. package/dist/src/tools/analytics/revenue-by-channel.js +70 -0
  58. package/dist/src/tools/analytics/revenue-by-channel.js.map +7 -0
  59. package/dist/src/tools/analytics/revenue-overview.js +77 -0
  60. package/dist/src/tools/analytics/revenue-overview.js.map +7 -0
  61. package/dist/src/tools/analytics/revenue-trend.js +69 -0
  62. package/dist/src/tools/analytics/revenue-trend.js.map +7 -0
  63. package/dist/src/tools/analytics/source-medium-breakdown.js +86 -0
  64. package/dist/src/tools/analytics/source-medium-breakdown.js.map +7 -0
  65. package/dist/src/tools/analytics/top-landing-pages.js +79 -0
  66. package/dist/src/tools/analytics/top-landing-pages.js.map +7 -0
  67. package/dist/src/tools/google-ads/account-overview.js +103 -0
  68. package/dist/src/tools/google-ads/account-overview.js.map +7 -0
  69. package/dist/src/tools/google-ads/account-risks.js +267 -0
  70. package/dist/src/tools/google-ads/account-risks.js.map +7 -0
  71. package/dist/src/tools/google-ads/break-even-analysis.js +107 -0
  72. package/dist/src/tools/google-ads/break-even-analysis.js.map +7 -0
  73. package/dist/src/tools/google-ads/campaign-performance.js +157 -0
  74. package/dist/src/tools/google-ads/campaign-performance.js.map +7 -0
  75. package/dist/src/tools/google-ads/channel-mix.js +129 -0
  76. package/dist/src/tools/google-ads/channel-mix.js.map +7 -0
  77. package/dist/src/tools/google-ads/compare-accounts.js +122 -0
  78. package/dist/src/tools/google-ads/compare-accounts.js.map +7 -0
  79. package/dist/src/tools/google-ads/customer-clients.js +77 -0
  80. package/dist/src/tools/google-ads/customer-clients.js.map +7 -0
  81. package/dist/src/tools/google-ads/customer-info.js +64 -0
  82. package/dist/src/tools/google-ads/customer-info.js.map +7 -0
  83. package/dist/src/tools/google-ads/index.js +12 -0
  84. package/dist/src/tools/google-ads/index.js.map +7 -0
  85. package/dist/src/tools/google-ads/scaling-health.js +174 -0
  86. package/dist/src/tools/google-ads/scaling-health.js.map +7 -0
  87. package/dist/src/tools/google-ads/search-terms-summary.js +131 -0
  88. package/dist/src/tools/google-ads/search-terms-summary.js.map +7 -0
  89. package/dist/src/tools/google-ads/time-series.js +126 -0
  90. package/dist/src/tools/google-ads/time-series.js.map +7 -0
  91. package/dist/src/tools/index.js +5 -0
  92. package/dist/src/tools/index.js.map +7 -0
  93. package/dist/src/tools/search-console/country-breakdown.js +85 -0
  94. package/dist/src/tools/search-console/country-breakdown.js.map +7 -0
  95. package/dist/src/tools/search-console/device-breakdown.js +85 -0
  96. package/dist/src/tools/search-console/device-breakdown.js.map +7 -0
  97. package/dist/src/tools/search-console/high-impression-low-click-queries.js +95 -0
  98. package/dist/src/tools/search-console/high-impression-low-click-queries.js.map +7 -0
  99. package/dist/src/tools/search-console/index.js +15 -0
  100. package/dist/src/tools/search-console/index.js.map +7 -0
  101. package/dist/src/tools/search-console/list-accessible-sites.js +42 -0
  102. package/dist/src/tools/search-console/list-accessible-sites.js.map +7 -0
  103. package/dist/src/tools/search-console/low-ctr-opportunities.js +98 -0
  104. package/dist/src/tools/search-console/low-ctr-opportunities.js.map +7 -0
  105. package/dist/src/tools/search-console/page-performance.js +104 -0
  106. package/dist/src/tools/search-console/page-performance.js.map +7 -0
  107. package/dist/src/tools/search-console/product-demand-low-capture-queries.js +93 -0
  108. package/dist/src/tools/search-console/product-demand-low-capture-queries.js.map +7 -0
  109. package/dist/src/tools/search-console/query-page-matrix.js +99 -0
  110. package/dist/src/tools/search-console/query-page-matrix.js.map +7 -0
  111. package/dist/src/tools/search-console/query-performance.js +109 -0
  112. package/dist/src/tools/search-console/query-performance.js.map +7 -0
  113. package/dist/src/tools/search-console/quick-win-opportunities.js +93 -0
  114. package/dist/src/tools/search-console/quick-win-opportunities.js.map +7 -0
  115. package/dist/src/tools/search-console/rising-non-brand-queries.js +121 -0
  116. package/dist/src/tools/search-console/rising-non-brand-queries.js.map +7 -0
  117. package/dist/src/tools/search-console/search-performance.js +89 -0
  118. package/dist/src/tools/search-console/search-performance.js.map +7 -0
  119. package/dist/src/tools/search-console/site-context.js +43 -0
  120. package/dist/src/tools/search-console/site-context.js.map +7 -0
  121. package/dist/src/tools/search-console/visibility-declines.js +146 -0
  122. package/dist/src/tools/search-console/visibility-declines.js.map +7 -0
  123. package/dist/src/tools/vtex/computed-price.js +48 -0
  124. package/dist/src/tools/vtex/computed-price.js.map +7 -0
  125. package/dist/src/tools/vtex/index.js +11 -0
  126. package/dist/src/tools/vtex/index.js.map +7 -0
  127. package/dist/src/tools/vtex/inventory-check.js +148 -0
  128. package/dist/src/tools/vtex/inventory-check.js.map +7 -0
  129. package/dist/src/tools/vtex/order-details.js +56 -0
  130. package/dist/src/tools/vtex/order-details.js.map +7 -0
  131. package/dist/src/tools/vtex/orders-summary.js +83 -0
  132. package/dist/src/tools/vtex/orders-summary.js.map +7 -0
  133. package/dist/src/tools/vtex/product-offers.js +28 -0
  134. package/dist/src/tools/vtex/product-offers.js.map +7 -0
  135. package/dist/src/tools/vtex/sku-offers.js +30 -0
  136. package/dist/src/tools/vtex/sku-offers.js.map +7 -0
  137. package/dist/src/tools/vtex/sku-price.js +42 -0
  138. package/dist/src/tools/vtex/sku-price.js.map +7 -0
  139. package/dist/src/tools/vtex/update-inventory.js +43 -0
  140. package/dist/src/tools/vtex/update-inventory.js.map +7 -0
  141. package/dist/src/tools/vtex/update-lead-time.js +32 -0
  142. package/dist/src/tools/vtex/update-lead-time.js.map +7 -0
  143. package/dist/src/tools/vtex/warehouse-inventory.js +42 -0
  144. package/dist/src/tools/vtex/warehouse-inventory.js.map +7 -0
  145. package/dist/src/utils/case-conversion.js +21 -0
  146. package/dist/src/utils/case-conversion.js.map +7 -0
  147. package/dist/src/utils/currency.js +52 -0
  148. package/dist/src/utils/currency.js.map +7 -0
  149. package/dist/src/utils/format-order-details.js +137 -0
  150. package/dist/src/utils/format-order-details.js.map +7 -0
  151. package/dist/src/utils/google-ads.js +78 -0
  152. package/dist/src/utils/google-ads.js.map +7 -0
  153. package/dist/src/utils/money.js +83 -0
  154. package/dist/src/utils/money.js.map +7 -0
  155. package/dist/src/utils/order-status.js +11 -0
  156. package/dist/src/utils/order-status.js.map +7 -0
  157. package/dist/src/utils/pagination.js +45 -0
  158. package/dist/src/utils/pagination.js.map +7 -0
  159. package/dist/src/utils/strip-payload.js +40 -0
  160. package/dist/src/utils/strip-payload.js.map +7 -0
  161. package/dist/src/utils/type-guards.js +7 -0
  162. package/dist/src/utils/type-guards.js.map +7 -0
  163. package/package.json +66 -0
  164. package/public/favicon.ico +0 -0
  165. package/public/icon.svg +6 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/tools/analytics/revenue-overview.ts"],
4
+ "sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport {\n extractQuotaSnapshot,\n getMetricValueByName,\n resolveGa4PropertyId,\n round,\n toPercent,\n} from \"../../analytics/ga4-report-utils.js\";\nimport { runReport } from \"../../services/analytics/ga4-client.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nconst dateRegex = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nexport const revenueOverviewSchema = z.object({\n startDate: z.string().regex(dateRegex).describe(\"Start date in YYYY-MM-DD format\"),\n endDate: z.string().regex(dateRegex).describe(\"End date in YYYY-MM-DD format\"),\n propertyId: z.string().optional().describe(\"GA4 property ID. If omitted, uses GA4_PROPERTY_ID\"),\n});\n\nexport async function revenueOverviewHandler(params: z.infer<typeof revenueOverviewSchema>) {\n try {\n const propertyId = resolveGa4PropertyId(params.propertyId);\n const report = await runReport(propertyId, {\n dateRanges: [{ startDate: params.startDate, endDate: params.endDate }],\n metrics: [\n { name: \"sessions\" },\n { name: \"totalUsers\" },\n { name: \"transactions\" },\n { name: \"purchaseRevenue\" },\n { name: \"averagePurchaseRevenue\" },\n { name: \"totalPurchasers\" },\n { name: \"purchaserRate\" },\n ],\n returnPropertyQuota: true,\n });\n\n const row = report.rows?.[0] ?? {};\n const sessions = getMetricValueByName(row, report.metricHeaders, \"sessions\");\n const totalUsers = getMetricValueByName(row, report.metricHeaders, \"totalUsers\");\n const transactions = getMetricValueByName(row, report.metricHeaders, \"transactions\");\n const purchaseRevenue = getMetricValueByName(row, report.metricHeaders, \"purchaseRevenue\");\n const averagePurchaseRevenue = getMetricValueByName(\n row,\n report.metricHeaders,\n \"averagePurchaseRevenue\"\n );\n const totalPurchasers = getMetricValueByName(row, report.metricHeaders, \"totalPurchasers\");\n const purchaserRate = getMetricValueByName(row, report.metricHeaders, \"purchaserRate\");\n\n return object(\n stripNulls({\n property_id: propertyId,\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n currency_code: report.metadata?.currencyCode,\n overview: {\n sessions,\n total_users: totalUsers,\n transactions,\n total_purchasers: totalPurchasers,\n purchase_revenue: round(purchaseRevenue),\n average_purchase_revenue: round(averagePurchaseRevenue),\n purchaser_rate_percent: round(purchaserRate * 100),\n transactions_per_session_percent: round(toPercent(transactions, sessions)),\n transactions_per_user_percent: round(toPercent(transactions, totalUsers)),\n revenue_per_session: round(sessions > 0 ? purchaseRevenue / sessions : 0),\n },\n quota: extractQuotaSnapshot(report),\n })\n );\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Failed to fetch GA4 revenue overview\");\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAE3B,MAAM,YAAY;AAEX,MAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,iCAAiC;AAAA,EACjF,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,+BAA+B;AAAA,EAC7E,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAChG,CAAC;AAED,eAAsB,uBAAuB,QAA+C;AAC1F,MAAI;AACF,UAAM,aAAa,qBAAqB,OAAO,UAAU;AACzD,UAAM,SAAS,MAAM,UAAU,YAAY;AAAA,MACzC,YAAY,CAAC,EAAE,WAAW,OAAO,WAAW,SAAS,OAAO,QAAQ,CAAC;AAAA,MACrE,SAAS;AAAA,QACP,EAAE,MAAM,WAAW;AAAA,QACnB,EAAE,MAAM,aAAa;AAAA,QACrB,EAAE,MAAM,eAAe;AAAA,QACvB,EAAE,MAAM,kBAAkB;AAAA,QAC1B,EAAE,MAAM,yBAAyB;AAAA,QACjC,EAAE,MAAM,kBAAkB;AAAA,QAC1B,EAAE,MAAM,gBAAgB;AAAA,MAC1B;AAAA,MACA,qBAAqB;AAAA,IACvB,CAAC;AAED,UAAM,MAAM,OAAO,OAAO,CAAC,KAAK,CAAC;AACjC,UAAM,WAAW,qBAAqB,KAAK,OAAO,eAAe,UAAU;AAC3E,UAAM,aAAa,qBAAqB,KAAK,OAAO,eAAe,YAAY;AAC/E,UAAM,eAAe,qBAAqB,KAAK,OAAO,eAAe,cAAc;AACnF,UAAM,kBAAkB,qBAAqB,KAAK,OAAO,eAAe,iBAAiB;AACzF,UAAM,yBAAyB;AAAA,MAC7B;AAAA,MACA,OAAO;AAAA,MACP;AAAA,IACF;AACA,UAAM,kBAAkB,qBAAqB,KAAK,OAAO,eAAe,iBAAiB;AACzF,UAAM,gBAAgB,qBAAqB,KAAK,OAAO,eAAe,eAAe;AAErF,WAAO;AAAA,MACL,WAAW;AAAA,QACT,aAAa;AAAA,QACb,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,eAAe,OAAO,UAAU;AAAA,QAChC,UAAU;AAAA,UACR;AAAA,UACA,aAAa;AAAA,UACb;AAAA,UACA,kBAAkB;AAAA,UAClB,kBAAkB,MAAM,eAAe;AAAA,UACvC,0BAA0B,MAAM,sBAAsB;AAAA,UACtD,wBAAwB,MAAM,gBAAgB,GAAG;AAAA,UACjD,kCAAkC,MAAM,UAAU,cAAc,QAAQ,CAAC;AAAA,UACzE,+BAA+B,MAAM,UAAU,cAAc,UAAU,CAAC;AAAA,UACxE,qBAAqB,MAAM,WAAW,IAAI,kBAAkB,WAAW,CAAC;AAAA,QAC1E;AAAA,QACA,OAAO,qBAAqB,MAAM;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,sCAAsC;AAAA,EAC1F;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,69 @@
1
+ import { error, object } from "mcp-use/server";
2
+ import { z } from "zod";
3
+ import {
4
+ extractQuotaSnapshot,
5
+ formatGa4Date,
6
+ getDimensionValue,
7
+ getMetricValueByName,
8
+ resolveGa4PropertyId,
9
+ round
10
+ } from "../../analytics/ga4-report-utils.js";
11
+ import { runReport } from "../../services/analytics/ga4-client.js";
12
+ import { stripNulls } from "../../utils/strip-payload.js";
13
+ const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
14
+ const revenueTrendSchema = z.object({
15
+ startDate: z.string().regex(dateRegex).describe("Start date in YYYY-MM-DD format"),
16
+ endDate: z.string().regex(dateRegex).describe("End date in YYYY-MM-DD format"),
17
+ propertyId: z.string().optional().describe("GA4 property ID. If omitted, uses GA4_PROPERTY_ID")
18
+ });
19
+ async function revenueTrendHandler(params) {
20
+ try {
21
+ const propertyId = resolveGa4PropertyId(params.propertyId);
22
+ const report = await runReport(propertyId, {
23
+ dateRanges: [{ startDate: params.startDate, endDate: params.endDate }],
24
+ dimensions: [{ name: "date" }],
25
+ metrics: [{ name: "transactions" }, { name: "purchaseRevenue" }],
26
+ orderBys: [{ dimension: { dimensionName: "date" } }],
27
+ returnPropertyQuota: true
28
+ });
29
+ const daily = (report.rows ?? []).map((row) => ({
30
+ date: formatGa4Date(getDimensionValue(row)),
31
+ transactions: getMetricValueByName(row, report.metricHeaders, "transactions"),
32
+ purchase_revenue: round(getMetricValueByName(row, report.metricHeaders, "purchaseRevenue"))
33
+ }));
34
+ const totalRevenue = daily.reduce((total, day) => total + day.purchase_revenue, 0);
35
+ const totalTransactions = daily.reduce((total, day) => total + day.transactions, 0);
36
+ const topRevenueDay = daily.reduce((currentTop, day) => {
37
+ if (!currentTop || day.purchase_revenue > currentTop.purchase_revenue) {
38
+ return day;
39
+ }
40
+ return currentTop;
41
+ }, void 0);
42
+ return object(
43
+ stripNulls({
44
+ property_id: propertyId,
45
+ date_range: {
46
+ start_date: params.startDate,
47
+ end_date: params.endDate
48
+ },
49
+ currency_code: report.metadata?.currencyCode,
50
+ overview: {
51
+ days: daily.length,
52
+ total_transactions: totalTransactions,
53
+ total_purchase_revenue: round(totalRevenue),
54
+ average_daily_revenue: round(daily.length > 0 ? totalRevenue / daily.length : 0),
55
+ top_revenue_day: topRevenueDay
56
+ },
57
+ daily,
58
+ quota: extractQuotaSnapshot(report)
59
+ })
60
+ );
61
+ } catch (err) {
62
+ return error(err instanceof Error ? err.message : "Failed to fetch GA4 revenue trend");
63
+ }
64
+ }
65
+ export {
66
+ revenueTrendHandler,
67
+ revenueTrendSchema
68
+ };
69
+ //# sourceMappingURL=revenue-trend.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/tools/analytics/revenue-trend.ts"],
4
+ "sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport {\n extractQuotaSnapshot,\n formatGa4Date,\n getDimensionValue,\n getMetricValueByName,\n resolveGa4PropertyId,\n round,\n} from \"../../analytics/ga4-report-utils.js\";\nimport { runReport } from \"../../services/analytics/ga4-client.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nconst dateRegex = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nexport const revenueTrendSchema = z.object({\n startDate: z.string().regex(dateRegex).describe(\"Start date in YYYY-MM-DD format\"),\n endDate: z.string().regex(dateRegex).describe(\"End date in YYYY-MM-DD format\"),\n propertyId: z.string().optional().describe(\"GA4 property ID. If omitted, uses GA4_PROPERTY_ID\"),\n});\n\nexport async function revenueTrendHandler(params: z.infer<typeof revenueTrendSchema>) {\n try {\n const propertyId = resolveGa4PropertyId(params.propertyId);\n const report = await runReport(propertyId, {\n dateRanges: [{ startDate: params.startDate, endDate: params.endDate }],\n dimensions: [{ name: \"date\" }],\n metrics: [{ name: \"transactions\" }, { name: \"purchaseRevenue\" }],\n orderBys: [{ dimension: { dimensionName: \"date\" } }],\n returnPropertyQuota: true,\n });\n\n const daily = (report.rows ?? []).map((row) => ({\n date: formatGa4Date(getDimensionValue(row)),\n transactions: getMetricValueByName(row, report.metricHeaders, \"transactions\"),\n purchase_revenue: round(getMetricValueByName(row, report.metricHeaders, \"purchaseRevenue\")),\n }));\n\n const totalRevenue = daily.reduce((total, day) => total + day.purchase_revenue, 0);\n const totalTransactions = daily.reduce((total, day) => total + day.transactions, 0);\n const topRevenueDay = daily.reduce<(typeof daily)[number] | undefined>((currentTop, day) => {\n if (!currentTop || day.purchase_revenue > currentTop.purchase_revenue) {\n return day;\n }\n\n return currentTop;\n }, undefined);\n\n return object(\n stripNulls({\n property_id: propertyId,\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n currency_code: report.metadata?.currencyCode,\n overview: {\n days: daily.length,\n total_transactions: totalTransactions,\n total_purchase_revenue: round(totalRevenue),\n average_daily_revenue: round(daily.length > 0 ? totalRevenue / daily.length : 0),\n top_revenue_day: topRevenueDay,\n },\n daily,\n quota: extractQuotaSnapshot(report),\n })\n );\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Failed to fetch GA4 revenue trend\");\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAE3B,MAAM,YAAY;AAEX,MAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,iCAAiC;AAAA,EACjF,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,+BAA+B;AAAA,EAC7E,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAChG,CAAC;AAED,eAAsB,oBAAoB,QAA4C;AACpF,MAAI;AACF,UAAM,aAAa,qBAAqB,OAAO,UAAU;AACzD,UAAM,SAAS,MAAM,UAAU,YAAY;AAAA,MACzC,YAAY,CAAC,EAAE,WAAW,OAAO,WAAW,SAAS,OAAO,QAAQ,CAAC;AAAA,MACrE,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC;AAAA,MAC7B,SAAS,CAAC,EAAE,MAAM,eAAe,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAAA,MAC/D,UAAU,CAAC,EAAE,WAAW,EAAE,eAAe,OAAO,EAAE,CAAC;AAAA,MACnD,qBAAqB;AAAA,IACvB,CAAC;AAED,UAAM,SAAS,OAAO,QAAQ,CAAC,GAAG,IAAI,CAAC,SAAS;AAAA,MAC9C,MAAM,cAAc,kBAAkB,GAAG,CAAC;AAAA,MAC1C,cAAc,qBAAqB,KAAK,OAAO,eAAe,cAAc;AAAA,MAC5E,kBAAkB,MAAM,qBAAqB,KAAK,OAAO,eAAe,iBAAiB,CAAC;AAAA,IAC5F,EAAE;AAEF,UAAM,eAAe,MAAM,OAAO,CAAC,OAAO,QAAQ,QAAQ,IAAI,kBAAkB,CAAC;AACjF,UAAM,oBAAoB,MAAM,OAAO,CAAC,OAAO,QAAQ,QAAQ,IAAI,cAAc,CAAC;AAClF,UAAM,gBAAgB,MAAM,OAA2C,CAAC,YAAY,QAAQ;AAC1F,UAAI,CAAC,cAAc,IAAI,mBAAmB,WAAW,kBAAkB;AACrE,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT,GAAG,MAAS;AAEZ,WAAO;AAAA,MACL,WAAW;AAAA,QACT,aAAa;AAAA,QACb,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,eAAe,OAAO,UAAU;AAAA,QAChC,UAAU;AAAA,UACR,MAAM,MAAM;AAAA,UACZ,oBAAoB;AAAA,UACpB,wBAAwB,MAAM,YAAY;AAAA,UAC1C,uBAAuB,MAAM,MAAM,SAAS,IAAI,eAAe,MAAM,SAAS,CAAC;AAAA,UAC/E,iBAAiB;AAAA,QACnB;AAAA,QACA;AAAA,QACA,OAAO,qBAAqB,MAAM;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,mCAAmC;AAAA,EACvF;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,86 @@
1
+ import { error, object } from "mcp-use/server";
2
+ import { z } from "zod";
3
+ import {
4
+ extractQuotaSnapshot,
5
+ getDimensionValue,
6
+ getMetricValueByName,
7
+ resolveGa4PropertyId,
8
+ round,
9
+ toPercent
10
+ } from "../../analytics/ga4-report-utils.js";
11
+ import { runReport } from "../../services/analytics/ga4-client.js";
12
+ import { stripNulls } from "../../utils/strip-payload.js";
13
+ const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
14
+ const sourceMediumBreakdownSchema = z.object({
15
+ startDate: z.string().regex(dateRegex).describe("Start date in YYYY-MM-DD format"),
16
+ endDate: z.string().regex(dateRegex).describe("End date in YYYY-MM-DD format"),
17
+ propertyId: z.string().optional().describe("GA4 property ID. If omitted, uses GA4_PROPERTY_ID"),
18
+ limit: z.number().int().min(1).max(100).optional().describe("Maximum rows to return")
19
+ });
20
+ async function sourceMediumBreakdownHandler(params) {
21
+ try {
22
+ const propertyId = resolveGa4PropertyId(params.propertyId);
23
+ const limit = params.limit ?? 20;
24
+ const [breakdownReport, totalReport] = await Promise.all([
25
+ runReport(propertyId, {
26
+ dateRanges: [{ startDate: params.startDate, endDate: params.endDate }],
27
+ dimensions: [{ name: "sessionSourceMedium" }],
28
+ metrics: [{ name: "sessions" }, { name: "totalUsers" }],
29
+ orderBys: [{ metric: { metricName: "sessions" }, desc: true }],
30
+ limit,
31
+ returnPropertyQuota: true
32
+ }),
33
+ runReport(propertyId, {
34
+ dateRanges: [{ startDate: params.startDate, endDate: params.endDate }],
35
+ metrics: [{ name: "sessions" }, { name: "totalUsers" }]
36
+ })
37
+ ]);
38
+ const totalSessions = getMetricValueByName(
39
+ totalReport.rows?.[0] ?? {},
40
+ totalReport.metricHeaders,
41
+ "sessions"
42
+ );
43
+ const totalUsers = getMetricValueByName(
44
+ totalReport.rows?.[0] ?? {},
45
+ totalReport.metricHeaders,
46
+ "totalUsers"
47
+ );
48
+ const rows = (breakdownReport.rows ?? []).map((row) => {
49
+ const sessions = getMetricValueByName(row, breakdownReport.metricHeaders, "sessions");
50
+ const users = getMetricValueByName(row, breakdownReport.metricHeaders, "totalUsers");
51
+ return {
52
+ source_medium: getDimensionValue(row),
53
+ sessions,
54
+ users,
55
+ session_share_percent: round(toPercent(sessions, totalSessions)),
56
+ user_share_percent: round(toPercent(users, totalUsers))
57
+ };
58
+ });
59
+ return object(
60
+ stripNulls({
61
+ property_id: propertyId,
62
+ date_range: {
63
+ start_date: params.startDate,
64
+ end_date: params.endDate
65
+ },
66
+ overview: {
67
+ total_sessions: totalSessions,
68
+ total_users: totalUsers,
69
+ returned_rows: rows.length,
70
+ available_rows: breakdownReport.rowCount
71
+ },
72
+ source_mediums: rows,
73
+ quota: extractQuotaSnapshot(breakdownReport)
74
+ })
75
+ );
76
+ } catch (err) {
77
+ return error(
78
+ err instanceof Error ? err.message : "Failed to fetch GA4 source / medium breakdown"
79
+ );
80
+ }
81
+ }
82
+ export {
83
+ sourceMediumBreakdownHandler,
84
+ sourceMediumBreakdownSchema
85
+ };
86
+ //# sourceMappingURL=source-medium-breakdown.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/tools/analytics/source-medium-breakdown.ts"],
4
+ "sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport {\n extractQuotaSnapshot,\n getDimensionValue,\n getMetricValueByName,\n resolveGa4PropertyId,\n round,\n toPercent,\n} from \"../../analytics/ga4-report-utils.js\";\nimport { runReport } from \"../../services/analytics/ga4-client.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nconst dateRegex = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nexport const sourceMediumBreakdownSchema = z.object({\n startDate: z.string().regex(dateRegex).describe(\"Start date in YYYY-MM-DD format\"),\n endDate: z.string().regex(dateRegex).describe(\"End date in YYYY-MM-DD format\"),\n propertyId: z.string().optional().describe(\"GA4 property ID. If omitted, uses GA4_PROPERTY_ID\"),\n limit: z.number().int().min(1).max(100).optional().describe(\"Maximum rows to return\"),\n});\n\nexport async function sourceMediumBreakdownHandler(\n params: z.infer<typeof sourceMediumBreakdownSchema>\n) {\n try {\n const propertyId = resolveGa4PropertyId(params.propertyId);\n const limit = params.limit ?? 20;\n\n const [breakdownReport, totalReport] = await Promise.all([\n runReport(propertyId, {\n dateRanges: [{ startDate: params.startDate, endDate: params.endDate }],\n dimensions: [{ name: \"sessionSourceMedium\" }],\n metrics: [{ name: \"sessions\" }, { name: \"totalUsers\" }],\n orderBys: [{ metric: { metricName: \"sessions\" }, desc: true }],\n limit,\n returnPropertyQuota: true,\n }),\n runReport(propertyId, {\n dateRanges: [{ startDate: params.startDate, endDate: params.endDate }],\n metrics: [{ name: \"sessions\" }, { name: \"totalUsers\" }],\n }),\n ]);\n\n const totalSessions = getMetricValueByName(\n totalReport.rows?.[0] ?? {},\n totalReport.metricHeaders,\n \"sessions\"\n );\n const totalUsers = getMetricValueByName(\n totalReport.rows?.[0] ?? {},\n totalReport.metricHeaders,\n \"totalUsers\"\n );\n\n const rows = (breakdownReport.rows ?? []).map((row) => {\n const sessions = getMetricValueByName(row, breakdownReport.metricHeaders, \"sessions\");\n const users = getMetricValueByName(row, breakdownReport.metricHeaders, \"totalUsers\");\n\n return {\n source_medium: getDimensionValue(row),\n sessions,\n users,\n session_share_percent: round(toPercent(sessions, totalSessions)),\n user_share_percent: round(toPercent(users, totalUsers)),\n };\n });\n\n return object(\n stripNulls({\n property_id: propertyId,\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n overview: {\n total_sessions: totalSessions,\n total_users: totalUsers,\n returned_rows: rows.length,\n available_rows: breakdownReport.rowCount,\n },\n source_mediums: rows,\n quota: extractQuotaSnapshot(breakdownReport),\n })\n );\n } catch (err) {\n return error(\n err instanceof Error ? err.message : \"Failed to fetch GA4 source / medium breakdown\"\n );\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAE3B,MAAM,YAAY;AAEX,MAAM,8BAA8B,EAAE,OAAO;AAAA,EAClD,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,iCAAiC;AAAA,EACjF,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,+BAA+B;AAAA,EAC7E,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,EAC9F,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wBAAwB;AACtF,CAAC;AAED,eAAsB,6BACpB,QACA;AACA,MAAI;AACF,UAAM,aAAa,qBAAqB,OAAO,UAAU;AACzD,UAAM,QAAQ,OAAO,SAAS;AAE9B,UAAM,CAAC,iBAAiB,WAAW,IAAI,MAAM,QAAQ,IAAI;AAAA,MACvD,UAAU,YAAY;AAAA,QACpB,YAAY,CAAC,EAAE,WAAW,OAAO,WAAW,SAAS,OAAO,QAAQ,CAAC;AAAA,QACrE,YAAY,CAAC,EAAE,MAAM,sBAAsB,CAAC;AAAA,QAC5C,SAAS,CAAC,EAAE,MAAM,WAAW,GAAG,EAAE,MAAM,aAAa,CAAC;AAAA,QACtD,UAAU,CAAC,EAAE,QAAQ,EAAE,YAAY,WAAW,GAAG,MAAM,KAAK,CAAC;AAAA,QAC7D;AAAA,QACA,qBAAqB;AAAA,MACvB,CAAC;AAAA,MACD,UAAU,YAAY;AAAA,QACpB,YAAY,CAAC,EAAE,WAAW,OAAO,WAAW,SAAS,OAAO,QAAQ,CAAC;AAAA,QACrE,SAAS,CAAC,EAAE,MAAM,WAAW,GAAG,EAAE,MAAM,aAAa,CAAC;AAAA,MACxD,CAAC;AAAA,IACH,CAAC;AAED,UAAM,gBAAgB;AAAA,MACpB,YAAY,OAAO,CAAC,KAAK,CAAC;AAAA,MAC1B,YAAY;AAAA,MACZ;AAAA,IACF;AACA,UAAM,aAAa;AAAA,MACjB,YAAY,OAAO,CAAC,KAAK,CAAC;AAAA,MAC1B,YAAY;AAAA,MACZ;AAAA,IACF;AAEA,UAAM,QAAQ,gBAAgB,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ;AACrD,YAAM,WAAW,qBAAqB,KAAK,gBAAgB,eAAe,UAAU;AACpF,YAAM,QAAQ,qBAAqB,KAAK,gBAAgB,eAAe,YAAY;AAEnF,aAAO;AAAA,QACL,eAAe,kBAAkB,GAAG;AAAA,QACpC;AAAA,QACA;AAAA,QACA,uBAAuB,MAAM,UAAU,UAAU,aAAa,CAAC;AAAA,QAC/D,oBAAoB,MAAM,UAAU,OAAO,UAAU,CAAC;AAAA,MACxD;AAAA,IACF,CAAC;AAED,WAAO;AAAA,MACL,WAAW;AAAA,QACT,aAAa;AAAA,QACb,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,UAAU;AAAA,UACR,gBAAgB;AAAA,UAChB,aAAa;AAAA,UACb,eAAe,KAAK;AAAA,UACpB,gBAAgB,gBAAgB;AAAA,QAClC;AAAA,QACA,gBAAgB;AAAA,QAChB,OAAO,qBAAqB,eAAe;AAAA,MAC7C,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,eAAe,QAAQ,IAAI,UAAU;AAAA,IACvC;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,79 @@
1
+ import { error, object } from "mcp-use/server";
2
+ import { z } from "zod";
3
+ import {
4
+ extractQuotaSnapshot,
5
+ getDimensionValue,
6
+ getMetricValueByName,
7
+ resolveGa4PropertyId,
8
+ round,
9
+ toPercent
10
+ } from "../../analytics/ga4-report-utils.js";
11
+ import { runReport } from "../../services/analytics/ga4-client.js";
12
+ import { stripNulls } from "../../utils/strip-payload.js";
13
+ const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
14
+ const topLandingPagesSchema = z.object({
15
+ startDate: z.string().regex(dateRegex).describe("Start date in YYYY-MM-DD format"),
16
+ endDate: z.string().regex(dateRegex).describe("End date in YYYY-MM-DD format"),
17
+ propertyId: z.string().optional().describe("GA4 property ID. If omitted, uses GA4_PROPERTY_ID"),
18
+ limit: z.number().int().min(1).max(100).optional().describe("Maximum rows to return")
19
+ });
20
+ async function topLandingPagesHandler(params) {
21
+ try {
22
+ const propertyId = resolveGa4PropertyId(params.propertyId);
23
+ const limit = params.limit ?? 20;
24
+ const [landingReport, totalReport] = await Promise.all([
25
+ runReport(propertyId, {
26
+ dateRanges: [{ startDate: params.startDate, endDate: params.endDate }],
27
+ dimensions: [{ name: "landingPage" }],
28
+ metrics: [{ name: "sessions" }, { name: "totalUsers" }],
29
+ orderBys: [{ metric: { metricName: "sessions" }, desc: true }],
30
+ limit,
31
+ returnPropertyQuota: true
32
+ }),
33
+ runReport(propertyId, {
34
+ dateRanges: [{ startDate: params.startDate, endDate: params.endDate }],
35
+ metrics: [{ name: "sessions" }, { name: "totalUsers" }]
36
+ })
37
+ ]);
38
+ const totalSessions = getMetricValueByName(
39
+ totalReport.rows?.[0] ?? {},
40
+ totalReport.metricHeaders,
41
+ "sessions"
42
+ );
43
+ const landingPages = (landingReport.rows ?? []).map((row) => {
44
+ const sessions = getMetricValueByName(row, landingReport.metricHeaders, "sessions");
45
+ const users = getMetricValueByName(row, landingReport.metricHeaders, "totalUsers");
46
+ return {
47
+ landing_page: getDimensionValue(row),
48
+ sessions,
49
+ users,
50
+ session_share_percent: round(toPercent(sessions, totalSessions)),
51
+ is_not_set: getDimensionValue(row) === "(not set)"
52
+ };
53
+ });
54
+ return object(
55
+ stripNulls({
56
+ property_id: propertyId,
57
+ date_range: {
58
+ start_date: params.startDate,
59
+ end_date: params.endDate
60
+ },
61
+ overview: {
62
+ total_sessions: totalSessions,
63
+ returned_rows: landingPages.length,
64
+ available_rows: landingReport.rowCount,
65
+ top_landing_page: landingPages[0]?.landing_page
66
+ },
67
+ landing_pages: landingPages,
68
+ quota: extractQuotaSnapshot(landingReport)
69
+ })
70
+ );
71
+ } catch (err) {
72
+ return error(err instanceof Error ? err.message : "Failed to fetch GA4 top landing pages");
73
+ }
74
+ }
75
+ export {
76
+ topLandingPagesHandler,
77
+ topLandingPagesSchema
78
+ };
79
+ //# sourceMappingURL=top-landing-pages.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/tools/analytics/top-landing-pages.ts"],
4
+ "sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport {\n extractQuotaSnapshot,\n getDimensionValue,\n getMetricValueByName,\n resolveGa4PropertyId,\n round,\n toPercent,\n} from \"../../analytics/ga4-report-utils.js\";\nimport { runReport } from \"../../services/analytics/ga4-client.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nconst dateRegex = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nexport const topLandingPagesSchema = z.object({\n startDate: z.string().regex(dateRegex).describe(\"Start date in YYYY-MM-DD format\"),\n endDate: z.string().regex(dateRegex).describe(\"End date in YYYY-MM-DD format\"),\n propertyId: z.string().optional().describe(\"GA4 property ID. If omitted, uses GA4_PROPERTY_ID\"),\n limit: z.number().int().min(1).max(100).optional().describe(\"Maximum rows to return\"),\n});\n\nexport async function topLandingPagesHandler(params: z.infer<typeof topLandingPagesSchema>) {\n try {\n const propertyId = resolveGa4PropertyId(params.propertyId);\n const limit = params.limit ?? 20;\n\n const [landingReport, totalReport] = await Promise.all([\n runReport(propertyId, {\n dateRanges: [{ startDate: params.startDate, endDate: params.endDate }],\n dimensions: [{ name: \"landingPage\" }],\n metrics: [{ name: \"sessions\" }, { name: \"totalUsers\" }],\n orderBys: [{ metric: { metricName: \"sessions\" }, desc: true }],\n limit,\n returnPropertyQuota: true,\n }),\n runReport(propertyId, {\n dateRanges: [{ startDate: params.startDate, endDate: params.endDate }],\n metrics: [{ name: \"sessions\" }, { name: \"totalUsers\" }],\n }),\n ]);\n\n const totalSessions = getMetricValueByName(\n totalReport.rows?.[0] ?? {},\n totalReport.metricHeaders,\n \"sessions\"\n );\n\n const landingPages = (landingReport.rows ?? []).map((row) => {\n const sessions = getMetricValueByName(row, landingReport.metricHeaders, \"sessions\");\n const users = getMetricValueByName(row, landingReport.metricHeaders, \"totalUsers\");\n\n return {\n landing_page: getDimensionValue(row),\n sessions,\n users,\n session_share_percent: round(toPercent(sessions, totalSessions)),\n is_not_set: getDimensionValue(row) === \"(not set)\",\n };\n });\n\n return object(\n stripNulls({\n property_id: propertyId,\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n overview: {\n total_sessions: totalSessions,\n returned_rows: landingPages.length,\n available_rows: landingReport.rowCount,\n top_landing_page: landingPages[0]?.landing_page,\n },\n landing_pages: landingPages,\n quota: extractQuotaSnapshot(landingReport),\n })\n );\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Failed to fetch GA4 top landing pages\");\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAE3B,MAAM,YAAY;AAEX,MAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,iCAAiC;AAAA,EACjF,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,+BAA+B;AAAA,EAC7E,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,EAC9F,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wBAAwB;AACtF,CAAC;AAED,eAAsB,uBAAuB,QAA+C;AAC1F,MAAI;AACF,UAAM,aAAa,qBAAqB,OAAO,UAAU;AACzD,UAAM,QAAQ,OAAO,SAAS;AAE9B,UAAM,CAAC,eAAe,WAAW,IAAI,MAAM,QAAQ,IAAI;AAAA,MACrD,UAAU,YAAY;AAAA,QACpB,YAAY,CAAC,EAAE,WAAW,OAAO,WAAW,SAAS,OAAO,QAAQ,CAAC;AAAA,QACrE,YAAY,CAAC,EAAE,MAAM,cAAc,CAAC;AAAA,QACpC,SAAS,CAAC,EAAE,MAAM,WAAW,GAAG,EAAE,MAAM,aAAa,CAAC;AAAA,QACtD,UAAU,CAAC,EAAE,QAAQ,EAAE,YAAY,WAAW,GAAG,MAAM,KAAK,CAAC;AAAA,QAC7D;AAAA,QACA,qBAAqB;AAAA,MACvB,CAAC;AAAA,MACD,UAAU,YAAY;AAAA,QACpB,YAAY,CAAC,EAAE,WAAW,OAAO,WAAW,SAAS,OAAO,QAAQ,CAAC;AAAA,QACrE,SAAS,CAAC,EAAE,MAAM,WAAW,GAAG,EAAE,MAAM,aAAa,CAAC;AAAA,MACxD,CAAC;AAAA,IACH,CAAC;AAED,UAAM,gBAAgB;AAAA,MACpB,YAAY,OAAO,CAAC,KAAK,CAAC;AAAA,MAC1B,YAAY;AAAA,MACZ;AAAA,IACF;AAEA,UAAM,gBAAgB,cAAc,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ;AAC3D,YAAM,WAAW,qBAAqB,KAAK,cAAc,eAAe,UAAU;AAClF,YAAM,QAAQ,qBAAqB,KAAK,cAAc,eAAe,YAAY;AAEjF,aAAO;AAAA,QACL,cAAc,kBAAkB,GAAG;AAAA,QACnC;AAAA,QACA;AAAA,QACA,uBAAuB,MAAM,UAAU,UAAU,aAAa,CAAC;AAAA,QAC/D,YAAY,kBAAkB,GAAG,MAAM;AAAA,MACzC;AAAA,IACF,CAAC;AAED,WAAO;AAAA,MACL,WAAW;AAAA,QACT,aAAa;AAAA,QACb,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,UAAU;AAAA,UACR,gBAAgB;AAAA,UAChB,eAAe,aAAa;AAAA,UAC5B,gBAAgB,cAAc;AAAA,UAC9B,kBAAkB,aAAa,CAAC,GAAG;AAAA,QACrC;AAAA,QACA,eAAe;AAAA,QACf,OAAO,qBAAqB,aAAa;AAAA,MAC3C,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,uCAAuC;AAAA,EAC3F;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,103 @@
1
+ import { error, object } from "mcp-use/server";
2
+ import { z } from "zod";
3
+ import {
4
+ dateRegex,
5
+ getFieldValue,
6
+ microsToCurrency,
7
+ parseGoogleAdsMetricValue,
8
+ resolveGoogleAdsCustomerId,
9
+ resolveGoogleAdsDeveloperToken,
10
+ resolveGoogleAdsLoginCustomerId,
11
+ round,
12
+ toPercent
13
+ } from "../../utils/google-ads.js";
14
+ import { searchGoogleAds } from "../../services/google-ads/google-ads-client.js";
15
+ import { stripNulls } from "../../utils/strip-payload.js";
16
+ const googleAdsAccountOverviewSchema = z.object({
17
+ startDate: z.string().regex(dateRegex).describe("Start date in YYYY-MM-DD format."),
18
+ endDate: z.string().regex(dateRegex).describe("End date in YYYY-MM-DD format."),
19
+ customerId: z.string().describe("Google Ads customer ID to query. Accepts digits with or without hyphens."),
20
+ loginCustomerId: z.string().optional().describe(
21
+ "Optional manager account ID used as login customer. If omitted, uses GOOGLE_ADS_LOGIN_CUSTOMER_ID when configured."
22
+ )
23
+ });
24
+ async function googleAdsAccountOverviewHandler(params) {
25
+ try {
26
+ const customerId = resolveGoogleAdsCustomerId(params.customerId);
27
+ const loginCustomerId = resolveGoogleAdsLoginCustomerId(params.loginCustomerId);
28
+ const developerToken = resolveGoogleAdsDeveloperToken();
29
+ const result = await searchGoogleAds(
30
+ customerId,
31
+ [
32
+ "SELECT",
33
+ "customer.id,",
34
+ "customer.descriptive_name,",
35
+ "customer.currency_code,",
36
+ "customer.time_zone,",
37
+ "metrics.impressions,",
38
+ "metrics.clicks,",
39
+ "metrics.cost_micros,",
40
+ "metrics.conversions,",
41
+ "metrics.conversions_value,",
42
+ "metrics.ctr,",
43
+ "metrics.average_cpc",
44
+ "FROM customer",
45
+ `WHERE segments.date BETWEEN '${params.startDate}' AND '${params.endDate}'`
46
+ ].join(" "),
47
+ developerToken,
48
+ loginCustomerId
49
+ );
50
+ const row = result.rows[0] ?? {};
51
+ const impressions = parseGoogleAdsMetricValue(getFieldValue(row, "metrics.impressions"));
52
+ const clicks = parseGoogleAdsMetricValue(getFieldValue(row, "metrics.clicks"));
53
+ const cost = microsToCurrency(getFieldValue(row, "metrics.costMicros"));
54
+ const conversions = round(
55
+ parseGoogleAdsMetricValue(getFieldValue(row, "metrics.conversions"))
56
+ );
57
+ const conversionValue = round(
58
+ parseGoogleAdsMetricValue(getFieldValue(row, "metrics.conversionsValue"))
59
+ );
60
+ const ctrPercent = round(
61
+ parseGoogleAdsMetricValue(getFieldValue(row, "metrics.ctr")) * 100
62
+ );
63
+ const averageCpc = microsToCurrency(getFieldValue(row, "metrics.averageCpc"));
64
+ return object(
65
+ stripNulls({
66
+ customer_id: customerId,
67
+ login_customer_id: loginCustomerId,
68
+ date_range: {
69
+ start_date: params.startDate,
70
+ end_date: params.endDate
71
+ },
72
+ currency_code: getFieldValue(row, "customer.currencyCode"),
73
+ customer_name: getFieldValue(row, "customer.descriptiveName"),
74
+ time_zone: getFieldValue(row, "customer.timeZone"),
75
+ overview: {
76
+ impressions,
77
+ clicks,
78
+ cost,
79
+ conversions,
80
+ conversion_value: conversionValue,
81
+ ctr_percent: ctrPercent,
82
+ average_cpc: averageCpc,
83
+ cpa: round(cost / conversions),
84
+ roas: round(conversionValue / cost),
85
+ conversion_rate_percent: round(toPercent(conversions, clicks))
86
+ },
87
+ metadata: {
88
+ row_count: result.rows.length,
89
+ request_id: result.requestId
90
+ }
91
+ })
92
+ );
93
+ } catch (err) {
94
+ return error(
95
+ err instanceof Error ? err.message : "Failed to fetch Google Ads account overview"
96
+ );
97
+ }
98
+ }
99
+ export {
100
+ googleAdsAccountOverviewHandler,
101
+ googleAdsAccountOverviewSchema
102
+ };
103
+ //# sourceMappingURL=account-overview.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/tools/google-ads/account-overview.ts"],
4
+ "sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport {\n dateRegex,\n getFieldValue,\n microsToCurrency,\n parseGoogleAdsMetricValue,\n resolveGoogleAdsCustomerId,\n resolveGoogleAdsDeveloperToken,\n resolveGoogleAdsLoginCustomerId,\n round,\n toPercent,\n} from \"../../utils/google-ads.js\";\nimport { searchGoogleAds } from \"../../services/google-ads/google-ads-client.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const googleAdsAccountOverviewSchema = z.object({\n startDate: z.string().regex(dateRegex).describe(\"Start date in YYYY-MM-DD format.\"),\n endDate: z.string().regex(dateRegex).describe(\"End date in YYYY-MM-DD format.\"),\n customerId: z.string().describe(\"Google Ads customer ID to query. Accepts digits with or without hyphens.\"),\n loginCustomerId: z\n .string()\n .optional()\n .describe(\n \"Optional manager account ID used as login customer. If omitted, uses GOOGLE_ADS_LOGIN_CUSTOMER_ID when configured.\"\n ),\n});\n\nexport async function googleAdsAccountOverviewHandler(\n params: z.infer<typeof googleAdsAccountOverviewSchema>\n) {\n try {\n const customerId = resolveGoogleAdsCustomerId(params.customerId);\n const loginCustomerId = resolveGoogleAdsLoginCustomerId(params.loginCustomerId);\n const developerToken = resolveGoogleAdsDeveloperToken();\n\n const result = await searchGoogleAds(\n customerId,\n [\n \"SELECT\",\n \"customer.id,\",\n \"customer.descriptive_name,\",\n \"customer.currency_code,\",\n \"customer.time_zone,\",\n \"metrics.impressions,\",\n \"metrics.clicks,\",\n \"metrics.cost_micros,\",\n \"metrics.conversions,\",\n \"metrics.conversions_value,\",\n \"metrics.ctr,\",\n \"metrics.average_cpc\",\n \"FROM customer\",\n `WHERE segments.date BETWEEN '${params.startDate}' AND '${params.endDate}'`,\n ].join(\" \"),\n developerToken,\n loginCustomerId\n );\n\n const row = result.rows[0] ?? {};\n const impressions = parseGoogleAdsMetricValue(getFieldValue(row, \"metrics.impressions\"));\n const clicks = parseGoogleAdsMetricValue(getFieldValue(row, \"metrics.clicks\"));\n const cost = microsToCurrency(getFieldValue(row, \"metrics.costMicros\"));\n const conversions = round(\n parseGoogleAdsMetricValue(getFieldValue(row, \"metrics.conversions\"))\n );\n const conversionValue = round(\n parseGoogleAdsMetricValue(getFieldValue(row, \"metrics.conversionsValue\"))\n );\n const ctrPercent = round(\n parseGoogleAdsMetricValue(getFieldValue(row, \"metrics.ctr\")) * 100\n );\n const averageCpc = microsToCurrency(getFieldValue(row, \"metrics.averageCpc\"));\n\n return object(\n stripNulls({\n customer_id: customerId,\n login_customer_id: loginCustomerId,\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n currency_code: getFieldValue(row, \"customer.currencyCode\"),\n customer_name: getFieldValue(row, \"customer.descriptiveName\"),\n time_zone: getFieldValue(row, \"customer.timeZone\"),\n overview: {\n impressions,\n clicks,\n cost,\n conversions,\n conversion_value: conversionValue,\n ctr_percent: ctrPercent,\n average_cpc: averageCpc,\n cpa: round(cost / conversions),\n roas: round(conversionValue / cost),\n conversion_rate_percent: round(toPercent(conversions, clicks)),\n },\n metadata: {\n row_count: result.rows.length,\n request_id: result.requestId,\n },\n })\n );\n } catch (err) {\n return error(\n err instanceof Error ? err.message : \"Failed to fetch Google Ads account overview\"\n );\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,uBAAuB;AAChC,SAAS,kBAAkB;AAEpB,MAAM,iCAAiC,EAAE,OAAO;AAAA,EACrD,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,kCAAkC;AAAA,EAClF,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,gCAAgC;AAAA,EAC9E,YAAY,EAAE,OAAO,EAAE,SAAS,0EAA0E;AAAA,EAC1G,iBAAiB,EACd,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ,CAAC;AAED,eAAsB,gCACpB,QACA;AACA,MAAI;AACF,UAAM,aAAa,2BAA2B,OAAO,UAAU;AAC/D,UAAM,kBAAkB,gCAAgC,OAAO,eAAe;AAC9E,UAAM,iBAAiB,+BAA+B;AAEtD,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,gCAAgC,OAAO,SAAS,UAAU,OAAO,OAAO;AAAA,MAC1E,EAAE,KAAK,GAAG;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAEA,UAAM,MAAM,OAAO,KAAK,CAAC,KAAK,CAAC;AAC/B,UAAM,cAAc,0BAA0B,cAAc,KAAK,qBAAqB,CAAC;AACvF,UAAM,SAAS,0BAA0B,cAAc,KAAK,gBAAgB,CAAC;AAC7E,UAAM,OAAO,iBAAiB,cAAc,KAAK,oBAAoB,CAAC;AACtE,UAAM,cAAc;AAAA,MAClB,0BAA0B,cAAc,KAAK,qBAAqB,CAAC;AAAA,IACrE;AACA,UAAM,kBAAkB;AAAA,MACtB,0BAA0B,cAAc,KAAK,0BAA0B,CAAC;AAAA,IAC1E;AACA,UAAM,aAAa;AAAA,MACjB,0BAA0B,cAAc,KAAK,aAAa,CAAC,IAAI;AAAA,IACjE;AACA,UAAM,aAAa,iBAAiB,cAAc,KAAK,oBAAoB,CAAC;AAE5E,WAAO;AAAA,MACL,WAAW;AAAA,QACT,aAAa;AAAA,QACb,mBAAmB;AAAA,QACnB,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,eAAe,cAAc,KAAK,uBAAuB;AAAA,QACzD,eAAe,cAAc,KAAK,0BAA0B;AAAA,QAC5D,WAAW,cAAc,KAAK,mBAAmB;AAAA,QACjD,UAAU;AAAA,UACR;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,kBAAkB;AAAA,UAClB,aAAa;AAAA,UACb,aAAa;AAAA,UACb,KAAK,MAAM,OAAO,WAAW;AAAA,UAC7B,MAAM,MAAM,kBAAkB,IAAI;AAAA,UAClC,yBAAyB,MAAM,UAAU,aAAa,MAAM,CAAC;AAAA,QAC/D;AAAA,QACA,UAAU;AAAA,UACR,WAAW,OAAO,KAAK;AAAA,UACvB,YAAY,OAAO;AAAA,QACrB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,eAAe,QAAQ,IAAI,UAAU;AAAA,IACvC;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }