chatgpt-ads-mcp
v0.1.0
Published
MCP server for the OpenAI ChatGPT Ads (Advertiser) API — manage campaigns, ad groups, ads, creatives, and reporting from any MCP client.
Maintainers
Readme
ChatGPT Ads MCP Server
An MCP server that lets an AI assistant (Claude Desktop, Claude Code, or any MCP client) manage your ChatGPT Ads campaigns through plain conversation. It wraps the official OpenAI Advertiser API, so you can say things like "create a paused campaign with a $500 lifetime budget" or "show me yesterday's clicks and spend by campaign" and the assistant calls the API for you.
You provide: one API key from ChatGPT Ads Manager. You get: full campaign management without touching the dashboard.
What it can do
| Area | Tools |
| --- | --- |
| Campaigns | list_campaigns, get_campaign, create_campaign, update_campaign, activate_campaign, pause_campaign, archive_campaign |
| Ad groups | list_ad_groups, get_ad_group, create_ad_group, update_ad_group, activate_ad_group, pause_ad_group, archive_ad_group |
| Ads | list_ads, get_ad, create_ad, update_ad, activate_ad, pause_ad, archive_ad |
| Creatives | upload_creative (image URL or local file → file_id) |
| Reporting | get_insights (account / campaign / ad-group / ad level: impressions, clicks, spend, CTR, CPC, CPM) |
| Targeting | search_locations (find country/region/DMA IDs by name; use with include_location_ids on campaigns) |
| Find by name | find_campaigns, find_ad_groups, find_ads (match by name across all pages — no ID needed) |
| Accounts | list_accounts, get_ad_account (account name, currency, timezone) |
That's full create-read-update plus the activate / pause / archive lifecycle — 29 tools in total. It supports multiple ad accounts from a single server (see below). List tools also accept fetch_all: true to return every page at once.
Documentation
- Tool reference — every tool with its parameters (auto-generated from the server).
- Configuration — environment variables, single vs. multiple accounts, client setup, security.
- Architecture — how the server is structured and why.
- Contributing — local setup and how to add a tool.
- Changelog — version history.
Setup (step by step)
You don't need to be technical — just follow these in order.
macOS shortcut: after installing Node.js and downloading this repo, run
bash setup.shfrom the project folder. It installs, builds, asks for your API key, and wires up the Claude Desktop config automatically. The manual steps below are the equivalent for any platform.
Easiest: run via npx (once published to npm)
If the package is published to npm (see docs/PUBLISHING.md), you don't need to clone or build anything — point Claude Desktop straight at it:
{
"mcpServers": {
"chatgpt-ads": {
"command": "npx",
"args": ["-y", "chatgpt-ads-mcp"],
"env": { "OPENAI_ADS_API_KEY": "sk-ads-..." }
}
}
}npx always fetches the latest published version, so you get fixes automatically (no
re-downloading). The manual build steps below remain available if you prefer running
from source.
1. Get your API key
- Go to ChatGPT Ads Manager → Settings → API keys.
- Create a key. Each key is tied to one ad account.
- Copy it somewhere safe. You'll paste it into the config below — never put it in a shared file or commit it to GitHub.
2. Install Node.js
If you don't already have it, install Node.js 18 or newer from nodejs.org. (This project is tested on Node 22.)
3. Download and build this server
In a terminal:
git clone https://github.com/codynguyen18/chatgpt-ads-mcp.git
cd chatgpt-ads-mcp
npm install
npm run buildThis creates a dist/ folder containing the runnable server. Note the full path —
run pwd and copy it; you'll need it in the next step.
4. Connect it to your AI assistant
Claude Desktop — open its config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Add this (replace the path and the key with your own):
{
"mcpServers": {
"chatgpt-ads": {
"command": "node",
"args": ["/full/path/to/chatgpt-ads-mcp/dist/index.js"],
"env": {
"OPENAI_ADS_API_KEY": "paste-your-key-here"
}
}
}
}Restart Claude Desktop. You should see the ChatGPT Ads tools appear.
Claude Code — register it from the project folder:
claude mcp add chatgpt-ads --env OPENAI_ADS_API_KEY=paste-your-key-here -- node /full/path/to/chatgpt-ads-mcp/dist/index.jsMultiple ad accounts
One server can manage several ad accounts. Because each API key is tied to one ad account, you give each account a name and its own key, then tell the assistant which one to use ("…in the client-a account").
Set OPENAI_ADS_ACCOUNTS to a JSON object of name: key, and optionally
OPENAI_ADS_DEFAULT_ACCOUNT for the one to use when you don't say:
{
"mcpServers": {
"chatgpt-ads": {
"command": "node",
"args": ["/full/path/to/chatgpt-ads-mcp/dist/index.js"],
"env": {
"OPENAI_ADS_ACCOUNTS": "{\"main\":\"sk-ads-aaa\",\"client-a\":\"sk-ads-bbb\",\"client-b\":\"sk-ads-ccc\"}",
"OPENAI_ADS_DEFAULT_ACCOUNT": "main"
}
}
}
}The value of
OPENAI_ADS_ACCOUNTSis JSON inside a string, so the inner quotes are escaped with\"— copy the shape above and swap in your names/keys.
Then in conversation:
- "List campaigns in the client-a account."
- "Pause everything in client-b."
- "Which ad accounts do you have access to?" → uses
list_accounts.
If you don't name an account, the assistant uses your default (or, if you only
configured one, that one). If several are configured with no default, it will ask
you to pick. A single OPENAI_ADS_API_KEY still works and is registered as the
account named default.
Try it
Once connected, just talk to your assistant:
- "List my active campaigns."
- "Create a paused campaign called 'Summer Launch' with a $500 lifetime budget targeting California and Texas." (it uses
search_locations, theninclude_location_ids) - "In that campaign, make an ad group with a $4 max bid."
- "Upload this image https://example.com/banner.png and use it in a new ad titled 'Try it free' linking to https://mysite.com."
- "Pause the ad group named 'Test'." (it uses
find_ad_groupsto resolve the name, then pauses) - "Show me impressions, clicks, and spend by campaign for the last 7 days."
- "What currency is my ad account in?" (uses
get_ad_account)
The assistant picks the right tool and fills in the details.
Good to know
- Money is in "micros." The API measures budgets and bids in micros of your
account currency, where 1,000,000 micros = 1.00 (so $25 =
25000000). You can just say "$25" in conversation and the assistant converts it — this is only relevant if you read the raw numbers. - Archiving is permanent.
archive_*cannot be undone. Pause instead if you only want to stop delivery temporarily. - Real spend. Activating campaigns/ads can spend real money on a live account.
A safe habit: create things as
paused, review in the dashboard, then activate. - One key per ad account. Each ChatGPT Ads API key is scoped to a single ad account. To manage several, see Multiple ad accounts below.
Configuration
| Environment variable | Required | Description |
| --- | --- | --- |
| OPENAI_ADS_API_KEY | Yes | Your ChatGPT Ads API key (scoped to one ad account). |
| OPENAI_ADS_BASE_URL | No | Override the API base URL. Defaults to https://api.ads.openai.com/v1. |
See .env.example for a template.
Troubleshooting
- "Missing OPENAI_ADS_API_KEY" — the key isn't reaching the server. Double-check
the
envblock in your config and restart the client. - 401 / 403 errors — the key is wrong, revoked, or for a different ad account.
- 404 errors — usually the resource ID doesn't exist, or the endpoint isn't available for your account yet.
- Tools don't appear — confirm the
argspath points to the builtdist/index.js(notsrc/), and that you rannpm run build.
For developers
npm install # install dependencies
npm run build # compile TypeScript to dist/
npm run dev # recompile on change
npm start # run the built server (expects OPENAI_ADS_API_KEY in the env)
npm run docs:tools # regenerate docs/TOOL_REFERENCE.md from the serverSource layout:
src/index.ts— entry point; loads accounts and starts the stdio server.src/config.ts— parses the account configuration from environment variables.src/client.ts— multi-account HTTP client over the Advertiser API (auth, query/body, upload, errors).src/tools.ts— the 29 MCP tool definitions and their handlers.
See CONTRIBUTING.md for conventions and how to add a tool, and docs/ARCHITECTURE.md for the design.
Not included (and why)
OpenAI's Ads platform has two measurement features that are deliberately out of scope for this server:
- JavaScript pixel — browser-side tracking code you paste into your website. It isn't a server API, so it has no place in an MCP server.
- Conversions API — a server-to-server feed for sending conversion events (purchases, sign-ups). It's designed to fire automatically from your backend the moment an event happens, in real time and at volume — not to be triggered by hand through a chat assistant. That logic belongs in your application code. (The only niche fits would be backfilling a test event or logging an offline conversion.)
If you do want a tool for sending the occasional offline/test conversion, it's a small addition — open an issue.
Notes & disclaimer
The OpenAI Advertiser API is new (2026) and still evolving. This server is built
against the published reference and may need small updates as endpoints change.
Where the docs are sparse, the create/update tools accept an optional extra
field so the assistant can pass additional raw API fields without a code change.
This is an unofficial, community project and is not affiliated with or endorsed by OpenAI.
License
MIT
