@yoryoboy/bi-mcp 1.5.2 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -87
- package/bin/bi-mcp.js +9 -9
- package/dist/.tsbuildinfo +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-use.json +2 -2
- package/dist/public/icon.svg +6 -6
- package/dist/scripts/_helpers.js.map +1 -1
- package/dist/scripts/admin-profile-delete.js.map +1 -1
- package/dist/scripts/admin-profile-list.js.map +1 -1
- package/dist/scripts/admin-profile-upsert.js.map +1 -1
- package/dist/scripts/admin-vtex-list.js.map +1 -1
- package/dist/scripts/admin-vtex-upsert.js.map +1 -1
- package/dist/scripts/admin-vtex-validate.js.map +1 -1
- package/dist/scripts/decrypt-secret.js +36 -0
- package/dist/scripts/decrypt-secret.js.map +7 -0
- package/dist/scripts/run-migrations.js.map +1 -1
- package/dist/scripts/test-db-connection.js.map +1 -1
- package/dist/src/analytics/ga4-channel-groups.js.map +1 -1
- package/dist/src/analytics/ga4-report-utils.js.map +1 -1
- package/dist/src/config/benchmarks.js.map +1 -1
- package/dist/src/config/google-store.js.map +1 -1
- package/dist/src/config/google.js.map +1 -1
- package/dist/src/config/mercadolibre-profile-store.js.map +1 -1
- package/dist/src/config/mercadolibre.js.map +1 -1
- package/dist/src/config/meta.js.map +1 -1
- package/dist/src/config/profile-store.js.map +1 -1
- package/dist/src/config/vtex-crypto.js.map +1 -1
- package/dist/src/config/vtex-profile-store.js.map +1 -1
- package/dist/src/config/vtex.js.map +1 -1
- package/dist/src/db/client.js.map +1 -1
- package/dist/src/meta/meta-utils.js.map +1 -1
- package/dist/src/prompts/reporte-ventas.js.map +1 -1
- package/dist/src/services/analytics/ga4-client.js.map +1 -1
- package/dist/src/services/analytics/oauth.js.map +1 -1
- package/dist/src/services/google-ads/google-ads-client.js.map +1 -1
- package/dist/src/services/mercadolibre/mercadolibre-api.js.map +1 -1
- package/dist/src/services/mercadolibre/mercadolibre-items.js.map +1 -1
- package/dist/src/services/mercadolibre/mercadolibre-orders.js +19 -5
- package/dist/src/services/mercadolibre/mercadolibre-orders.js.map +2 -2
- package/dist/src/services/mercadolibre/mercadolibre-questions.js.map +1 -1
- package/dist/src/services/meta/meta-ads.js.map +1 -1
- package/dist/src/services/meta/meta-api.js.map +1 -1
- package/dist/src/services/search-console/search-console-client.js.map +1 -1
- package/dist/src/services/search-console/search-console-utils.js.map +1 -1
- package/dist/src/services/vtex/vtex-api.js.map +1 -1
- package/dist/src/services/vtex/vtex-catalog-write.js.map +1 -1
- package/dist/src/services/vtex/vtex-catalog.js.map +1 -1
- package/dist/src/services/vtex/vtex-logistics.js.map +1 -1
- package/dist/src/services/vtex/vtex-orders-write.js.map +1 -1
- package/dist/src/services/vtex/vtex-orders.js.map +1 -1
- package/dist/src/services/vtex/vtex-pricing-write.js.map +1 -1
- package/dist/src/services/vtex/vtex-pricing.js.map +1 -1
- package/dist/src/services/vtex/vtex-write.js.map +1 -1
- package/dist/src/tools/analytics/attribution-gaps.js.map +1 -1
- package/dist/src/tools/analytics/channel-mix.js.map +1 -1
- package/dist/src/tools/analytics/ecommerce-tracking-health.js.map +1 -1
- package/dist/src/tools/analytics/engagement-overview.js.map +1 -1
- package/dist/src/tools/analytics/index.js.map +1 -1
- package/dist/src/tools/analytics/list-accessible-properties.js.map +1 -1
- package/dist/src/tools/analytics/property-info.js.map +1 -1
- package/dist/src/tools/analytics/revenue-by-channel.js.map +1 -1
- package/dist/src/tools/analytics/revenue-overview.js.map +1 -1
- package/dist/src/tools/analytics/revenue-trend.js.map +1 -1
- package/dist/src/tools/analytics/source-medium-breakdown.js.map +1 -1
- package/dist/src/tools/analytics/top-landing-pages.js.map +1 -1
- package/dist/src/tools/config/check-database-connection.js.map +1 -1
- package/dist/src/tools/config/index.js.map +1 -1
- package/dist/src/tools/config/list-profiles.js.map +1 -1
- package/dist/src/tools/google-ads/account-overview.js.map +1 -1
- package/dist/src/tools/google-ads/account-risks.js.map +1 -1
- package/dist/src/tools/google-ads/break-even-analysis.js.map +1 -1
- package/dist/src/tools/google-ads/campaign-performance.js.map +1 -1
- package/dist/src/tools/google-ads/channel-mix.js.map +1 -1
- package/dist/src/tools/google-ads/compare-accounts.js.map +1 -1
- package/dist/src/tools/google-ads/customer-clients.js.map +1 -1
- package/dist/src/tools/google-ads/customer-info.js.map +1 -1
- package/dist/src/tools/google-ads/index.js.map +1 -1
- package/dist/src/tools/google-ads/scaling-health.js.map +1 -1
- package/dist/src/tools/google-ads/search-terms-summary.js.map +1 -1
- package/dist/src/tools/google-ads/time-series.js.map +1 -1
- package/dist/src/tools/index.js.map +1 -1
- package/dist/src/tools/mercadolibre/answer-question.js.map +1 -1
- package/dist/src/tools/mercadolibre/create-item.js.map +1 -1
- package/dist/src/tools/mercadolibre/estimate-listing-fee.js.map +1 -1
- package/dist/src/tools/mercadolibre/get-account-context.js.map +1 -1
- package/dist/src/tools/mercadolibre/get-category-requirements.js.map +1 -1
- package/dist/src/tools/mercadolibre/get-item-details.js.map +1 -1
- package/dist/src/tools/mercadolibre/get-item-visits.js.map +1 -1
- package/dist/src/tools/mercadolibre/get-listing-quality.js.map +1 -1
- package/dist/src/tools/mercadolibre/get-order-details.js.map +1 -1
- package/dist/src/tools/mercadolibre/get-orders-summary.js +670 -38
- package/dist/src/tools/mercadolibre/get-orders-summary.js.map +2 -2
- package/dist/src/tools/mercadolibre/get-sales-by-item.js.map +1 -1
- package/dist/src/tools/mercadolibre/get-sales-trend.js.map +1 -1
- package/dist/src/tools/mercadolibre/get-shipping-summary.js.map +1 -1
- package/dist/src/tools/mercadolibre/get-store-performance.js.map +1 -1
- package/dist/src/tools/mercadolibre/helpers.js +13 -0
- package/dist/src/tools/mercadolibre/helpers.js.map +2 -2
- package/dist/src/tools/mercadolibre/index.js.map +1 -1
- package/dist/src/tools/mercadolibre/pause-or-reactivate-item.js.map +1 -1
- package/dist/src/tools/mercadolibre/predict-category.js.map +1 -1
- package/dist/src/tools/mercadolibre/profile-resolution.js.map +1 -1
- package/dist/src/tools/mercadolibre/search-items.js.map +1 -1
- package/dist/src/tools/mercadolibre/search-questions.js.map +1 -1
- package/dist/src/tools/mercadolibre/update-item-basic-fields.js.map +1 -1
- package/dist/src/tools/mercadolibre/update-item-description.js.map +1 -1
- package/dist/src/tools/mercadolibre/update-item-pictures.js.map +1 -1
- package/dist/src/tools/mercadolibre/validate-connection.js.map +1 -1
- package/dist/src/tools/mercadolibre/write-helpers.js.map +1 -1
- package/dist/src/tools/meta/account-overview.js.map +1 -1
- package/dist/src/tools/meta/ad-account-info.js.map +1 -1
- package/dist/src/tools/meta/ads-performance.js.map +1 -1
- package/dist/src/tools/meta/campaign-performance.js.map +1 -1
- package/dist/src/tools/meta/index.js.map +1 -1
- package/dist/src/tools/meta/list-accessible-ad-accounts.js.map +1 -1
- package/dist/src/tools/meta/list-accessible-businesses.js.map +1 -1
- package/dist/src/tools/meta/placement-mix.js.map +1 -1
- package/dist/src/tools/meta/time-series.js.map +1 -1
- package/dist/src/tools/search-console/country-breakdown.js.map +1 -1
- package/dist/src/tools/search-console/device-breakdown.js.map +1 -1
- package/dist/src/tools/search-console/high-impression-low-click-queries.js.map +1 -1
- package/dist/src/tools/search-console/index.js.map +1 -1
- package/dist/src/tools/search-console/list-accessible-sites.js.map +1 -1
- package/dist/src/tools/search-console/low-ctr-opportunities.js.map +1 -1
- package/dist/src/tools/search-console/page-performance.js.map +1 -1
- package/dist/src/tools/search-console/product-demand-low-capture-queries.js.map +1 -1
- package/dist/src/tools/search-console/query-page-matrix.js.map +1 -1
- package/dist/src/tools/search-console/query-performance.js.map +1 -1
- package/dist/src/tools/search-console/quick-win-opportunities.js.map +1 -1
- package/dist/src/tools/search-console/rising-non-brand-queries.js.map +1 -1
- package/dist/src/tools/search-console/search-performance.js.map +1 -1
- package/dist/src/tools/search-console/site-context.js.map +1 -1
- package/dist/src/tools/search-console/visibility-declines.js.map +1 -1
- package/dist/src/tools/vtex/activate-sku.js.map +1 -1
- package/dist/src/tools/vtex/add-order-tracking.js.map +1 -1
- package/dist/src/tools/vtex/associate-specification.js.map +1 -1
- package/dist/src/tools/vtex/attach-catalog-image.js.map +1 -1
- package/dist/src/tools/vtex/cancel-order.js.map +1 -1
- package/dist/src/tools/vtex/computed-price.js.map +1 -1
- package/dist/src/tools/vtex/create-brand.js.map +1 -1
- package/dist/src/tools/vtex/create-category.js.map +1 -1
- package/dist/src/tools/vtex/create-product-with-sku.js.map +1 -1
- package/dist/src/tools/vtex/create-product.js.map +1 -1
- package/dist/src/tools/vtex/create-sku.js.map +1 -1
- package/dist/src/tools/vtex/create-specification-value.js.map +1 -1
- package/dist/src/tools/vtex/create-specification.js.map +1 -1
- package/dist/src/tools/vtex/deactivate-sku.js.map +1 -1
- package/dist/src/tools/vtex/delete-fixed-price.js.map +1 -1
- package/dist/src/tools/vtex/index.js.map +1 -1
- package/dist/src/tools/vtex/inventory-check.js.map +1 -1
- package/dist/src/tools/vtex/invoice-order.js.map +1 -1
- package/dist/src/tools/vtex/order-details.js.map +1 -1
- package/dist/src/tools/vtex/orders-summary.js.map +1 -1
- package/dist/src/tools/vtex/product-offers.js.map +1 -1
- package/dist/src/tools/vtex/profile-resolution.js.map +1 -1
- package/dist/src/tools/vtex/sku-offers.js.map +1 -1
- package/dist/src/tools/vtex/sku-price.js.map +1 -1
- package/dist/src/tools/vtex/toggle-unlimited-quantity.js.map +1 -1
- package/dist/src/tools/vtex/update-inventory.js.map +1 -1
- package/dist/src/tools/vtex/update-lead-time.js.map +1 -1
- package/dist/src/tools/vtex/update-product-basic-fields.js.map +1 -1
- package/dist/src/tools/vtex/update-sku-basic-fields.js.map +1 -1
- package/dist/src/tools/vtex/update-sku-price.js.map +1 -1
- package/dist/src/tools/vtex/upsert-fixed-price.js.map +1 -1
- package/dist/src/tools/vtex/warehouse-inventory.js.map +1 -1
- package/dist/src/tools/vtex/write-helpers.js.map +1 -1
- package/dist/src/utils/case-conversion.js.map +1 -1
- package/dist/src/utils/currency.js.map +1 -1
- package/dist/src/utils/format-order-details.js.map +1 -1
- package/dist/src/utils/google-ads.js.map +1 -1
- package/dist/src/utils/money.js.map +1 -1
- package/dist/src/utils/order-status.js.map +1 -1
- package/dist/src/utils/pagination.js.map +1 -1
- package/dist/src/utils/strip-payload.js.map +1 -1
- package/dist/src/utils/type-guards.js.map +1 -1
- package/package.json +4 -3
- package/public/icon.svg +6 -6
- package/dist/src/google-ads/report-utils.js +0 -78
- package/dist/src/google-ads/report-utils.js.map +0 -7
- package/dist/src/search-console/search-console-utils.js +0 -275
- package/dist/src/search-console/search-console-utils.js.map +0 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/mercadolibre/update-item-pictures.ts"],
|
|
4
|
-
"sourcesContent": ["import { z } from \"zod\";\n\nimport {\n addMercadoLibreItemPicture,\n getMercadoLibreItem,\n updateMercadoLibreItem,\n} from \"../../services/mercadolibre/mercadolibre-items.js\";\nimport {\n buildMercadoLibreWriteSuccessResponse,\n handleMercadoLibreWriteError,\n mercadolibreProfileIdSchemaField,\n resolveMercadoLibreWriteProfile,\n} from \"./write-helpers.js\";\n\nexport const meliUpdateItemPicturesSchema = z.object({\n profileId: mercadolibreProfileIdSchemaField,\n itemId: z.string().trim().min(1).describe(\"MercadoLibre item id.\"),\n mode: z.enum([\"add\", \"replace\"]).describe(\"Whether to add new pictures or replace the full pictures array.\"),\n pictures: z\n .array(z.object({ source: z.string().trim().url().describe(\"Public image URL.\") }))\n .min(1)\n .max(12)\n .describe(\"One or more public image URLs to attach.\"),\n});\n\nexport async function meliUpdateItemPicturesHandler(\n params: z.infer<typeof meliUpdateItemPicturesSchema>\n) {\n try {\n const profileResolution = await resolveMercadoLibreWriteProfile(params.profileId);\n if (!profileResolution.ok) {\n return profileResolution.response;\n }\n\n const profileId = profileResolution.value.profileId;\n const before = await getMercadoLibreItem(profileId, params.itemId);\n\n let after: Record<string, unknown>;\n if (params.mode === \"replace\") {\n after = await updateMercadoLibreItem(profileId, params.itemId, {\n pictures: params.pictures,\n });\n } else {\n for (const picture of params.pictures) {\n await addMercadoLibreItemPicture(profileId, params.itemId, picture.source);\n }\n after = await getMercadoLibreItem(profileId, params.itemId);\n }\n\n return buildMercadoLibreWriteSuccessResponse({\n profileId,\n operation: \"update_item_pictures\",\n resourceId: params.itemId,\n message: `MercadoLibre item pictures ${params.mode === \"replace\" ? \"replaced\" : \"updated\"} successfully.`,\n before,\n after,\n details: {\n mode: params.mode,\n pictures_count: params.pictures.length,\n },\n });\n } catch (err) {\n return handleMercadoLibreWriteError(err, `Failed to update pictures for ${params.itemId}`);\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { z } from \"zod\";\r\n\r\nimport {\r\n addMercadoLibreItemPicture,\r\n getMercadoLibreItem,\r\n updateMercadoLibreItem,\r\n} from \"../../services/mercadolibre/mercadolibre-items.js\";\r\nimport {\r\n buildMercadoLibreWriteSuccessResponse,\r\n handleMercadoLibreWriteError,\r\n mercadolibreProfileIdSchemaField,\r\n resolveMercadoLibreWriteProfile,\r\n} from \"./write-helpers.js\";\r\n\r\nexport const meliUpdateItemPicturesSchema = z.object({\r\n profileId: mercadolibreProfileIdSchemaField,\r\n itemId: z.string().trim().min(1).describe(\"MercadoLibre item id.\"),\r\n mode: z.enum([\"add\", \"replace\"]).describe(\"Whether to add new pictures or replace the full pictures array.\"),\r\n pictures: z\r\n .array(z.object({ source: z.string().trim().url().describe(\"Public image URL.\") }))\r\n .min(1)\r\n .max(12)\r\n .describe(\"One or more public image URLs to attach.\"),\r\n});\r\n\r\nexport async function meliUpdateItemPicturesHandler(\r\n params: z.infer<typeof meliUpdateItemPicturesSchema>\r\n) {\r\n try {\r\n const profileResolution = await resolveMercadoLibreWriteProfile(params.profileId);\r\n if (!profileResolution.ok) {\r\n return profileResolution.response;\r\n }\r\n\r\n const profileId = profileResolution.value.profileId;\r\n const before = await getMercadoLibreItem(profileId, params.itemId);\r\n\r\n let after: Record<string, unknown>;\r\n if (params.mode === \"replace\") {\r\n after = await updateMercadoLibreItem(profileId, params.itemId, {\r\n pictures: params.pictures,\r\n });\r\n } else {\r\n for (const picture of params.pictures) {\r\n await addMercadoLibreItemPicture(profileId, params.itemId, picture.source);\r\n }\r\n after = await getMercadoLibreItem(profileId, params.itemId);\r\n }\r\n\r\n return buildMercadoLibreWriteSuccessResponse({\r\n profileId,\r\n operation: \"update_item_pictures\",\r\n resourceId: params.itemId,\r\n message: `MercadoLibre item pictures ${params.mode === \"replace\" ? \"replaced\" : \"updated\"} successfully.`,\r\n before,\r\n after,\r\n details: {\r\n mode: params.mode,\r\n pictures_count: params.pictures.length,\r\n },\r\n });\r\n } catch (err) {\r\n return handleMercadoLibreWriteError(err, `Failed to update pictures for ${params.itemId}`);\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,SAAS;AAElB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,MAAM,+BAA+B,EAAE,OAAO;AAAA,EACnD,WAAW;AAAA,EACX,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,SAAS,uBAAuB;AAAA,EACjE,MAAM,EAAE,KAAK,CAAC,OAAO,SAAS,CAAC,EAAE,SAAS,iEAAiE;AAAA,EAC3G,UAAU,EACP,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,mBAAmB,EAAE,CAAC,CAAC,EACjF,IAAI,CAAC,EACL,IAAI,EAAE,EACN,SAAS,0CAA0C;AACxD,CAAC;AAED,eAAsB,8BACpB,QACA;AACA,MAAI;AACF,UAAM,oBAAoB,MAAM,gCAAgC,OAAO,SAAS;AAChF,QAAI,CAAC,kBAAkB,IAAI;AACzB,aAAO,kBAAkB;AAAA,IAC3B;AAEA,UAAM,YAAY,kBAAkB,MAAM;AAC1C,UAAM,SAAS,MAAM,oBAAoB,WAAW,OAAO,MAAM;AAEjE,QAAI;AACJ,QAAI,OAAO,SAAS,WAAW;AAC7B,cAAQ,MAAM,uBAAuB,WAAW,OAAO,QAAQ;AAAA,QAC7D,UAAU,OAAO;AAAA,MACnB,CAAC;AAAA,IACH,OAAO;AACL,iBAAW,WAAW,OAAO,UAAU;AACrC,cAAM,2BAA2B,WAAW,OAAO,QAAQ,QAAQ,MAAM;AAAA,MAC3E;AACA,cAAQ,MAAM,oBAAoB,WAAW,OAAO,MAAM;AAAA,IAC5D;AAEA,WAAO,sCAAsC;AAAA,MAC3C;AAAA,MACA,WAAW;AAAA,MACX,YAAY,OAAO;AAAA,MACnB,SAAS,8BAA8B,OAAO,SAAS,YAAY,aAAa,SAAS;AAAA,MACzF;AAAA,MACA;AAAA,MACA,SAAS;AAAA,QACP,MAAM,OAAO;AAAA,QACb,gBAAgB,OAAO,SAAS;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,WAAO,6BAA6B,KAAK,iCAAiC,OAAO,MAAM,EAAE;AAAA,EAC3F;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/mercadolibre/validate-connection.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { getMercadoLibreConnectionRow } from \"../../config/mercadolibre-profile-store.js\";\nimport { getMercadoLibreAccessForProfile } from \"../../config/mercadolibre.js\";\nimport { getMercadoLibreUsersMe, formatMercadoLibreError } from \"../../services/mercadolibre/mercadolibre-api.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\nimport { resolveMercadoLibreProfileOrSelection } from \"./profile-resolution.js\";\nimport { mercadolibreProfileIdSchemaField } from \"./write-helpers.js\";\n\nexport const meliValidateConnectionSchema = z.object({\n profileId: mercadolibreProfileIdSchemaField,\n});\n\nexport async function meliValidateConnectionHandler(\n params: z.infer<typeof meliValidateConnectionSchema>\n) {\n try {\n const profileResolution = await resolveMercadoLibreProfileOrSelection(params.profileId);\n if (!profileResolution.ok) {\n return profileResolution.response;\n }\n\n const profileId = profileResolution.value.profileId;\n const before = await getMercadoLibreConnectionRow(profileId);\n const access = await getMercadoLibreAccessForProfile(profileId);\n const account = await getMercadoLibreUsersMe(profileId);\n const after = await getMercadoLibreConnectionRow(profileId);\n\n const refreshed =\n before?.expiresAt?.toISOString() !== after?.expiresAt?.toISOString() ||\n before?.encryptedAccessToken !== after?.encryptedAccessToken;\n\n return object(\n stripNulls({\n profile_id: profileId,\n validation_status: after?.status ?? \"active\",\n refreshed,\n seller_id: access.sellerId,\n account_id: account.id,\n nickname: account.nickname,\n expires_at: access.expiresAt,\n scopes: access.scopes,\n })\n );\n } catch (err) {\n return error(formatMercadoLibreError(err, \"Failed to validate MercadoLibre connection\"));\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport { getMercadoLibreConnectionRow } from \"../../config/mercadolibre-profile-store.js\";\r\nimport { getMercadoLibreAccessForProfile } from \"../../config/mercadolibre.js\";\r\nimport { getMercadoLibreUsersMe, formatMercadoLibreError } from \"../../services/mercadolibre/mercadolibre-api.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\nimport { resolveMercadoLibreProfileOrSelection } from \"./profile-resolution.js\";\r\nimport { mercadolibreProfileIdSchemaField } from \"./write-helpers.js\";\r\n\r\nexport const meliValidateConnectionSchema = z.object({\r\n profileId: mercadolibreProfileIdSchemaField,\r\n});\r\n\r\nexport async function meliValidateConnectionHandler(\r\n params: z.infer<typeof meliValidateConnectionSchema>\r\n) {\r\n try {\r\n const profileResolution = await resolveMercadoLibreProfileOrSelection(params.profileId);\r\n if (!profileResolution.ok) {\r\n return profileResolution.response;\r\n }\r\n\r\n const profileId = profileResolution.value.profileId;\r\n const before = await getMercadoLibreConnectionRow(profileId);\r\n const access = await getMercadoLibreAccessForProfile(profileId);\r\n const account = await getMercadoLibreUsersMe(profileId);\r\n const after = await getMercadoLibreConnectionRow(profileId);\r\n\r\n const refreshed =\r\n before?.expiresAt?.toISOString() !== after?.expiresAt?.toISOString() ||\r\n before?.encryptedAccessToken !== after?.encryptedAccessToken;\r\n\r\n return object(\r\n stripNulls({\r\n profile_id: profileId,\r\n validation_status: after?.status ?? \"active\",\r\n refreshed,\r\n seller_id: access.sellerId,\r\n account_id: account.id,\r\n nickname: account.nickname,\r\n expires_at: access.expiresAt,\r\n scopes: access.scopes,\r\n })\r\n );\r\n } catch (err) {\r\n return error(formatMercadoLibreError(err, \"Failed to validate MercadoLibre connection\"));\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,oCAAoC;AAC7C,SAAS,uCAAuC;AAChD,SAAS,wBAAwB,+BAA+B;AAChE,SAAS,kBAAkB;AAC3B,SAAS,6CAA6C;AACtD,SAAS,wCAAwC;AAE1C,MAAM,+BAA+B,EAAE,OAAO;AAAA,EACnD,WAAW;AACb,CAAC;AAED,eAAsB,8BACpB,QACA;AACA,MAAI;AACF,UAAM,oBAAoB,MAAM,sCAAsC,OAAO,SAAS;AACtF,QAAI,CAAC,kBAAkB,IAAI;AACzB,aAAO,kBAAkB;AAAA,IAC3B;AAEA,UAAM,YAAY,kBAAkB,MAAM;AAC1C,UAAM,SAAS,MAAM,6BAA6B,SAAS;AAC3D,UAAM,SAAS,MAAM,gCAAgC,SAAS;AAC9D,UAAM,UAAU,MAAM,uBAAuB,SAAS;AACtD,UAAM,QAAQ,MAAM,6BAA6B,SAAS;AAE1D,UAAM,YACJ,QAAQ,WAAW,YAAY,MAAM,OAAO,WAAW,YAAY,KACnE,QAAQ,yBAAyB,OAAO;AAE1C,WAAO;AAAA,MACL,WAAW;AAAA,QACT,YAAY;AAAA,QACZ,mBAAmB,OAAO,UAAU;AAAA,QACpC;AAAA,QACA,WAAW,OAAO;AAAA,QAClB,YAAY,QAAQ;AAAA,QACpB,UAAU,QAAQ;AAAA,QAClB,YAAY,OAAO;AAAA,QACnB,QAAQ,OAAO;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,wBAAwB,KAAK,4CAA4C,CAAC;AAAA,EACzF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/mercadolibre/write-helpers.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { formatMercadoLibreError } from \"../../services/mercadolibre/mercadolibre-api.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\nimport { resolveMercadoLibreProfileOrSelection } from \"./profile-resolution.js\";\n\nexport const mercadolibreProfileIdSchemaField = z\n .string()\n .trim()\n .min(1)\n .optional()\n .describe(\n \"Explicit MercadoLibre profile id to use. If omitted, the tool returns a guided selection payload with available active profiles.\"\n );\n\nexport async function resolveMercadoLibreWriteProfile(profileId?: string) {\n const profileResolution = await resolveMercadoLibreProfileOrSelection(profileId);\n if (!profileResolution.ok) {\n return profileResolution;\n }\n\n return {\n ok: true as const,\n value: {\n profileId: profileResolution.value.profileId,\n },\n };\n}\n\nexport function buildMercadoLibreWriteSuccessResponse(params: {\n profileId: string;\n operation: string;\n resourceId?: string;\n message: string;\n before?: Record<string, unknown> | null;\n after?: Record<string, unknown> | null;\n details?: Record<string, unknown>;\n}) {\n return object(\n stripNulls({\n ok: true,\n profile_id: params.profileId,\n operation: params.operation,\n resource_id: params.resourceId,\n message: params.message,\n summary: {\n before: params.before,\n after: params.after,\n },\n details: params.details,\n })\n );\n}\n\nexport function handleMercadoLibreWriteError(err: unknown, fallback: string) {\n return error(formatMercadoLibreError(err, fallback));\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport { formatMercadoLibreError } from \"../../services/mercadolibre/mercadolibre-api.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\nimport { resolveMercadoLibreProfileOrSelection } from \"./profile-resolution.js\";\r\n\r\nexport const mercadolibreProfileIdSchemaField = z\r\n .string()\r\n .trim()\r\n .min(1)\r\n .optional()\r\n .describe(\r\n \"Explicit MercadoLibre profile id to use. If omitted, the tool returns a guided selection payload with available active profiles.\"\r\n );\r\n\r\nexport async function resolveMercadoLibreWriteProfile(profileId?: string) {\r\n const profileResolution = await resolveMercadoLibreProfileOrSelection(profileId);\r\n if (!profileResolution.ok) {\r\n return profileResolution;\r\n }\r\n\r\n return {\r\n ok: true as const,\r\n value: {\r\n profileId: profileResolution.value.profileId,\r\n },\r\n };\r\n}\r\n\r\nexport function buildMercadoLibreWriteSuccessResponse(params: {\r\n profileId: string;\r\n operation: string;\r\n resourceId?: string;\r\n message: string;\r\n before?: Record<string, unknown> | null;\r\n after?: Record<string, unknown> | null;\r\n details?: Record<string, unknown>;\r\n}) {\r\n return object(\r\n stripNulls({\r\n ok: true,\r\n profile_id: params.profileId,\r\n operation: params.operation,\r\n resource_id: params.resourceId,\r\n message: params.message,\r\n summary: {\r\n before: params.before,\r\n after: params.after,\r\n },\r\n details: params.details,\r\n })\r\n );\r\n}\r\n\r\nexport function handleMercadoLibreWriteError(err: unknown, fallback: string) {\r\n return error(formatMercadoLibreError(err, fallback));\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,+BAA+B;AACxC,SAAS,kBAAkB;AAC3B,SAAS,6CAA6C;AAE/C,MAAM,mCAAmC,EAC7C,OAAO,EACP,KAAK,EACL,IAAI,CAAC,EACL,SAAS,EACT;AAAA,EACC;AACF;AAEF,eAAsB,gCAAgC,WAAoB;AACxE,QAAM,oBAAoB,MAAM,sCAAsC,SAAS;AAC/E,MAAI,CAAC,kBAAkB,IAAI;AACzB,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO;AAAA,MACL,WAAW,kBAAkB,MAAM;AAAA,IACrC;AAAA,EACF;AACF;AAEO,SAAS,sCAAsC,QAQnD;AACD,SAAO;AAAA,IACL,WAAW;AAAA,MACT,IAAI;AAAA,MACJ,YAAY,OAAO;AAAA,MACnB,WAAW,OAAO;AAAA,MAClB,aAAa,OAAO;AAAA,MACpB,SAAS,OAAO;AAAA,MAChB,SAAS;AAAA,QACP,QAAQ,OAAO;AAAA,QACf,OAAO,OAAO;AAAA,MAChB;AAAA,MACA,SAAS,OAAO;AAAA,IAClB,CAAC;AAAA,EACH;AACF;AAEO,SAAS,6BAA6B,KAAc,UAAkB;AAC3E,SAAO,MAAM,wBAAwB,KAAK,QAAQ,CAAC;AACrD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/meta/account-overview.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport {\n getMetaInsights,\n listAccessibleMetaAdAccounts,\n} from \"../../services/meta/meta-ads.js\";\nimport {\n aggregateInsightsByCurrency,\n dateRegex,\n getMetricBundle,\n normalizeRequestedAccountIds,\n resolveRequestedAccounts,\n} from \"../../meta/meta-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const metaAccountOverviewSchema = 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 adAccountIds: z\n .array(z.string())\n .optional()\n .describe(\n \"Optional list of Meta ad account IDs. Accepts digits with or without the act_ prefix. If omitted, uses all accessible ad accounts.\"\n ),\n});\n\nexport async function metaAccountOverviewHandler(\n params: z.infer<typeof metaAccountOverviewSchema>\n) {\n try {\n const accessibleAccounts = (await listAccessibleMetaAdAccounts()).adAccounts;\n const requestedIds = normalizeRequestedAccountIds(params.adAccountIds);\n const accounts = resolveRequestedAccounts(requestedIds, accessibleAccounts);\n\n const accountResults = await Promise.all(\n accounts.map(async (account) => {\n const insights = await getMetaInsights(`act_${account.account_id}`, {\n time_range: JSON.stringify({ since: params.startDate, until: params.endDate }),\n level: \"account\",\n });\n const insight = insights[0];\n return {\n ad_account_id: account.account_id,\n act_id: `act_${account.account_id}`,\n account_name: account.name,\n currency_code: account.currency,\n business: account.business,\n overview: getMetricBundle(insight),\n };\n })\n );\n\n return object(\n stripNulls({\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n accounts: accountResults,\n summary_by_currency: aggregateInsightsByCurrency(\n accountResults.map((account, index) => ({\n currencyCode: account.currency_code,\n insight: {\n spend: String(accountResults[index].overview.spend),\n impressions: String(accountResults[index].overview.impressions),\n clicks: String(accountResults[index].overview.clicks),\n reach: String(accountResults[index].overview.reach),\n ctr: String(accountResults[index].overview.ctr_percent),\n cpc: String(accountResults[index].overview.cpc),\n cpm: String(accountResults[index].overview.cpm),\n actions: [\n {\n action_type: \"purchase\",\n value: String(accountResults[index].overview.purchases),\n },\n ],\n action_values: [\n {\n action_type: \"purchase\",\n value: String(accountResults[index].overview.purchase_value),\n },\n ],\n },\n }))\n ),\n metadata: {\n requested_accounts: requestedIds?.length || 0,\n analyzed_accounts: accountResults.length,\n note:\n \"Results are returned per ad account. Summary aggregates are split by currency to avoid unsafe cross-currency totals.\",\n },\n })\n );\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Failed to fetch Meta account overview\");\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport {\r\n getMetaInsights,\r\n listAccessibleMetaAdAccounts,\r\n} from \"../../services/meta/meta-ads.js\";\r\nimport {\r\n aggregateInsightsByCurrency,\r\n dateRegex,\r\n getMetricBundle,\r\n normalizeRequestedAccountIds,\r\n resolveRequestedAccounts,\r\n} from \"../../meta/meta-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const metaAccountOverviewSchema = z.object({\r\n startDate: z.string().regex(dateRegex).describe(\"Start date in YYYY-MM-DD format.\"),\r\n endDate: z.string().regex(dateRegex).describe(\"End date in YYYY-MM-DD format.\"),\r\n adAccountIds: z\r\n .array(z.string())\r\n .optional()\r\n .describe(\r\n \"Optional list of Meta ad account IDs. Accepts digits with or without the act_ prefix. If omitted, uses all accessible ad accounts.\"\r\n ),\r\n});\r\n\r\nexport async function metaAccountOverviewHandler(\r\n params: z.infer<typeof metaAccountOverviewSchema>\r\n) {\r\n try {\r\n const accessibleAccounts = (await listAccessibleMetaAdAccounts()).adAccounts;\r\n const requestedIds = normalizeRequestedAccountIds(params.adAccountIds);\r\n const accounts = resolveRequestedAccounts(requestedIds, accessibleAccounts);\r\n\r\n const accountResults = await Promise.all(\r\n accounts.map(async (account) => {\r\n const insights = await getMetaInsights(`act_${account.account_id}`, {\r\n time_range: JSON.stringify({ since: params.startDate, until: params.endDate }),\r\n level: \"account\",\r\n });\r\n const insight = insights[0];\r\n return {\r\n ad_account_id: account.account_id,\r\n act_id: `act_${account.account_id}`,\r\n account_name: account.name,\r\n currency_code: account.currency,\r\n business: account.business,\r\n overview: getMetricBundle(insight),\r\n };\r\n })\r\n );\r\n\r\n return object(\r\n stripNulls({\r\n date_range: {\r\n start_date: params.startDate,\r\n end_date: params.endDate,\r\n },\r\n accounts: accountResults,\r\n summary_by_currency: aggregateInsightsByCurrency(\r\n accountResults.map((account, index) => ({\r\n currencyCode: account.currency_code,\r\n insight: {\r\n spend: String(accountResults[index].overview.spend),\r\n impressions: String(accountResults[index].overview.impressions),\r\n clicks: String(accountResults[index].overview.clicks),\r\n reach: String(accountResults[index].overview.reach),\r\n ctr: String(accountResults[index].overview.ctr_percent),\r\n cpc: String(accountResults[index].overview.cpc),\r\n cpm: String(accountResults[index].overview.cpm),\r\n actions: [\r\n {\r\n action_type: \"purchase\",\r\n value: String(accountResults[index].overview.purchases),\r\n },\r\n ],\r\n action_values: [\r\n {\r\n action_type: \"purchase\",\r\n value: String(accountResults[index].overview.purchase_value),\r\n },\r\n ],\r\n },\r\n }))\r\n ),\r\n metadata: {\r\n requested_accounts: requestedIds?.length || 0,\r\n analyzed_accounts: accountResults.length,\r\n note:\r\n \"Results are returned per ad account. Summary aggregates are split by currency to avoid unsafe cross-currency totals.\",\r\n },\r\n })\r\n );\r\n } catch (err) {\r\n return error(err instanceof Error ? err.message : \"Failed to fetch Meta account overview\");\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,4BAA4B,EAAE,OAAO;AAAA,EAChD,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,kCAAkC;AAAA,EAClF,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,gCAAgC;AAAA,EAC9E,cAAc,EACX,MAAM,EAAE,OAAO,CAAC,EAChB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ,CAAC;AAED,eAAsB,2BACpB,QACA;AACA,MAAI;AACF,UAAM,sBAAsB,MAAM,6BAA6B,GAAG;AAClE,UAAM,eAAe,6BAA6B,OAAO,YAAY;AACrE,UAAM,WAAW,yBAAyB,cAAc,kBAAkB;AAE1E,UAAM,iBAAiB,MAAM,QAAQ;AAAA,MACnC,SAAS,IAAI,OAAO,YAAY;AAC9B,cAAM,WAAW,MAAM,gBAAgB,OAAO,QAAQ,UAAU,IAAI;AAAA,UAClE,YAAY,KAAK,UAAU,EAAE,OAAO,OAAO,WAAW,OAAO,OAAO,QAAQ,CAAC;AAAA,UAC7E,OAAO;AAAA,QACT,CAAC;AACD,cAAM,UAAU,SAAS,CAAC;AAC1B,eAAO;AAAA,UACL,eAAe,QAAQ;AAAA,UACvB,QAAQ,OAAO,QAAQ,UAAU;AAAA,UACjC,cAAc,QAAQ;AAAA,UACtB,eAAe,QAAQ;AAAA,UACvB,UAAU,QAAQ;AAAA,UAClB,UAAU,gBAAgB,OAAO;AAAA,QACnC;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,WAAW;AAAA,QACT,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,UAAU;AAAA,QACV,qBAAqB;AAAA,UACnB,eAAe,IAAI,CAAC,SAAS,WAAW;AAAA,YACtC,cAAc,QAAQ;AAAA,YACtB,SAAS;AAAA,cACP,OAAO,OAAO,eAAe,KAAK,EAAE,SAAS,KAAK;AAAA,cAClD,aAAa,OAAO,eAAe,KAAK,EAAE,SAAS,WAAW;AAAA,cAC9D,QAAQ,OAAO,eAAe,KAAK,EAAE,SAAS,MAAM;AAAA,cACpD,OAAO,OAAO,eAAe,KAAK,EAAE,SAAS,KAAK;AAAA,cAClD,KAAK,OAAO,eAAe,KAAK,EAAE,SAAS,WAAW;AAAA,cACtD,KAAK,OAAO,eAAe,KAAK,EAAE,SAAS,GAAG;AAAA,cAC9C,KAAK,OAAO,eAAe,KAAK,EAAE,SAAS,GAAG;AAAA,cAC9C,SAAS;AAAA,gBACP;AAAA,kBACE,aAAa;AAAA,kBACb,OAAO,OAAO,eAAe,KAAK,EAAE,SAAS,SAAS;AAAA,gBACxD;AAAA,cACF;AAAA,cACA,eAAe;AAAA,gBACb;AAAA,kBACE,aAAa;AAAA,kBACb,OAAO,OAAO,eAAe,KAAK,EAAE,SAAS,cAAc;AAAA,gBAC7D;AAAA,cACF;AAAA,YACF;AAAA,UACF,EAAE;AAAA,QACJ;AAAA,QACA,UAAU;AAAA,UACR,oBAAoB,cAAc,UAAU;AAAA,UAC5C,mBAAmB,eAAe;AAAA,UAClC,MACE;AAAA,QACJ;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,uCAAuC;AAAA,EAC3F;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/meta/ad-account-info.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { getMetaAdAccountInfo } from \"../../services/meta/meta-ads.js\";\nimport { getMetaAdAccountStatusLabel, normalizeMetaAdAccountId } from \"../../meta/meta-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const metaAdAccountInfoSchema = z.object({\n adAccountId: z\n .string()\n .describe(\"Meta ad account ID to inspect. Accepts digits with or without the act_ prefix.\"),\n});\n\nexport async function metaAdAccountInfoHandler(\n params: z.infer<typeof metaAdAccountInfoSchema>\n) {\n try {\n const adAccountId = normalizeMetaAdAccountId(params.adAccountId);\n const account = await getMetaAdAccountInfo(adAccountId);\n\n return object(\n stripNulls({\n ad_account: {\n id: account.id,\n account_id: account.account_id,\n act_id: `act_${adAccountId}`,\n name: account.name,\n currency: account.currency,\n account_status: account.account_status,\n account_status_label: getMetaAdAccountStatusLabel(account.account_status),\n timezone_name: account.timezone_name,\n timezone_offset_hours_utc: account.timezone_offset_hours_utc,\n business: account.business,\n },\n })\n );\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Failed to fetch Meta ad account info\");\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport { getMetaAdAccountInfo } from \"../../services/meta/meta-ads.js\";\r\nimport { getMetaAdAccountStatusLabel, normalizeMetaAdAccountId } from \"../../meta/meta-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const metaAdAccountInfoSchema = z.object({\r\n adAccountId: z\r\n .string()\r\n .describe(\"Meta ad account ID to inspect. Accepts digits with or without the act_ prefix.\"),\r\n});\r\n\r\nexport async function metaAdAccountInfoHandler(\r\n params: z.infer<typeof metaAdAccountInfoSchema>\r\n) {\r\n try {\r\n const adAccountId = normalizeMetaAdAccountId(params.adAccountId);\r\n const account = await getMetaAdAccountInfo(adAccountId);\r\n\r\n return object(\r\n stripNulls({\r\n ad_account: {\r\n id: account.id,\r\n account_id: account.account_id,\r\n act_id: `act_${adAccountId}`,\r\n name: account.name,\r\n currency: account.currency,\r\n account_status: account.account_status,\r\n account_status_label: getMetaAdAccountStatusLabel(account.account_status),\r\n timezone_name: account.timezone_name,\r\n timezone_offset_hours_utc: account.timezone_offset_hours_utc,\r\n business: account.business,\r\n },\r\n })\r\n );\r\n } catch (err) {\r\n return error(err instanceof Error ? err.message : \"Failed to fetch Meta ad account info\");\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,4BAA4B;AACrC,SAAS,6BAA6B,gCAAgC;AACtE,SAAS,kBAAkB;AAEpB,MAAM,0BAA0B,EAAE,OAAO;AAAA,EAC9C,aAAa,EACV,OAAO,EACP,SAAS,gFAAgF;AAC9F,CAAC;AAED,eAAsB,yBACpB,QACA;AACA,MAAI;AACF,UAAM,cAAc,yBAAyB,OAAO,WAAW;AAC/D,UAAM,UAAU,MAAM,qBAAqB,WAAW;AAEtD,WAAO;AAAA,MACL,WAAW;AAAA,QACT,YAAY;AAAA,UACV,IAAI,QAAQ;AAAA,UACZ,YAAY,QAAQ;AAAA,UACpB,QAAQ,OAAO,WAAW;AAAA,UAC1B,MAAM,QAAQ;AAAA,UACd,UAAU,QAAQ;AAAA,UAClB,gBAAgB,QAAQ;AAAA,UACxB,sBAAsB,4BAA4B,QAAQ,cAAc;AAAA,UACxE,eAAe,QAAQ;AAAA,UACvB,2BAA2B,QAAQ;AAAA,UACnC,UAAU,QAAQ;AAAA,QACpB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,sCAAsC;AAAA,EAC1F;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/meta/ads-performance.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport {\n getMetaAds,\n getMetaInsights,\n listAccessibleMetaAdAccounts,\n} from \"../../services/meta/meta-ads.js\";\nimport {\n dateRegex,\n getMetricBundle,\n normalizeRequestedAccountIds,\n resolveRequestedAccounts,\n} from \"../../meta/meta-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const metaAdsPerformanceSchema = 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 adAccountIds: z\n .array(z.string())\n .optional()\n .describe(\n \"Optional list of Meta ad account IDs. Accepts digits with or without the act_ prefix. If omitted, uses all accessible ad accounts.\"\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe(\"Maximum number of ads to return per ad account. Default: 25.\"),\n});\n\nexport async function metaAdsPerformanceHandler(\n params: z.infer<typeof metaAdsPerformanceSchema>\n) {\n try {\n const accessibleAccounts = (await listAccessibleMetaAdAccounts()).adAccounts;\n const requestedIds = normalizeRequestedAccountIds(params.adAccountIds);\n const accounts = resolveRequestedAccounts(requestedIds, accessibleAccounts);\n const limit = params.limit ?? 25;\n\n const results = await Promise.all(\n accounts.map(async (account) => {\n const ads = await getMetaAds(account.account_id || \"\", limit);\n const rows = await Promise.all(\n ads.map(async (ad) => {\n const insight = (\n await getMetaInsights(ad.id || \"\", {\n time_range: JSON.stringify({ since: params.startDate, until: params.endDate }),\n level: \"ad\",\n })\n )[0];\n\n return {\n ad_id: ad.id,\n ad_name: ad.name,\n status: ad.status,\n effective_status: ad.effective_status,\n creative_id: ad.creative?.id,\n ...getMetricBundle(insight),\n };\n })\n );\n\n rows.sort((left, right) => right.spend - left.spend);\n\n return {\n ad_account_id: account.account_id,\n account_name: account.name,\n currency_code: account.currency,\n ads: rows,\n };\n })\n );\n\n return object(\n stripNulls({\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n accounts: results,\n metadata: {\n analyzed_accounts: results.length,\n ads_per_account_limit: limit,\n note:\n \"Ads are ranked inside each ad account. This output is intended for creative review and performance diagnosis, not for full asset exports.\",\n },\n })\n );\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Failed to fetch Meta ads performance\");\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport {\r\n getMetaAds,\r\n getMetaInsights,\r\n listAccessibleMetaAdAccounts,\r\n} from \"../../services/meta/meta-ads.js\";\r\nimport {\r\n dateRegex,\r\n getMetricBundle,\r\n normalizeRequestedAccountIds,\r\n resolveRequestedAccounts,\r\n} from \"../../meta/meta-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const metaAdsPerformanceSchema = z.object({\r\n startDate: z.string().regex(dateRegex).describe(\"Start date in YYYY-MM-DD format.\"),\r\n endDate: z.string().regex(dateRegex).describe(\"End date in YYYY-MM-DD format.\"),\r\n adAccountIds: z\r\n .array(z.string())\r\n .optional()\r\n .describe(\r\n \"Optional list of Meta ad account IDs. Accepts digits with or without the act_ prefix. If omitted, uses all accessible ad accounts.\"\r\n ),\r\n limit: z\r\n .number()\r\n .int()\r\n .min(1)\r\n .max(100)\r\n .optional()\r\n .describe(\"Maximum number of ads to return per ad account. Default: 25.\"),\r\n});\r\n\r\nexport async function metaAdsPerformanceHandler(\r\n params: z.infer<typeof metaAdsPerformanceSchema>\r\n) {\r\n try {\r\n const accessibleAccounts = (await listAccessibleMetaAdAccounts()).adAccounts;\r\n const requestedIds = normalizeRequestedAccountIds(params.adAccountIds);\r\n const accounts = resolveRequestedAccounts(requestedIds, accessibleAccounts);\r\n const limit = params.limit ?? 25;\r\n\r\n const results = await Promise.all(\r\n accounts.map(async (account) => {\r\n const ads = await getMetaAds(account.account_id || \"\", limit);\r\n const rows = await Promise.all(\r\n ads.map(async (ad) => {\r\n const insight = (\r\n await getMetaInsights(ad.id || \"\", {\r\n time_range: JSON.stringify({ since: params.startDate, until: params.endDate }),\r\n level: \"ad\",\r\n })\r\n )[0];\r\n\r\n return {\r\n ad_id: ad.id,\r\n ad_name: ad.name,\r\n status: ad.status,\r\n effective_status: ad.effective_status,\r\n creative_id: ad.creative?.id,\r\n ...getMetricBundle(insight),\r\n };\r\n })\r\n );\r\n\r\n rows.sort((left, right) => right.spend - left.spend);\r\n\r\n return {\r\n ad_account_id: account.account_id,\r\n account_name: account.name,\r\n currency_code: account.currency,\r\n ads: rows,\r\n };\r\n })\r\n );\r\n\r\n return object(\r\n stripNulls({\r\n date_range: {\r\n start_date: params.startDate,\r\n end_date: params.endDate,\r\n },\r\n accounts: results,\r\n metadata: {\r\n analyzed_accounts: results.length,\r\n ads_per_account_limit: limit,\r\n note:\r\n \"Ads are ranked inside each ad account. This output is intended for creative review and performance diagnosis, not for full asset exports.\",\r\n },\r\n })\r\n );\r\n } catch (err) {\r\n return error(err instanceof Error ? err.message : \"Failed to fetch Meta ads performance\");\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,kCAAkC;AAAA,EAClF,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,gCAAgC;AAAA,EAC9E,cAAc,EACX,MAAM,EAAE,OAAO,CAAC,EAChB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,OAAO,EACJ,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,GAAG,EACP,SAAS,EACT,SAAS,8DAA8D;AAC5E,CAAC;AAED,eAAsB,0BACpB,QACA;AACA,MAAI;AACF,UAAM,sBAAsB,MAAM,6BAA6B,GAAG;AAClE,UAAM,eAAe,6BAA6B,OAAO,YAAY;AACrE,UAAM,WAAW,yBAAyB,cAAc,kBAAkB;AAC1E,UAAM,QAAQ,OAAO,SAAS;AAE9B,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,SAAS,IAAI,OAAO,YAAY;AAC9B,cAAM,MAAM,MAAM,WAAW,QAAQ,cAAc,IAAI,KAAK;AAC5D,cAAM,OAAO,MAAM,QAAQ;AAAA,UACzB,IAAI,IAAI,OAAO,OAAO;AACpB,kBAAM,WACJ,MAAM,gBAAgB,GAAG,MAAM,IAAI;AAAA,cACjC,YAAY,KAAK,UAAU,EAAE,OAAO,OAAO,WAAW,OAAO,OAAO,QAAQ,CAAC;AAAA,cAC7E,OAAO;AAAA,YACT,CAAC,GACD,CAAC;AAEH,mBAAO;AAAA,cACL,OAAO,GAAG;AAAA,cACV,SAAS,GAAG;AAAA,cACZ,QAAQ,GAAG;AAAA,cACX,kBAAkB,GAAG;AAAA,cACrB,aAAa,GAAG,UAAU;AAAA,cAC1B,GAAG,gBAAgB,OAAO;AAAA,YAC5B;AAAA,UACF,CAAC;AAAA,QACH;AAEA,aAAK,KAAK,CAAC,MAAM,UAAU,MAAM,QAAQ,KAAK,KAAK;AAEnD,eAAO;AAAA,UACL,eAAe,QAAQ;AAAA,UACvB,cAAc,QAAQ;AAAA,UACtB,eAAe,QAAQ;AAAA,UACvB,KAAK;AAAA,QACP;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,WAAW;AAAA,QACT,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,UAAU;AAAA,QACV,UAAU;AAAA,UACR,mBAAmB,QAAQ;AAAA,UAC3B,uBAAuB;AAAA,UACvB,MACE;AAAA,QACJ;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,sCAAsC;AAAA,EAC1F;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/meta/campaign-performance.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport {\n getMetaCampaigns,\n getMetaInsights,\n listAccessibleMetaAdAccounts,\n} from \"../../services/meta/meta-ads.js\";\nimport {\n dateRegex,\n getMetricBundle,\n normalizeRequestedAccountIds,\n resolveRequestedAccounts,\n} from \"../../meta/meta-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const metaCampaignPerformanceSchema = 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 adAccountIds: z\n .array(z.string())\n .optional()\n .describe(\n \"Optional list of Meta ad account IDs. Accepts digits with or without the act_ prefix. If omitted, uses all accessible ad accounts.\"\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe(\"Maximum number of campaigns to return per ad account. Default: 25.\"),\n});\n\nexport async function metaCampaignPerformanceHandler(\n params: z.infer<typeof metaCampaignPerformanceSchema>\n) {\n try {\n const accessibleAccounts = (await listAccessibleMetaAdAccounts()).adAccounts;\n const requestedIds = normalizeRequestedAccountIds(params.adAccountIds);\n const accounts = resolveRequestedAccounts(requestedIds, accessibleAccounts);\n const limit = params.limit ?? 25;\n\n const results = await Promise.all(\n accounts.map(async (account) => {\n const campaigns = await getMetaCampaigns(account.account_id || \"\", limit);\n const rows = await Promise.all(\n campaigns.map(async (campaign) => {\n const insight = (\n await getMetaInsights(campaign.id || \"\", {\n time_range: JSON.stringify({ since: params.startDate, until: params.endDate }),\n level: \"campaign\",\n })\n )[0];\n\n return {\n campaign_id: campaign.id,\n campaign_name: campaign.name,\n status: campaign.status,\n effective_status: campaign.effective_status,\n objective: campaign.objective,\n ...getMetricBundle(insight),\n };\n })\n );\n\n rows.sort((left, right) => right.spend - left.spend);\n\n return {\n ad_account_id: account.account_id,\n account_name: account.name,\n currency_code: account.currency,\n campaigns: rows,\n };\n })\n );\n\n return object(\n stripNulls({\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n accounts: results,\n metadata: {\n analyzed_accounts: results.length,\n campaigns_per_account_limit: limit,\n note:\n \"Campaigns are ranked inside each ad account to preserve account context and avoid unsafe cross-account aggregation.\",\n },\n })\n );\n } catch (err) {\n return error(\n err instanceof Error ? err.message : \"Failed to fetch Meta campaign performance\"\n );\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport {\r\n getMetaCampaigns,\r\n getMetaInsights,\r\n listAccessibleMetaAdAccounts,\r\n} from \"../../services/meta/meta-ads.js\";\r\nimport {\r\n dateRegex,\r\n getMetricBundle,\r\n normalizeRequestedAccountIds,\r\n resolveRequestedAccounts,\r\n} from \"../../meta/meta-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const metaCampaignPerformanceSchema = z.object({\r\n startDate: z.string().regex(dateRegex).describe(\"Start date in YYYY-MM-DD format.\"),\r\n endDate: z.string().regex(dateRegex).describe(\"End date in YYYY-MM-DD format.\"),\r\n adAccountIds: z\r\n .array(z.string())\r\n .optional()\r\n .describe(\r\n \"Optional list of Meta ad account IDs. Accepts digits with or without the act_ prefix. If omitted, uses all accessible ad accounts.\"\r\n ),\r\n limit: z\r\n .number()\r\n .int()\r\n .min(1)\r\n .max(100)\r\n .optional()\r\n .describe(\"Maximum number of campaigns to return per ad account. Default: 25.\"),\r\n});\r\n\r\nexport async function metaCampaignPerformanceHandler(\r\n params: z.infer<typeof metaCampaignPerformanceSchema>\r\n) {\r\n try {\r\n const accessibleAccounts = (await listAccessibleMetaAdAccounts()).adAccounts;\r\n const requestedIds = normalizeRequestedAccountIds(params.adAccountIds);\r\n const accounts = resolveRequestedAccounts(requestedIds, accessibleAccounts);\r\n const limit = params.limit ?? 25;\r\n\r\n const results = await Promise.all(\r\n accounts.map(async (account) => {\r\n const campaigns = await getMetaCampaigns(account.account_id || \"\", limit);\r\n const rows = await Promise.all(\r\n campaigns.map(async (campaign) => {\r\n const insight = (\r\n await getMetaInsights(campaign.id || \"\", {\r\n time_range: JSON.stringify({ since: params.startDate, until: params.endDate }),\r\n level: \"campaign\",\r\n })\r\n )[0];\r\n\r\n return {\r\n campaign_id: campaign.id,\r\n campaign_name: campaign.name,\r\n status: campaign.status,\r\n effective_status: campaign.effective_status,\r\n objective: campaign.objective,\r\n ...getMetricBundle(insight),\r\n };\r\n })\r\n );\r\n\r\n rows.sort((left, right) => right.spend - left.spend);\r\n\r\n return {\r\n ad_account_id: account.account_id,\r\n account_name: account.name,\r\n currency_code: account.currency,\r\n campaigns: rows,\r\n };\r\n })\r\n );\r\n\r\n return object(\r\n stripNulls({\r\n date_range: {\r\n start_date: params.startDate,\r\n end_date: params.endDate,\r\n },\r\n accounts: results,\r\n metadata: {\r\n analyzed_accounts: results.length,\r\n campaigns_per_account_limit: limit,\r\n note:\r\n \"Campaigns are ranked inside each ad account to preserve account context and avoid unsafe cross-account aggregation.\",\r\n },\r\n })\r\n );\r\n } catch (err) {\r\n return error(\r\n err instanceof Error ? err.message : \"Failed to fetch Meta campaign performance\"\r\n );\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,gCAAgC,EAAE,OAAO;AAAA,EACpD,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,kCAAkC;AAAA,EAClF,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,gCAAgC;AAAA,EAC9E,cAAc,EACX,MAAM,EAAE,OAAO,CAAC,EAChB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,OAAO,EACJ,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,GAAG,EACP,SAAS,EACT,SAAS,oEAAoE;AAClF,CAAC;AAED,eAAsB,+BACpB,QACA;AACA,MAAI;AACF,UAAM,sBAAsB,MAAM,6BAA6B,GAAG;AAClE,UAAM,eAAe,6BAA6B,OAAO,YAAY;AACrE,UAAM,WAAW,yBAAyB,cAAc,kBAAkB;AAC1E,UAAM,QAAQ,OAAO,SAAS;AAE9B,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,SAAS,IAAI,OAAO,YAAY;AAC9B,cAAM,YAAY,MAAM,iBAAiB,QAAQ,cAAc,IAAI,KAAK;AACxE,cAAM,OAAO,MAAM,QAAQ;AAAA,UACzB,UAAU,IAAI,OAAO,aAAa;AAChC,kBAAM,WACJ,MAAM,gBAAgB,SAAS,MAAM,IAAI;AAAA,cACvC,YAAY,KAAK,UAAU,EAAE,OAAO,OAAO,WAAW,OAAO,OAAO,QAAQ,CAAC;AAAA,cAC7E,OAAO;AAAA,YACT,CAAC,GACD,CAAC;AAEH,mBAAO;AAAA,cACL,aAAa,SAAS;AAAA,cACtB,eAAe,SAAS;AAAA,cACxB,QAAQ,SAAS;AAAA,cACjB,kBAAkB,SAAS;AAAA,cAC3B,WAAW,SAAS;AAAA,cACpB,GAAG,gBAAgB,OAAO;AAAA,YAC5B;AAAA,UACF,CAAC;AAAA,QACH;AAEA,aAAK,KAAK,CAAC,MAAM,UAAU,MAAM,QAAQ,KAAK,KAAK;AAEnD,eAAO;AAAA,UACL,eAAe,QAAQ;AAAA,UACvB,cAAc,QAAQ;AAAA,UACtB,eAAe,QAAQ;AAAA,UACvB,WAAW;AAAA,QACb;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,WAAW;AAAA,QACT,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,UAAU;AAAA,QACV,UAAU;AAAA,UACR,mBAAmB,QAAQ;AAAA,UAC3B,6BAA6B;AAAA,UAC7B,MACE;AAAA,QACJ;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,eAAe,QAAQ,IAAI,UAAU;AAAA,IACvC;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/meta/index.ts"],
|
|
4
|
-
"sourcesContent": ["export * from \"./list-accessible-businesses.js\";\nexport * from \"./list-accessible-ad-accounts.js\";\nexport * from \"./ad-account-info.js\";\nexport * from \"./account-overview.js\";\nexport * from \"./campaign-performance.js\";\nexport * from \"./ads-performance.js\";\nexport * from \"./time-series.js\";\nexport * from \"./placement-mix.js\";\n"],
|
|
4
|
+
"sourcesContent": ["export * from \"./list-accessible-businesses.js\";\r\nexport * from \"./list-accessible-ad-accounts.js\";\r\nexport * from \"./ad-account-info.js\";\r\nexport * from \"./account-overview.js\";\r\nexport * from \"./campaign-performance.js\";\r\nexport * from \"./ads-performance.js\";\r\nexport * from \"./time-series.js\";\r\nexport * from \"./placement-mix.js\";\r\n"],
|
|
5
5
|
"mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/meta/list-accessible-ad-accounts.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { listAccessibleMetaAdAccounts } from \"../../services/meta/meta-ads.js\";\nimport { getMetaAdAccountStatusLabel } from \"../../meta/meta-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const metaListAccessibleAdAccountsSchema = z.object({\n after: z\n .string()\n .optional()\n .describe(\"Optional pagination cursor returned by a previous Meta ad accounts listing.\"),\n});\n\nexport async function metaListAccessibleAdAccountsHandler(\n params: z.infer<typeof metaListAccessibleAdAccountsSchema>\n) {\n try {\n const result = await listAccessibleMetaAdAccounts(params.after);\n\n return object(\n stripNulls({\n ad_accounts: result.adAccounts.map((account) => ({\n id: account.id,\n account_id: account.account_id,\n act_id: account.account_id ? `act_${account.account_id}` : account.id,\n name: account.name,\n currency: account.currency,\n account_status: account.account_status,\n account_status_label: getMetaAdAccountStatusLabel(account.account_status),\n timezone_name: account.timezone_name,\n timezone_offset_hours_utc: account.timezone_offset_hours_utc,\n business: account.business,\n })),\n metadata: {\n returned_ad_accounts: result.adAccounts.length,\n pagination: {\n has_more: result.paging.has_more,\n next_after: result.paging.after,\n },\n note: result.paging.has_more\n ? \"Partial data. Use metadata.pagination.next_after to request the next page.\"\n : \"Complete data for the current token and page size.\",\n },\n })\n );\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Failed to list accessible Meta ad accounts\");\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport { listAccessibleMetaAdAccounts } from \"../../services/meta/meta-ads.js\";\r\nimport { getMetaAdAccountStatusLabel } from \"../../meta/meta-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const metaListAccessibleAdAccountsSchema = z.object({\r\n after: z\r\n .string()\r\n .optional()\r\n .describe(\"Optional pagination cursor returned by a previous Meta ad accounts listing.\"),\r\n});\r\n\r\nexport async function metaListAccessibleAdAccountsHandler(\r\n params: z.infer<typeof metaListAccessibleAdAccountsSchema>\r\n) {\r\n try {\r\n const result = await listAccessibleMetaAdAccounts(params.after);\r\n\r\n return object(\r\n stripNulls({\r\n ad_accounts: result.adAccounts.map((account) => ({\r\n id: account.id,\r\n account_id: account.account_id,\r\n act_id: account.account_id ? `act_${account.account_id}` : account.id,\r\n name: account.name,\r\n currency: account.currency,\r\n account_status: account.account_status,\r\n account_status_label: getMetaAdAccountStatusLabel(account.account_status),\r\n timezone_name: account.timezone_name,\r\n timezone_offset_hours_utc: account.timezone_offset_hours_utc,\r\n business: account.business,\r\n })),\r\n metadata: {\r\n returned_ad_accounts: result.adAccounts.length,\r\n pagination: {\r\n has_more: result.paging.has_more,\r\n next_after: result.paging.after,\r\n },\r\n note: result.paging.has_more\r\n ? \"Partial data. Use metadata.pagination.next_after to request the next page.\"\r\n : \"Complete data for the current token and page size.\",\r\n },\r\n })\r\n );\r\n } catch (err) {\r\n return error(err instanceof Error ? err.message : \"Failed to list accessible Meta ad accounts\");\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,oCAAoC;AAC7C,SAAS,mCAAmC;AAC5C,SAAS,kBAAkB;AAEpB,MAAM,qCAAqC,EAAE,OAAO;AAAA,EACzD,OAAO,EACJ,OAAO,EACP,SAAS,EACT,SAAS,6EAA6E;AAC3F,CAAC;AAED,eAAsB,oCACpB,QACA;AACA,MAAI;AACF,UAAM,SAAS,MAAM,6BAA6B,OAAO,KAAK;AAE9D,WAAO;AAAA,MACL,WAAW;AAAA,QACT,aAAa,OAAO,WAAW,IAAI,CAAC,aAAa;AAAA,UAC/C,IAAI,QAAQ;AAAA,UACZ,YAAY,QAAQ;AAAA,UACpB,QAAQ,QAAQ,aAAa,OAAO,QAAQ,UAAU,KAAK,QAAQ;AAAA,UACnE,MAAM,QAAQ;AAAA,UACd,UAAU,QAAQ;AAAA,UAClB,gBAAgB,QAAQ;AAAA,UACxB,sBAAsB,4BAA4B,QAAQ,cAAc;AAAA,UACxE,eAAe,QAAQ;AAAA,UACvB,2BAA2B,QAAQ;AAAA,UACnC,UAAU,QAAQ;AAAA,QACpB,EAAE;AAAA,QACF,UAAU;AAAA,UACR,sBAAsB,OAAO,WAAW;AAAA,UACxC,YAAY;AAAA,YACV,UAAU,OAAO,OAAO;AAAA,YACxB,YAAY,OAAO,OAAO;AAAA,UAC5B;AAAA,UACA,MAAM,OAAO,OAAO,WAChB,+EACA;AAAA,QACN;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,4CAA4C;AAAA,EAChG;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/meta/list-accessible-businesses.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { listAccessibleMetaBusinesses } from \"../../services/meta/meta-ads.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const metaListAccessibleBusinessesSchema = z.object({\n after: z\n .string()\n .optional()\n .describe(\"Optional pagination cursor returned by a previous Meta businesses listing.\"),\n});\n\nexport async function metaListAccessibleBusinessesHandler(\n params: z.infer<typeof metaListAccessibleBusinessesSchema>\n) {\n try {\n const result = await listAccessibleMetaBusinesses(params.after);\n\n return object(\n stripNulls({\n businesses: result.businesses.map((business) => ({\n id: business.id,\n name: business.name,\n verification_status: business.verification_status,\n })),\n metadata: {\n returned_businesses: result.businesses.length,\n pagination: {\n has_more: result.paging.has_more,\n next_after: result.paging.after,\n },\n note: result.paging.has_more\n ? \"Partial data. Use metadata.pagination.next_after to request the next page.\"\n : \"Complete data for the current token and page size.\",\n },\n })\n );\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Failed to list accessible Meta businesses\");\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport { listAccessibleMetaBusinesses } from \"../../services/meta/meta-ads.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const metaListAccessibleBusinessesSchema = z.object({\r\n after: z\r\n .string()\r\n .optional()\r\n .describe(\"Optional pagination cursor returned by a previous Meta businesses listing.\"),\r\n});\r\n\r\nexport async function metaListAccessibleBusinessesHandler(\r\n params: z.infer<typeof metaListAccessibleBusinessesSchema>\r\n) {\r\n try {\r\n const result = await listAccessibleMetaBusinesses(params.after);\r\n\r\n return object(\r\n stripNulls({\r\n businesses: result.businesses.map((business) => ({\r\n id: business.id,\r\n name: business.name,\r\n verification_status: business.verification_status,\r\n })),\r\n metadata: {\r\n returned_businesses: result.businesses.length,\r\n pagination: {\r\n has_more: result.paging.has_more,\r\n next_after: result.paging.after,\r\n },\r\n note: result.paging.has_more\r\n ? \"Partial data. Use metadata.pagination.next_after to request the next page.\"\r\n : \"Complete data for the current token and page size.\",\r\n },\r\n })\r\n );\r\n } catch (err) {\r\n return error(err instanceof Error ? err.message : \"Failed to list accessible Meta businesses\");\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,oCAAoC;AAC7C,SAAS,kBAAkB;AAEpB,MAAM,qCAAqC,EAAE,OAAO;AAAA,EACzD,OAAO,EACJ,OAAO,EACP,SAAS,EACT,SAAS,4EAA4E;AAC1F,CAAC;AAED,eAAsB,oCACpB,QACA;AACA,MAAI;AACF,UAAM,SAAS,MAAM,6BAA6B,OAAO,KAAK;AAE9D,WAAO;AAAA,MACL,WAAW;AAAA,QACT,YAAY,OAAO,WAAW,IAAI,CAAC,cAAc;AAAA,UAC/C,IAAI,SAAS;AAAA,UACb,MAAM,SAAS;AAAA,UACf,qBAAqB,SAAS;AAAA,QAChC,EAAE;AAAA,QACF,UAAU;AAAA,UACR,qBAAqB,OAAO,WAAW;AAAA,UACvC,YAAY;AAAA,YACV,UAAU,OAAO,OAAO;AAAA,YACxB,YAAY,OAAO,OAAO;AAAA,UAC5B;AAAA,UACA,MAAM,OAAO,OAAO,WAChB,+EACA;AAAA,QACN;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,2CAA2C;AAAA,EAC/F;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/meta/placement-mix.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport {\n getMetaPlacementInsights,\n listAccessibleMetaAdAccounts,\n} from \"../../services/meta/meta-ads.js\";\nimport {\n dateRegex,\n getMetricBundle,\n normalizeRequestedAccountIds,\n resolveRequestedAccounts,\n} from \"../../meta/meta-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const metaPlacementMixSchema = 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 adAccountIds: z\n .array(z.string())\n .optional()\n .describe(\n \"Optional list of Meta ad account IDs. Accepts digits with or without the act_ prefix. If omitted, uses all accessible ad accounts.\"\n ),\n});\n\nexport async function metaPlacementMixHandler(\n params: z.infer<typeof metaPlacementMixSchema>\n) {\n try {\n const accessibleAccounts = (await listAccessibleMetaAdAccounts()).adAccounts;\n const requestedIds = normalizeRequestedAccountIds(params.adAccountIds);\n const accounts = resolveRequestedAccounts(requestedIds, accessibleAccounts);\n\n const results = await Promise.all(\n accounts.map(async (account) => {\n const rows = await getMetaPlacementInsights(account.account_id || \"\", {\n time_range: JSON.stringify({ since: params.startDate, until: params.endDate }),\n level: \"account\",\n breakdowns: \"publisher_platform,platform_position,impression_device\",\n });\n\n return {\n ad_account_id: account.account_id,\n account_name: account.name,\n currency_code: account.currency,\n placements: rows\n .map((row) => ({\n publisher_platform: row.publisher_platform,\n platform_position: row.platform_position,\n impression_device: row.impression_device,\n ...getMetricBundle(row),\n }))\n .sort((left, right) => right.spend - left.spend),\n };\n })\n );\n\n return object(\n stripNulls({\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n accounts: results,\n metadata: {\n analyzed_accounts: results.length,\n note:\n \"Placement mix is returned per ad account. Use this to compare Facebook, Instagram, and placement efficiency inside each account.\",\n },\n })\n );\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Failed to fetch Meta placement mix\");\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport {\r\n getMetaPlacementInsights,\r\n listAccessibleMetaAdAccounts,\r\n} from \"../../services/meta/meta-ads.js\";\r\nimport {\r\n dateRegex,\r\n getMetricBundle,\r\n normalizeRequestedAccountIds,\r\n resolveRequestedAccounts,\r\n} from \"../../meta/meta-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const metaPlacementMixSchema = z.object({\r\n startDate: z.string().regex(dateRegex).describe(\"Start date in YYYY-MM-DD format.\"),\r\n endDate: z.string().regex(dateRegex).describe(\"End date in YYYY-MM-DD format.\"),\r\n adAccountIds: z\r\n .array(z.string())\r\n .optional()\r\n .describe(\r\n \"Optional list of Meta ad account IDs. Accepts digits with or without the act_ prefix. If omitted, uses all accessible ad accounts.\"\r\n ),\r\n});\r\n\r\nexport async function metaPlacementMixHandler(\r\n params: z.infer<typeof metaPlacementMixSchema>\r\n) {\r\n try {\r\n const accessibleAccounts = (await listAccessibleMetaAdAccounts()).adAccounts;\r\n const requestedIds = normalizeRequestedAccountIds(params.adAccountIds);\r\n const accounts = resolveRequestedAccounts(requestedIds, accessibleAccounts);\r\n\r\n const results = await Promise.all(\r\n accounts.map(async (account) => {\r\n const rows = await getMetaPlacementInsights(account.account_id || \"\", {\r\n time_range: JSON.stringify({ since: params.startDate, until: params.endDate }),\r\n level: \"account\",\r\n breakdowns: \"publisher_platform,platform_position,impression_device\",\r\n });\r\n\r\n return {\r\n ad_account_id: account.account_id,\r\n account_name: account.name,\r\n currency_code: account.currency,\r\n placements: rows\r\n .map((row) => ({\r\n publisher_platform: row.publisher_platform,\r\n platform_position: row.platform_position,\r\n impression_device: row.impression_device,\r\n ...getMetricBundle(row),\r\n }))\r\n .sort((left, right) => right.spend - left.spend),\r\n };\r\n })\r\n );\r\n\r\n return object(\r\n stripNulls({\r\n date_range: {\r\n start_date: params.startDate,\r\n end_date: params.endDate,\r\n },\r\n accounts: results,\r\n metadata: {\r\n analyzed_accounts: results.length,\r\n note:\r\n \"Placement mix is returned per ad account. Use this to compare Facebook, Instagram, and placement efficiency inside each account.\",\r\n },\r\n })\r\n );\r\n } catch (err) {\r\n return error(err instanceof Error ? err.message : \"Failed to fetch Meta placement mix\");\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,yBAAyB,EAAE,OAAO;AAAA,EAC7C,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,kCAAkC;AAAA,EAClF,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,gCAAgC;AAAA,EAC9E,cAAc,EACX,MAAM,EAAE,OAAO,CAAC,EAChB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ,CAAC;AAED,eAAsB,wBACpB,QACA;AACA,MAAI;AACF,UAAM,sBAAsB,MAAM,6BAA6B,GAAG;AAClE,UAAM,eAAe,6BAA6B,OAAO,YAAY;AACrE,UAAM,WAAW,yBAAyB,cAAc,kBAAkB;AAE1E,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,SAAS,IAAI,OAAO,YAAY;AAC9B,cAAM,OAAO,MAAM,yBAAyB,QAAQ,cAAc,IAAI;AAAA,UACpE,YAAY,KAAK,UAAU,EAAE,OAAO,OAAO,WAAW,OAAO,OAAO,QAAQ,CAAC;AAAA,UAC7E,OAAO;AAAA,UACP,YAAY;AAAA,QACd,CAAC;AAED,eAAO;AAAA,UACL,eAAe,QAAQ;AAAA,UACvB,cAAc,QAAQ;AAAA,UACtB,eAAe,QAAQ;AAAA,UACvB,YAAY,KACT,IAAI,CAAC,SAAS;AAAA,YACb,oBAAoB,IAAI;AAAA,YACxB,mBAAmB,IAAI;AAAA,YACvB,mBAAmB,IAAI;AAAA,YACvB,GAAG,gBAAgB,GAAG;AAAA,UACxB,EAAE,EACD,KAAK,CAAC,MAAM,UAAU,MAAM,QAAQ,KAAK,KAAK;AAAA,QACnD;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,WAAW;AAAA,QACT,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,UAAU;AAAA,QACV,UAAU;AAAA,UACR,mBAAmB,QAAQ;AAAA,UAC3B,MACE;AAAA,QACJ;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,oCAAoC;AAAA,EACxF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/meta/time-series.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport {\n getMetaInsights,\n listAccessibleMetaAdAccounts,\n} from \"../../services/meta/meta-ads.js\";\nimport {\n dateRegex,\n getMetricBundle,\n normalizeRequestedAccountIds,\n resolveRequestedAccounts,\n} from \"../../meta/meta-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const metaTimeSeriesSchema = 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 adAccountIds: z\n .array(z.string())\n .optional()\n .describe(\n \"Optional list of Meta ad account IDs. Accepts digits with or without the act_ prefix. If omitted, uses all accessible ad accounts.\"\n ),\n timeIncrement: z\n .enum([\"1\", \"7\", \"monthly\"])\n .optional()\n .describe(\"Time increment for the series. Use 1 for daily, 7 for weekly, or monthly.\"),\n});\n\nexport async function metaTimeSeriesHandler(\n params: z.infer<typeof metaTimeSeriesSchema>\n) {\n try {\n const accessibleAccounts = (await listAccessibleMetaAdAccounts()).adAccounts;\n const requestedIds = normalizeRequestedAccountIds(params.adAccountIds);\n const accounts = resolveRequestedAccounts(requestedIds, accessibleAccounts);\n const timeIncrement = params.timeIncrement ?? \"1\";\n\n const results = await Promise.all(\n accounts.map(async (account) => {\n const rows = await getMetaInsights(`act_${account.account_id}`, {\n time_range: JSON.stringify({ since: params.startDate, until: params.endDate }),\n time_increment: timeIncrement,\n level: \"account\",\n });\n\n return {\n ad_account_id: account.account_id,\n account_name: account.name,\n currency_code: account.currency,\n series: rows.map((row) => ({\n date_start: row.date_start,\n date_stop: row.date_stop,\n ...getMetricBundle(row),\n })),\n };\n })\n );\n\n return object(\n stripNulls({\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n time_increment: timeIncrement,\n accounts: results,\n metadata: {\n analyzed_accounts: results.length,\n note: \"Time series are returned per ad account to preserve currency and account context.\",\n },\n })\n );\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Failed to fetch Meta time series\");\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport {\r\n getMetaInsights,\r\n listAccessibleMetaAdAccounts,\r\n} from \"../../services/meta/meta-ads.js\";\r\nimport {\r\n dateRegex,\r\n getMetricBundle,\r\n normalizeRequestedAccountIds,\r\n resolveRequestedAccounts,\r\n} from \"../../meta/meta-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const metaTimeSeriesSchema = z.object({\r\n startDate: z.string().regex(dateRegex).describe(\"Start date in YYYY-MM-DD format.\"),\r\n endDate: z.string().regex(dateRegex).describe(\"End date in YYYY-MM-DD format.\"),\r\n adAccountIds: z\r\n .array(z.string())\r\n .optional()\r\n .describe(\r\n \"Optional list of Meta ad account IDs. Accepts digits with or without the act_ prefix. If omitted, uses all accessible ad accounts.\"\r\n ),\r\n timeIncrement: z\r\n .enum([\"1\", \"7\", \"monthly\"])\r\n .optional()\r\n .describe(\"Time increment for the series. Use 1 for daily, 7 for weekly, or monthly.\"),\r\n});\r\n\r\nexport async function metaTimeSeriesHandler(\r\n params: z.infer<typeof metaTimeSeriesSchema>\r\n) {\r\n try {\r\n const accessibleAccounts = (await listAccessibleMetaAdAccounts()).adAccounts;\r\n const requestedIds = normalizeRequestedAccountIds(params.adAccountIds);\r\n const accounts = resolveRequestedAccounts(requestedIds, accessibleAccounts);\r\n const timeIncrement = params.timeIncrement ?? \"1\";\r\n\r\n const results = await Promise.all(\r\n accounts.map(async (account) => {\r\n const rows = await getMetaInsights(`act_${account.account_id}`, {\r\n time_range: JSON.stringify({ since: params.startDate, until: params.endDate }),\r\n time_increment: timeIncrement,\r\n level: \"account\",\r\n });\r\n\r\n return {\r\n ad_account_id: account.account_id,\r\n account_name: account.name,\r\n currency_code: account.currency,\r\n series: rows.map((row) => ({\r\n date_start: row.date_start,\r\n date_stop: row.date_stop,\r\n ...getMetricBundle(row),\r\n })),\r\n };\r\n })\r\n );\r\n\r\n return object(\r\n stripNulls({\r\n date_range: {\r\n start_date: params.startDate,\r\n end_date: params.endDate,\r\n },\r\n time_increment: timeIncrement,\r\n accounts: results,\r\n metadata: {\r\n analyzed_accounts: results.length,\r\n note: \"Time series are returned per ad account to preserve currency and account context.\",\r\n },\r\n })\r\n );\r\n } catch (err) {\r\n return error(err instanceof Error ? err.message : \"Failed to fetch Meta time series\");\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,kCAAkC;AAAA,EAClF,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,gCAAgC;AAAA,EAC9E,cAAc,EACX,MAAM,EAAE,OAAO,CAAC,EAChB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,eAAe,EACZ,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,EAC1B,SAAS,EACT,SAAS,2EAA2E;AACzF,CAAC;AAED,eAAsB,sBACpB,QACA;AACA,MAAI;AACF,UAAM,sBAAsB,MAAM,6BAA6B,GAAG;AAClE,UAAM,eAAe,6BAA6B,OAAO,YAAY;AACrE,UAAM,WAAW,yBAAyB,cAAc,kBAAkB;AAC1E,UAAM,gBAAgB,OAAO,iBAAiB;AAE9C,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,SAAS,IAAI,OAAO,YAAY;AAC9B,cAAM,OAAO,MAAM,gBAAgB,OAAO,QAAQ,UAAU,IAAI;AAAA,UAC9D,YAAY,KAAK,UAAU,EAAE,OAAO,OAAO,WAAW,OAAO,OAAO,QAAQ,CAAC;AAAA,UAC7E,gBAAgB;AAAA,UAChB,OAAO;AAAA,QACT,CAAC;AAED,eAAO;AAAA,UACL,eAAe,QAAQ;AAAA,UACvB,cAAc,QAAQ;AAAA,UACtB,eAAe,QAAQ;AAAA,UACvB,QAAQ,KAAK,IAAI,CAAC,SAAS;AAAA,YACzB,YAAY,IAAI;AAAA,YAChB,WAAW,IAAI;AAAA,YACf,GAAG,gBAAgB,GAAG;AAAA,UACxB,EAAE;AAAA,QACJ;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,WAAW;AAAA,QACT,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,gBAAgB;AAAA,QAChB,UAAU;AAAA,QACV,UAAU;AAAA,UACR,mBAAmB,QAAQ;AAAA,UAC3B,MAAM;AAAA,QACR;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,kCAAkC;AAAA,EACtF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/search-console/country-breakdown.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { querySearchConsolePerformance } from \"../../services/search-console/search-console-client.js\";\nimport {\n buildSearchConsoleQueryBody,\n endDateSchemaField,\n profileIdSchemaField,\n resolveSearchConsoleSiteUrl,\n searchTypeSchemaField,\n siteUrlSchemaField,\n startDateSchemaField,\n sumSearchConsoleRows,\n toPercent,\n normalizeSearchConsoleRow,\n round,\n} from \"../../services/search-console/search-console-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const searchConsoleCountryBreakdownSchema = z.object({\n startDate: startDateSchemaField,\n endDate: endDateSchemaField,\n siteUrl: siteUrlSchemaField,\n profileId: profileIdSchemaField,\n searchType: searchTypeSchemaField,\n queryContains: z.string().optional().describe(\"Optional query substring filter.\"),\n pageContains: z.string().optional().describe(\"Optional page substring filter.\"),\n});\n\nexport async function searchConsoleCountryBreakdownHandler(\n params: z.infer<typeof searchConsoleCountryBreakdownSchema>\n) {\n try {\n const siteUrl = await resolveSearchConsoleSiteUrl(params.siteUrl, params.profileId);\n const dimensionFilters = [];\n\n if (params.queryContains?.trim()) {\n dimensionFilters.push({\n dimension: \"query\",\n operator: \"contains\",\n expression: params.queryContains.trim(),\n });\n }\n\n if (params.pageContains?.trim()) {\n dimensionFilters.push({\n dimension: \"page\",\n operator: \"contains\",\n expression: params.pageContains.trim(),\n });\n }\n\n const response = await querySearchConsolePerformance(\n siteUrl,\n buildSearchConsoleQueryBody({\n startDate: params.startDate,\n endDate: params.endDate,\n dimensions: [\"country\"],\n searchType: params.searchType,\n dimensionFilters,\n })\n );\n\n const rows = (response.rows ?? []).map((row) => normalizeSearchConsoleRow(row, [\"country\"]));\n const totals = sumSearchConsoleRows(rows);\n\n return object(\n stripNulls({\n site_url: siteUrl,\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n country_breakdown: rows.map((row) => ({\n country: row.dimensions.country,\n clicks: row.clicks,\n impressions: row.impressions,\n ctr_percent: row.ctr_percent,\n position: row.position,\n impression_share_percent: round(toPercent(row.impressions, totals.impressions), 2),\n click_share_percent: round(toPercent(row.clicks, totals.clicks), 2),\n })),\n })\n );\n } catch (err) {\n return error(\n err instanceof Error ? err.message : \"Failed to fetch Search Console country breakdown\"\n );\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport { querySearchConsolePerformance } from \"../../services/search-console/search-console-client.js\";\r\nimport {\r\n buildSearchConsoleQueryBody,\r\n endDateSchemaField,\r\n profileIdSchemaField,\r\n resolveSearchConsoleSiteUrl,\r\n searchTypeSchemaField,\r\n siteUrlSchemaField,\r\n startDateSchemaField,\r\n sumSearchConsoleRows,\r\n toPercent,\r\n normalizeSearchConsoleRow,\r\n round,\r\n} from \"../../services/search-console/search-console-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const searchConsoleCountryBreakdownSchema = z.object({\r\n startDate: startDateSchemaField,\r\n endDate: endDateSchemaField,\r\n siteUrl: siteUrlSchemaField,\r\n profileId: profileIdSchemaField,\r\n searchType: searchTypeSchemaField,\r\n queryContains: z.string().optional().describe(\"Optional query substring filter.\"),\r\n pageContains: z.string().optional().describe(\"Optional page substring filter.\"),\r\n});\r\n\r\nexport async function searchConsoleCountryBreakdownHandler(\r\n params: z.infer<typeof searchConsoleCountryBreakdownSchema>\r\n) {\r\n try {\r\n const siteUrl = await resolveSearchConsoleSiteUrl(params.siteUrl, params.profileId);\r\n const dimensionFilters = [];\r\n\r\n if (params.queryContains?.trim()) {\r\n dimensionFilters.push({\r\n dimension: \"query\",\r\n operator: \"contains\",\r\n expression: params.queryContains.trim(),\r\n });\r\n }\r\n\r\n if (params.pageContains?.trim()) {\r\n dimensionFilters.push({\r\n dimension: \"page\",\r\n operator: \"contains\",\r\n expression: params.pageContains.trim(),\r\n });\r\n }\r\n\r\n const response = await querySearchConsolePerformance(\r\n siteUrl,\r\n buildSearchConsoleQueryBody({\r\n startDate: params.startDate,\r\n endDate: params.endDate,\r\n dimensions: [\"country\"],\r\n searchType: params.searchType,\r\n dimensionFilters,\r\n })\r\n );\r\n\r\n const rows = (response.rows ?? []).map((row) => normalizeSearchConsoleRow(row, [\"country\"]));\r\n const totals = sumSearchConsoleRows(rows);\r\n\r\n return object(\r\n stripNulls({\r\n site_url: siteUrl,\r\n date_range: {\r\n start_date: params.startDate,\r\n end_date: params.endDate,\r\n },\r\n country_breakdown: rows.map((row) => ({\r\n country: row.dimensions.country,\r\n clicks: row.clicks,\r\n impressions: row.impressions,\r\n ctr_percent: row.ctr_percent,\r\n position: row.position,\r\n impression_share_percent: round(toPercent(row.impressions, totals.impressions), 2),\r\n click_share_percent: round(toPercent(row.clicks, totals.clicks), 2),\r\n })),\r\n })\r\n );\r\n } catch (err) {\r\n return error(\r\n err instanceof Error ? err.message : \"Failed to fetch Search Console country breakdown\"\r\n );\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,qCAAqC;AAC9C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,sCAAsC,EAAE,OAAO;AAAA,EAC1D,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,EAChF,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAChF,CAAC;AAED,eAAsB,qCACpB,QACA;AACA,MAAI;AACF,UAAM,UAAU,MAAM,4BAA4B,OAAO,SAAS,OAAO,SAAS;AAClF,UAAM,mBAAmB,CAAC;AAE1B,QAAI,OAAO,eAAe,KAAK,GAAG;AAChC,uBAAiB,KAAK;AAAA,QACpB,WAAW;AAAA,QACX,UAAU;AAAA,QACV,YAAY,OAAO,cAAc,KAAK;AAAA,MACxC,CAAC;AAAA,IACH;AAEA,QAAI,OAAO,cAAc,KAAK,GAAG;AAC/B,uBAAiB,KAAK;AAAA,QACpB,WAAW;AAAA,QACX,UAAU;AAAA,QACV,YAAY,OAAO,aAAa,KAAK;AAAA,MACvC,CAAC;AAAA,IACH;AAEA,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,MACA,4BAA4B;AAAA,QAC1B,WAAW,OAAO;AAAA,QAClB,SAAS,OAAO;AAAA,QAChB,YAAY,CAAC,SAAS;AAAA,QACtB,YAAY,OAAO;AAAA,QACnB;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,QAAQ,SAAS,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,0BAA0B,KAAK,CAAC,SAAS,CAAC,CAAC;AAC3F,UAAM,SAAS,qBAAqB,IAAI;AAExC,WAAO;AAAA,MACL,WAAW;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,mBAAmB,KAAK,IAAI,CAAC,SAAS;AAAA,UACpC,SAAS,IAAI,WAAW;AAAA,UACxB,QAAQ,IAAI;AAAA,UACZ,aAAa,IAAI;AAAA,UACjB,aAAa,IAAI;AAAA,UACjB,UAAU,IAAI;AAAA,UACd,0BAA0B,MAAM,UAAU,IAAI,aAAa,OAAO,WAAW,GAAG,CAAC;AAAA,UACjF,qBAAqB,MAAM,UAAU,IAAI,QAAQ,OAAO,MAAM,GAAG,CAAC;AAAA,QACpE,EAAE;AAAA,MACJ,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,eAAe,QAAQ,IAAI,UAAU;AAAA,IACvC;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/search-console/device-breakdown.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { querySearchConsolePerformance } from \"../../services/search-console/search-console-client.js\";\nimport {\n buildSearchConsoleQueryBody,\n endDateSchemaField,\n profileIdSchemaField,\n resolveSearchConsoleSiteUrl,\n searchTypeSchemaField,\n siteUrlSchemaField,\n startDateSchemaField,\n sumSearchConsoleRows,\n toPercent,\n normalizeSearchConsoleRow,\n round,\n} from \"../../services/search-console/search-console-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const searchConsoleDeviceBreakdownSchema = z.object({\n startDate: startDateSchemaField,\n endDate: endDateSchemaField,\n siteUrl: siteUrlSchemaField,\n profileId: profileIdSchemaField,\n searchType: searchTypeSchemaField,\n queryContains: z.string().optional().describe(\"Optional query substring filter.\"),\n pageContains: z.string().optional().describe(\"Optional page substring filter.\"),\n});\n\nexport async function searchConsoleDeviceBreakdownHandler(\n params: z.infer<typeof searchConsoleDeviceBreakdownSchema>\n) {\n try {\n const siteUrl = await resolveSearchConsoleSiteUrl(params.siteUrl, params.profileId);\n const dimensionFilters = [];\n\n if (params.queryContains?.trim()) {\n dimensionFilters.push({\n dimension: \"query\",\n operator: \"contains\",\n expression: params.queryContains.trim(),\n });\n }\n\n if (params.pageContains?.trim()) {\n dimensionFilters.push({\n dimension: \"page\",\n operator: \"contains\",\n expression: params.pageContains.trim(),\n });\n }\n\n const response = await querySearchConsolePerformance(\n siteUrl,\n buildSearchConsoleQueryBody({\n startDate: params.startDate,\n endDate: params.endDate,\n dimensions: [\"device\"],\n searchType: params.searchType,\n dimensionFilters,\n })\n );\n\n const rows = (response.rows ?? []).map((row) => normalizeSearchConsoleRow(row, [\"device\"]));\n const totals = sumSearchConsoleRows(rows);\n\n return object(\n stripNulls({\n site_url: siteUrl,\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n device_breakdown: rows.map((row) => ({\n device: row.dimensions.device,\n clicks: row.clicks,\n impressions: row.impressions,\n ctr_percent: row.ctr_percent,\n position: row.position,\n impression_share_percent: round(toPercent(row.impressions, totals.impressions), 2),\n click_share_percent: round(toPercent(row.clicks, totals.clicks), 2),\n })),\n })\n );\n } catch (err) {\n return error(\n err instanceof Error ? err.message : \"Failed to fetch Search Console device breakdown\"\n );\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport { querySearchConsolePerformance } from \"../../services/search-console/search-console-client.js\";\r\nimport {\r\n buildSearchConsoleQueryBody,\r\n endDateSchemaField,\r\n profileIdSchemaField,\r\n resolveSearchConsoleSiteUrl,\r\n searchTypeSchemaField,\r\n siteUrlSchemaField,\r\n startDateSchemaField,\r\n sumSearchConsoleRows,\r\n toPercent,\r\n normalizeSearchConsoleRow,\r\n round,\r\n} from \"../../services/search-console/search-console-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const searchConsoleDeviceBreakdownSchema = z.object({\r\n startDate: startDateSchemaField,\r\n endDate: endDateSchemaField,\r\n siteUrl: siteUrlSchemaField,\r\n profileId: profileIdSchemaField,\r\n searchType: searchTypeSchemaField,\r\n queryContains: z.string().optional().describe(\"Optional query substring filter.\"),\r\n pageContains: z.string().optional().describe(\"Optional page substring filter.\"),\r\n});\r\n\r\nexport async function searchConsoleDeviceBreakdownHandler(\r\n params: z.infer<typeof searchConsoleDeviceBreakdownSchema>\r\n) {\r\n try {\r\n const siteUrl = await resolveSearchConsoleSiteUrl(params.siteUrl, params.profileId);\r\n const dimensionFilters = [];\r\n\r\n if (params.queryContains?.trim()) {\r\n dimensionFilters.push({\r\n dimension: \"query\",\r\n operator: \"contains\",\r\n expression: params.queryContains.trim(),\r\n });\r\n }\r\n\r\n if (params.pageContains?.trim()) {\r\n dimensionFilters.push({\r\n dimension: \"page\",\r\n operator: \"contains\",\r\n expression: params.pageContains.trim(),\r\n });\r\n }\r\n\r\n const response = await querySearchConsolePerformance(\r\n siteUrl,\r\n buildSearchConsoleQueryBody({\r\n startDate: params.startDate,\r\n endDate: params.endDate,\r\n dimensions: [\"device\"],\r\n searchType: params.searchType,\r\n dimensionFilters,\r\n })\r\n );\r\n\r\n const rows = (response.rows ?? []).map((row) => normalizeSearchConsoleRow(row, [\"device\"]));\r\n const totals = sumSearchConsoleRows(rows);\r\n\r\n return object(\r\n stripNulls({\r\n site_url: siteUrl,\r\n date_range: {\r\n start_date: params.startDate,\r\n end_date: params.endDate,\r\n },\r\n device_breakdown: rows.map((row) => ({\r\n device: row.dimensions.device,\r\n clicks: row.clicks,\r\n impressions: row.impressions,\r\n ctr_percent: row.ctr_percent,\r\n position: row.position,\r\n impression_share_percent: round(toPercent(row.impressions, totals.impressions), 2),\r\n click_share_percent: round(toPercent(row.clicks, totals.clicks), 2),\r\n })),\r\n })\r\n );\r\n } catch (err) {\r\n return error(\r\n err instanceof Error ? err.message : \"Failed to fetch Search Console device breakdown\"\r\n );\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,qCAAqC;AAC9C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,qCAAqC,EAAE,OAAO;AAAA,EACzD,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,EAChF,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAChF,CAAC;AAED,eAAsB,oCACpB,QACA;AACA,MAAI;AACF,UAAM,UAAU,MAAM,4BAA4B,OAAO,SAAS,OAAO,SAAS;AAClF,UAAM,mBAAmB,CAAC;AAE1B,QAAI,OAAO,eAAe,KAAK,GAAG;AAChC,uBAAiB,KAAK;AAAA,QACpB,WAAW;AAAA,QACX,UAAU;AAAA,QACV,YAAY,OAAO,cAAc,KAAK;AAAA,MACxC,CAAC;AAAA,IACH;AAEA,QAAI,OAAO,cAAc,KAAK,GAAG;AAC/B,uBAAiB,KAAK;AAAA,QACpB,WAAW;AAAA,QACX,UAAU;AAAA,QACV,YAAY,OAAO,aAAa,KAAK;AAAA,MACvC,CAAC;AAAA,IACH;AAEA,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,MACA,4BAA4B;AAAA,QAC1B,WAAW,OAAO;AAAA,QAClB,SAAS,OAAO;AAAA,QAChB,YAAY,CAAC,QAAQ;AAAA,QACrB,YAAY,OAAO;AAAA,QACnB;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,QAAQ,SAAS,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,0BAA0B,KAAK,CAAC,QAAQ,CAAC,CAAC;AAC1F,UAAM,SAAS,qBAAqB,IAAI;AAExC,WAAO;AAAA,MACL,WAAW;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,kBAAkB,KAAK,IAAI,CAAC,SAAS;AAAA,UACnC,QAAQ,IAAI,WAAW;AAAA,UACvB,QAAQ,IAAI;AAAA,UACZ,aAAa,IAAI;AAAA,UACjB,aAAa,IAAI;AAAA,UACjB,UAAU,IAAI;AAAA,UACd,0BAA0B,MAAM,UAAU,IAAI,aAAa,OAAO,WAAW,GAAG,CAAC;AAAA,UACjF,qBAAqB,MAAM,UAAU,IAAI,QAAQ,OAAO,MAAM,GAAG,CAAC;AAAA,QACpE,EAAE;AAAA,MACJ,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,eAAe,QAAQ,IAAI,UAAU;AAAA,IACvC;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/search-console/high-impression-low-click-queries.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { querySearchConsolePerformance } from \"../../services/search-console/search-console-client.js\";\nimport {\n brandTermsSchemaField,\n buildSearchConsoleQueryBody,\n classifyBrandLabel,\n endDateSchemaField,\n profileIdSchemaField,\n resolveSearchConsoleSiteUrl,\n rowLimitSchemaField,\n scoreHighImpressionLowClickOpportunity,\n searchTypeSchemaField,\n siteUrlSchemaField,\n startDateSchemaField,\n normalizeSearchConsoleRow,\n} from \"../../services/search-console/search-console-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const searchConsoleHighImpressionLowClickQueriesSchema = z.object({\n startDate: startDateSchemaField,\n endDate: endDateSchemaField,\n siteUrl: siteUrlSchemaField,\n profileId: profileIdSchemaField,\n searchType: searchTypeSchemaField,\n brandTerms: brandTermsSchemaField,\n includeBrand: z\n .enum([\"all\", \"only_brand\", \"only_non_brand\"])\n .optional()\n .describe(\"How to filter the query list when brandTerms are provided.\"),\n minImpressions: z\n .number()\n .min(1)\n .optional()\n .describe(\"Minimum impressions required to consider a query an opportunity.\"),\n maxCtr: z\n .number()\n .min(0)\n .max(100)\n .optional()\n .describe(\"Maximum CTR percentage allowed to count as low capture.\"),\n rowLimit: rowLimitSchemaField,\n});\n\nexport async function searchConsoleHighImpressionLowClickQueriesHandler(\n params: z.infer<typeof searchConsoleHighImpressionLowClickQueriesSchema>\n) {\n try {\n const siteUrl = await resolveSearchConsoleSiteUrl(params.siteUrl, params.profileId);\n const minImpressions = params.minImpressions ?? 100;\n const maxCtr = params.maxCtr ?? 3;\n const includeBrand = params.includeBrand ?? \"all\";\n const response = await querySearchConsolePerformance(\n siteUrl,\n buildSearchConsoleQueryBody({\n startDate: params.startDate,\n endDate: params.endDate,\n dimensions: [\"query\"],\n searchType: params.searchType,\n rowLimit: params.rowLimit ?? 250,\n })\n );\n\n const opportunities = (response.rows ?? [])\n .map((row) => normalizeSearchConsoleRow(row, [\"query\"]))\n .map((row) => ({\n query: row.dimensions.query,\n clicks: row.clicks,\n impressions: row.impressions,\n ctr_percent: row.ctr_percent,\n position: row.position,\n brand_classification: classifyBrandLabel(row.dimensions.query, params.brandTerms),\n }))\n .filter((row) => row.impressions >= minImpressions && row.ctr_percent <= maxCtr)\n .filter((row) => {\n if (includeBrand === \"only_brand\") {\n return row.brand_classification === \"brand\";\n }\n\n if (includeBrand === \"only_non_brand\") {\n return row.brand_classification === \"non_brand\";\n }\n\n return true;\n })\n .map((row) => ({\n ...row,\n opportunity_score: scoreHighImpressionLowClickOpportunity({\n impressions: row.impressions,\n ctrPercent: row.ctr_percent,\n position: row.position,\n }),\n reason: \"High impression volume with low click capture.\",\n }))\n .sort((left, right) => right.opportunity_score - left.opportunity_score);\n\n return object(\n stripNulls({\n site_url: siteUrl,\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n thresholds: {\n min_impressions: minImpressions,\n max_ctr_percent: maxCtr,\n },\n opportunities,\n })\n );\n } catch (err) {\n return error(\n err instanceof Error\n ? err.message\n : \"Failed to find Search Console high-impression low-click queries\"\n );\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport { querySearchConsolePerformance } from \"../../services/search-console/search-console-client.js\";\r\nimport {\r\n brandTermsSchemaField,\r\n buildSearchConsoleQueryBody,\r\n classifyBrandLabel,\r\n endDateSchemaField,\r\n profileIdSchemaField,\r\n resolveSearchConsoleSiteUrl,\r\n rowLimitSchemaField,\r\n scoreHighImpressionLowClickOpportunity,\r\n searchTypeSchemaField,\r\n siteUrlSchemaField,\r\n startDateSchemaField,\r\n normalizeSearchConsoleRow,\r\n} from \"../../services/search-console/search-console-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const searchConsoleHighImpressionLowClickQueriesSchema = z.object({\r\n startDate: startDateSchemaField,\r\n endDate: endDateSchemaField,\r\n siteUrl: siteUrlSchemaField,\r\n profileId: profileIdSchemaField,\r\n searchType: searchTypeSchemaField,\r\n brandTerms: brandTermsSchemaField,\r\n includeBrand: z\r\n .enum([\"all\", \"only_brand\", \"only_non_brand\"])\r\n .optional()\r\n .describe(\"How to filter the query list when brandTerms are provided.\"),\r\n minImpressions: z\r\n .number()\r\n .min(1)\r\n .optional()\r\n .describe(\"Minimum impressions required to consider a query an opportunity.\"),\r\n maxCtr: z\r\n .number()\r\n .min(0)\r\n .max(100)\r\n .optional()\r\n .describe(\"Maximum CTR percentage allowed to count as low capture.\"),\r\n rowLimit: rowLimitSchemaField,\r\n});\r\n\r\nexport async function searchConsoleHighImpressionLowClickQueriesHandler(\r\n params: z.infer<typeof searchConsoleHighImpressionLowClickQueriesSchema>\r\n) {\r\n try {\r\n const siteUrl = await resolveSearchConsoleSiteUrl(params.siteUrl, params.profileId);\r\n const minImpressions = params.minImpressions ?? 100;\r\n const maxCtr = params.maxCtr ?? 3;\r\n const includeBrand = params.includeBrand ?? \"all\";\r\n const response = await querySearchConsolePerformance(\r\n siteUrl,\r\n buildSearchConsoleQueryBody({\r\n startDate: params.startDate,\r\n endDate: params.endDate,\r\n dimensions: [\"query\"],\r\n searchType: params.searchType,\r\n rowLimit: params.rowLimit ?? 250,\r\n })\r\n );\r\n\r\n const opportunities = (response.rows ?? [])\r\n .map((row) => normalizeSearchConsoleRow(row, [\"query\"]))\r\n .map((row) => ({\r\n query: row.dimensions.query,\r\n clicks: row.clicks,\r\n impressions: row.impressions,\r\n ctr_percent: row.ctr_percent,\r\n position: row.position,\r\n brand_classification: classifyBrandLabel(row.dimensions.query, params.brandTerms),\r\n }))\r\n .filter((row) => row.impressions >= minImpressions && row.ctr_percent <= maxCtr)\r\n .filter((row) => {\r\n if (includeBrand === \"only_brand\") {\r\n return row.brand_classification === \"brand\";\r\n }\r\n\r\n if (includeBrand === \"only_non_brand\") {\r\n return row.brand_classification === \"non_brand\";\r\n }\r\n\r\n return true;\r\n })\r\n .map((row) => ({\r\n ...row,\r\n opportunity_score: scoreHighImpressionLowClickOpportunity({\r\n impressions: row.impressions,\r\n ctrPercent: row.ctr_percent,\r\n position: row.position,\r\n }),\r\n reason: \"High impression volume with low click capture.\",\r\n }))\r\n .sort((left, right) => right.opportunity_score - left.opportunity_score);\r\n\r\n return object(\r\n stripNulls({\r\n site_url: siteUrl,\r\n date_range: {\r\n start_date: params.startDate,\r\n end_date: params.endDate,\r\n },\r\n thresholds: {\r\n min_impressions: minImpressions,\r\n max_ctr_percent: maxCtr,\r\n },\r\n opportunities,\r\n })\r\n );\r\n } catch (err) {\r\n return error(\r\n err instanceof Error\r\n ? err.message\r\n : \"Failed to find Search Console high-impression low-click queries\"\r\n );\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,qCAAqC;AAC9C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,mDAAmD,EAAE,OAAO;AAAA,EACvE,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,cAAc,EACX,KAAK,CAAC,OAAO,cAAc,gBAAgB,CAAC,EAC5C,SAAS,EACT,SAAS,4DAA4D;AAAA,EACxE,gBAAgB,EACb,OAAO,EACP,IAAI,CAAC,EACL,SAAS,EACT,SAAS,kEAAkE;AAAA,EAC9E,QAAQ,EACL,OAAO,EACP,IAAI,CAAC,EACL,IAAI,GAAG,EACP,SAAS,EACT,SAAS,yDAAyD;AAAA,EACrE,UAAU;AACZ,CAAC;AAED,eAAsB,kDACpB,QACA;AACA,MAAI;AACF,UAAM,UAAU,MAAM,4BAA4B,OAAO,SAAS,OAAO,SAAS;AAClF,UAAM,iBAAiB,OAAO,kBAAkB;AAChD,UAAM,SAAS,OAAO,UAAU;AAChC,UAAM,eAAe,OAAO,gBAAgB;AAC5C,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,MACA,4BAA4B;AAAA,QAC1B,WAAW,OAAO;AAAA,QAClB,SAAS,OAAO;AAAA,QAChB,YAAY,CAAC,OAAO;AAAA,QACpB,YAAY,OAAO;AAAA,QACnB,UAAU,OAAO,YAAY;AAAA,MAC/B,CAAC;AAAA,IACH;AAEA,UAAM,iBAAiB,SAAS,QAAQ,CAAC,GACtC,IAAI,CAAC,QAAQ,0BAA0B,KAAK,CAAC,OAAO,CAAC,CAAC,EACtD,IAAI,CAAC,SAAS;AAAA,MACb,OAAO,IAAI,WAAW;AAAA,MACtB,QAAQ,IAAI;AAAA,MACZ,aAAa,IAAI;AAAA,MACjB,aAAa,IAAI;AAAA,MACjB,UAAU,IAAI;AAAA,MACd,sBAAsB,mBAAmB,IAAI,WAAW,OAAO,OAAO,UAAU;AAAA,IAClF,EAAE,EACD,OAAO,CAAC,QAAQ,IAAI,eAAe,kBAAkB,IAAI,eAAe,MAAM,EAC9E,OAAO,CAAC,QAAQ;AACf,UAAI,iBAAiB,cAAc;AACjC,eAAO,IAAI,yBAAyB;AAAA,MACtC;AAEA,UAAI,iBAAiB,kBAAkB;AACrC,eAAO,IAAI,yBAAyB;AAAA,MACtC;AAEA,aAAO;AAAA,IACT,CAAC,EACA,IAAI,CAAC,SAAS;AAAA,MACb,GAAG;AAAA,MACH,mBAAmB,uCAAuC;AAAA,QACxD,aAAa,IAAI;AAAA,QACjB,YAAY,IAAI;AAAA,QAChB,UAAU,IAAI;AAAA,MAChB,CAAC;AAAA,MACD,QAAQ;AAAA,IACV,EAAE,EACD,KAAK,CAAC,MAAM,UAAU,MAAM,oBAAoB,KAAK,iBAAiB;AAEzE,WAAO;AAAA,MACL,WAAW;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,YAAY;AAAA,UACV,iBAAiB;AAAA,UACjB,iBAAiB;AAAA,QACnB;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,eAAe,QACX,IAAI,UACJ;AAAA,IACN;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/search-console/index.ts"],
|
|
4
|
-
"sourcesContent": ["export * from \"./list-accessible-sites.js\";\nexport * from \"./site-context.js\";\nexport * from \"./search-performance.js\";\nexport * from \"./query-performance.js\";\nexport * from \"./page-performance.js\";\nexport * from \"./query-page-matrix.js\";\nexport * from \"./device-breakdown.js\";\nexport * from \"./country-breakdown.js\";\nexport * from \"./high-impression-low-click-queries.js\";\nexport * from \"./low-ctr-opportunities.js\";\nexport * from \"./visibility-declines.js\";\nexport * from \"./product-demand-low-capture-queries.js\";\nexport * from \"./rising-non-brand-queries.js\";\nexport * from \"./quick-win-opportunities.js\";\n"],
|
|
4
|
+
"sourcesContent": ["export * from \"./list-accessible-sites.js\";\r\nexport * from \"./site-context.js\";\r\nexport * from \"./search-performance.js\";\r\nexport * from \"./query-performance.js\";\r\nexport * from \"./page-performance.js\";\r\nexport * from \"./query-page-matrix.js\";\r\nexport * from \"./device-breakdown.js\";\r\nexport * from \"./country-breakdown.js\";\r\nexport * from \"./high-impression-low-click-queries.js\";\r\nexport * from \"./low-ctr-opportunities.js\";\r\nexport * from \"./visibility-declines.js\";\r\nexport * from \"./product-demand-low-capture-queries.js\";\r\nexport * from \"./rising-non-brand-queries.js\";\r\nexport * from \"./quick-win-opportunities.js\";\r\n"],
|
|
5
5
|
"mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/search-console/list-accessible-sites.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { listSearchConsoleSites } from \"../../services/search-console/search-console-client.js\";\nimport {\n inferSearchConsolePropertyType,\n normalizePermissionLevel,\n normalizeSearchConsoleSiteEntry,\n} from \"../../services/search-console/search-console-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const listAccessibleSitesSchema = z.object({});\n\nexport async function listAccessibleSitesHandler(\n _params: z.infer<typeof listAccessibleSitesSchema>\n) {\n try {\n const sites = await listSearchConsoleSites();\n const normalizedSites = sites\n .map(normalizeSearchConsoleSiteEntry)\n .sort((left, right) => left.site_url.localeCompare(right.site_url));\n\n const preferredDomainProperty = normalizedSites.find(\n (site) =>\n site.property_type === \"domain\" &&\n (site.permission_level === \"siteowner\" || site.permission_level === \"owner\")\n );\n\n return object(\n stripNulls({\n total_sites: normalizedSites.length,\n recommended_default_site_url: preferredDomainProperty?.site_url ?? normalizedSites[0]?.site_url,\n sites: normalizedSites,\n summary: {\n domain_properties: normalizedSites.filter((site) => site.property_type === \"domain\").length,\n url_prefix_properties: normalizedSites.filter((site) => site.property_type === \"url_prefix\").length,\n owner_level_sites: sites.filter((site) => {\n const permissionLevel = normalizePermissionLevel(site.permissionLevel);\n return permissionLevel === \"owner\" || permissionLevel === \"siteowner\";\n }).length,\n },\n })\n );\n } catch (err) {\n return error(\n err instanceof Error ? err.message : \"Failed to list accessible Search Console sites\"\n );\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport { listSearchConsoleSites } from \"../../services/search-console/search-console-client.js\";\r\nimport {\r\n inferSearchConsolePropertyType,\r\n normalizePermissionLevel,\r\n normalizeSearchConsoleSiteEntry,\r\n} from \"../../services/search-console/search-console-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const listAccessibleSitesSchema = z.object({});\r\n\r\nexport async function listAccessibleSitesHandler(\r\n _params: z.infer<typeof listAccessibleSitesSchema>\r\n) {\r\n try {\r\n const sites = await listSearchConsoleSites();\r\n const normalizedSites = sites\r\n .map(normalizeSearchConsoleSiteEntry)\r\n .sort((left, right) => left.site_url.localeCompare(right.site_url));\r\n\r\n const preferredDomainProperty = normalizedSites.find(\r\n (site) =>\r\n site.property_type === \"domain\" &&\r\n (site.permission_level === \"siteowner\" || site.permission_level === \"owner\")\r\n );\r\n\r\n return object(\r\n stripNulls({\r\n total_sites: normalizedSites.length,\r\n recommended_default_site_url: preferredDomainProperty?.site_url ?? normalizedSites[0]?.site_url,\r\n sites: normalizedSites,\r\n summary: {\r\n domain_properties: normalizedSites.filter((site) => site.property_type === \"domain\").length,\r\n url_prefix_properties: normalizedSites.filter((site) => site.property_type === \"url_prefix\").length,\r\n owner_level_sites: sites.filter((site) => {\r\n const permissionLevel = normalizePermissionLevel(site.permissionLevel);\r\n return permissionLevel === \"owner\" || permissionLevel === \"siteowner\";\r\n }).length,\r\n },\r\n })\r\n );\r\n } catch (err) {\r\n return error(\r\n err instanceof Error ? err.message : \"Failed to list accessible Search Console sites\"\r\n );\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,8BAA8B;AACvC;AAAA,EAEE;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,4BAA4B,EAAE,OAAO,CAAC,CAAC;AAEpD,eAAsB,2BACpB,SACA;AACA,MAAI;AACF,UAAM,QAAQ,MAAM,uBAAuB;AAC3C,UAAM,kBAAkB,MACrB,IAAI,+BAA+B,EACnC,KAAK,CAAC,MAAM,UAAU,KAAK,SAAS,cAAc,MAAM,QAAQ,CAAC;AAEpE,UAAM,0BAA0B,gBAAgB;AAAA,MAC9C,CAAC,SACC,KAAK,kBAAkB,aACtB,KAAK,qBAAqB,eAAe,KAAK,qBAAqB;AAAA,IACxE;AAEA,WAAO;AAAA,MACL,WAAW;AAAA,QACT,aAAa,gBAAgB;AAAA,QAC7B,8BAA8B,yBAAyB,YAAY,gBAAgB,CAAC,GAAG;AAAA,QACvF,OAAO;AAAA,QACP,SAAS;AAAA,UACP,mBAAmB,gBAAgB,OAAO,CAAC,SAAS,KAAK,kBAAkB,QAAQ,EAAE;AAAA,UACrF,uBAAuB,gBAAgB,OAAO,CAAC,SAAS,KAAK,kBAAkB,YAAY,EAAE;AAAA,UAC7F,mBAAmB,MAAM,OAAO,CAAC,SAAS;AACxC,kBAAM,kBAAkB,yBAAyB,KAAK,eAAe;AACrE,mBAAO,oBAAoB,WAAW,oBAAoB;AAAA,UAC5D,CAAC,EAAE;AAAA,QACL;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,eAAe,QAAQ,IAAI,UAAU;AAAA,IACvC;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/search-console/low-ctr-opportunities.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { querySearchConsolePerformance } from \"../../services/search-console/search-console-client.js\";\nimport {\n brandTermsSchemaField,\n buildSearchConsoleQueryBody,\n classifyBrandLabel,\n endDateSchemaField,\n profileIdSchemaField,\n resolveSearchConsoleSiteUrl,\n scoreQuickWinOpportunity,\n searchTypeSchemaField,\n siteUrlSchemaField,\n startDateSchemaField,\n normalizeSearchConsoleRow,\n} from \"../../services/search-console/search-console-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const searchConsoleLowCtrOpportunitiesSchema = z.object({\n startDate: startDateSchemaField,\n endDate: endDateSchemaField,\n siteUrl: siteUrlSchemaField,\n profileId: profileIdSchemaField,\n searchType: searchTypeSchemaField,\n brandTerms: brandTermsSchemaField,\n includeBrand: z\n .enum([\"all\", \"only_brand\", \"only_non_brand\"])\n .optional()\n .describe(\"How to filter the query list when brandTerms are provided.\"),\n minImpressions: z\n .number()\n .min(1)\n .optional()\n .describe(\"Minimum impressions required to consider a CTR opportunity.\"),\n maxCtr: z\n .number()\n .min(0)\n .max(100)\n .optional()\n .describe(\"Maximum CTR percentage allowed to count as underperforming.\"),\n maxPosition: z\n .number()\n .min(1)\n .max(100)\n .optional()\n .describe(\"Maximum average position to keep only queries that already rank reasonably well.\"),\n});\n\nexport async function searchConsoleLowCtrOpportunitiesHandler(\n params: z.infer<typeof searchConsoleLowCtrOpportunitiesSchema>\n) {\n try {\n const siteUrl = await resolveSearchConsoleSiteUrl(params.siteUrl, params.profileId);\n const minImpressions = params.minImpressions ?? 100;\n const maxCtr = params.maxCtr ?? 4;\n const maxPosition = params.maxPosition ?? 10;\n const includeBrand = params.includeBrand ?? \"all\";\n\n const response = await querySearchConsolePerformance(\n siteUrl,\n buildSearchConsoleQueryBody({\n startDate: params.startDate,\n endDate: params.endDate,\n dimensions: [\"query\"],\n searchType: params.searchType,\n rowLimit: 250,\n })\n );\n\n const opportunities = (response.rows ?? [])\n .map((row) => normalizeSearchConsoleRow(row, [\"query\"]))\n .map((row) => ({\n query: row.dimensions.query,\n clicks: row.clicks,\n impressions: row.impressions,\n ctr_percent: row.ctr_percent,\n position: row.position,\n brand_classification: classifyBrandLabel(row.dimensions.query, params.brandTerms),\n }))\n .filter(\n (row) =>\n row.impressions >= minImpressions &&\n row.ctr_percent <= maxCtr &&\n row.position > 0 &&\n row.position <= maxPosition\n )\n .filter((row) => {\n if (includeBrand === \"only_brand\") {\n return row.brand_classification === \"brand\";\n }\n\n if (includeBrand === \"only_non_brand\") {\n return row.brand_classification === \"non_brand\";\n }\n\n return true;\n })\n .map((row) => ({\n ...row,\n opportunity_score: scoreQuickWinOpportunity({\n impressions: row.impressions,\n ctrPercent: row.ctr_percent,\n position: row.position,\n }),\n reason: \"Ranking is already acceptable, so low CTR suggests snippet or title optimization potential.\",\n }))\n .sort((left, right) => right.opportunity_score - left.opportunity_score);\n\n return object(\n stripNulls({\n site_url: siteUrl,\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n thresholds: {\n min_impressions: minImpressions,\n max_ctr_percent: maxCtr,\n max_position: maxPosition,\n },\n opportunities,\n })\n );\n } catch (err) {\n return error(\n err instanceof Error ? err.message : \"Failed to find Search Console low-CTR opportunities\"\n );\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport { querySearchConsolePerformance } from \"../../services/search-console/search-console-client.js\";\r\nimport {\r\n brandTermsSchemaField,\r\n buildSearchConsoleQueryBody,\r\n classifyBrandLabel,\r\n endDateSchemaField,\r\n profileIdSchemaField,\r\n resolveSearchConsoleSiteUrl,\r\n scoreQuickWinOpportunity,\r\n searchTypeSchemaField,\r\n siteUrlSchemaField,\r\n startDateSchemaField,\r\n normalizeSearchConsoleRow,\r\n} from \"../../services/search-console/search-console-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const searchConsoleLowCtrOpportunitiesSchema = z.object({\r\n startDate: startDateSchemaField,\r\n endDate: endDateSchemaField,\r\n siteUrl: siteUrlSchemaField,\r\n profileId: profileIdSchemaField,\r\n searchType: searchTypeSchemaField,\r\n brandTerms: brandTermsSchemaField,\r\n includeBrand: z\r\n .enum([\"all\", \"only_brand\", \"only_non_brand\"])\r\n .optional()\r\n .describe(\"How to filter the query list when brandTerms are provided.\"),\r\n minImpressions: z\r\n .number()\r\n .min(1)\r\n .optional()\r\n .describe(\"Minimum impressions required to consider a CTR opportunity.\"),\r\n maxCtr: z\r\n .number()\r\n .min(0)\r\n .max(100)\r\n .optional()\r\n .describe(\"Maximum CTR percentage allowed to count as underperforming.\"),\r\n maxPosition: z\r\n .number()\r\n .min(1)\r\n .max(100)\r\n .optional()\r\n .describe(\"Maximum average position to keep only queries that already rank reasonably well.\"),\r\n});\r\n\r\nexport async function searchConsoleLowCtrOpportunitiesHandler(\r\n params: z.infer<typeof searchConsoleLowCtrOpportunitiesSchema>\r\n) {\r\n try {\r\n const siteUrl = await resolveSearchConsoleSiteUrl(params.siteUrl, params.profileId);\r\n const minImpressions = params.minImpressions ?? 100;\r\n const maxCtr = params.maxCtr ?? 4;\r\n const maxPosition = params.maxPosition ?? 10;\r\n const includeBrand = params.includeBrand ?? \"all\";\r\n\r\n const response = await querySearchConsolePerformance(\r\n siteUrl,\r\n buildSearchConsoleQueryBody({\r\n startDate: params.startDate,\r\n endDate: params.endDate,\r\n dimensions: [\"query\"],\r\n searchType: params.searchType,\r\n rowLimit: 250,\r\n })\r\n );\r\n\r\n const opportunities = (response.rows ?? [])\r\n .map((row) => normalizeSearchConsoleRow(row, [\"query\"]))\r\n .map((row) => ({\r\n query: row.dimensions.query,\r\n clicks: row.clicks,\r\n impressions: row.impressions,\r\n ctr_percent: row.ctr_percent,\r\n position: row.position,\r\n brand_classification: classifyBrandLabel(row.dimensions.query, params.brandTerms),\r\n }))\r\n .filter(\r\n (row) =>\r\n row.impressions >= minImpressions &&\r\n row.ctr_percent <= maxCtr &&\r\n row.position > 0 &&\r\n row.position <= maxPosition\r\n )\r\n .filter((row) => {\r\n if (includeBrand === \"only_brand\") {\r\n return row.brand_classification === \"brand\";\r\n }\r\n\r\n if (includeBrand === \"only_non_brand\") {\r\n return row.brand_classification === \"non_brand\";\r\n }\r\n\r\n return true;\r\n })\r\n .map((row) => ({\r\n ...row,\r\n opportunity_score: scoreQuickWinOpportunity({\r\n impressions: row.impressions,\r\n ctrPercent: row.ctr_percent,\r\n position: row.position,\r\n }),\r\n reason: \"Ranking is already acceptable, so low CTR suggests snippet or title optimization potential.\",\r\n }))\r\n .sort((left, right) => right.opportunity_score - left.opportunity_score);\r\n\r\n return object(\r\n stripNulls({\r\n site_url: siteUrl,\r\n date_range: {\r\n start_date: params.startDate,\r\n end_date: params.endDate,\r\n },\r\n thresholds: {\r\n min_impressions: minImpressions,\r\n max_ctr_percent: maxCtr,\r\n max_position: maxPosition,\r\n },\r\n opportunities,\r\n })\r\n );\r\n } catch (err) {\r\n return error(\r\n err instanceof Error ? err.message : \"Failed to find Search Console low-CTR opportunities\"\r\n );\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,qCAAqC;AAC9C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,yCAAyC,EAAE,OAAO;AAAA,EAC7D,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,cAAc,EACX,KAAK,CAAC,OAAO,cAAc,gBAAgB,CAAC,EAC5C,SAAS,EACT,SAAS,4DAA4D;AAAA,EACxE,gBAAgB,EACb,OAAO,EACP,IAAI,CAAC,EACL,SAAS,EACT,SAAS,6DAA6D;AAAA,EACzE,QAAQ,EACL,OAAO,EACP,IAAI,CAAC,EACL,IAAI,GAAG,EACP,SAAS,EACT,SAAS,6DAA6D;AAAA,EACzE,aAAa,EACV,OAAO,EACP,IAAI,CAAC,EACL,IAAI,GAAG,EACP,SAAS,EACT,SAAS,kFAAkF;AAChG,CAAC;AAED,eAAsB,wCACpB,QACA;AACA,MAAI;AACF,UAAM,UAAU,MAAM,4BAA4B,OAAO,SAAS,OAAO,SAAS;AAClF,UAAM,iBAAiB,OAAO,kBAAkB;AAChD,UAAM,SAAS,OAAO,UAAU;AAChC,UAAM,cAAc,OAAO,eAAe;AAC1C,UAAM,eAAe,OAAO,gBAAgB;AAE5C,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,MACA,4BAA4B;AAAA,QAC1B,WAAW,OAAO;AAAA,QAClB,SAAS,OAAO;AAAA,QAChB,YAAY,CAAC,OAAO;AAAA,QACpB,YAAY,OAAO;AAAA,QACnB,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAEA,UAAM,iBAAiB,SAAS,QAAQ,CAAC,GACtC,IAAI,CAAC,QAAQ,0BAA0B,KAAK,CAAC,OAAO,CAAC,CAAC,EACtD,IAAI,CAAC,SAAS;AAAA,MACb,OAAO,IAAI,WAAW;AAAA,MACtB,QAAQ,IAAI;AAAA,MACZ,aAAa,IAAI;AAAA,MACjB,aAAa,IAAI;AAAA,MACjB,UAAU,IAAI;AAAA,MACd,sBAAsB,mBAAmB,IAAI,WAAW,OAAO,OAAO,UAAU;AAAA,IAClF,EAAE,EACD;AAAA,MACC,CAAC,QACC,IAAI,eAAe,kBACnB,IAAI,eAAe,UACnB,IAAI,WAAW,KACf,IAAI,YAAY;AAAA,IACpB,EACC,OAAO,CAAC,QAAQ;AACf,UAAI,iBAAiB,cAAc;AACjC,eAAO,IAAI,yBAAyB;AAAA,MACtC;AAEA,UAAI,iBAAiB,kBAAkB;AACrC,eAAO,IAAI,yBAAyB;AAAA,MACtC;AAEA,aAAO;AAAA,IACT,CAAC,EACA,IAAI,CAAC,SAAS;AAAA,MACb,GAAG;AAAA,MACH,mBAAmB,yBAAyB;AAAA,QAC1C,aAAa,IAAI;AAAA,QACjB,YAAY,IAAI;AAAA,QAChB,UAAU,IAAI;AAAA,MAChB,CAAC;AAAA,MACD,QAAQ;AAAA,IACV,EAAE,EACD,KAAK,CAAC,MAAM,UAAU,MAAM,oBAAoB,KAAK,iBAAiB;AAEzE,WAAO;AAAA,MACL,WAAW;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,YAAY;AAAA,UACV,iBAAiB;AAAA,UACjB,iBAAiB;AAAA,UACjB,cAAc;AAAA,QAChB;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,eAAe,QAAQ,IAAI,UAAU;AAAA,IACvC;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/search-console/page-performance.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { querySearchConsolePerformance } from \"../../services/search-console/search-console-client.js\";\nimport {\n buildPaginationMetadata,\n buildSearchConsoleQueryBody,\n endDateSchemaField,\n profileIdSchemaField,\n resolveSearchConsoleSiteUrl,\n rowLimitSchemaField,\n searchConsoleDimensionFilterSchema,\n searchTypeSchemaField,\n siteUrlSchemaField,\n startDateSchemaField,\n startRowSchemaField,\n sumSearchConsoleRows,\n normalizeSearchConsoleRow,\n} from \"../../services/search-console/search-console-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const searchConsolePagePerformanceSchema = z.object({\n startDate: startDateSchemaField,\n endDate: endDateSchemaField,\n siteUrl: siteUrlSchemaField,\n profileId: profileIdSchemaField,\n searchType: searchTypeSchemaField,\n pageContains: z\n .string()\n .optional()\n .describe(\"Optional substring that page URLs must contain.\"),\n pageRegex: z\n .string()\n .optional()\n .describe(\"Optional regex expression to match page URLs.\"),\n rowLimit: rowLimitSchemaField,\n startRow: startRowSchemaField,\n});\n\nexport async function searchConsolePagePerformanceHandler(\n params: z.infer<typeof searchConsolePagePerformanceSchema>\n) {\n try {\n const siteUrl = await resolveSearchConsoleSiteUrl(params.siteUrl, params.profileId);\n const dimensionFilters = [];\n\n if (params.pageContains?.trim()) {\n dimensionFilters.push({\n dimension: \"page\",\n operator: \"contains\",\n expression: params.pageContains.trim(),\n });\n }\n\n if (params.pageRegex?.trim()) {\n dimensionFilters.push({\n dimension: \"page\",\n operator: \"includingRegex\",\n expression: params.pageRegex.trim(),\n });\n }\n\n const response = await querySearchConsolePerformance(\n siteUrl,\n buildSearchConsoleQueryBody({\n startDate: params.startDate,\n endDate: params.endDate,\n dimensions: [\"page\"],\n searchType: params.searchType,\n dimensionFilters,\n rowLimit: params.rowLimit,\n startRow: params.startRow,\n })\n );\n\n const rows = (response.rows ?? []).map((row) => normalizeSearchConsoleRow(row, [\"page\"]));\n const totals = sumSearchConsoleRows(rows);\n\n return object(\n stripNulls({\n site_url: siteUrl,\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n filters: {\n search_type: params.searchType ?? \"web\",\n page_contains: params.pageContains,\n page_regex: params.pageRegex,\n },\n overview: {\n total_clicks: totals.clicks,\n total_impressions: totals.impressions,\n average_ctr_percent: totals.ctrPercent,\n average_position: totals.averagePosition,\n },\n pages: rows.map((row) => ({\n page: row.dimensions.page,\n clicks: row.clicks,\n impressions: row.impressions,\n ctr_percent: row.ctr_percent,\n position: row.position,\n })),\n metadata: buildPaginationMetadata({\n startRow: params.startRow,\n rowLimit: params.rowLimit,\n returnedRows: rows.length,\n }),\n })\n );\n } catch (err) {\n return error(\n err instanceof Error ? err.message : \"Failed to fetch Search Console page performance\"\n );\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport { querySearchConsolePerformance } from \"../../services/search-console/search-console-client.js\";\r\nimport {\r\n buildPaginationMetadata,\r\n buildSearchConsoleQueryBody,\r\n endDateSchemaField,\r\n profileIdSchemaField,\r\n resolveSearchConsoleSiteUrl,\r\n rowLimitSchemaField,\r\n searchConsoleDimensionFilterSchema,\r\n searchTypeSchemaField,\r\n siteUrlSchemaField,\r\n startDateSchemaField,\r\n startRowSchemaField,\r\n sumSearchConsoleRows,\r\n normalizeSearchConsoleRow,\r\n} from \"../../services/search-console/search-console-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const searchConsolePagePerformanceSchema = z.object({\r\n startDate: startDateSchemaField,\r\n endDate: endDateSchemaField,\r\n siteUrl: siteUrlSchemaField,\r\n profileId: profileIdSchemaField,\r\n searchType: searchTypeSchemaField,\r\n pageContains: z\r\n .string()\r\n .optional()\r\n .describe(\"Optional substring that page URLs must contain.\"),\r\n pageRegex: z\r\n .string()\r\n .optional()\r\n .describe(\"Optional regex expression to match page URLs.\"),\r\n rowLimit: rowLimitSchemaField,\r\n startRow: startRowSchemaField,\r\n});\r\n\r\nexport async function searchConsolePagePerformanceHandler(\r\n params: z.infer<typeof searchConsolePagePerformanceSchema>\r\n) {\r\n try {\r\n const siteUrl = await resolveSearchConsoleSiteUrl(params.siteUrl, params.profileId);\r\n const dimensionFilters = [];\r\n\r\n if (params.pageContains?.trim()) {\r\n dimensionFilters.push({\r\n dimension: \"page\",\r\n operator: \"contains\",\r\n expression: params.pageContains.trim(),\r\n });\r\n }\r\n\r\n if (params.pageRegex?.trim()) {\r\n dimensionFilters.push({\r\n dimension: \"page\",\r\n operator: \"includingRegex\",\r\n expression: params.pageRegex.trim(),\r\n });\r\n }\r\n\r\n const response = await querySearchConsolePerformance(\r\n siteUrl,\r\n buildSearchConsoleQueryBody({\r\n startDate: params.startDate,\r\n endDate: params.endDate,\r\n dimensions: [\"page\"],\r\n searchType: params.searchType,\r\n dimensionFilters,\r\n rowLimit: params.rowLimit,\r\n startRow: params.startRow,\r\n })\r\n );\r\n\r\n const rows = (response.rows ?? []).map((row) => normalizeSearchConsoleRow(row, [\"page\"]));\r\n const totals = sumSearchConsoleRows(rows);\r\n\r\n return object(\r\n stripNulls({\r\n site_url: siteUrl,\r\n date_range: {\r\n start_date: params.startDate,\r\n end_date: params.endDate,\r\n },\r\n filters: {\r\n search_type: params.searchType ?? \"web\",\r\n page_contains: params.pageContains,\r\n page_regex: params.pageRegex,\r\n },\r\n overview: {\r\n total_clicks: totals.clicks,\r\n total_impressions: totals.impressions,\r\n average_ctr_percent: totals.ctrPercent,\r\n average_position: totals.averagePosition,\r\n },\r\n pages: rows.map((row) => ({\r\n page: row.dimensions.page,\r\n clicks: row.clicks,\r\n impressions: row.impressions,\r\n ctr_percent: row.ctr_percent,\r\n position: row.position,\r\n })),\r\n metadata: buildPaginationMetadata({\r\n startRow: params.startRow,\r\n rowLimit: params.rowLimit,\r\n returnedRows: rows.length,\r\n }),\r\n })\r\n );\r\n } catch (err) {\r\n return error(\r\n err instanceof Error ? err.message : \"Failed to fetch Search Console page performance\"\r\n );\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,qCAAqC;AAC9C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,qCAAqC,EAAE,OAAO;AAAA,EACzD,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,cAAc,EACX,OAAO,EACP,SAAS,EACT,SAAS,iDAAiD;AAAA,EAC7D,WAAW,EACR,OAAO,EACP,SAAS,EACT,SAAS,+CAA+C;AAAA,EAC3D,UAAU;AAAA,EACV,UAAU;AACZ,CAAC;AAED,eAAsB,oCACpB,QACA;AACA,MAAI;AACF,UAAM,UAAU,MAAM,4BAA4B,OAAO,SAAS,OAAO,SAAS;AAClF,UAAM,mBAAmB,CAAC;AAE1B,QAAI,OAAO,cAAc,KAAK,GAAG;AAC/B,uBAAiB,KAAK;AAAA,QACpB,WAAW;AAAA,QACX,UAAU;AAAA,QACV,YAAY,OAAO,aAAa,KAAK;AAAA,MACvC,CAAC;AAAA,IACH;AAEA,QAAI,OAAO,WAAW,KAAK,GAAG;AAC5B,uBAAiB,KAAK;AAAA,QACpB,WAAW;AAAA,QACX,UAAU;AAAA,QACV,YAAY,OAAO,UAAU,KAAK;AAAA,MACpC,CAAC;AAAA,IACH;AAEA,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,MACA,4BAA4B;AAAA,QAC1B,WAAW,OAAO;AAAA,QAClB,SAAS,OAAO;AAAA,QAChB,YAAY,CAAC,MAAM;AAAA,QACnB,YAAY,OAAO;AAAA,QACnB;AAAA,QACA,UAAU,OAAO;AAAA,QACjB,UAAU,OAAO;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,UAAM,QAAQ,SAAS,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,0BAA0B,KAAK,CAAC,MAAM,CAAC,CAAC;AACxF,UAAM,SAAS,qBAAqB,IAAI;AAExC,WAAO;AAAA,MACL,WAAW;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,SAAS;AAAA,UACP,aAAa,OAAO,cAAc;AAAA,UAClC,eAAe,OAAO;AAAA,UACtB,YAAY,OAAO;AAAA,QACrB;AAAA,QACA,UAAU;AAAA,UACR,cAAc,OAAO;AAAA,UACrB,mBAAmB,OAAO;AAAA,UAC1B,qBAAqB,OAAO;AAAA,UAC5B,kBAAkB,OAAO;AAAA,QAC3B;AAAA,QACA,OAAO,KAAK,IAAI,CAAC,SAAS;AAAA,UACxB,MAAM,IAAI,WAAW;AAAA,UACrB,QAAQ,IAAI;AAAA,UACZ,aAAa,IAAI;AAAA,UACjB,aAAa,IAAI;AAAA,UACjB,UAAU,IAAI;AAAA,QAChB,EAAE;AAAA,QACF,UAAU,wBAAwB;AAAA,UAChC,UAAU,OAAO;AAAA,UACjB,UAAU,OAAO;AAAA,UACjB,cAAc,KAAK;AAAA,QACrB,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,eAAe,QAAQ,IAAI,UAAU;AAAA,IACvC;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/search-console/product-demand-low-capture-queries.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { querySearchConsolePerformance } from \"../../services/search-console/search-console-client.js\";\nimport {\n brandTermsSchemaField,\n buildSearchConsoleQueryBody,\n classifyBrandLabel,\n endDateSchemaField,\n looksLikeProductQuery,\n profileIdSchemaField,\n resolveSearchConsoleSiteUrl,\n rowLimitSchemaField,\n searchTypeSchemaField,\n siteUrlSchemaField,\n startDateSchemaField,\n normalizeSearchConsoleRow,\n scoreHighImpressionLowClickOpportunity,\n} from \"../../services/search-console/search-console-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const searchConsoleProductDemandLowCaptureQueriesSchema = z.object({\n startDate: startDateSchemaField,\n endDate: endDateSchemaField,\n siteUrl: siteUrlSchemaField,\n profileId: profileIdSchemaField,\n searchType: searchTypeSchemaField,\n brandTerms: brandTermsSchemaField,\n productTerms: z\n .array(z.string().min(1))\n .max(100)\n .optional()\n .describe(\"Optional product tokens used to better detect product-intent queries.\"),\n minImpressions: z\n .number()\n .min(1)\n .optional()\n .describe(\"Minimum impressions required to consider a product query.\"),\n maxCtr: z\n .number()\n .min(0)\n .max(100)\n .optional()\n .describe(\"Maximum CTR percentage allowed to count as low capture.\"),\n maxPosition: z\n .number()\n .min(1)\n .max(100)\n .optional()\n .describe(\"Maximum average position allowed to keep only queries with some ranking potential.\"),\n rowLimit: rowLimitSchemaField,\n});\n\nexport async function searchConsoleProductDemandLowCaptureQueriesHandler(\n params: z.infer<typeof searchConsoleProductDemandLowCaptureQueriesSchema>\n) {\n try {\n const siteUrl = await resolveSearchConsoleSiteUrl(params.siteUrl, params.profileId);\n const minImpressions = params.minImpressions ?? 80;\n const maxCtr = params.maxCtr ?? 4;\n const maxPosition = params.maxPosition ?? 20;\n\n const response = await querySearchConsolePerformance(\n siteUrl,\n buildSearchConsoleQueryBody({\n startDate: params.startDate,\n endDate: params.endDate,\n dimensions: [\"query\", \"page\"],\n searchType: params.searchType,\n rowLimit: params.rowLimit ?? 250,\n })\n );\n\n const opportunities = (response.rows ?? [])\n .map((row) => normalizeSearchConsoleRow(row, [\"query\", \"page\"]))\n .filter((row) => looksLikeProductQuery(row.dimensions.query, params.productTerms))\n .map((row) => ({\n query: row.dimensions.query,\n page: row.dimensions.page,\n clicks: row.clicks,\n impressions: row.impressions,\n ctr_percent: row.ctr_percent,\n position: row.position,\n brand_classification: classifyBrandLabel(row.dimensions.query, params.brandTerms),\n }))\n .filter(\n (row) =>\n row.impressions >= minImpressions &&\n row.ctr_percent <= maxCtr &&\n row.position > 0 &&\n row.position <= maxPosition\n )\n .map((row) => ({\n ...row,\n opportunity_score: scoreHighImpressionLowClickOpportunity({\n impressions: row.impressions,\n ctrPercent: row.ctr_percent,\n position: row.position,\n }),\n reason: \"Product-intent query shows demand but weak click capture.\",\n }))\n .sort((left, right) => right.opportunity_score - left.opportunity_score);\n\n return object(\n stripNulls({\n site_url: siteUrl,\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n thresholds: {\n min_impressions: minImpressions,\n max_ctr_percent: maxCtr,\n max_position: maxPosition,\n },\n opportunities,\n })\n );\n } catch (err) {\n return error(\n err instanceof Error\n ? err.message\n : \"Failed to find Search Console product demand low-capture queries\"\n );\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport { querySearchConsolePerformance } from \"../../services/search-console/search-console-client.js\";\r\nimport {\r\n brandTermsSchemaField,\r\n buildSearchConsoleQueryBody,\r\n classifyBrandLabel,\r\n endDateSchemaField,\r\n looksLikeProductQuery,\r\n profileIdSchemaField,\r\n resolveSearchConsoleSiteUrl,\r\n rowLimitSchemaField,\r\n searchTypeSchemaField,\r\n siteUrlSchemaField,\r\n startDateSchemaField,\r\n normalizeSearchConsoleRow,\r\n scoreHighImpressionLowClickOpportunity,\r\n} from \"../../services/search-console/search-console-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const searchConsoleProductDemandLowCaptureQueriesSchema = z.object({\r\n startDate: startDateSchemaField,\r\n endDate: endDateSchemaField,\r\n siteUrl: siteUrlSchemaField,\r\n profileId: profileIdSchemaField,\r\n searchType: searchTypeSchemaField,\r\n brandTerms: brandTermsSchemaField,\r\n productTerms: z\r\n .array(z.string().min(1))\r\n .max(100)\r\n .optional()\r\n .describe(\"Optional product tokens used to better detect product-intent queries.\"),\r\n minImpressions: z\r\n .number()\r\n .min(1)\r\n .optional()\r\n .describe(\"Minimum impressions required to consider a product query.\"),\r\n maxCtr: z\r\n .number()\r\n .min(0)\r\n .max(100)\r\n .optional()\r\n .describe(\"Maximum CTR percentage allowed to count as low capture.\"),\r\n maxPosition: z\r\n .number()\r\n .min(1)\r\n .max(100)\r\n .optional()\r\n .describe(\"Maximum average position allowed to keep only queries with some ranking potential.\"),\r\n rowLimit: rowLimitSchemaField,\r\n});\r\n\r\nexport async function searchConsoleProductDemandLowCaptureQueriesHandler(\r\n params: z.infer<typeof searchConsoleProductDemandLowCaptureQueriesSchema>\r\n) {\r\n try {\r\n const siteUrl = await resolveSearchConsoleSiteUrl(params.siteUrl, params.profileId);\r\n const minImpressions = params.minImpressions ?? 80;\r\n const maxCtr = params.maxCtr ?? 4;\r\n const maxPosition = params.maxPosition ?? 20;\r\n\r\n const response = await querySearchConsolePerformance(\r\n siteUrl,\r\n buildSearchConsoleQueryBody({\r\n startDate: params.startDate,\r\n endDate: params.endDate,\r\n dimensions: [\"query\", \"page\"],\r\n searchType: params.searchType,\r\n rowLimit: params.rowLimit ?? 250,\r\n })\r\n );\r\n\r\n const opportunities = (response.rows ?? [])\r\n .map((row) => normalizeSearchConsoleRow(row, [\"query\", \"page\"]))\r\n .filter((row) => looksLikeProductQuery(row.dimensions.query, params.productTerms))\r\n .map((row) => ({\r\n query: row.dimensions.query,\r\n page: row.dimensions.page,\r\n clicks: row.clicks,\r\n impressions: row.impressions,\r\n ctr_percent: row.ctr_percent,\r\n position: row.position,\r\n brand_classification: classifyBrandLabel(row.dimensions.query, params.brandTerms),\r\n }))\r\n .filter(\r\n (row) =>\r\n row.impressions >= minImpressions &&\r\n row.ctr_percent <= maxCtr &&\r\n row.position > 0 &&\r\n row.position <= maxPosition\r\n )\r\n .map((row) => ({\r\n ...row,\r\n opportunity_score: scoreHighImpressionLowClickOpportunity({\r\n impressions: row.impressions,\r\n ctrPercent: row.ctr_percent,\r\n position: row.position,\r\n }),\r\n reason: \"Product-intent query shows demand but weak click capture.\",\r\n }))\r\n .sort((left, right) => right.opportunity_score - left.opportunity_score);\r\n\r\n return object(\r\n stripNulls({\r\n site_url: siteUrl,\r\n date_range: {\r\n start_date: params.startDate,\r\n end_date: params.endDate,\r\n },\r\n thresholds: {\r\n min_impressions: minImpressions,\r\n max_ctr_percent: maxCtr,\r\n max_position: maxPosition,\r\n },\r\n opportunities,\r\n })\r\n );\r\n } catch (err) {\r\n return error(\r\n err instanceof Error\r\n ? err.message\r\n : \"Failed to find Search Console product demand low-capture queries\"\r\n );\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,qCAAqC;AAC9C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,oDAAoD,EAAE,OAAO;AAAA,EACxE,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,cAAc,EACX,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EACvB,IAAI,GAAG,EACP,SAAS,EACT,SAAS,uEAAuE;AAAA,EACnF,gBAAgB,EACb,OAAO,EACP,IAAI,CAAC,EACL,SAAS,EACT,SAAS,2DAA2D;AAAA,EACvE,QAAQ,EACL,OAAO,EACP,IAAI,CAAC,EACL,IAAI,GAAG,EACP,SAAS,EACT,SAAS,yDAAyD;AAAA,EACrE,aAAa,EACV,OAAO,EACP,IAAI,CAAC,EACL,IAAI,GAAG,EACP,SAAS,EACT,SAAS,oFAAoF;AAAA,EAChG,UAAU;AACZ,CAAC;AAED,eAAsB,mDACpB,QACA;AACA,MAAI;AACF,UAAM,UAAU,MAAM,4BAA4B,OAAO,SAAS,OAAO,SAAS;AAClF,UAAM,iBAAiB,OAAO,kBAAkB;AAChD,UAAM,SAAS,OAAO,UAAU;AAChC,UAAM,cAAc,OAAO,eAAe;AAE1C,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,MACA,4BAA4B;AAAA,QAC1B,WAAW,OAAO;AAAA,QAClB,SAAS,OAAO;AAAA,QAChB,YAAY,CAAC,SAAS,MAAM;AAAA,QAC5B,YAAY,OAAO;AAAA,QACnB,UAAU,OAAO,YAAY;AAAA,MAC/B,CAAC;AAAA,IACH;AAEA,UAAM,iBAAiB,SAAS,QAAQ,CAAC,GACtC,IAAI,CAAC,QAAQ,0BAA0B,KAAK,CAAC,SAAS,MAAM,CAAC,CAAC,EAC9D,OAAO,CAAC,QAAQ,sBAAsB,IAAI,WAAW,OAAO,OAAO,YAAY,CAAC,EAChF,IAAI,CAAC,SAAS;AAAA,MACb,OAAO,IAAI,WAAW;AAAA,MACtB,MAAM,IAAI,WAAW;AAAA,MACrB,QAAQ,IAAI;AAAA,MACZ,aAAa,IAAI;AAAA,MACjB,aAAa,IAAI;AAAA,MACjB,UAAU,IAAI;AAAA,MACd,sBAAsB,mBAAmB,IAAI,WAAW,OAAO,OAAO,UAAU;AAAA,IAClF,EAAE,EACD;AAAA,MACC,CAAC,QACC,IAAI,eAAe,kBACnB,IAAI,eAAe,UACnB,IAAI,WAAW,KACf,IAAI,YAAY;AAAA,IACpB,EACC,IAAI,CAAC,SAAS;AAAA,MACb,GAAG;AAAA,MACH,mBAAmB,uCAAuC;AAAA,QACxD,aAAa,IAAI;AAAA,QACjB,YAAY,IAAI;AAAA,QAChB,UAAU,IAAI;AAAA,MAChB,CAAC;AAAA,MACD,QAAQ;AAAA,IACV,EAAE,EACD,KAAK,CAAC,MAAM,UAAU,MAAM,oBAAoB,KAAK,iBAAiB;AAEzE,WAAO;AAAA,MACL,WAAW;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,YAAY;AAAA,UACV,iBAAiB;AAAA,UACjB,iBAAiB;AAAA,UACjB,cAAc;AAAA,QAChB;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,eAAe,QACX,IAAI,UACJ;AAAA,IACN;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/search-console/query-page-matrix.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { querySearchConsolePerformance } from \"../../services/search-console/search-console-client.js\";\nimport {\n buildPaginationMetadata,\n buildSearchConsoleQueryBody,\n endDateSchemaField,\n profileIdSchemaField,\n resolveSearchConsoleSiteUrl,\n rowLimitSchemaField,\n searchTypeSchemaField,\n siteUrlSchemaField,\n startDateSchemaField,\n startRowSchemaField,\n normalizeSearchConsoleRow,\n} from \"../../services/search-console/search-console-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const searchConsoleQueryPageMatrixSchema = z.object({\n startDate: startDateSchemaField,\n endDate: endDateSchemaField,\n siteUrl: siteUrlSchemaField,\n profileId: profileIdSchemaField,\n searchType: searchTypeSchemaField,\n queryContains: z\n .string()\n .optional()\n .describe(\"Optional substring that queries must contain.\"),\n pageContains: z\n .string()\n .optional()\n .describe(\"Optional substring that landing pages must contain.\"),\n rowLimit: rowLimitSchemaField,\n startRow: startRowSchemaField,\n});\n\nexport async function searchConsoleQueryPageMatrixHandler(\n params: z.infer<typeof searchConsoleQueryPageMatrixSchema>\n) {\n try {\n const siteUrl = await resolveSearchConsoleSiteUrl(params.siteUrl, params.profileId);\n const dimensionFilters = [];\n\n if (params.queryContains?.trim()) {\n dimensionFilters.push({\n dimension: \"query\",\n operator: \"contains\",\n expression: params.queryContains.trim(),\n });\n }\n\n if (params.pageContains?.trim()) {\n dimensionFilters.push({\n dimension: \"page\",\n operator: \"contains\",\n expression: params.pageContains.trim(),\n });\n }\n\n const response = await querySearchConsolePerformance(\n siteUrl,\n buildSearchConsoleQueryBody({\n startDate: params.startDate,\n endDate: params.endDate,\n dimensions: [\"query\", \"page\"],\n searchType: params.searchType,\n dimensionFilters,\n rowLimit: params.rowLimit,\n startRow: params.startRow,\n })\n );\n\n const rows = (response.rows ?? []).map((row) =>\n normalizeSearchConsoleRow(row, [\"query\", \"page\"])\n );\n\n return object(\n stripNulls({\n site_url: siteUrl,\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n filters: {\n search_type: params.searchType ?? \"web\",\n query_contains: params.queryContains,\n page_contains: params.pageContains,\n },\n rows: rows.map((row) => ({\n query: row.dimensions.query,\n page: row.dimensions.page,\n clicks: row.clicks,\n impressions: row.impressions,\n ctr_percent: row.ctr_percent,\n position: row.position,\n })),\n metadata: buildPaginationMetadata({\n startRow: params.startRow,\n rowLimit: params.rowLimit,\n returnedRows: rows.length,\n }),\n })\n );\n } catch (err) {\n return error(\n err instanceof Error ? err.message : \"Failed to fetch Search Console query-page matrix\"\n );\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\r\nimport { z } from \"zod\";\r\n\r\nimport { querySearchConsolePerformance } from \"../../services/search-console/search-console-client.js\";\r\nimport {\r\n buildPaginationMetadata,\r\n buildSearchConsoleQueryBody,\r\n endDateSchemaField,\r\n profileIdSchemaField,\r\n resolveSearchConsoleSiteUrl,\r\n rowLimitSchemaField,\r\n searchTypeSchemaField,\r\n siteUrlSchemaField,\r\n startDateSchemaField,\r\n startRowSchemaField,\r\n normalizeSearchConsoleRow,\r\n} from \"../../services/search-console/search-console-utils.js\";\r\nimport { stripNulls } from \"../../utils/strip-payload.js\";\r\n\r\nexport const searchConsoleQueryPageMatrixSchema = z.object({\r\n startDate: startDateSchemaField,\r\n endDate: endDateSchemaField,\r\n siteUrl: siteUrlSchemaField,\r\n profileId: profileIdSchemaField,\r\n searchType: searchTypeSchemaField,\r\n queryContains: z\r\n .string()\r\n .optional()\r\n .describe(\"Optional substring that queries must contain.\"),\r\n pageContains: z\r\n .string()\r\n .optional()\r\n .describe(\"Optional substring that landing pages must contain.\"),\r\n rowLimit: rowLimitSchemaField,\r\n startRow: startRowSchemaField,\r\n});\r\n\r\nexport async function searchConsoleQueryPageMatrixHandler(\r\n params: z.infer<typeof searchConsoleQueryPageMatrixSchema>\r\n) {\r\n try {\r\n const siteUrl = await resolveSearchConsoleSiteUrl(params.siteUrl, params.profileId);\r\n const dimensionFilters = [];\r\n\r\n if (params.queryContains?.trim()) {\r\n dimensionFilters.push({\r\n dimension: \"query\",\r\n operator: \"contains\",\r\n expression: params.queryContains.trim(),\r\n });\r\n }\r\n\r\n if (params.pageContains?.trim()) {\r\n dimensionFilters.push({\r\n dimension: \"page\",\r\n operator: \"contains\",\r\n expression: params.pageContains.trim(),\r\n });\r\n }\r\n\r\n const response = await querySearchConsolePerformance(\r\n siteUrl,\r\n buildSearchConsoleQueryBody({\r\n startDate: params.startDate,\r\n endDate: params.endDate,\r\n dimensions: [\"query\", \"page\"],\r\n searchType: params.searchType,\r\n dimensionFilters,\r\n rowLimit: params.rowLimit,\r\n startRow: params.startRow,\r\n })\r\n );\r\n\r\n const rows = (response.rows ?? []).map((row) =>\r\n normalizeSearchConsoleRow(row, [\"query\", \"page\"])\r\n );\r\n\r\n return object(\r\n stripNulls({\r\n site_url: siteUrl,\r\n date_range: {\r\n start_date: params.startDate,\r\n end_date: params.endDate,\r\n },\r\n filters: {\r\n search_type: params.searchType ?? \"web\",\r\n query_contains: params.queryContains,\r\n page_contains: params.pageContains,\r\n },\r\n rows: rows.map((row) => ({\r\n query: row.dimensions.query,\r\n page: row.dimensions.page,\r\n clicks: row.clicks,\r\n impressions: row.impressions,\r\n ctr_percent: row.ctr_percent,\r\n position: row.position,\r\n })),\r\n metadata: buildPaginationMetadata({\r\n startRow: params.startRow,\r\n rowLimit: params.rowLimit,\r\n returnedRows: rows.length,\r\n }),\r\n })\r\n );\r\n } catch (err) {\r\n return error(\r\n err instanceof Error ? err.message : \"Failed to fetch Search Console query-page matrix\"\r\n );\r\n }\r\n}\r\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,qCAAqC;AAC9C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,qCAAqC,EAAE,OAAO;AAAA,EACzD,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,eAAe,EACZ,OAAO,EACP,SAAS,EACT,SAAS,+CAA+C;AAAA,EAC3D,cAAc,EACX,OAAO,EACP,SAAS,EACT,SAAS,qDAAqD;AAAA,EACjE,UAAU;AAAA,EACV,UAAU;AACZ,CAAC;AAED,eAAsB,oCACpB,QACA;AACA,MAAI;AACF,UAAM,UAAU,MAAM,4BAA4B,OAAO,SAAS,OAAO,SAAS;AAClF,UAAM,mBAAmB,CAAC;AAE1B,QAAI,OAAO,eAAe,KAAK,GAAG;AAChC,uBAAiB,KAAK;AAAA,QACpB,WAAW;AAAA,QACX,UAAU;AAAA,QACV,YAAY,OAAO,cAAc,KAAK;AAAA,MACxC,CAAC;AAAA,IACH;AAEA,QAAI,OAAO,cAAc,KAAK,GAAG;AAC/B,uBAAiB,KAAK;AAAA,QACpB,WAAW;AAAA,QACX,UAAU;AAAA,QACV,YAAY,OAAO,aAAa,KAAK;AAAA,MACvC,CAAC;AAAA,IACH;AAEA,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,MACA,4BAA4B;AAAA,QAC1B,WAAW,OAAO;AAAA,QAClB,SAAS,OAAO;AAAA,QAChB,YAAY,CAAC,SAAS,MAAM;AAAA,QAC5B,YAAY,OAAO;AAAA,QACnB;AAAA,QACA,UAAU,OAAO;AAAA,QACjB,UAAU,OAAO;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,UAAM,QAAQ,SAAS,QAAQ,CAAC,GAAG;AAAA,MAAI,CAAC,QACtC,0BAA0B,KAAK,CAAC,SAAS,MAAM,CAAC;AAAA,IAClD;AAEA,WAAO;AAAA,MACL,WAAW;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,SAAS;AAAA,UACP,aAAa,OAAO,cAAc;AAAA,UAClC,gBAAgB,OAAO;AAAA,UACvB,eAAe,OAAO;AAAA,QACxB;AAAA,QACA,MAAM,KAAK,IAAI,CAAC,SAAS;AAAA,UACvB,OAAO,IAAI,WAAW;AAAA,UACtB,MAAM,IAAI,WAAW;AAAA,UACrB,QAAQ,IAAI;AAAA,UACZ,aAAa,IAAI;AAAA,UACjB,aAAa,IAAI;AAAA,UACjB,UAAU,IAAI;AAAA,QAChB,EAAE;AAAA,QACF,UAAU,wBAAwB;AAAA,UAChC,UAAU,OAAO;AAAA,UACjB,UAAU,OAAO;AAAA,UACjB,cAAc,KAAK;AAAA,QACrB,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,eAAe,QAAQ,IAAI,UAAU;AAAA,IACvC;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|