adloop 0.19.2__tar.gz → 0.19.4__tar.gz
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.
- {adloop-0.19.2 → adloop-0.19.4}/PKG-INFO +1 -1
- {adloop-0.19.2 → adloop-0.19.4}/pyproject.toml +1 -1
- {adloop-0.19.2 → adloop-0.19.4}/pyproject.toml.orig +1 -1
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/server.py +170 -109
- {adloop-0.19.2 → adloop-0.19.4}/README.md +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/__init__.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/__main__.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/_mcp_patches.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/__init__.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/ai_max.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/brands.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/client.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/conversion_actions.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/currency.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/custom_conversion_goals.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/enums.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/forecast.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/gaql.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/image_fetch.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/pmax.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/read.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/validate_only.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ads/write.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/auth.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/cli.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/config.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/crossref.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/diagnostics.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ga4/__init__.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ga4/client.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ga4/reports.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ga4/tracking.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/ga4/write.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/gsc/__init__.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/gsc/client.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/gsc/reports.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/gtm/__init__.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/gtm/client.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/gtm/read.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/merchant/__init__.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/merchant/client.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/merchant/read.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/pagespeed.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/reddit/__init__.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/reddit/auth.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/reddit/client.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/reddit/read.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/reddit/schedule.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/reddit/write.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/rules/__init__.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/rules/adloop.md +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/rules/commands/analyze-performance.md +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/rules/commands/budget-plan.md +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/rules/commands/create-ad.md +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/rules/commands/create-campaign.md +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/rules/commands/diagnose-tracking.md +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/rules/commands/optimize-campaign.md +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/rules_install.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/runtime.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/safety/__init__.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/safety/audit.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/safety/guards.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/safety/preview.py +0 -0
- {adloop-0.19.2 → adloop-0.19.4}/src/adloop/tracking.py +0 -0
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import functools
|
|
6
|
+
import inspect
|
|
6
7
|
import json
|
|
7
8
|
from typing import Annotated, Callable
|
|
8
9
|
|
|
9
10
|
from fastmcp import FastMCP
|
|
11
|
+
from fastmcp.utilities.docstring_parsing import parse_docstring
|
|
10
12
|
from mcp.types import ToolAnnotations
|
|
11
13
|
from pydantic import BeforeValidator
|
|
12
14
|
|
|
@@ -166,6 +168,65 @@ mcp = FastMCP(
|
|
|
166
168
|
)
|
|
167
169
|
|
|
168
170
|
|
|
171
|
+
# The API each toolset calls, linked at the end of every tool description:
|
|
172
|
+
# directory reviews ask descriptions to reference the API they target.
|
|
173
|
+
_API_DOCS: dict[str, str] = {
|
|
174
|
+
"ads": "Google Ads API: https://developers.google.com/google-ads/api/docs/start",
|
|
175
|
+
"ga4": (
|
|
176
|
+
"Google Analytics Data API: "
|
|
177
|
+
"https://developers.google.com/analytics/devguides/reporting/data/v1 "
|
|
178
|
+
"and Admin API: https://developers.google.com/analytics/devguides/config/admin/v1"
|
|
179
|
+
),
|
|
180
|
+
"tracking": (
|
|
181
|
+
"Google Analytics Data API: "
|
|
182
|
+
"https://developers.google.com/analytics/devguides/reporting/data/v1 "
|
|
183
|
+
"and Google Ads API: https://developers.google.com/google-ads/api/docs/start"
|
|
184
|
+
),
|
|
185
|
+
"gtm": "Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2",
|
|
186
|
+
"gsc": "Search Console API: https://developers.google.com/webmaster-tools",
|
|
187
|
+
"web": "PageSpeed Insights API: https://developers.google.com/speed/docs/insights/v5/about",
|
|
188
|
+
"merchant": "Merchant API: https://developers.google.com/merchant/api/overview",
|
|
189
|
+
"reddit": "Reddit Ads API: https://ads-api.reddit.com/docs/v3/",
|
|
190
|
+
# health_check and confirm_and_apply act on whichever platform is set up.
|
|
191
|
+
"core": (
|
|
192
|
+
"Google Ads API: https://developers.google.com/google-ads/api/docs/start, "
|
|
193
|
+
"Google Analytics Data API: "
|
|
194
|
+
"https://developers.google.com/analytics/devguides/reporting/data/v1 "
|
|
195
|
+
"and Reddit Ads API: https://ads-api.reddit.com/docs/v3/"
|
|
196
|
+
),
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def _tool(*, title: str, annotations: ToolAnnotations, tags: set[str], **kwargs):
|
|
201
|
+
"""Register a tool with its title in both places MCP defines one, and
|
|
202
|
+
with a link to the API it calls.
|
|
203
|
+
|
|
204
|
+
The tool's own ``title`` is what clients display; ``annotations.title``
|
|
205
|
+
is what directory reviews (Claude's connector portal) check. One title,
|
|
206
|
+
copied into the shared annotation preset, keeps them from drifting.
|
|
207
|
+
Descriptions that already link their API (the free-form query tools,
|
|
208
|
+
which point at the query reference) keep their own link.
|
|
209
|
+
"""
|
|
210
|
+
annotations = annotations.model_copy(update={"title": title})
|
|
211
|
+
docs = " ".join(_API_DOCS[tag] for tag in sorted(tags) if tag in _API_DOCS)
|
|
212
|
+
|
|
213
|
+
def register(fn):
|
|
214
|
+
# FastMCP's own parser: it moves an Args: section into the
|
|
215
|
+
# parameter schema, so the description must not repeat it.
|
|
216
|
+
description = parse_docstring(fn).description or inspect.cleandoc(fn.__doc__ or "")
|
|
217
|
+
if docs and "https://" not in description:
|
|
218
|
+
description = f"{description}\n\n{docs}"
|
|
219
|
+
return mcp.tool(
|
|
220
|
+
title=title,
|
|
221
|
+
annotations=annotations,
|
|
222
|
+
tags=tags,
|
|
223
|
+
description=description,
|
|
224
|
+
**kwargs,
|
|
225
|
+
)(fn)
|
|
226
|
+
|
|
227
|
+
return register
|
|
228
|
+
|
|
229
|
+
|
|
169
230
|
def _reddit_structured_error(exc: Exception) -> dict | None:
|
|
170
231
|
"""Reddit-specific translations; keyed on exception type so Reddit's
|
|
171
232
|
``invalid_grant`` never gets the "Reconnect Google" hint below."""
|
|
@@ -400,7 +461,7 @@ def _safe(fn: Callable) -> Callable:
|
|
|
400
461
|
# ---------------------------------------------------------------------------
|
|
401
462
|
|
|
402
463
|
|
|
403
|
-
@
|
|
464
|
+
@_tool(title="Connection health check", annotations=_READONLY, tags={"core"})
|
|
404
465
|
@_safe
|
|
405
466
|
def health_check() -> dict:
|
|
406
467
|
"""Test AdLoop connectivity — checks OAuth token, GA4 API, Google Ads API,
|
|
@@ -531,7 +592,7 @@ def health_check() -> dict:
|
|
|
531
592
|
# ---------------------------------------------------------------------------
|
|
532
593
|
|
|
533
594
|
|
|
534
|
-
@
|
|
595
|
+
@_tool(title="List Analytics properties", annotations=_READONLY, tags={"ga4"})
|
|
535
596
|
@_safe
|
|
536
597
|
def get_account_summaries() -> dict:
|
|
537
598
|
"""List all GA4 accounts and properties accessible by the authenticated user.
|
|
@@ -544,7 +605,7 @@ def get_account_summaries() -> dict:
|
|
|
544
605
|
return _impl(current_config())
|
|
545
606
|
|
|
546
607
|
|
|
547
|
-
@
|
|
608
|
+
@_tool(title="Analytics report", annotations=_READONLY, tags={"ga4"})
|
|
548
609
|
@_safe
|
|
549
610
|
def run_ga4_report(
|
|
550
611
|
dimensions: _StrListOpt = None,
|
|
@@ -577,7 +638,7 @@ def run_ga4_report(
|
|
|
577
638
|
)
|
|
578
639
|
|
|
579
640
|
|
|
580
|
-
@
|
|
641
|
+
@_tool(title="Analytics realtime report", annotations=_READONLY, tags={"ga4"})
|
|
581
642
|
@_safe
|
|
582
643
|
def run_realtime_report(
|
|
583
644
|
dimensions: _StrListOpt = None,
|
|
@@ -600,7 +661,7 @@ def run_realtime_report(
|
|
|
600
661
|
)
|
|
601
662
|
|
|
602
663
|
|
|
603
|
-
@
|
|
664
|
+
@_tool(title="List Analytics events", annotations=_READONLY, tags={"ga4"})
|
|
604
665
|
@_safe
|
|
605
666
|
def get_tracking_events(
|
|
606
667
|
date_range_start: str = "28daysAgo",
|
|
@@ -627,7 +688,7 @@ def get_tracking_events(
|
|
|
627
688
|
# ---------------------------------------------------------------------------
|
|
628
689
|
|
|
629
690
|
|
|
630
|
-
@
|
|
691
|
+
@_tool(title="List Search Console properties", annotations=_READONLY, tags={"gsc"})
|
|
631
692
|
@_safe
|
|
632
693
|
def list_gsc_sites() -> dict:
|
|
633
694
|
"""List all Google Search Console properties the authenticated user can access.
|
|
@@ -641,7 +702,7 @@ def list_gsc_sites() -> dict:
|
|
|
641
702
|
return _impl(current_config())
|
|
642
703
|
|
|
643
704
|
|
|
644
|
-
@
|
|
705
|
+
@_tool(title="Search Console report", annotations=_READONLY, tags={"gsc"})
|
|
645
706
|
@_safe
|
|
646
707
|
def run_gsc_report(
|
|
647
708
|
site_url: str = "",
|
|
@@ -693,7 +754,7 @@ def run_gsc_report(
|
|
|
693
754
|
# ---------------------------------------------------------------------------
|
|
694
755
|
|
|
695
756
|
|
|
696
|
-
@
|
|
757
|
+
@_tool(title="PageSpeed analysis", annotations=_READONLY, tags={"web"})
|
|
697
758
|
@_safe
|
|
698
759
|
def analyze_page_speed(url: str, strategy: str = "mobile") -> dict:
|
|
699
760
|
"""Run PageSpeed Insights for a landing page — Lighthouse + real-user data.
|
|
@@ -712,7 +773,7 @@ def analyze_page_speed(url: str, strategy: str = "mobile") -> dict:
|
|
|
712
773
|
return _impl(current_config(), url=url, strategy=strategy)
|
|
713
774
|
|
|
714
775
|
|
|
715
|
-
@
|
|
776
|
+
@_tool(
|
|
716
777
|
title="List Merchant Center accounts",
|
|
717
778
|
annotations=_READONLY,
|
|
718
779
|
tags={"merchant"},
|
|
@@ -730,7 +791,7 @@ def list_merchant_accounts() -> dict:
|
|
|
730
791
|
return _impl(current_config())
|
|
731
792
|
|
|
732
793
|
|
|
733
|
-
@
|
|
794
|
+
@_tool(title="Merchant Center feed health", annotations=_READONLY, tags={"merchant"})
|
|
734
795
|
@_safe
|
|
735
796
|
def get_merchant_feed_health(account_id: str = "") -> dict:
|
|
736
797
|
"""Merchant Center feed health — disapproved products + account issues.
|
|
@@ -750,7 +811,7 @@ def get_merchant_feed_health(account_id: str = "") -> dict:
|
|
|
750
811
|
return _impl(current_config(), account_id=account_id)
|
|
751
812
|
|
|
752
813
|
|
|
753
|
-
@
|
|
814
|
+
@_tool(title="List Google Ads accounts", annotations=_READONLY, tags={"ads"})
|
|
754
815
|
@_safe
|
|
755
816
|
def list_accounts(limit: int = 200) -> dict:
|
|
756
817
|
"""List accessible Google Ads accounts.
|
|
@@ -769,7 +830,7 @@ def list_accounts(limit: int = 200) -> dict:
|
|
|
769
830
|
return _impl(current_config(), limit=limit)
|
|
770
831
|
|
|
771
832
|
|
|
772
|
-
@
|
|
833
|
+
@_tool(title="Campaign performance", annotations=_READONLY, tags={"ads"})
|
|
773
834
|
@_safe
|
|
774
835
|
def get_campaign_performance(
|
|
775
836
|
customer_id: str = "",
|
|
@@ -798,7 +859,7 @@ def get_campaign_performance(
|
|
|
798
859
|
)
|
|
799
860
|
|
|
800
861
|
|
|
801
|
-
@
|
|
862
|
+
@_tool(title="Ad performance", annotations=_READONLY, tags={"ads"})
|
|
802
863
|
@_safe
|
|
803
864
|
def get_ad_performance(
|
|
804
865
|
customer_id: str = "",
|
|
@@ -826,7 +887,7 @@ def get_ad_performance(
|
|
|
826
887
|
)
|
|
827
888
|
|
|
828
889
|
|
|
829
|
-
@
|
|
890
|
+
@_tool(title="Keyword performance", annotations=_READONLY, tags={"ads"})
|
|
830
891
|
@_safe
|
|
831
892
|
def get_keyword_performance(
|
|
832
893
|
customer_id: str = "",
|
|
@@ -854,7 +915,7 @@ def get_keyword_performance(
|
|
|
854
915
|
)
|
|
855
916
|
|
|
856
917
|
|
|
857
|
-
@
|
|
918
|
+
@_tool(title="Search terms report", annotations=_READONLY, tags={"ads"})
|
|
858
919
|
@_safe
|
|
859
920
|
def get_search_terms(
|
|
860
921
|
customer_id: str = "",
|
|
@@ -882,7 +943,7 @@ def get_search_terms(
|
|
|
882
943
|
)
|
|
883
944
|
|
|
884
945
|
|
|
885
|
-
@
|
|
946
|
+
@_tool(title="List negative keywords", annotations=_READONLY, tags={"ads"})
|
|
886
947
|
@_safe
|
|
887
948
|
def get_negative_keywords(
|
|
888
949
|
customer_id: str = "",
|
|
@@ -902,7 +963,7 @@ def get_negative_keywords(
|
|
|
902
963
|
)
|
|
903
964
|
|
|
904
965
|
|
|
905
|
-
@
|
|
966
|
+
@_tool(
|
|
906
967
|
title="List shared negative keyword lists",
|
|
907
968
|
annotations=_READONLY,
|
|
908
969
|
tags={"ads"},
|
|
@@ -922,7 +983,7 @@ def get_negative_keyword_lists(
|
|
|
922
983
|
return _impl(current_config(), customer_id=customer_id or current_config().ads.customer_id)
|
|
923
984
|
|
|
924
985
|
|
|
925
|
-
@
|
|
986
|
+
@_tool(
|
|
926
987
|
title="Keywords in a negative keyword list",
|
|
927
988
|
annotations=_READONLY,
|
|
928
989
|
tags={"ads"},
|
|
@@ -945,7 +1006,7 @@ def get_negative_keyword_list_keywords(
|
|
|
945
1006
|
)
|
|
946
1007
|
|
|
947
1008
|
|
|
948
|
-
@
|
|
1009
|
+
@_tool(
|
|
949
1010
|
title="Campaigns using a negative keyword list",
|
|
950
1011
|
annotations=_READONLY,
|
|
951
1012
|
tags={"ads"},
|
|
@@ -974,7 +1035,7 @@ def get_negative_keyword_list_campaigns(
|
|
|
974
1035
|
# ---------------------------------------------------------------------------
|
|
975
1036
|
|
|
976
1037
|
|
|
977
|
-
@
|
|
1038
|
+
@_tool(title="Google Ads recommendations", annotations=_READONLY, tags={"ads"})
|
|
978
1039
|
@_safe
|
|
979
1040
|
def get_recommendations(
|
|
980
1041
|
customer_id: str = "",
|
|
@@ -1003,7 +1064,7 @@ def get_recommendations(
|
|
|
1003
1064
|
)
|
|
1004
1065
|
|
|
1005
1066
|
|
|
1006
|
-
@
|
|
1067
|
+
@_tool(title="Performance Max performance", annotations=_READONLY, tags={"ads"})
|
|
1007
1068
|
@_safe
|
|
1008
1069
|
def get_pmax_performance(
|
|
1009
1070
|
customer_id: str = "",
|
|
@@ -1034,7 +1095,7 @@ def get_pmax_performance(
|
|
|
1034
1095
|
)
|
|
1035
1096
|
|
|
1036
1097
|
|
|
1037
|
-
@
|
|
1098
|
+
@_tool(
|
|
1038
1099
|
title="Performance Max asset performance",
|
|
1039
1100
|
annotations=_READONLY,
|
|
1040
1101
|
tags={"ads"},
|
|
@@ -1067,7 +1128,7 @@ def get_asset_performance(
|
|
|
1067
1128
|
)
|
|
1068
1129
|
|
|
1069
1130
|
|
|
1070
|
-
@
|
|
1131
|
+
@_tool(
|
|
1071
1132
|
title="Performance Max asset combinations",
|
|
1072
1133
|
annotations=_READONLY,
|
|
1073
1134
|
tags={"ads"},
|
|
@@ -1094,7 +1155,7 @@ def get_detailed_asset_performance(
|
|
|
1094
1155
|
)
|
|
1095
1156
|
|
|
1096
1157
|
|
|
1097
|
-
@
|
|
1158
|
+
@_tool(title="Audience performance", annotations=_READONLY, tags={"ads"})
|
|
1098
1159
|
@_safe
|
|
1099
1160
|
def get_audience_performance(
|
|
1100
1161
|
customer_id: str = "",
|
|
@@ -1125,7 +1186,7 @@ def get_audience_performance(
|
|
|
1125
1186
|
)
|
|
1126
1187
|
|
|
1127
1188
|
|
|
1128
|
-
@
|
|
1189
|
+
@_tool(title="Demographic targeting", annotations=_READONLY, tags={"ads"})
|
|
1129
1190
|
@_safe
|
|
1130
1191
|
def get_demographic_targeting(
|
|
1131
1192
|
ad_group_id: str = "",
|
|
@@ -1158,7 +1219,7 @@ def get_demographic_targeting(
|
|
|
1158
1219
|
# ---------------------------------------------------------------------------
|
|
1159
1220
|
|
|
1160
1221
|
|
|
1161
|
-
@
|
|
1222
|
+
@_tool(
|
|
1162
1223
|
title="Campaign conversions against Analytics",
|
|
1163
1224
|
annotations=_READONLY,
|
|
1164
1225
|
tags={"tracking"},
|
|
@@ -1192,7 +1253,7 @@ def analyze_campaign_conversions(
|
|
|
1192
1253
|
)
|
|
1193
1254
|
|
|
1194
1255
|
|
|
1195
|
-
@
|
|
1256
|
+
@_tool(title="Landing page analysis", annotations=_READONLY, tags={"tracking"})
|
|
1196
1257
|
@_safe
|
|
1197
1258
|
def landing_page_analysis(
|
|
1198
1259
|
date_range_start: str = "",
|
|
@@ -1218,7 +1279,7 @@ def landing_page_analysis(
|
|
|
1218
1279
|
)
|
|
1219
1280
|
|
|
1220
1281
|
|
|
1221
|
-
@
|
|
1282
|
+
@_tool(title="Attribution check", annotations=_READONLY, tags={"tracking"})
|
|
1222
1283
|
@_safe
|
|
1223
1284
|
def attribution_check(
|
|
1224
1285
|
date_range_start: str = "",
|
|
@@ -1249,7 +1310,7 @@ def attribution_check(
|
|
|
1249
1310
|
)
|
|
1250
1311
|
|
|
1251
1312
|
|
|
1252
|
-
@
|
|
1313
|
+
@_tool(title="Tracking coverage audit", annotations=_READONLY, tags={"gtm"})
|
|
1253
1314
|
@_safe
|
|
1254
1315
|
def audit_event_coverage(
|
|
1255
1316
|
expected_events: list[str],
|
|
@@ -1302,7 +1363,7 @@ def audit_event_coverage(
|
|
|
1302
1363
|
)
|
|
1303
1364
|
|
|
1304
1365
|
|
|
1305
|
-
@
|
|
1366
|
+
@_tool(title="List Tag Manager accounts", annotations=_READONLY, tags={"gtm"})
|
|
1306
1367
|
@_safe
|
|
1307
1368
|
def list_gtm_accounts() -> dict:
|
|
1308
1369
|
"""List all GTM accounts the AdLoop service account / OAuth user can read.
|
|
@@ -1317,7 +1378,7 @@ def list_gtm_accounts() -> dict:
|
|
|
1317
1378
|
return _impl(current_config())
|
|
1318
1379
|
|
|
1319
1380
|
|
|
1320
|
-
@
|
|
1381
|
+
@_tool(title="List Tag Manager containers", annotations=_READONLY, tags={"gtm"})
|
|
1321
1382
|
@_safe
|
|
1322
1383
|
def list_gtm_containers(gtm_account_id: str = "") -> dict:
|
|
1323
1384
|
"""List all containers under a GTM account.
|
|
@@ -1337,7 +1398,7 @@ def list_gtm_containers(gtm_account_id: str = "") -> dict:
|
|
|
1337
1398
|
return _impl(current_config(), account_id=gtm_account_id)
|
|
1338
1399
|
|
|
1339
1400
|
|
|
1340
|
-
@
|
|
1401
|
+
@_tool(title="List Tag Manager tags", annotations=_READONLY, tags={"gtm"})
|
|
1341
1402
|
@_safe
|
|
1342
1403
|
def list_gtm_tags(gtm_account_id: str = "", gtm_container_id: str = "") -> dict:
|
|
1343
1404
|
"""List every tag in the LIVE GTM container.
|
|
@@ -1357,7 +1418,7 @@ def list_gtm_tags(gtm_account_id: str = "", gtm_container_id: str = "") -> dict:
|
|
|
1357
1418
|
)
|
|
1358
1419
|
|
|
1359
1420
|
|
|
1360
|
-
@
|
|
1421
|
+
@_tool(title="Tag Manager tag details", annotations=_READONLY, tags={"gtm"})
|
|
1361
1422
|
@_safe
|
|
1362
1423
|
def get_gtm_tag(
|
|
1363
1424
|
tag_id: str, gtm_account_id: str = "", gtm_container_id: str = ""
|
|
@@ -1382,7 +1443,7 @@ def get_gtm_tag(
|
|
|
1382
1443
|
)
|
|
1383
1444
|
|
|
1384
1445
|
|
|
1385
|
-
@
|
|
1446
|
+
@_tool(title="List Tag Manager triggers", annotations=_READONLY, tags={"gtm"})
|
|
1386
1447
|
@_safe
|
|
1387
1448
|
def list_gtm_triggers(gtm_account_id: str = "", gtm_container_id: str = "") -> dict:
|
|
1388
1449
|
"""List every trigger in the LIVE GTM container.
|
|
@@ -1402,7 +1463,7 @@ def list_gtm_triggers(gtm_account_id: str = "", gtm_container_id: str = "") -> d
|
|
|
1402
1463
|
)
|
|
1403
1464
|
|
|
1404
1465
|
|
|
1405
|
-
@
|
|
1466
|
+
@_tool(title="Tag Manager trigger details", annotations=_READONLY, tags={"gtm"})
|
|
1406
1467
|
@_safe
|
|
1407
1468
|
def get_gtm_trigger(
|
|
1408
1469
|
trigger_id: str, gtm_account_id: str = "", gtm_container_id: str = ""
|
|
@@ -1427,7 +1488,7 @@ def get_gtm_trigger(
|
|
|
1427
1488
|
)
|
|
1428
1489
|
|
|
1429
1490
|
|
|
1430
|
-
@
|
|
1491
|
+
@_tool(title="List Tag Manager variables", annotations=_READONLY, tags={"gtm"})
|
|
1431
1492
|
@_safe
|
|
1432
1493
|
def list_gtm_variables(gtm_account_id: str = "", gtm_container_id: str = "") -> dict:
|
|
1433
1494
|
"""List GTM variables — both custom and enabled built-in.
|
|
@@ -1449,7 +1510,7 @@ def list_gtm_variables(gtm_account_id: str = "", gtm_container_id: str = "") ->
|
|
|
1449
1510
|
)
|
|
1450
1511
|
|
|
1451
1512
|
|
|
1452
|
-
@
|
|
1513
|
+
@_tool(title="List Tag Manager workspaces", annotations=_READONLY, tags={"gtm"})
|
|
1453
1514
|
@_safe
|
|
1454
1515
|
def list_gtm_workspaces(gtm_account_id: str = "", gtm_container_id: str = "") -> dict:
|
|
1455
1516
|
"""List workspaces (drafts) under a GTM container.
|
|
@@ -1469,7 +1530,7 @@ def list_gtm_workspaces(gtm_account_id: str = "", gtm_container_id: str = "") ->
|
|
|
1469
1530
|
)
|
|
1470
1531
|
|
|
1471
1532
|
|
|
1472
|
-
@
|
|
1533
|
+
@_tool(title="Tag Manager workspace changes", annotations=_READONLY, tags={"gtm"})
|
|
1473
1534
|
@_safe
|
|
1474
1535
|
def get_gtm_workspace_diff(
|
|
1475
1536
|
workspace_id: str, gtm_account_id: str = "", gtm_container_id: str = ""
|
|
@@ -1496,7 +1557,7 @@ def get_gtm_workspace_diff(
|
|
|
1496
1557
|
)
|
|
1497
1558
|
|
|
1498
1559
|
|
|
1499
|
-
@
|
|
1560
|
+
@_tool(title="Tag Manager version history", annotations=_READONLY, tags={"gtm"})
|
|
1500
1561
|
@_safe
|
|
1501
1562
|
def list_gtm_versions(
|
|
1502
1563
|
gtm_account_id: str = "", gtm_container_id: str = "", page_size: int = 50
|
|
@@ -1522,7 +1583,7 @@ def list_gtm_versions(
|
|
|
1522
1583
|
)
|
|
1523
1584
|
|
|
1524
1585
|
|
|
1525
|
-
@
|
|
1586
|
+
@_tool(title="Tag Manager version details", annotations=_READONLY, tags={"gtm"})
|
|
1526
1587
|
@_safe
|
|
1527
1588
|
def get_gtm_version(
|
|
1528
1589
|
container_version_id: str, gtm_account_id: str = "", gtm_container_id: str = ""
|
|
@@ -1547,7 +1608,7 @@ def get_gtm_version(
|
|
|
1547
1608
|
)
|
|
1548
1609
|
|
|
1549
1610
|
|
|
1550
|
-
@
|
|
1611
|
+
@_tool(title="Custom Google Ads query", annotations=_READONLY, tags={"ads"})
|
|
1551
1612
|
@_safe
|
|
1552
1613
|
def run_gaql(
|
|
1553
1614
|
query: str,
|
|
@@ -1577,7 +1638,7 @@ def run_gaql(
|
|
|
1577
1638
|
# ---------------------------------------------------------------------------
|
|
1578
1639
|
|
|
1579
1640
|
|
|
1580
|
-
@
|
|
1641
|
+
@_tool(title="Draft a campaign", annotations=_WRITE, tags={"ads"})
|
|
1581
1642
|
@_safe
|
|
1582
1643
|
def draft_campaign(
|
|
1583
1644
|
campaign_name: str,
|
|
@@ -1644,7 +1705,7 @@ def draft_campaign(
|
|
|
1644
1705
|
)
|
|
1645
1706
|
|
|
1646
1707
|
|
|
1647
|
-
@
|
|
1708
|
+
@_tool(title="Draft an ad group", annotations=_WRITE, tags={"ads"})
|
|
1648
1709
|
@_safe
|
|
1649
1710
|
def draft_ad_group(
|
|
1650
1711
|
campaign_id: str,
|
|
@@ -1677,7 +1738,7 @@ def draft_ad_group(
|
|
|
1677
1738
|
)
|
|
1678
1739
|
|
|
1679
1740
|
|
|
1680
|
-
@
|
|
1741
|
+
@_tool(title="Draft campaign changes", annotations=_WRITE, tags={"ads"})
|
|
1681
1742
|
@_safe
|
|
1682
1743
|
def update_campaign(
|
|
1683
1744
|
campaign_id: str,
|
|
@@ -1734,7 +1795,7 @@ def update_campaign(
|
|
|
1734
1795
|
)
|
|
1735
1796
|
|
|
1736
1797
|
|
|
1737
|
-
@
|
|
1798
|
+
@_tool(title="Draft a responsive search ad", annotations=_WRITE, tags={"ads"})
|
|
1738
1799
|
@_safe
|
|
1739
1800
|
def draft_responsive_search_ad(
|
|
1740
1801
|
ad_group_id: str,
|
|
@@ -1777,7 +1838,7 @@ def draft_responsive_search_ad(
|
|
|
1777
1838
|
)
|
|
1778
1839
|
|
|
1779
1840
|
|
|
1780
|
-
@
|
|
1841
|
+
@_tool(title="Update a responsive search ad", annotations=_WRITE, tags={"ads"})
|
|
1781
1842
|
@_safe
|
|
1782
1843
|
def update_responsive_search_ad(
|
|
1783
1844
|
ad_id: str,
|
|
@@ -1836,7 +1897,7 @@ def update_responsive_search_ad(
|
|
|
1836
1897
|
)
|
|
1837
1898
|
|
|
1838
1899
|
|
|
1839
|
-
@
|
|
1900
|
+
@_tool(title="Draft keywords", annotations=_WRITE, tags={"ads"})
|
|
1840
1901
|
@_safe
|
|
1841
1902
|
def draft_keywords(
|
|
1842
1903
|
ad_group_id: str,
|
|
@@ -1858,7 +1919,7 @@ def draft_keywords(
|
|
|
1858
1919
|
)
|
|
1859
1920
|
|
|
1860
1921
|
|
|
1861
|
-
@
|
|
1922
|
+
@_tool(title="Custom conversion goals", annotations=_READONLY, tags={"ads"})
|
|
1862
1923
|
@_safe
|
|
1863
1924
|
def get_custom_conversion_goals(
|
|
1864
1925
|
campaign_id: str = "",
|
|
@@ -1887,7 +1948,7 @@ def get_custom_conversion_goals(
|
|
|
1887
1948
|
)
|
|
1888
1949
|
|
|
1889
1950
|
|
|
1890
|
-
@
|
|
1951
|
+
@_tool(
|
|
1891
1952
|
title="Draft a custom conversion goal",
|
|
1892
1953
|
annotations=_WRITE,
|
|
1893
1954
|
tags={"ads"},
|
|
@@ -1931,7 +1992,7 @@ def draft_custom_conversion_goal(
|
|
|
1931
1992
|
)
|
|
1932
1993
|
|
|
1933
1994
|
|
|
1934
|
-
@
|
|
1995
|
+
@_tool(
|
|
1935
1996
|
title="Draft changes to a custom conversion goal",
|
|
1936
1997
|
annotations=_WRITE,
|
|
1937
1998
|
tags={"ads"},
|
|
@@ -1969,7 +2030,7 @@ def draft_update_custom_conversion_goal(
|
|
|
1969
2030
|
)
|
|
1970
2031
|
|
|
1971
2032
|
|
|
1972
|
-
@
|
|
2033
|
+
@_tool(
|
|
1973
2034
|
title="Draft assigning a custom conversion goal",
|
|
1974
2035
|
annotations=_WRITE,
|
|
1975
2036
|
tags={"ads"},
|
|
@@ -2012,7 +2073,7 @@ def draft_assign_custom_conversion_goal(
|
|
|
2012
2073
|
)
|
|
2013
2074
|
|
|
2014
2075
|
|
|
2015
|
-
@
|
|
2076
|
+
@_tool(
|
|
2016
2077
|
title="Draft clearing a custom conversion goal",
|
|
2017
2078
|
annotations=_WRITE,
|
|
2018
2079
|
tags={"ads"},
|
|
@@ -2043,7 +2104,7 @@ def draft_clear_custom_conversion_goal(
|
|
|
2043
2104
|
)
|
|
2044
2105
|
|
|
2045
2106
|
|
|
2046
|
-
@
|
|
2107
|
+
@_tool(title="Draft negative keywords", annotations=_WRITE, tags={"ads"})
|
|
2047
2108
|
@_safe
|
|
2048
2109
|
def add_negative_keywords(
|
|
2049
2110
|
campaign_id: str,
|
|
@@ -2068,7 +2129,7 @@ def add_negative_keywords(
|
|
|
2068
2129
|
)
|
|
2069
2130
|
|
|
2070
2131
|
|
|
2071
|
-
@
|
|
2132
|
+
@_tool(title="Draft negative locations", annotations=_WRITE, tags={"ads"})
|
|
2072
2133
|
@_safe
|
|
2073
2134
|
def add_negative_locations(
|
|
2074
2135
|
campaign_id: str,
|
|
@@ -2092,7 +2153,7 @@ def add_negative_locations(
|
|
|
2092
2153
|
)
|
|
2093
2154
|
|
|
2094
2155
|
|
|
2095
|
-
@
|
|
2156
|
+
@_tool(
|
|
2096
2157
|
title="Draft a shared negative keyword list",
|
|
2097
2158
|
annotations=_WRITE,
|
|
2098
2159
|
tags={"ads"},
|
|
@@ -2124,7 +2185,7 @@ def propose_negative_keyword_list(
|
|
|
2124
2185
|
)
|
|
2125
2186
|
|
|
2126
2187
|
|
|
2127
|
-
@
|
|
2188
|
+
@_tool(
|
|
2128
2189
|
title="Draft additions to a negative keyword list",
|
|
2129
2190
|
annotations=_WRITE,
|
|
2130
2191
|
tags={"ads"},
|
|
@@ -2161,7 +2222,7 @@ def add_to_negative_keyword_list(
|
|
|
2161
2222
|
)
|
|
2162
2223
|
|
|
2163
2224
|
|
|
2164
|
-
@
|
|
2225
|
+
@_tool(title="Draft attaching a shared set", annotations=_WRITE, tags={"ads"})
|
|
2165
2226
|
@_safe
|
|
2166
2227
|
def attach_shared_set_to_campaigns(
|
|
2167
2228
|
shared_set_id: str,
|
|
@@ -2192,7 +2253,7 @@ def attach_shared_set_to_campaigns(
|
|
|
2192
2253
|
)
|
|
2193
2254
|
|
|
2194
2255
|
|
|
2195
|
-
@
|
|
2256
|
+
@_tool(title="Draft detaching a shared set", annotations=_WRITE, tags={"ads"})
|
|
2196
2257
|
@_safe
|
|
2197
2258
|
def detach_shared_set_from_campaigns(
|
|
2198
2259
|
shared_set_id: str,
|
|
@@ -2223,7 +2284,7 @@ def detach_shared_set_from_campaigns(
|
|
|
2223
2284
|
)
|
|
2224
2285
|
|
|
2225
2286
|
|
|
2226
|
-
@
|
|
2287
|
+
@_tool(title="AI Max settings", annotations=_READONLY, tags={"ads"})
|
|
2227
2288
|
@_safe
|
|
2228
2289
|
def get_ai_max_settings(
|
|
2229
2290
|
campaign_id: str = "",
|
|
@@ -2253,7 +2314,7 @@ def get_ai_max_settings(
|
|
|
2253
2314
|
campaign_id=campaign_id,
|
|
2254
2315
|
)
|
|
2255
2316
|
|
|
2256
|
-
@
|
|
2317
|
+
@_tool(title="Draft AI Max settings", annotations=_WRITE, tags={"ads"})
|
|
2257
2318
|
@_safe
|
|
2258
2319
|
def draft_ai_max_settings(
|
|
2259
2320
|
campaign_id: str,
|
|
@@ -2318,7 +2379,7 @@ def draft_ai_max_settings(
|
|
|
2318
2379
|
)
|
|
2319
2380
|
|
|
2320
2381
|
|
|
2321
|
-
@
|
|
2382
|
+
@_tool(
|
|
2322
2383
|
title="Prepare a campaign for brand exclusions",
|
|
2323
2384
|
annotations=_WRITE,
|
|
2324
2385
|
tags={"ads"},
|
|
@@ -2361,7 +2422,7 @@ def draft_prepare_brand_exclusions(
|
|
|
2361
2422
|
include_paused_ad_groups=include_paused_ad_groups,
|
|
2362
2423
|
)
|
|
2363
2424
|
|
|
2364
|
-
@
|
|
2425
|
+
@_tool(title="Draft demographic targeting", annotations=_WRITE, tags={"ads"})
|
|
2365
2426
|
@_safe
|
|
2366
2427
|
def draft_demographic_targeting(
|
|
2367
2428
|
customer_id: str = "",
|
|
@@ -2413,7 +2474,7 @@ def draft_demographic_targeting(
|
|
|
2413
2474
|
)
|
|
2414
2475
|
|
|
2415
2476
|
|
|
2416
|
-
@
|
|
2477
|
+
@_tool(title="Draft ad group changes", annotations=_WRITE, tags={"ads"})
|
|
2417
2478
|
@_safe
|
|
2418
2479
|
def update_ad_group(
|
|
2419
2480
|
ad_group_id: str,
|
|
@@ -2433,7 +2494,7 @@ def update_ad_group(
|
|
|
2433
2494
|
)
|
|
2434
2495
|
|
|
2435
2496
|
|
|
2436
|
-
@
|
|
2497
|
+
@_tool(title="Draft callouts", annotations=_WRITE, tags={"ads"})
|
|
2437
2498
|
@_safe
|
|
2438
2499
|
def draft_callouts(
|
|
2439
2500
|
campaign_id: str,
|
|
@@ -2451,7 +2512,7 @@ def draft_callouts(
|
|
|
2451
2512
|
)
|
|
2452
2513
|
|
|
2453
2514
|
|
|
2454
|
-
@
|
|
2515
|
+
@_tool(title="Draft structured snippets", annotations=_WRITE, tags={"ads"})
|
|
2455
2516
|
@_safe
|
|
2456
2517
|
def draft_structured_snippets(
|
|
2457
2518
|
campaign_id: str,
|
|
@@ -2469,7 +2530,7 @@ def draft_structured_snippets(
|
|
|
2469
2530
|
)
|
|
2470
2531
|
|
|
2471
2532
|
|
|
2472
|
-
@
|
|
2533
|
+
@_tool(title="Draft image assets", annotations=_WRITE, tags={"ads"})
|
|
2473
2534
|
@_safe
|
|
2474
2535
|
def draft_image_assets(
|
|
2475
2536
|
campaign_id: str,
|
|
@@ -2503,7 +2564,7 @@ def draft_image_assets(
|
|
|
2503
2564
|
)
|
|
2504
2565
|
|
|
2505
2566
|
|
|
2506
|
-
@
|
|
2567
|
+
@_tool(title="Draft pausing an entity", annotations=_WRITE, tags={"ads"})
|
|
2507
2568
|
@_safe
|
|
2508
2569
|
def pause_entity(
|
|
2509
2570
|
entity_type: str,
|
|
@@ -2531,7 +2592,7 @@ def pause_entity(
|
|
|
2531
2592
|
)
|
|
2532
2593
|
|
|
2533
2594
|
|
|
2534
|
-
@
|
|
2595
|
+
@_tool(title="Draft enabling an entity", annotations=_WRITE, tags={"ads"})
|
|
2535
2596
|
@_safe
|
|
2536
2597
|
def enable_entity(
|
|
2537
2598
|
entity_type: str,
|
|
@@ -2559,7 +2620,7 @@ def enable_entity(
|
|
|
2559
2620
|
)
|
|
2560
2621
|
|
|
2561
2622
|
|
|
2562
|
-
@
|
|
2623
|
+
@_tool(title="Draft removing an entity", annotations=_DESTRUCTIVE, tags={"ads"})
|
|
2563
2624
|
@_safe
|
|
2564
2625
|
def remove_entity(
|
|
2565
2626
|
entity_type: str,
|
|
@@ -2595,7 +2656,7 @@ def remove_entity(
|
|
|
2595
2656
|
)
|
|
2596
2657
|
|
|
2597
2658
|
|
|
2598
|
-
@
|
|
2659
|
+
@_tool(title="Draft sitelinks", annotations=_WRITE, tags={"ads"})
|
|
2599
2660
|
@_safe
|
|
2600
2661
|
def draft_sitelinks(
|
|
2601
2662
|
campaign_id: str,
|
|
@@ -2628,7 +2689,7 @@ def draft_sitelinks(
|
|
|
2628
2689
|
)
|
|
2629
2690
|
|
|
2630
2691
|
|
|
2631
|
-
@
|
|
2692
|
+
@_tool(title="Apply a previewed change", annotations=_DESTRUCTIVE, tags={"core"})
|
|
2632
2693
|
@_safe
|
|
2633
2694
|
def confirm_and_apply(
|
|
2634
2695
|
plan_id: str,
|
|
@@ -2681,7 +2742,7 @@ def _reddit_account(ad_account_id: str) -> str:
|
|
|
2681
2742
|
return ad_account_id or current_config().reddit.ad_account_id
|
|
2682
2743
|
|
|
2683
2744
|
|
|
2684
|
-
@
|
|
2745
|
+
@_tool(title="List Reddit ad accounts", annotations=_READONLY, tags={"reddit"})
|
|
2685
2746
|
@_safe
|
|
2686
2747
|
def list_reddit_accounts() -> dict:
|
|
2687
2748
|
"""List Reddit businesses and ad accounts the connected Reddit user can access.
|
|
@@ -2695,7 +2756,7 @@ def list_reddit_accounts() -> dict:
|
|
|
2695
2756
|
return _impl(current_config())
|
|
2696
2757
|
|
|
2697
2758
|
|
|
2698
|
-
@
|
|
2759
|
+
@_tool(
|
|
2699
2760
|
title="Reddit billing + posting profiles", annotations=_READONLY, tags={"reddit"}
|
|
2700
2761
|
)
|
|
2701
2762
|
@_safe
|
|
@@ -2710,7 +2771,7 @@ def list_reddit_funding_instruments(ad_account_id: str = "") -> dict:
|
|
|
2710
2771
|
return _impl(current_config(), ad_account_id=_reddit_account(ad_account_id))
|
|
2711
2772
|
|
|
2712
2773
|
|
|
2713
|
-
@
|
|
2774
|
+
@_tool(title="Reddit campaigns", annotations=_READONLY, tags={"reddit"})
|
|
2714
2775
|
@_safe
|
|
2715
2776
|
def get_reddit_campaigns(ad_account_id: str = "", include_archived: bool = False) -> dict:
|
|
2716
2777
|
"""List Reddit campaigns with status, objective, budget mode and bids.
|
|
@@ -2729,7 +2790,7 @@ def get_reddit_campaigns(ad_account_id: str = "", include_archived: bool = False
|
|
|
2729
2790
|
)
|
|
2730
2791
|
|
|
2731
2792
|
|
|
2732
|
-
@
|
|
2793
|
+
@_tool(title="Reddit ad groups", annotations=_READONLY, tags={"reddit"})
|
|
2733
2794
|
@_safe
|
|
2734
2795
|
def get_reddit_ad_groups(ad_account_id: str = "", campaign_id: str = "") -> dict:
|
|
2735
2796
|
"""List Reddit ad groups (budget, bid, pixel, weekly schedule, targeting summary), optionally per campaign.
|
|
@@ -2746,7 +2807,7 @@ def get_reddit_ad_groups(ad_account_id: str = "", campaign_id: str = "") -> dict
|
|
|
2746
2807
|
)
|
|
2747
2808
|
|
|
2748
2809
|
|
|
2749
|
-
@
|
|
2810
|
+
@_tool(title="Reddit ads", annotations=_READONLY, tags={"reddit"})
|
|
2750
2811
|
@_safe
|
|
2751
2812
|
def get_reddit_ads(
|
|
2752
2813
|
ad_account_id: str = "",
|
|
@@ -2772,7 +2833,7 @@ def get_reddit_ads(
|
|
|
2772
2833
|
)
|
|
2773
2834
|
|
|
2774
2835
|
|
|
2775
|
-
@
|
|
2836
|
+
@_tool(title="Reddit performance", annotations=_READONLY, tags={"reddit"})
|
|
2776
2837
|
@_safe
|
|
2777
2838
|
def get_reddit_performance(
|
|
2778
2839
|
ad_account_id: str = "",
|
|
@@ -2808,7 +2869,7 @@ def get_reddit_performance(
|
|
|
2808
2869
|
)
|
|
2809
2870
|
|
|
2810
2871
|
|
|
2811
|
-
@
|
|
2872
|
+
@_tool(title="Raw Reddit report", annotations=_READONLY, tags={"reddit"})
|
|
2812
2873
|
@_safe
|
|
2813
2874
|
def run_reddit_report(
|
|
2814
2875
|
fields: _StrList,
|
|
@@ -2844,7 +2905,7 @@ def run_reddit_report(
|
|
|
2844
2905
|
)
|
|
2845
2906
|
|
|
2846
2907
|
|
|
2847
|
-
@
|
|
2908
|
+
@_tool(title="Reddit pixels", annotations=_READONLY, tags={"reddit"})
|
|
2848
2909
|
@_safe
|
|
2849
2910
|
def get_reddit_pixels(ad_account_id: str = "") -> dict:
|
|
2850
2911
|
"""Reddit pixels of the account and when each event (purchase, sign_up, lead, ...) last fired.
|
|
@@ -2858,7 +2919,7 @@ def get_reddit_pixels(ad_account_id: str = "") -> dict:
|
|
|
2858
2919
|
return _impl(current_config(), ad_account_id=_reddit_account(ad_account_id))
|
|
2859
2920
|
|
|
2860
2921
|
|
|
2861
|
-
@
|
|
2922
|
+
@_tool(title="Search Reddit targeting", annotations=_READONLY, tags={"reddit"})
|
|
2862
2923
|
@_safe
|
|
2863
2924
|
def search_reddit_targeting(
|
|
2864
2925
|
kind: str, query: str = "", country: str = "", website_url: str = "", limit: int = 25
|
|
@@ -2880,7 +2941,7 @@ def search_reddit_targeting(
|
|
|
2880
2941
|
)
|
|
2881
2942
|
|
|
2882
2943
|
|
|
2883
|
-
@
|
|
2944
|
+
@_tool(title="Reddit account change history", annotations=_READONLY, tags={"reddit"})
|
|
2884
2945
|
@_safe
|
|
2885
2946
|
def get_reddit_account_history(
|
|
2886
2947
|
ad_account_id: str = "",
|
|
@@ -2911,7 +2972,7 @@ def get_reddit_account_history(
|
|
|
2911
2972
|
)
|
|
2912
2973
|
|
|
2913
2974
|
|
|
2914
|
-
@
|
|
2975
|
+
@_tool(title="Estimate a Reddit ad group", annotations=_READONLY, tags={"reddit"})
|
|
2915
2976
|
@_safe
|
|
2916
2977
|
def estimate_reddit_ad_group(
|
|
2917
2978
|
daily_budget: float | None = None,
|
|
@@ -2971,7 +3032,7 @@ def estimate_reddit_ad_group(
|
|
|
2971
3032
|
)
|
|
2972
3033
|
|
|
2973
3034
|
|
|
2974
|
-
@
|
|
3035
|
+
@_tool(title="Draft pausing a Reddit entity", annotations=_WRITE, tags={"reddit"})
|
|
2975
3036
|
@_safe
|
|
2976
3037
|
def pause_reddit_entity(
|
|
2977
3038
|
entity_type: str, entity_id: str, ad_account_id: str = ""
|
|
@@ -2991,7 +3052,7 @@ def pause_reddit_entity(
|
|
|
2991
3052
|
)
|
|
2992
3053
|
|
|
2993
3054
|
|
|
2994
|
-
@
|
|
3055
|
+
@_tool(title="Draft enabling a Reddit entity", annotations=_WRITE, tags={"reddit"})
|
|
2995
3056
|
@_safe
|
|
2996
3057
|
def enable_reddit_entity(
|
|
2997
3058
|
entity_type: str, entity_id: str, ad_account_id: str = ""
|
|
@@ -3011,7 +3072,7 @@ def enable_reddit_entity(
|
|
|
3011
3072
|
)
|
|
3012
3073
|
|
|
3013
3074
|
|
|
3014
|
-
@
|
|
3075
|
+
@_tool(title="Draft archiving a Reddit entity", annotations=_DESTRUCTIVE, tags={"reddit"})
|
|
3015
3076
|
@_safe
|
|
3016
3077
|
def remove_reddit_entity(
|
|
3017
3078
|
entity_type: str, entity_id: str, ad_account_id: str = ""
|
|
@@ -3032,7 +3093,7 @@ def remove_reddit_entity(
|
|
|
3032
3093
|
)
|
|
3033
3094
|
|
|
3034
3095
|
|
|
3035
|
-
@
|
|
3096
|
+
@_tool(title="Draft Reddit campaign changes", annotations=_WRITE, tags={"reddit"})
|
|
3036
3097
|
@_safe
|
|
3037
3098
|
def update_reddit_campaign(
|
|
3038
3099
|
campaign_id: str,
|
|
@@ -3080,7 +3141,7 @@ def update_reddit_campaign(
|
|
|
3080
3141
|
)
|
|
3081
3142
|
|
|
3082
3143
|
|
|
3083
|
-
@
|
|
3144
|
+
@_tool(title="Draft Reddit ad group changes", annotations=_WRITE, tags={"reddit"})
|
|
3084
3145
|
@_safe
|
|
3085
3146
|
def update_reddit_ad_group(
|
|
3086
3147
|
ad_group_id: str,
|
|
@@ -3151,7 +3212,7 @@ def update_reddit_ad_group(
|
|
|
3151
3212
|
)
|
|
3152
3213
|
|
|
3153
3214
|
|
|
3154
|
-
@
|
|
3215
|
+
@_tool(title="Draft Reddit ad changes", annotations=_WRITE, tags={"reddit"})
|
|
3155
3216
|
@_safe
|
|
3156
3217
|
def update_reddit_ad(
|
|
3157
3218
|
ad_id: str,
|
|
@@ -3178,7 +3239,7 @@ def update_reddit_ad(
|
|
|
3178
3239
|
)
|
|
3179
3240
|
|
|
3180
3241
|
|
|
3181
|
-
@
|
|
3242
|
+
@_tool(title="Draft a Reddit campaign", annotations=_WRITE, tags={"reddit"})
|
|
3182
3243
|
@_safe
|
|
3183
3244
|
def draft_reddit_campaign(
|
|
3184
3245
|
campaign_name: str,
|
|
@@ -3237,7 +3298,7 @@ def draft_reddit_campaign(
|
|
|
3237
3298
|
)
|
|
3238
3299
|
|
|
3239
3300
|
|
|
3240
|
-
@
|
|
3301
|
+
@_tool(title="Draft a Reddit ad group", annotations=_WRITE, tags={"reddit"})
|
|
3241
3302
|
@_safe
|
|
3242
3303
|
def draft_reddit_ad_group(
|
|
3243
3304
|
campaign_id: str,
|
|
@@ -3318,7 +3379,7 @@ def draft_reddit_ad_group(
|
|
|
3318
3379
|
)
|
|
3319
3380
|
|
|
3320
3381
|
|
|
3321
|
-
@
|
|
3382
|
+
@_tool(title="Draft a Reddit ad", annotations=_WRITE, tags={"reddit"})
|
|
3322
3383
|
@_safe
|
|
3323
3384
|
def draft_reddit_ad(
|
|
3324
3385
|
ad_group_id: str,
|
|
@@ -3374,7 +3435,7 @@ def draft_reddit_ad(
|
|
|
3374
3435
|
# ---------------------------------------------------------------------------
|
|
3375
3436
|
|
|
3376
3437
|
|
|
3377
|
-
@
|
|
3438
|
+
@_tool(title="Draft an Analytics key event", annotations=_WRITE, tags={"ga4"})
|
|
3378
3439
|
@_safe
|
|
3379
3440
|
def draft_key_event(
|
|
3380
3441
|
event_name: str,
|
|
@@ -3399,7 +3460,7 @@ def draft_key_event(
|
|
|
3399
3460
|
)
|
|
3400
3461
|
|
|
3401
3462
|
|
|
3402
|
-
@
|
|
3463
|
+
@_tool(title="Draft a conversion action", annotations=_WRITE, tags={"ads"})
|
|
3403
3464
|
@_safe
|
|
3404
3465
|
def draft_create_conversion_action(
|
|
3405
3466
|
name: str,
|
|
@@ -3452,7 +3513,7 @@ def draft_create_conversion_action(
|
|
|
3452
3513
|
)
|
|
3453
3514
|
|
|
3454
3515
|
|
|
3455
|
-
@
|
|
3516
|
+
@_tool(title="Draft conversion action changes", annotations=_WRITE, tags={"ads"})
|
|
3456
3517
|
@_safe
|
|
3457
3518
|
def draft_update_conversion_action(
|
|
3458
3519
|
conversion_action_id: str,
|
|
@@ -3499,7 +3560,7 @@ def draft_update_conversion_action(
|
|
|
3499
3560
|
)
|
|
3500
3561
|
|
|
3501
3562
|
|
|
3502
|
-
@
|
|
3563
|
+
@_tool(title="Draft removing a conversion action", annotations=_WRITE, tags={"ads"})
|
|
3503
3564
|
@_safe
|
|
3504
3565
|
def draft_remove_conversion_action(
|
|
3505
3566
|
conversion_action_id: str,
|
|
@@ -3523,7 +3584,7 @@ def draft_remove_conversion_action(
|
|
|
3523
3584
|
)
|
|
3524
3585
|
|
|
3525
3586
|
|
|
3526
|
-
@
|
|
3587
|
+
@_tool(title="Validate tracking", annotations=_READONLY, tags={"tracking"})
|
|
3527
3588
|
@_safe
|
|
3528
3589
|
def validate_tracking(
|
|
3529
3590
|
expected_events: _StrList,
|
|
@@ -3551,7 +3612,7 @@ def validate_tracking(
|
|
|
3551
3612
|
)
|
|
3552
3613
|
|
|
3553
3614
|
|
|
3554
|
-
@
|
|
3615
|
+
@_tool(title="Generate tracking code", annotations=_READONLY, tags={"tracking"})
|
|
3555
3616
|
@_safe
|
|
3556
3617
|
def generate_tracking_code(
|
|
3557
3618
|
event_name: str,
|
|
@@ -3586,7 +3647,7 @@ def generate_tracking_code(
|
|
|
3586
3647
|
# ---------------------------------------------------------------------------
|
|
3587
3648
|
|
|
3588
3649
|
|
|
3589
|
-
@
|
|
3650
|
+
@_tool(title="Budget forecast", annotations=_READONLY, tags={"ads"})
|
|
3590
3651
|
@_safe
|
|
3591
3652
|
def estimate_budget(
|
|
3592
3653
|
keywords: _DictList,
|
|
@@ -3623,7 +3684,7 @@ def estimate_budget(
|
|
|
3623
3684
|
)
|
|
3624
3685
|
|
|
3625
3686
|
|
|
3626
|
-
@
|
|
3687
|
+
@_tool(title="Keyword ideas", annotations=_READONLY, tags={"ads"})
|
|
3627
3688
|
@_safe
|
|
3628
3689
|
def discover_keywords(
|
|
3629
3690
|
seed_keywords: _StrList = [], # noqa: B006 — mutable default required for MCP JSON schema
|
|
@@ -3671,7 +3732,7 @@ def discover_keywords(
|
|
|
3671
3732
|
# ---------------------------------------------------------------------------
|
|
3672
3733
|
|
|
3673
3734
|
|
|
3674
|
-
@
|
|
3735
|
+
@_tool(title="Suggest brands", annotations=_READONLY, tags={"ads"})
|
|
3675
3736
|
@_safe
|
|
3676
3737
|
def suggest_brands(
|
|
3677
3738
|
brand_prefix: str,
|
|
@@ -3708,7 +3769,7 @@ def suggest_brands(
|
|
|
3708
3769
|
)
|
|
3709
3770
|
|
|
3710
3771
|
|
|
3711
|
-
@
|
|
3772
|
+
@_tool(title="Check brand names", annotations=_READONLY, tags={"ads"})
|
|
3712
3773
|
@_safe
|
|
3713
3774
|
def check_brand_names(
|
|
3714
3775
|
brand_names: _StrList,
|
|
@@ -3741,7 +3802,7 @@ def check_brand_names(
|
|
|
3741
3802
|
customer_id=customer_id or current_config().ads.customer_id,
|
|
3742
3803
|
)
|
|
3743
3804
|
|
|
3744
|
-
@
|
|
3805
|
+
@_tool(title="List brand lists", annotations=_READONLY, tags={"ads"})
|
|
3745
3806
|
@_safe
|
|
3746
3807
|
def get_brand_lists(
|
|
3747
3808
|
customer_id: str = "",
|
|
@@ -3761,7 +3822,7 @@ def get_brand_lists(
|
|
|
3761
3822
|
customer_id=customer_id or current_config().ads.customer_id,
|
|
3762
3823
|
)
|
|
3763
3824
|
|
|
3764
|
-
@
|
|
3825
|
+
@_tool(title="Brands in a brand list", annotations=_READONLY, tags={"ads"})
|
|
3765
3826
|
@_safe
|
|
3766
3827
|
def get_brand_list_brands(
|
|
3767
3828
|
shared_set_id: str,
|
|
@@ -3785,7 +3846,7 @@ def get_brand_list_brands(
|
|
|
3785
3846
|
shared_set_id=shared_set_id,
|
|
3786
3847
|
)
|
|
3787
3848
|
|
|
3788
|
-
@
|
|
3849
|
+
@_tool(title="Campaigns using a brand list", annotations=_READONLY, tags={"ads"})
|
|
3789
3850
|
@_safe
|
|
3790
3851
|
def get_brand_list_campaigns(
|
|
3791
3852
|
shared_set_id: str = "",
|
|
@@ -3811,7 +3872,7 @@ def get_brand_list_campaigns(
|
|
|
3811
3872
|
shared_set_id=shared_set_id,
|
|
3812
3873
|
)
|
|
3813
3874
|
|
|
3814
|
-
@
|
|
3875
|
+
@_tool(title="Draft a brand list", annotations=_WRITE, tags={"ads"})
|
|
3815
3876
|
@_safe
|
|
3816
3877
|
def propose_brand_list(
|
|
3817
3878
|
list_name: str,
|
|
@@ -3849,7 +3910,7 @@ def propose_brand_list(
|
|
|
3849
3910
|
negative=negative,
|
|
3850
3911
|
)
|
|
3851
3912
|
|
|
3852
|
-
@
|
|
3913
|
+
@_tool(title="Draft additions to a brand list", annotations=_WRITE, tags={"ads"})
|
|
3853
3914
|
@_safe
|
|
3854
3915
|
def add_to_brand_list(
|
|
3855
3916
|
shared_set_id: str,
|
|
@@ -3879,7 +3940,7 @@ def add_to_brand_list(
|
|
|
3879
3940
|
brand_ids=brand_ids,
|
|
3880
3941
|
)
|
|
3881
3942
|
|
|
3882
|
-
@
|
|
3943
|
+
@_tool(title="Draft removing brands from a list", annotations=_DESTRUCTIVE, tags={"ads"})
|
|
3883
3944
|
@_safe
|
|
3884
3945
|
def remove_from_brand_list(
|
|
3885
3946
|
shared_set_id: str,
|
|
@@ -3909,7 +3970,7 @@ def remove_from_brand_list(
|
|
|
3909
3970
|
criterion_ids=criterion_ids,
|
|
3910
3971
|
)
|
|
3911
3972
|
|
|
3912
|
-
@
|
|
3973
|
+
@_tool(title="Draft attaching a brand list", annotations=_WRITE, tags={"ads"})
|
|
3913
3974
|
@_safe
|
|
3914
3975
|
def attach_brand_list_to_campaigns(
|
|
3915
3976
|
shared_set_id: str,
|
|
@@ -3946,7 +4007,7 @@ def attach_brand_list_to_campaigns(
|
|
|
3946
4007
|
negative=negative,
|
|
3947
4008
|
)
|
|
3948
4009
|
|
|
3949
|
-
@
|
|
4010
|
+
@_tool(title="Draft detaching a brand list", annotations=_DESTRUCTIVE, tags={"ads"})
|
|
3950
4011
|
@_safe
|
|
3951
4012
|
def detach_brand_list_from_campaigns(
|
|
3952
4013
|
shared_set_id: str,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|