# adsense — an Agent Skill for Google ads (display + reporting)
A [Claude Code](https://claude.com/claude-code) Agent Skill that covers the whole job
of putting Google ads on a content site and reading what they earn — **from the
terminal, with no MCP server and no npm install.** It's the sibling of the
[`search-console`](https://github.com/coffeegrind123/search-console-skill) skill and
follows the same philosophy: audit the ecosystem, keep the recipes, drop the packaging.
## Why not an MCP server?
There are ~5 AdSense reporting MCP servers on GitHub (and ~20 more for the *Google Ads
API*, which is the advertiser side — buying ads — and irrelevant to a publisher). I read
the source of the three real AdSense ones (`AppsYogi-com/adsense-mcp-server`,
`vishmathpati/adsense-mcp`, `Raffaele86/adsense-mcp`) and didn't install any:
- They wrap **one** `reports:generate` endpoint (parameterized by `dimensions`) plus a
few read-only `list` calls behind ~10 "tools." Earnings-by-country is *"add
`dimensions=COUNTRY_NAME`."* That's the whole trick.
- **The setup burden is identical** — you still create the Google Cloud OAuth client and
do a one-time consent click. A server saves the agent writing curl; it saves you nothing.
- The heaviest one pulls a native OS-keychain module (`keytar`) and a SQLite cache. No
install hooks or telemetry in any of them, so they're safe — just unnecessary.
## What's in it
**Display (the part with no API):**
- The copy-paste ad markup, extracted from what the popular React libraries emit and the
official `googleads/google-publisher-tag-samples` — AdSense loader, Auto Ads, manual
units (display / in-article / in-feed / multiplex), and the **GPT** alternative with
`defineSizeMapping` + native `lazyLoad`.
- **The four things that actually break it:** CLS (reserve slot height), **CSP** (the #1
silent blocker on a hardened site, with the ad-domain allowlist), **Consent Mode v2 +
a certified CMP** (mandatory for EEA/UK since Jan 2024 — Google's free CMP suffices),
and **ads.txt**.
- A **policy checklist** with real thresholds (distilled from `mmlTools/seo-adsense-inspector`'s
hard-coded rules + current Google policy): word-count gates, ad density, placement,
required pages, and the **scaled-content trap** that bites large auto-generated silos.
- A **"my ads aren't showing" diagnostic**, ordered by how often each cause is the real one.
- **Measure the damage** — the `web-vitals/attribution` field snippet that names the
exact ad slot causing CLS, the real main-thread cost of the Google ad tag
(~1,764 ms, from `patrickhulce/third-party-web`), the `lighthouse-plugin-publisher-ads`
`cumulative-ad-shift` CI gate, and a before/after methodology.
- **The revenue ladder** — AdSense Auto Ads → manual units → GAM+GPT → GAM+Prebid header
bidding, with the honest CWV/latency tax and the traffic thresholds where each rung
starts to pay off, plus the real Prebid↔GPT handoff and the **ad-refresh policy line**
(AdSense forbids it; GAM allows ≥30s viewability-gated).
- **Ads on a cross-origin-isolated page** — why a `COEP: require-corp` game page (WASM
threads / SharedArrayBuffer) cannot host ads, why `credentialless` doesn't rescue it,
and the pre-game-interstitial architecture (Google H5 Games Ads) that monetizes the
session without touching the isolated document.
**Reporting (curl + OAuth):**
- Working OAuth refresh-token auth — and the one auth fact that trips everyone:
**AdSense does NOT support service accounts** (unlike Search Console), so there is one
unavoidable human consent click, then it's headless.
- The real endpoints (`accounts`, `reports:generate`, `sites`, `alerts`, `policyIssues`,
`payments`) and the full metric/dimension enum vocabulary.
- Analysis recipes: RPM by page, unfilled-slot coverage, country/platform/format ROI —
each one report call + a dimension.
- Reporting honesty rules (estimated-until-finalized, RPM-not-earnings, refuse the
verdict on <2–4 weeks of data).
## Install
```bash
git clone https://github.com/coffeegrind123/adsense-skill.git ~/.claude/skills/adsense
```
Auto-loads when you mention AdSense, Google ads, ad placement/sizes, ad revenue/RPM,
ads.txt, consent banners for ads, or GPT / Google Ad Manager — or invoke it with
`/adsense`.
## Credentials
The skill reads `~/.adsense_oauth.json` (0600) at call time. **No credential ever lives
in this repo** — `.gitignore` blocks `*.json`, `*oauth*`, `*.pem`, `*.key`, `.env`.
## Site-specific overlay
If a `LOCAL.md` sits next to `SKILL.md`, the skill reads it first — it holds the
publisher ID, the live setup state, and the concrete injection points/gotchas for
whatever site the install points at. It's gitignored (per-install).
## License
MIT — see [LICENSE](LICENSE).