Skip to main content
Glama
goncaloaguer

Apple Ads Insights MCP

by goncaloaguer

Apple Ads Insights MCP

Read-only, analysis-first MCP server for the Apple Ads Platform API. Ask your AI assistant about your App Store campaigns — structure, keywords, search terms, reports — with a server that cannot modify anything.

Works with any MCP client: Claude, ChatGPT, Cursor, VS Code, Windsurf, Gemini CLI, and anything else that speaks MCP — see docs/CONNECT.md. Host it anywhere a container runs; a step-by-step free-tier Google Cloud Run guide is included.

Unofficial community project. Not affiliated with, endorsed, certified, or supported by Apple Inc. Apple, Apple Ads and App Store are trademarks of Apple Inc. You are responsible for your own compliance with the Apple Ads Terms of Service.

Status: 0.1.0 — Phase 1 private MVP. Structure and reporting tools are implemented and tested against a mocked API; live verification against an advertiser account is in progress (open items are tagged TODO-LIVE in docs/API_NOTES.md). Analysis, diagnostics and insights tools follow in Phases 2–3 (see PLAN.md).

Why this exists

  • Permanently read-only. Every outgoing API call must match a version-controlled allowlist derived from Apple's own SDK inventory (all 99 operations are classified; 47 reads enabled, 36 writes denied, CI fails if a write becomes reachable). Apple's API uses POST for both reads (/query) and creates, so the loader refuses any enabled POST that is not a /query. There is no write mode to misconfigure.

  • Single advertiser per deployment. You deploy it in your own Google Cloud project (or run it locally); your credentials never touch anyone else's infrastructure. A mandatory account allowlist blocks cross-account access, and the X-AP-Context header is derived only from it.

  • Built for analysis. Reports at campaign, ad group, ad, keyword and search-term level with Apple's groupBy dimensions and granularities, plus safety ceilings so an AI client loop can't burn your rate limits or your wallet.

  • Personal-use cost profile. Scale-to-zero Cloud Run, max 1 instance; normal personal use lands at ~$0/month.

  • Targets the current API. Built for the Apple Ads Platform API (api.ads.apple.com/v1), not the Campaign Management API v5 that Apple sunsets on January 26, 2027.

Related MCP server: Ads Analytics MCP

Tools (7, Phase 1)

Structure: list_ad_accounts · list_campaigns · list_ad_groups · list_keywords · list_ads

Reporting: get_report (levels: campaigns, adgroups, ads, keywords, searchterms) · get_daily_performance

Resources: apple-ads://report-fields, apple-ads://capabilities.

Planned (PLAN.md §6): compare_periods, rank_performance, analyze_trends, analyze_pacing, analyze_keywords, analyze_search_terms, get_account_history, diagnose_delivery, check_app_eligibility, get_impression_share, get_search_term_popularity, get_keyword_suggestions, get_recommendations, get_target_cpa_suggestion, search_apps, search_geo, get_supported_languages, get_app_details.

Note: Apple Ads reporting has no conversion, trial or revenue metrics — installs are the deepest in-platform outcome. Join with your MMP or subscription data outside this server.

Setup overview

  1. Create API credentials — invite an API user with the API Account Read Only role, generate an EC key pair, upload the public key, and note the clientId / teamId / keyId Apple shows (docs/AUTHENTICATION.md, ~10 minutes).

  2. Find your ad account ID(s) with python3 scripts/verify_credentials.py.

  3. Run it (either way):

    • Locally (stdio) for desktop MCP clients:

      pip install .
      cp .env.example .env   # fill in values, then: set -a; source .env; set +a
      apple-ads-mcp
    • Hosted — any container platform works (the image is a plain Dockerfile). A complete free-tier walkthrough for Google Cloud Run is in docs/DEPLOY_GCP.md (~15 min). Hosted mode is required for chat apps like claude.ai and ChatGPT.

  4. Connect your AI tool — per-client instructions in docs/CONNECT.md.

Remote authentication (pick exactly one)

Mode

Use when

How

bearer (default)

Your MCP client can send headers (Claude Code, Cursor, VS Code, Gemini CLI)

Authorization: Bearer <MCP_ACCESS_TOKEN> on /mcp

secret_path

Client only accepts a URL (claude.ai and ChatGPT custom connectors)

Endpoint served at /<MCP_PATH_SECRET>/mcp; /mcp returns 404

Secret-path mode treats the URL as the credential: it can appear in client settings, browser history, and infrastructure logs. Generate it with python3 -c "import secrets; print(secrets.token_urlsafe(32))", rotate it periodically, and prefer bearer mode when possible.

Safety & privacy properties

  • Exact-match operation allowlist; structural rule that an enabled POST must be a /query; mutating paths (/apply, /dismiss, /bulk-, /upload) refused at load time even if the registry file is tampered with.

  • Apple has no read-only OAuth scope, so the server checks the API user's roles at startup and warns on write-capable ones (APPLE_ADS_REQUIRE_READONLY_ROLE=true refuses to start). It cannot write either way.

  • Mandatory ALLOWED_ACCOUNT_IDS; every tool call re-checks the account.

  • Rate/loop safeguards: 60 tool calls per rolling hour, 20 upstream requests per call, duplicate-call suppression, 90-day report ceiling, bounded rows, pages, and response size; RateLimit-* headers honored.

  • No database, no persistent cache, no payload logging. Report rows, entity names, search terms and key material never appear in logs.

Data disclosure note: this server returns your advertising metrics to the MCP client you connect — typically a hosted AI assistant. Review your AI provider's data handling and your own obligations under Apple's terms before connecting a production account. Do not share one deployment across unrelated advertisers, and do not use returned data to train models without the necessary permissions.

Why not Apple's official SDK?

Apple publishes an official Python client (apple-ads-platform). We use its repository as the pinned source of truth for the operation inventory, but not as a runtime dependency: it exposes every write operation, is synchronous, and adds hundreds of generated modules to a credential-holding service. The full reasoning is in docs/ADR-001-client-layer.md.

Development

pip install -e ".[dev]"
python3 -m unittest discover tests       # invariants, units, mocked end-to-end
python3 scripts/check_api_drift.py       # inventory/registry drift gate

The operation inventory lives in spec/operations.json, extracted from Apple's SDK at the commit in spec/SDK_PIN. Any inventory update requires classifying changed operations in scripts/generate_registry.py and regenerating the registry in the same commit — CI enforces this.

Acknowledgments

No code was reused from other projects, but this server stands on prior art worth crediting:

Dependencies

Four direct runtime dependencies, declared in pyproject.toml: mcp (pinned >=1.9,<2; SDK 2.0 is API-incompatible), httpx, pydantic, and pyjwt[crypto] (ES256 signing via cryptography). The small footprint is deliberate — this server handles ad-account credentials, so every dependency is attack surface.

License

MIT — see LICENSE.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides read-only access to Meta Ads API, enabling campaign management, creative analysis, targeting research, and performance analytics via 39 tools.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides read access to campaign performance data from Google Ads, Meta Ads, and TikTok Ads via live API calls, enabling AI assistants to analyze and audit advertising campaigns.
    1
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    A read-only MCP server for querying Google Ads data using GAQL, enabling AI assistants to safely read campaign performance, ad groups, and keywords.
    12
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    Enables AI clients to read Google Ads account data through reporting tools for campaigns, ad groups, keywords, and raw GAQL queries, with no write or mutate capabilities.
    7
    -