Skip to main content
Glama

What is AdLens?

The AdMob console shows you totals. AdLens shows you causes.

Connect your AdMob account once (read-only) and you get:

  1. A fast web dashboard for revenue, impressions, eCPM, mediation and country breakdowns.

  2. An MCP server so Claude, Cursor, Codex and other AI clients can answer questions from the same live data, such as "Which ad format has the best eCPM this month?"

It is free, read-only, and stores none of your report data. You can use the hosted version or run your own.

Related MCP server: adsense-mcp

Features

Dashboard

  • Live, not synced: fetched from the AdMob API when you open a page.

  • Today at a glance: today, yesterday, last 7 days and this month, with impressions and eCPM.

  • Period comparisons: every KPI shows its change vs. the previous period.

  • Sortable breakdowns: by day, app, ad unit, format, mediation source or country.

  • Per-app deep dives with the same depth, plus dark and light themes.

MCP server

Five read-only tools that any MCP client can call:

Tool

What it does

account_overview

Lists your connections and apps (id, name, platform, package name)

revenue_summary

Totals plus daily or weekly series, using presets or explicit dates

breakdown

Revenue by app, ad unit, format, country, ad source (mediation) or date

top_movers

Period-over-period movers, with the previous period chosen automatically for presets

list_ad_units

Your ad unit inventory

Example prompts to try:

  • "Revenue summary for the last 30 days"

  • "Top movers by country, this week vs last week"

  • "Break down mediation revenue for my top app"

  • "Which ad format has the best eCPM this month?"

Getting started (hosted)

Setup takes about a minute.

  1. Sign in at adlens.moreproductive.in with an email one-time code or Google. A password is optional.

  2. Connect AdMob. You approve one Google OAuth consent screen with the admob.readonly scope.

  3. Use it your way. Open the dashboard, or generate an API key and connect your AI client (below).

Connect your AI assistant (MCP)

Generate an API key on the API Keys page of the dashboard. Keys look like ak_live_... and are shown once, so copy yours right away. Then add AdLens to your client.

The MCP endpoint is:

https://adlens.moreproductive.in/mcp

If you self-host, replace the domain with your own. AdLens is a standard Streamable HTTP MCP server authenticated with a Bearer token, so any client that supports a remote URL with custom headers will work.

claude mcp add --transport http adlens https://adlens.moreproductive.in/mcp \
  --header "Authorization: Bearer ak_live_..."

Or add it to .mcp.json:

{
  "mcpServers": {
    "adlens": {
      "type": "http",
      "url": "https://adlens.moreproductive.in/mcp",
      "headers": { "Authorization": "Bearer ak_live_..." }
    }
  }
}

Claude Desktop's config file has no native URL + header support, so bridge it with mcp-remote.

Edit claude_desktop_config.json:

  • macOS: ~/Library/Application Support/Claude/

  • Windows: %APPDATA%\Claude\

  • Linux: ~/.config/Claude/

{
  "mcpServers": {
    "adlens": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://adlens.moreproductive.in/mcp",
        "--header", "Authorization: Bearer ak_live_..."
      ]
    }
  }
}

On Windows, use npx.cmd instead of npx as the command:

{
  "mcpServers": {
    "adlens": {
      "command": "npx.cmd",
      "args": [
        "-y", "mcp-remote",
        "https://adlens.moreproductive.in/mcp",
        "--header", "Authorization: Bearer ak_live_..."
      ]
    }
  }
}

In ~/.codex/config.toml (Windows: %USERPROFILE%\.codex\config.toml):

[mcp_servers.adlens]
url = "https://adlens.moreproductive.in/mcp"
http_headers = { "Authorization" = "Bearer ak_live_..." }

For Cursor, edit ~/.cursor/mcp.json (Windows: %USERPROFILE%\.cursor\mcp.json):

{
  "mcpServers": {
    "adlens": {
      "url": "https://adlens.moreproductive.in/mcp",
      "headers": { "Authorization": "Bearer ak_live_..." }
    }
  }
}

For stdio-only clients, use the mcp-remote bridge shown in the Claude Desktop section.

In ~/.gemini/antigravity/mcp_config.json (Windows: %USERPROFILE%\.gemini\antigravity\mcp_config.json), or via the MCP Store panel → Manage MCP Servers → View raw config:

{
  "mcpServers": {
    "adlens": {
      "serverUrl": "https://adlens.moreproductive.in/mcp",
      "headers": { "Authorization": "Bearer ak_live_..." }
    }
  }
}

In opencode.json (project) or ~/.config/opencode/opencode.json. This path is the same on Windows (%USERPROFILE%\.config\opencode\opencode.json), not %APPDATA%. Setting oauth: false makes OpenCode use your Bearer key instead of trying OAuth sign-in first.

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "adlens": {
      "type": "remote",
      "url": "https://adlens.moreproductive.in/mcp",
      "enabled": true,
      "oauth": false,
      "headers": { "Authorization": "Bearer ak_live_..." },
      "timeout": 30000
    }
  }
}

