adloop 0.13.2__tar.gz → 0.14.0__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.13.2/README.md → adloop-0.14.0/PKG-INFO +67 -7
- adloop-0.13.2/PKG-INFO → adloop-0.14.0/README.md +39 -32
- {adloop-0.13.2 → adloop-0.14.0}/pyproject.toml +4 -2
- {adloop-0.13.2 → adloop-0.14.0}/pyproject.toml.orig +6 -3
- adloop-0.14.0/src/adloop/ads/conversion_actions.py +558 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/ads/read.py +46 -4
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/ads/write.py +339 -20
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/auth.py +23 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/cli.py +110 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/config.py +59 -12
- adloop-0.14.0/src/adloop/reddit/__init__.py +9 -0
- adloop-0.14.0/src/adloop/reddit/auth.py +504 -0
- adloop-0.14.0/src/adloop/reddit/client.py +270 -0
- adloop-0.14.0/src/adloop/reddit/read.py +1344 -0
- adloop-0.14.0/src/adloop/reddit/schedule.py +200 -0
- adloop-0.14.0/src/adloop/reddit/write.py +1684 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/rules/adloop.md +98 -17
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/safety/preview.py +4 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/server.py +1109 -72
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/__init__.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/__main__.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/_mcp_patches.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/ads/__init__.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/ads/client.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/ads/currency.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/ads/enums.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/ads/forecast.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/ads/gaql.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/ads/pmax.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/crossref.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/diagnostics.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/ga4/__init__.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/ga4/client.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/ga4/reports.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/ga4/tracking.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/ga4/write.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/gsc/__init__.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/gsc/client.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/gsc/reports.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/gtm/__init__.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/gtm/client.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/gtm/read.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/merchant/__init__.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/merchant/client.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/merchant/read.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/pagespeed.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/rules/__init__.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/rules/commands/analyze-performance.md +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/rules/commands/budget-plan.md +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/rules/commands/create-ad.md +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/rules/commands/create-campaign.md +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/rules/commands/diagnose-tracking.md +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/rules/commands/optimize-campaign.md +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/rules_install.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/runtime.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/safety/__init__.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/safety/audit.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/safety/guards.py +0 -0
- {adloop-0.13.2 → adloop-0.14.0}/src/adloop/tracking.py +0 -0
|
@@ -1,8 +1,37 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: adloop
|
|
3
|
+
Version: 0.14.0
|
|
4
|
+
Summary: The AI command center for Google Ads, Reddit Ads, GA4, and tracking code.
|
|
5
|
+
Keywords: mcp,google-ads,reddit-ads,google-analytics,ga4,cursor,marketing
|
|
6
|
+
Author: Daniel Klose
|
|
7
|
+
Author-email: Daniel Klose <info@daniel-klose.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
Requires-Dist: fastmcp>=3.0.0
|
|
10
|
+
Requires-Dist: google-ads>=31.1.0
|
|
11
|
+
Requires-Dist: google-analytics-data>=0.20.0
|
|
12
|
+
Requires-Dist: google-analytics-admin>=0.27.0
|
|
13
|
+
Requires-Dist: google-api-python-client>=2.100.0
|
|
14
|
+
Requires-Dist: google-auth-oauthlib>=1.0.0
|
|
15
|
+
Requires-Dist: google-api-python-client>=2.0.0
|
|
16
|
+
Requires-Dist: pyyaml>=6.0
|
|
17
|
+
Requires-Dist: requests>=2.31
|
|
18
|
+
Requires-Dist: pytest>=8.0 ; extra == 'dev'
|
|
19
|
+
Requires-Dist: pytest-asyncio>=0.23 ; extra == 'dev'
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Project-URL: Homepage, https://github.com/kLOsk/adloop
|
|
22
|
+
Project-URL: Repository, https://github.com/kLOsk/adloop
|
|
23
|
+
Project-URL: Issues, https://github.com/kLOsk/adloop/issues
|
|
24
|
+
Project-URL: Changelog, https://github.com/kLOsk/adloop/releases
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
<!-- mcp-name: com.getadloop/adloop -->
|
|
29
|
+
|
|
1
30
|
<div align="center">
|
|
2
31
|
|
|
3
32
|
# AdLoop
|
|
4
33
|
|
|
5
|
-
**The AI command center for Google Ads, GA4, and tracking code.**
|
|
34
|
+
**The AI command center for Google Ads, Reddit Ads, GA4, and tracking code.**
|
|
6
35
|
|
|
7
36
|
[](https://pypi.org/project/adloop/)
|
|
8
37
|
[](LICENSE)
|
|
@@ -12,14 +41,14 @@
|
|
|
12
41
|
[](https://developers.google.com/analytics/devguides/reporting/data/v1)
|
|
13
42
|
[](https://github.com/kLOsk/adloop)
|
|
14
43
|
|
|
15
|
-
An MCP server that gives your AI assistant read + write access to Google Ads and GA4 — with safety guardrails that prevent accidental spend.
|
|
44
|
+
An MCP server that gives your AI assistant read + write access to Google Ads, Reddit Ads and GA4 — with safety guardrails that prevent accidental spend.
|
|
16
45
|
|
|
17
|
-
**[☁️ Skip the setup — use AdLoop Cloud (free
|
|
46
|
+
**[☁️ Skip the setup — use AdLoop Cloud (free plan, no card)](https://getadloop.com)** · or self-host: `pip install adloop`
|
|
18
47
|
|
|
19
48
|
</div>
|
|
20
49
|
|
|
21
50
|
> [!TIP]
|
|
22
|
-
> **[AdLoop Cloud](https://getadloop.com) is the hosted version of this project
|
|
51
|
+
> **[AdLoop Cloud](https://getadloop.com) is the hosted version of this project, with a free plan that needs no credit card.** Connect Google in two clicks and use the full toolset from claude.ai, ChatGPT, Claude Code, Cursor, or Gemini. No Google Cloud project, no developer token, no OAuth verification wait. EU-hosted, GDPR-first, DPA included.
|
|
23
52
|
|
|
24
53
|
> 📚 **Documentation: [docs.getadloop.com](https://docs.getadloop.com)** — setup guides per AI client, toolsets, the safety model, and troubleshooting for both editions.
|
|
25
54
|
|
|
@@ -37,7 +66,7 @@ Both versions run the same tools with the same safety model. The difference is w
|
|
|
37
66
|
| **Works with** | claude.ai, ChatGPT, Claude Code, Cursor, Gemini | Claude Code, Cursor, Claude Desktop, any local MCP client |
|
|
38
67
|
| **Where your data flows** | EU servers (Germany), GDPR-first, DPA included | 100% your machine — nothing leaves it |
|
|
39
68
|
| **Updates** | Automatic | `pip install -U adloop` |
|
|
40
|
-
| **Price** | Free
|
|
69
|
+
| **Price** | Free plan, no card; [paid plans](https://getadloop.com/preise) for more accounts and volume | Free forever (MIT) |
|
|
41
70
|
|
|
42
71
|
**Not sure? [Start with Cloud](https://getadloop.com)** — it's the fastest way to see what AdLoop can do, and it's the only way to use AdLoop from claude.ai or ChatGPT. Self-host when you want everything on your own machine or need to modify the code. And if you're here to hack on AdLoop itself: welcome, keep scrolling.
|
|
43
72
|
|
|
@@ -169,6 +198,27 @@ These tools read the live GTM container and join it with the codebase + GA4 to f
|
|
|
169
198
|
|
|
170
199
|
> **Setup for GSC tools** — Enable the **Search Console API** in your GCP project. Upgrading OAuth users must re-authorize once for the new scope (delete `~/.adloop/token.json`, run any tool). The killer combo: cross-reference organic queries with `get_keyword_performance` to find paid/organic cannibalization and untapped keyword opportunities.
|
|
171
200
|
|
|
201
|
+
### Reddit Ads Tools
|
|
202
|
+
|
|
203
|
+
A second ad platform, same safety model. Reddit is a separate connection: its own developer app, its own OAuth, no developer token and no approval process. Every tool takes `ad_account_id` (defaults to `reddit.ad_account_id`).
|
|
204
|
+
|
|
205
|
+
| Tool | What It Does |
|
|
206
|
+
|------|-------------|
|
|
207
|
+
| `list_reddit_accounts` | Discover businesses and ad accounts (currency, time zone, approval state) |
|
|
208
|
+
| `list_reddit_funding_instruments` | Billing instruments and posting profiles — prerequisites for creating campaigns and ads |
|
|
209
|
+
| `get_reddit_campaigns` / `get_reddit_ad_groups` / `get_reddit_ads` | Structure with configured vs effective status, budgets, bids, pixel, targeting, weekly schedule, rejection reasons; `include_copy` returns each ad's post (headline, body, destination, media) |
|
|
210
|
+
| `get_reddit_performance` | Spend, clicks, CTR, CPC, conversions, CPA, ROAS per account/campaign/ad group/ad, optional breakdown (date, country, community, keyword, placement, …), compact mode with insights |
|
|
211
|
+
| `run_reddit_report` | Raw reports endpoint for any metric (REACH, video, per-event conversions) |
|
|
212
|
+
| `get_reddit_pixels` | Pixels and when each event last fired — flags ad groups optimizing for events the pixel never sent |
|
|
213
|
+
| `search_reddit_targeting` | Communities, interests, geolocations, languages, keyword suggestions, and Reddit's related-community suggestions (by seed communities or website) |
|
|
214
|
+
| `get_reddit_account_history` | Who changed what and when: field, before/after, member |
|
|
215
|
+
| `estimate_reddit_ad_group` | Audience size, delivery estimate and suggested bid range for a planned ad group (Reddit's counterpart of `estimate_budget`) |
|
|
216
|
+
| `pause_reddit_entity` / `enable_reddit_entity` / `remove_reddit_entity` | Status changes through the preview gate (remove = ARCHIVE, irreversible, double-confirmed) |
|
|
217
|
+
| `update_reddit_campaign` / `update_reddit_ad_group` / `update_reddit_ad` | Budget, bid, run dates, weekly schedule (day names, viewer-local hours), targeting and placements (validated with Reddit at draft time), landing URL and comment changes with old → new previews, budget cap and bid-increase guards |
|
|
218
|
+
| `draft_reddit_campaign` / `draft_reddit_ad_group` / `draft_reddit_ad` | Create campaign → ad group (pixel + targeting required) → post + ad, or promote an existing post with `post_id`. Everything is created **PAUSED**. |
|
|
219
|
+
|
|
220
|
+
> **Setup for Reddit Ads tools** — In Reddit Ads Manager open **Business Manager → Developer Application → Create app** (business admins only; no approval wait). Register the redirect URL exactly as `http://localhost:8765/callback`, then run `adloop init` and complete the Reddit Ads step: it opens Reddit's consent page (scopes `adsread` + `adsedit`, permanent grant), stores the refresh token at `~/.adloop/reddit_token.json`, and lets you pick the default ad account. Reddit rate-limits per user (reporting: 60 requests/min) and requires a descriptive User-Agent, which AdLoop builds from your app id and Reddit username. Reddit has no validate-only mode, so `confirm_and_apply(dry_run=true)` re-reads the target and re-checks the safety caps instead.
|
|
221
|
+
|
|
172
222
|
### Planning Tools
|
|
173
223
|
|
|
174
224
|
| Tool | What It Does |
|
|
@@ -418,6 +468,10 @@ All configuration lives in `~/.adloop/config.yaml`. See [`config.yaml.example`](
|
|
|
418
468
|
| `ads` | `developer_token` | — | Your Google Ads API developer token |
|
|
419
469
|
| `ads` | `customer_id` | — | Default Google Ads customer ID (auto-discovered by `adloop init`) |
|
|
420
470
|
| `ads` | `login_customer_id` | — | Your MCC account ID |
|
|
471
|
+
| `reddit` | `client_id` / `client_secret` | *(empty)* | Your Reddit developer app (Business Manager → Developer Application) |
|
|
472
|
+
| `reddit` | `ad_account_id` | *(empty)* | Default Reddit ad account for every Reddit tool (picked by `adloop init`) |
|
|
473
|
+
| `reddit` | `username` | *(empty)* | Your Reddit username, used only in the User-Agent Reddit requires |
|
|
474
|
+
| `reddit` | `token_path` | `~/.adloop/reddit_token.json` | Where the Reddit refresh token is stored |
|
|
421
475
|
| `safety` | `max_daily_budget` | `50.00` | Maximum allowed daily budget per campaign |
|
|
422
476
|
| `safety` | `require_dry_run` | `true` | Force all writes to dry-run mode |
|
|
423
477
|
| `safety` | `two_phase_apply` | `false` | Refuse real applies until the plan had a dry-run pass |
|
|
@@ -440,6 +494,7 @@ Most MCP clients (claude.ai, ChatGPT, Cursor, …) load **every tool schema into
|
|
|
440
494
|
| `gsc` | Search Console reads |
|
|
441
495
|
| `web` | PageSpeed / Core Web Vitals |
|
|
442
496
|
| `merchant` | Merchant Center feed health |
|
|
497
|
+
| `reddit` | Reddit Ads reads, writes, and planning |
|
|
443
498
|
|
|
444
499
|
`health_check` and `confirm_and_apply` are always included, whatever you select. Unset = the full catalog; unknown names fail at startup with the valid list. The effect is real: `ads,ga4` drops the session cost to ~13k tokens, and a `ga4`-only client pays ~2k — nearly 90% less. Toolsets are per *client*, not per install: one AdLoop config can serve a trimmed Cursor and a full-catalog Claude Code side by side.
|
|
445
500
|
|
|
@@ -450,7 +505,7 @@ On [AdLoop Cloud](https://getadloop.com), the same feature is per API key: pick
|
|
|
450
505
|
```
|
|
451
506
|
src/adloop/
|
|
452
507
|
├── __init__.py # Entry point — routes 'adloop init' to wizard, otherwise starts MCP server
|
|
453
|
-
├── server.py # FastMCP server —
|
|
508
|
+
├── server.py # FastMCP server — every tool registration with safety annotations and toolset tags
|
|
454
509
|
├── config.py # Config loader (~/.adloop/config.yaml)
|
|
455
510
|
├── auth.py # OAuth 2.0 flow (user-supplied credentials, headless fallback) + service accounts; GA4 / Ads / GTM scopes
|
|
456
511
|
├── cli.py # Interactive 'adloop init' setup wizard
|
|
@@ -470,6 +525,11 @@ src/adloop/
|
|
|
470
525
|
├── gtm/
|
|
471
526
|
│ ├── client.py # Google Tag Manager API v2 client
|
|
472
527
|
│ └── read.py # Live container fetching, tag/trigger/variable parsing, workspace diff, version history
|
|
528
|
+
├── reddit/
|
|
529
|
+
│ ├── auth.py # Reddit OAuth2 (own app, permanent refresh token, loopback flow for adloop init)
|
|
530
|
+
│ ├── client.py # Reddit Ads API v3 REST client — bearer refresh, per-user rate limits, pagination
|
|
531
|
+
│ ├── read.py # Accounts, campaigns, ad groups, ads, performance reports, pixels, targeting lookups
|
|
532
|
+
│ └── write.py # Draft/preflight/apply for status, budget, bid, targeting, and PAUSED creation
|
|
473
533
|
└── safety/
|
|
474
534
|
├── guards.py # Budget caps, bid limits, blocked operations, Broad Match safety
|
|
475
535
|
├── preview.py # Change plans and previews
|
|
@@ -491,7 +551,7 @@ What's been shipped and what's next:
|
|
|
491
551
|
- ~~Claude Code support~~ ✓ — `CLAUDE.md`, `.mcp.json`, `.claude/rules/`, `.claude/commands/`, CLI wizard snippets
|
|
492
552
|
- **Claude Desktop one-click install** — `adloop install claude-desktop` (and/or a `.dxt` extension bundle) that writes the AdLoop MCP entry into `claude_desktop_config.json` automatically, so Claude Desktop + Cowork users don't have to hand-edit JSON
|
|
493
553
|
- ~~PyPI package~~ ✓ — `pip install adloop`
|
|
494
|
-
- ~~[AdLoop Cloud](https://getadloop.com)~~ ✓ — the hosted version
|
|
554
|
+
- ~~[AdLoop Cloud](https://getadloop.com)~~ ✓ — the hosted version: no Google Cloud project, no developer token, connect Google in two clicks (EU-hosted, GDPR-first)
|
|
495
555
|
- ~~Headless server support~~ ✓ — manual URL copy-paste flow for servers without a browser
|
|
496
556
|
- ~~Behavioral eval suites~~ ✓ — 28 prompt-and-expectation tests covering read, write, tracking, and planning workflows
|
|
497
557
|
- ~~Google Tag Manager integration~~ ✓ — read tools for tags, triggers, variables, workspaces, and version history, plus the `audit_event_coverage` three-way join across codebase events, GTM tags, and GA4 actual fires
|
|
@@ -1,34 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
Name: adloop
|
|
3
|
-
Version: 0.13.2
|
|
4
|
-
Summary: The AI command center for Google Ads, GA4, and tracking code.
|
|
5
|
-
Keywords: mcp,google-ads,google-analytics,ga4,cursor,marketing
|
|
6
|
-
Author: Daniel Klose
|
|
7
|
-
Author-email: Daniel Klose <info@daniel-klose.com>
|
|
8
|
-
License: MIT
|
|
9
|
-
Requires-Dist: fastmcp>=3.0.0
|
|
10
|
-
Requires-Dist: google-ads>=31.1.0
|
|
11
|
-
Requires-Dist: google-analytics-data>=0.20.0
|
|
12
|
-
Requires-Dist: google-analytics-admin>=0.27.0
|
|
13
|
-
Requires-Dist: google-api-python-client>=2.100.0
|
|
14
|
-
Requires-Dist: google-auth-oauthlib>=1.0.0
|
|
15
|
-
Requires-Dist: google-api-python-client>=2.0.0
|
|
16
|
-
Requires-Dist: pyyaml>=6.0
|
|
17
|
-
Requires-Dist: pytest>=8.0 ; extra == 'dev'
|
|
18
|
-
Requires-Dist: pytest-asyncio>=0.23 ; extra == 'dev'
|
|
19
|
-
Requires-Python: >=3.11
|
|
20
|
-
Project-URL: Homepage, https://github.com/kLOsk/adloop
|
|
21
|
-
Project-URL: Repository, https://github.com/kLOsk/adloop
|
|
22
|
-
Project-URL: Issues, https://github.com/kLOsk/adloop/issues
|
|
23
|
-
Project-URL: Changelog, https://github.com/kLOsk/adloop/releases
|
|
24
|
-
Provides-Extra: dev
|
|
25
|
-
Description-Content-Type: text/markdown
|
|
1
|
+
<!-- mcp-name: com.getadloop/adloop -->
|
|
26
2
|
|
|
27
3
|
<div align="center">
|
|
28
4
|
|
|
29
5
|
# AdLoop
|
|
30
6
|
|
|
31
|
-
**The AI command center for Google Ads, GA4, and tracking code.**
|
|
7
|
+
**The AI command center for Google Ads, Reddit Ads, GA4, and tracking code.**
|
|
32
8
|
|
|
33
9
|
[](https://pypi.org/project/adloop/)
|
|
34
10
|
[](LICENSE)
|
|
@@ -38,14 +14,14 @@ Description-Content-Type: text/markdown
|
|
|
38
14
|
[](https://developers.google.com/analytics/devguides/reporting/data/v1)
|
|
39
15
|
[](https://github.com/kLOsk/adloop)
|
|
40
16
|
|
|
41
|
-
An MCP server that gives your AI assistant read + write access to Google Ads and GA4 — with safety guardrails that prevent accidental spend.
|
|
17
|
+
An MCP server that gives your AI assistant read + write access to Google Ads, Reddit Ads and GA4 — with safety guardrails that prevent accidental spend.
|
|
42
18
|
|
|
43
|
-
**[☁️ Skip the setup — use AdLoop Cloud (free
|
|
19
|
+
**[☁️ Skip the setup — use AdLoop Cloud (free plan, no card)](https://getadloop.com)** · or self-host: `pip install adloop`
|
|
44
20
|
|
|
45
21
|
</div>
|
|
46
22
|
|
|
47
23
|
> [!TIP]
|
|
48
|
-
> **[AdLoop Cloud](https://getadloop.com) is the hosted version of this project
|
|
24
|
+
> **[AdLoop Cloud](https://getadloop.com) is the hosted version of this project, with a free plan that needs no credit card.** Connect Google in two clicks and use the full toolset from claude.ai, ChatGPT, Claude Code, Cursor, or Gemini. No Google Cloud project, no developer token, no OAuth verification wait. EU-hosted, GDPR-first, DPA included.
|
|
49
25
|
|
|
50
26
|
> 📚 **Documentation: [docs.getadloop.com](https://docs.getadloop.com)** — setup guides per AI client, toolsets, the safety model, and troubleshooting for both editions.
|
|
51
27
|
|
|
@@ -63,7 +39,7 @@ Both versions run the same tools with the same safety model. The difference is w
|
|
|
63
39
|
| **Works with** | claude.ai, ChatGPT, Claude Code, Cursor, Gemini | Claude Code, Cursor, Claude Desktop, any local MCP client |
|
|
64
40
|
| **Where your data flows** | EU servers (Germany), GDPR-first, DPA included | 100% your machine — nothing leaves it |
|
|
65
41
|
| **Updates** | Automatic | `pip install -U adloop` |
|
|
66
|
-
| **Price** | Free
|
|
42
|
+
| **Price** | Free plan, no card; [paid plans](https://getadloop.com/preise) for more accounts and volume | Free forever (MIT) |
|
|
67
43
|
|
|
68
44
|
**Not sure? [Start with Cloud](https://getadloop.com)** — it's the fastest way to see what AdLoop can do, and it's the only way to use AdLoop from claude.ai or ChatGPT. Self-host when you want everything on your own machine or need to modify the code. And if you're here to hack on AdLoop itself: welcome, keep scrolling.
|
|
69
45
|
|
|
@@ -195,6 +171,27 @@ These tools read the live GTM container and join it with the codebase + GA4 to f
|
|
|
195
171
|
|
|
196
172
|
> **Setup for GSC tools** — Enable the **Search Console API** in your GCP project. Upgrading OAuth users must re-authorize once for the new scope (delete `~/.adloop/token.json`, run any tool). The killer combo: cross-reference organic queries with `get_keyword_performance` to find paid/organic cannibalization and untapped keyword opportunities.
|
|
197
173
|
|
|
174
|
+
### Reddit Ads Tools
|
|
175
|
+
|
|
176
|
+
A second ad platform, same safety model. Reddit is a separate connection: its own developer app, its own OAuth, no developer token and no approval process. Every tool takes `ad_account_id` (defaults to `reddit.ad_account_id`).
|
|
177
|
+
|
|
178
|
+
| Tool | What It Does |
|
|
179
|
+
|------|-------------|
|
|
180
|
+
| `list_reddit_accounts` | Discover businesses and ad accounts (currency, time zone, approval state) |
|
|
181
|
+
| `list_reddit_funding_instruments` | Billing instruments and posting profiles — prerequisites for creating campaigns and ads |
|
|
182
|
+
| `get_reddit_campaigns` / `get_reddit_ad_groups` / `get_reddit_ads` | Structure with configured vs effective status, budgets, bids, pixel, targeting, weekly schedule, rejection reasons; `include_copy` returns each ad's post (headline, body, destination, media) |
|
|
183
|
+
| `get_reddit_performance` | Spend, clicks, CTR, CPC, conversions, CPA, ROAS per account/campaign/ad group/ad, optional breakdown (date, country, community, keyword, placement, …), compact mode with insights |
|
|
184
|
+
| `run_reddit_report` | Raw reports endpoint for any metric (REACH, video, per-event conversions) |
|
|
185
|
+
| `get_reddit_pixels` | Pixels and when each event last fired — flags ad groups optimizing for events the pixel never sent |
|
|
186
|
+
| `search_reddit_targeting` | Communities, interests, geolocations, languages, keyword suggestions, and Reddit's related-community suggestions (by seed communities or website) |
|
|
187
|
+
| `get_reddit_account_history` | Who changed what and when: field, before/after, member |
|
|
188
|
+
| `estimate_reddit_ad_group` | Audience size, delivery estimate and suggested bid range for a planned ad group (Reddit's counterpart of `estimate_budget`) |
|
|
189
|
+
| `pause_reddit_entity` / `enable_reddit_entity` / `remove_reddit_entity` | Status changes through the preview gate (remove = ARCHIVE, irreversible, double-confirmed) |
|
|
190
|
+
| `update_reddit_campaign` / `update_reddit_ad_group` / `update_reddit_ad` | Budget, bid, run dates, weekly schedule (day names, viewer-local hours), targeting and placements (validated with Reddit at draft time), landing URL and comment changes with old → new previews, budget cap and bid-increase guards |
|
|
191
|
+
| `draft_reddit_campaign` / `draft_reddit_ad_group` / `draft_reddit_ad` | Create campaign → ad group (pixel + targeting required) → post + ad, or promote an existing post with `post_id`. Everything is created **PAUSED**. |
|
|
192
|
+
|
|
193
|
+
> **Setup for Reddit Ads tools** — In Reddit Ads Manager open **Business Manager → Developer Application → Create app** (business admins only; no approval wait). Register the redirect URL exactly as `http://localhost:8765/callback`, then run `adloop init` and complete the Reddit Ads step: it opens Reddit's consent page (scopes `adsread` + `adsedit`, permanent grant), stores the refresh token at `~/.adloop/reddit_token.json`, and lets you pick the default ad account. Reddit rate-limits per user (reporting: 60 requests/min) and requires a descriptive User-Agent, which AdLoop builds from your app id and Reddit username. Reddit has no validate-only mode, so `confirm_and_apply(dry_run=true)` re-reads the target and re-checks the safety caps instead.
|
|
194
|
+
|
|
198
195
|
### Planning Tools
|
|
199
196
|
|
|
200
197
|
| Tool | What It Does |
|
|
@@ -444,6 +441,10 @@ All configuration lives in `~/.adloop/config.yaml`. See [`config.yaml.example`](
|
|
|
444
441
|
| `ads` | `developer_token` | — | Your Google Ads API developer token |
|
|
445
442
|
| `ads` | `customer_id` | — | Default Google Ads customer ID (auto-discovered by `adloop init`) |
|
|
446
443
|
| `ads` | `login_customer_id` | — | Your MCC account ID |
|
|
444
|
+
| `reddit` | `client_id` / `client_secret` | *(empty)* | Your Reddit developer app (Business Manager → Developer Application) |
|
|
445
|
+
| `reddit` | `ad_account_id` | *(empty)* | Default Reddit ad account for every Reddit tool (picked by `adloop init`) |
|
|
446
|
+
| `reddit` | `username` | *(empty)* | Your Reddit username, used only in the User-Agent Reddit requires |
|
|
447
|
+
| `reddit` | `token_path` | `~/.adloop/reddit_token.json` | Where the Reddit refresh token is stored |
|
|
447
448
|
| `safety` | `max_daily_budget` | `50.00` | Maximum allowed daily budget per campaign |
|
|
448
449
|
| `safety` | `require_dry_run` | `true` | Force all writes to dry-run mode |
|
|
449
450
|
| `safety` | `two_phase_apply` | `false` | Refuse real applies until the plan had a dry-run pass |
|
|
@@ -466,6 +467,7 @@ Most MCP clients (claude.ai, ChatGPT, Cursor, …) load **every tool schema into
|
|
|
466
467
|
| `gsc` | Search Console reads |
|
|
467
468
|
| `web` | PageSpeed / Core Web Vitals |
|
|
468
469
|
| `merchant` | Merchant Center feed health |
|
|
470
|
+
| `reddit` | Reddit Ads reads, writes, and planning |
|
|
469
471
|
|
|
470
472
|
`health_check` and `confirm_and_apply` are always included, whatever you select. Unset = the full catalog; unknown names fail at startup with the valid list. The effect is real: `ads,ga4` drops the session cost to ~13k tokens, and a `ga4`-only client pays ~2k — nearly 90% less. Toolsets are per *client*, not per install: one AdLoop config can serve a trimmed Cursor and a full-catalog Claude Code side by side.
|
|
471
473
|
|
|
@@ -476,7 +478,7 @@ On [AdLoop Cloud](https://getadloop.com), the same feature is per API key: pick
|
|
|
476
478
|
```
|
|
477
479
|
src/adloop/
|
|
478
480
|
├── __init__.py # Entry point — routes 'adloop init' to wizard, otherwise starts MCP server
|
|
479
|
-
├── server.py # FastMCP server —
|
|
481
|
+
├── server.py # FastMCP server — every tool registration with safety annotations and toolset tags
|
|
480
482
|
├── config.py # Config loader (~/.adloop/config.yaml)
|
|
481
483
|
├── auth.py # OAuth 2.0 flow (user-supplied credentials, headless fallback) + service accounts; GA4 / Ads / GTM scopes
|
|
482
484
|
├── cli.py # Interactive 'adloop init' setup wizard
|
|
@@ -496,6 +498,11 @@ src/adloop/
|
|
|
496
498
|
├── gtm/
|
|
497
499
|
│ ├── client.py # Google Tag Manager API v2 client
|
|
498
500
|
│ └── read.py # Live container fetching, tag/trigger/variable parsing, workspace diff, version history
|
|
501
|
+
├── reddit/
|
|
502
|
+
│ ├── auth.py # Reddit OAuth2 (own app, permanent refresh token, loopback flow for adloop init)
|
|
503
|
+
│ ├── client.py # Reddit Ads API v3 REST client — bearer refresh, per-user rate limits, pagination
|
|
504
|
+
│ ├── read.py # Accounts, campaigns, ad groups, ads, performance reports, pixels, targeting lookups
|
|
505
|
+
│ └── write.py # Draft/preflight/apply for status, budget, bid, targeting, and PAUSED creation
|
|
499
506
|
└── safety/
|
|
500
507
|
├── guards.py # Budget caps, bid limits, blocked operations, Broad Match safety
|
|
501
508
|
├── preview.py # Change plans and previews
|
|
@@ -517,7 +524,7 @@ What's been shipped and what's next:
|
|
|
517
524
|
- ~~Claude Code support~~ ✓ — `CLAUDE.md`, `.mcp.json`, `.claude/rules/`, `.claude/commands/`, CLI wizard snippets
|
|
518
525
|
- **Claude Desktop one-click install** — `adloop install claude-desktop` (and/or a `.dxt` extension bundle) that writes the AdLoop MCP entry into `claude_desktop_config.json` automatically, so Claude Desktop + Cowork users don't have to hand-edit JSON
|
|
519
526
|
- ~~PyPI package~~ ✓ — `pip install adloop`
|
|
520
|
-
- ~~[AdLoop Cloud](https://getadloop.com)~~ ✓ — the hosted version
|
|
527
|
+
- ~~[AdLoop Cloud](https://getadloop.com)~~ ✓ — the hosted version: no Google Cloud project, no developer token, connect Google in two clicks (EU-hosted, GDPR-first)
|
|
521
528
|
- ~~Headless server support~~ ✓ — manual URL copy-paste flow for servers without a browser
|
|
522
529
|
- ~~Behavioral eval suites~~ ✓ — 28 prompt-and-expectation tests covering read, write, tracking, and planning workflows
|
|
523
530
|
- ~~Google Tag Manager integration~~ ✓ — read tools for tags, triggers, variables, workspaces, and version history, plus the `audit_event_coverage` three-way join across codebase events, GTM tags, and GA4 actual fires
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "adloop"
|
|
3
|
-
version = "0.
|
|
4
|
-
description = "The AI command center for Google Ads, GA4, and tracking code."
|
|
3
|
+
version = "0.14.0"
|
|
4
|
+
description = "The AI command center for Google Ads, Reddit Ads, GA4, and tracking code."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
7
7
|
keywords = [
|
|
8
8
|
"mcp",
|
|
9
9
|
"google-ads",
|
|
10
|
+
"reddit-ads",
|
|
10
11
|
"google-analytics",
|
|
11
12
|
"ga4",
|
|
12
13
|
"cursor",
|
|
@@ -21,6 +22,7 @@ dependencies = [
|
|
|
21
22
|
"google-auth-oauthlib>=1.0.0",
|
|
22
23
|
"google-api-python-client>=2.0.0",
|
|
23
24
|
"pyyaml>=6.0",
|
|
25
|
+
"requests>=2.31",
|
|
24
26
|
]
|
|
25
27
|
|
|
26
28
|
[[project.authors]]
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "adloop"
|
|
3
|
-
version = "0.
|
|
4
|
-
description = "The AI command center for Google Ads, GA4, and tracking code."
|
|
3
|
+
version = "0.14.0"
|
|
4
|
+
description = "The AI command center for Google Ads, Reddit Ads, GA4, and tracking code."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
7
7
|
{ name = "Daniel Klose", email = "info@daniel-klose.com" }
|
|
8
8
|
]
|
|
9
9
|
requires-python = ">=3.11"
|
|
10
10
|
license = { text = "MIT" }
|
|
11
|
-
keywords = ["mcp", "google-ads", "google-analytics", "ga4", "cursor", "marketing"]
|
|
11
|
+
keywords = ["mcp", "google-ads", "reddit-ads", "google-analytics", "ga4", "cursor", "marketing"]
|
|
12
12
|
dependencies = [
|
|
13
13
|
"fastmcp>=3.0.0",
|
|
14
14
|
"google-ads>=31.1.0",
|
|
@@ -18,6 +18,9 @@ dependencies = [
|
|
|
18
18
|
"google-auth-oauthlib>=1.0.0",
|
|
19
19
|
"google-api-python-client>=2.0.0",
|
|
20
20
|
"pyyaml>=6.0",
|
|
21
|
+
# Reddit Ads has no SDK; the REST client (adloop.reddit.client) and the
|
|
22
|
+
# PageSpeed helper call requests directly.
|
|
23
|
+
"requests>=2.31",
|
|
21
24
|
]
|
|
22
25
|
|
|
23
26
|
[project.urls]
|