# Apple Ads Mcp

> MCP server for Apple Search Ads API v5 — manage campaigns, keywords, budgets, and reports through AI assistants

- **Type:** MCP server
- **Install:** `agentstack add mcp-happygallo-apple-ads-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Happygallo](https://agentstack.voostack.com/s/happygallo)
- **Installs:** 0
- **Category:** [Search](https://agentstack.voostack.com/c/search)
- **Latest version:** 1.0.3
- **License:** MIT
- **Upstream author:** [Happygallo](https://github.com/Happygallo)
- **Source:** https://github.com/Happygallo/apple-ads-mcp
- **Website:** https://www.npmjs.com/package/apple-ads-mcp

## Install

```sh
agentstack add mcp-happygallo-apple-ads-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

Apple Ads MCP

  
  
  
  

  MCP server for the Apple Search Ads API v5.
  Connect it to any MCP-compatible AI client and manage your campaigns, keywords, budgets, and reporting through natural language.

  Quick Start &bull;
  Tools &bull;
  Resources &bull;
  Prompts &bull;
  Clients

---

**Ask your AI things like:**

> *"How did my campaigns perform last week?"*
> *"Pause the brand campaign and increase the budget on discovery to $500."*
> *"What search terms are triggering my ads? Add the best ones as exact-match keywords."*

Supports 54 tools, 3 resources, and 6 prompts — campaigns, ad groups, keywords, creatives, budgets, search terms, geo targeting, impression share, and performance reports.

### Features at a glance

| Feature | Description |
|---|---|
| **Campaign management** | Create, update, pause, and delete campaigns and ad groups |
| **Keyword optimization** | Add/remove targeting and negative keywords, update bids |
| **Performance reporting** | Campaign, ad group, keyword, ad, and geo reports with date presets |
| **Search term analysis** | See actual search queries triggering your ads |
| **Creative management** | Manage ads, creatives, and product pages |
| **Budget control** | Create and manage budget orders, analyze utilization |
| **Impression share** | Generate and retrieve impression share reports |
| **Multi-org support** | Switch between organizations at runtime |

---

## Quick Start