Tip: to test the endpoint without an AI client, run the MCP Inspector: npx @modelcontextprotocol/inspector

Self-hosting

AdLens is multi-tenant by design and easy to run yourself. You need:

  • Node.js (LTS) and pnpm, or just Docker

  • A Postgres database (the included Docker Compose file starts one)

  • A MojAuth project for sign-in (email OTP + Google). You'll need its API key.

  • A Google Cloud OAuth client with the AdMob API enabled and the admob.readonly scope

1. Clone and configure

git clone https://github.com/ys-pro-duction/AdLens.git
cd AdLens
cp .env.example .env   # then fill in the values below

Generate the random secrets with:

openssl rand -hex 32

Variable

Required

Description

APP_URL

yes

Public URL of your instance (use your https domain in production)

DATABASE_URL

yes

Postgres connection string

MOJOAUTH_API_KEY

yes

Your MojAuth project's key (email OTP + Google sign-in)

SESSION_SECRET

yes

Random secret used to sign session cookies

GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET

yes

Google OAuth client for connecting AdMob

ENCRYPTION_KEY

yes

32-byte hex key used to encrypt refresh tokens at rest

OAUTH_STATE_SECRET

no

Separate secret for signing OAuth state

TRUST_PROXY

no

Set to 1 when running behind nginx so rate limits see real client IPs

HOST

no

Bind address. Use 127.0.0.1 behind a reverse proxy

MOJOAUTH_AUDIENCE

no

Optional audience check for MojAuth tokens

MOJOAUTH_ISSUERS

no

Override the allowed MojAuth token issuers

.env.example is kept current and has the full annotated list.

In your Google Cloud OAuth client, register <APP_URL>/api/admob/callback as an authorized redirect URI. In your MojAuth dashboard, register the callback URL it shows you.

2a. Run with Docker (everything)

docker compose up --build

2b. Run locally for development

pnpm install
docker compose up -d db   # Postgres only
pnpm db:migrate
pnpm dev                  # API on :3000, web on :5173

3. Production

Build from the repo root (building a single package can leave a stale packages/db/dist):

git pull && pnpm install && pnpm db:migrate && pnpm build

In production the API serves the built web app (apps/web/dist), so there is a single process to run. Run it under a process manager of your choice (the hosted instance uses pm2, with Postgres in Docker).

Behind nginx (or any reverse proxy):

  • Set APP_URL to your https domain

  • Set TRUST_PROXY=1

  • Bind the app to localhost with HOST=127.0.0.1

Note: rate limits are held in memory per process, so AdLens is designed to run as a single process. If it is exposed directly (no proxy), leave TRUST_PROXY unset, because X-Forwarded-For can be spoofed.

Fair-use limits

AdLens is free, with no plans and no billing. Per-IP rate limits protect the service:

Endpoint

Limit

Dashboard API (/api)

300 requests / minute

MCP server (/mcp)

15 requests / minute

If you self-host, these limits are yours to adjust in the source.

Architecture

flowchart LR
  A[Vue dashboard] --> B[Express API]
  C[MCP clients] --> B
  B --> D[Live AdMob layer<br/>60-min cache · single-flight]
  D --> E[(Google AdMob API)]
  B --> F[(Postgres<br/>identity · encrypted keys )]

There is no worker, no warehouse and no stored metrics. Reports are fetched from Google on demand and aggregated in JS.

Tech stack & layout

TypeScript monorepo (pnpm workspaces):

apps/web        Vue 3 + Vite SPA (ECharts): dashboard, reports, mediation, API keys, settings
apps/api        Express API + stateless MCP server; serves web/dist in production
                (live AdMob serving layer: apps/api/src/live)
packages/db     Drizzle schema + migrations (multi-tenant: tenant_id everywhere)
packages/admob  AdMob OAuth + reporting API client
packages/crypto AES-256-GCM secrets, API key generation/hashing, scrypt
packages/shared Shared TypeScript types and AdMob constants

Disclaimer

AdLens is an independent project and is not affiliated with, endorsed by, or sponsored by Google. AdMob and Google are trademarks of Google LLC.

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    A Model Context Protocol (MCP) server that gives Claude Desktop direct access to your Google AdSense account. Ask plain English questions about your revenue — no dashboard required.
    10
    8 npm
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    MCP server for Google AdSense management. Create ad units, generate framework-specific ad code, manage earnings reports, and automate ads.txt — all from your AI assistant.
    12
    8 npm
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables querying mobile ad revenue from Google AdMob and Huawei Petal Ads through natural language, with read-only tools for account, app, ad unit, and revenue reports.
    11
    36 npm
    MIT