1. [Get your Apple credentials](#step-1--invite-an-api-user) (~10 min, one-time)
2. [Generate your key pair](#step-3--generate-your-key-pair) (2 commands)
3. [Add to your MCP client](#step-5--add-to-your-mcp-client)
4. Start chatting

---

## Setup

### Step 1 — Invite an API user

> Done by the **account admin** at [searchads.apple.com](https://searchads.apple.com).

1. Go to **Settings** → **User Management** → **Invite User**
2. Enter the email of the person who will use the API
3. Set the role:
   - **API Account Manager** — full read/write access
   - **API Account Read Only** — view-only access
4. Send the invitation

> The API user must be a **different Apple ID** from the admin. If you're the admin, use a second Apple ID.

### Step 2 — Accept and copy your credentials

> Done by the **invited user**.

1. Accept the email invitation and sign in to [searchads.apple.com](https://searchads.apple.com)
2. Go to **Settings** → **API** tab
3. Copy and save these three values:
   - **clientId** — starts with `SEARCHADS.`
   - **teamId** — starts with `SEARCHADS.`
   - **keyId** — a UUID

### Step 3 — Generate your key pair

Open Terminal and run:

```bash
openssl ecparam -genkey -name prime256v1 -noout -out ~/apple-ads-key.pem && \
openssl pkcs8 -topk8 -nocrypt -in ~/apple-ads-key.pem -out ~/apple-ads-key-pkcs8.pem
```

Then generate the public key:

```bash
openssl ec -in ~/apple-ads-key-pkcs8.pem -pubout -out ~/apple-ads-key-public.pem
```

This creates:
- **`~/apple-ads-key-pkcs8.pem`** — private key (keep this safe, used in your config)
- **`~/apple-ads-key-public.pem`** — public key (upload to Apple next)

### Step 4 — Upload public key to Apple

Print your public key:

```bash
cat ~/apple-ads-key-public.pem
```

Copy the entire output (including the `BEGIN` / `END` lines), then:

1. Go to **Settings** → **API** tab on [searchads.apple.com](https://searchads.apple.com)
2. Paste into the **Public Key** field
3. **Save**

### Step 5 — Add to your MCP client

Pick your client below and fill in your **clientId**, **teamId**, and **keyId** from Step 2, and the **full path** to your private key from Step 3.

> **Multiple orgs?** Omit `ASA_ORG_ID` and use `list_organizations` / `switch_organization` at runtime. Or set it in `env` to pick a default.

---

## Clients

Claude Desktop

Edit `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "apple-ads": {
      "command": "npx",
      "args": ["-y", "apple-ads-mcp"],
      "env": {
        "ASA_CLIENT_ID": "SEARCHADS.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "ASA_TEAM_ID": "SEARCHADS.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "ASA_KEY_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "ASA_PRIVATE_KEY_PATH": "/Users/yourname/apple-ads-key-pkcs8.pem"
      }
    }
  }
}
```

Restart Claude Desktop after saving.

Claude Code

```bash
claude mcp add apple-ads \
  -e ASA_CLIENT_ID=SEARCHADS.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  -e ASA_TEAM_ID=SEARCHADS.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  -e ASA_KEY_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  -e ASA_PRIVATE_KEY_PATH=/Users/yourname/apple-ads-key-pkcs8.pem \
  -- npx -y apple-ads-mcp
```

Cursor

Add to `.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "apple-ads": {
      "command": "npx",
      "args": ["-y", "apple-ads-mcp"],
      "env": {
        "ASA_CLIENT_ID": "SEARCHADS.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "ASA_TEAM_ID": "SEARCHADS.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "ASA_KEY_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "ASA_PRIVATE_KEY_PATH": "/Users/yourname/apple-ads-key-pkcs8.pem"
      }
    }
  }
}
```

VS Code

Add to your `settings.json`:

```json
{
  "mcp": {
    "servers": {
      "apple-ads": {
        "command": "npx",
        "args": ["-y", "apple-ads-mcp"],
        "env": {
          "ASA_CLIENT_ID": "SEARCHADS.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
          "ASA_TEAM_ID": "SEARCHADS.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
          "ASA_KEY_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
          "ASA_PRIVATE_KEY_PATH": "/Users/yourname/apple-ads-key-pkcs8.pem"
        }
      }
    }
  }
}
```

Windsurf

Add to `~/.codeium/windsurf/mcp_config.json`:

```json
{
  "mcpServers": {
    "apple-ads": {
      "command": "npx",
      "args": ["-y", "apple-ads-mcp"],
      "env": {
        "ASA_CLIENT_ID": "SEARCHADS.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "ASA_TEAM_ID": "SEARCHADS.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "ASA_KEY_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "ASA_PRIVATE_KEY_PATH": "/Users/yourname/apple-ads-key-pkcs8.pem"
      }
    }
  }
}
```

Other MCP clients

This server uses **STDIO transport**. Any MCP-compatible client can connect by running:

```bash
npx -y apple-ads-mcp
```

Set these environment variables:

| Variable | Description |
|---|---|
| `ASA_CLIENT_ID` | Your client ID (starts with `SEARCHADS.`) |
| `ASA_TEAM_ID` | Your team ID (starts with `SEARCHADS.`) |
| `ASA_KEY_ID` | Your key ID (UUID) |
| `ASA_PRIVATE_KEY_PATH` | Absolute path to your PKCS#8 private key |
| `ASA_ORG_ID` | *(optional)* Organization ID to use by default |

Inline key (no file)

Replace `ASA_PRIVATE_KEY_PATH` with `ASA_PRIVATE_KEY` and paste the PEM content with `\n` for line breaks:

```json
"ASA_PRIVATE_KEY": "-----BEGIN PRIVATE KEY-----\nMIGH...your-key...\n-----END PRIVATE KEY-----"
```

---

## Tools

| Category | Count | What you can do |
|---|---|---|
| **Organizations** | 3 | List and switch between organizations. Get user details. |
| **Campaigns** | 6 | List, create, update, delete campaigns. Pull performance reports. |
| **Ad Groups** | 6 | Manage ad groups within campaigns. Get ad group reports. |
| **Keywords** | 11 | Add/remove targeting and negative keywords. Update bids. Keyword reports. |
| **Search Terms** | 1 | See the actual queries people searched before tapping your ad. |
| **Ads** | 7 | List, create, update, delete ads. Get ad reports and rejection reasons. |
| **Creatives** | 5 | Manage creatives and product pages. |
| **Budget Orders** | 4 | Create, update, list, and get budget order details. |
| **Apps & Geo** | 5 | Search for eligible apps, check eligibility, find assets, search geolocations. |
| **Geo Performance** | 1 | Performance breakdown by country/region. |
| **Impression Share** | 3 | Create, list, and retrieve custom impression share reports. |
| **Optimization** | 2 | Campaign snapshots and budget utilization analysis. |

### All 54 tools

| Category | Tools |
|---|---|
| **Organizations** | `list_organizations`, `switch_organization`, `get_me_details` |
| **Campaigns** | `list_campaigns`, `get_campaign_details`, `create_campaign`, `update_campaign`, `delete_campaign`, `get_campaign_report` |
| **Ad Groups** | `list_ad_groups`, `get_ad_group`, `create_ad_group`, `update_ad_group`, `delete_ad_group`, `get_adgroup_report` |
| **Keywords** | `get_keyword_report`, `list_targeting_keywords`, `get_targeting_keyword`, `add_targeting_keywords`, `update_targeting_keywords`, `delete_targeting_keywords`, `list_negative_keywords`, `get_negative_keyword`, `add_negative_keywords`, `update_negative_keywords`, `delete_negative_keywords` |
| **Search Terms** | `get_search_term_report` |
| **Ads** | `list_ads`, `get_ad`, `create_ad`, `update_ad`, `delete_ad`, `get_ad_report`, `find_ad_rejection_reasons` |
| **Creatives** | `list_creatives`, `get_creative`, `create_creative`, `list_product_pages`, `get_product_page_by_id` |
| **Budget Orders** | `list_budget_orders`, `get_budget_order`, `create_budget_order`, `update_budget_order` |
| **Apps & Geo** | `search_apps`, `get_app_details`, `get_app_eligibility`, `find_app_assets`, `search_geolocations` |
| **Geo Performance** | `get_geo_performance` |
| **Impression Share** | `create_impression_share_report`, `get_impression_share_report_by_id`, `list_impression_share_reports` |
| **Optimization** | `get_campaign_snapshot`, `get_budget_analysis` |

---

## Resources

The server exposes 3 resources:

| URI | Description |
|---|---|
| `apple-ads://countries` | Supported countries and regions for Apple Search Ads |
| `apple-ads://device-sizes` | App preview device sizes for creative assets |
| `apple-ads://metrics-glossary` | Definitions, formulas, and benchmarks for all reporting metrics (CPA, CPT, TTR, etc.) |

---

## Prompts

6 built-in workflow prompts to guide common tasks:

| Prompt | Description |
|---|---|
| `campaign_health_check` | Comprehensive campaign analysis — reviews spend, conversions, CPA trends, and flags issues |
| `keyword_optimization` | Keyword and search term optimization workflow — finds wasted spend and new opportunities |
| `new_campaign_setup` | Guided new campaign creation — walks through app selection, structure, keywords, and budgets |
| `budget_reallocation` | Cross-campaign budget analysis — identifies over/under-spending and proposes budget shifts |
| `creative_review` | Creative A/B review — compares ad performance, flags rejections, recommends winners |
| `geo_expansion` | Geographic expansion analysis — ranks current markets and identifies new ones to enter |

---

Troubleshooting

> **"pkcs8 must be PKCS#8 formatted string"**
> Your key is in the wrong format. Re-run the `openssl pkcs8` command from [Step 3](#step-3--generate-your-key-pair).

> **"No organization selected"**
> Use `list_organizations` then `switch_organization`, or add `ASA_ORG_ID` to your config.

> **"Token request failed (401)"**
> Verify your **clientId**, **teamId**, and **keyId** match Apple's API tab. Check that you uploaded your public key.

> **"Failed to read private key"**
> Use an absolute path (e.g. `/Users/yourname/...`), not `~/...`.

> **Server disconnects immediately**
> A required credential is missing. You need all four: `ASA_CLIENT_ID`, `ASA_TEAM_ID`, `ASA_KEY_ID`, and `ASA_PRIVATE_KEY_PATH`.

Development

```bash
git clone https://github.com/javiergalloroca/AppleAdsMCP.git
cd AppleAdsMCP
npm install
npm run build
npm start
```

For hot reload: `npm run dev`

See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.

## License

MIT

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Happygallo](https://github.com/Happygallo)
- **Source:** [Happygallo/apple-ads-mcp](https://github.com/Happygallo/apple-ads-mcp)
- **License:** MIT
- **Homepage:** https://www.npmjs.com/package/apple-ads-mcp

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v1.0.3 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **1.0.3** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-happygallo-apple-ads-mcp
- Seller: https://agentstack.voostack.com/s/happygallo
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
