shopify-chatgpt-ads-mcp
Provides tools for managing ChatGPT ads through OpenAI's Advertiser API, including campaigns, ad groups, ads, previews, insights, feeds, pixels, locations, and audit logs, with paused-by-default creation and confirmation-gated spend changes.
Enables Shopify merchants to measure ChatGPT ad results using real Shopify orders, including True ROAS and tracking health through the Avada ChatGPT Ads app.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@shopify-chatgpt-ads-mcp How did my ChatGPT ads do last week compared with the week before?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Shopify ChatGPT Ads
Run your ChatGPT (OpenAI) ads from your own AI agent. An MCP server and agent skills for Shopify merchants: launch campaigns, read reports, guard the budget and fix the product feed from Claude Code, Codex, Cursor or any MCP client. Everything starts paused, and nothing spends without your explicit yes.
Not affiliated with OpenAI or Shopify. "ChatGPT", "OpenAI" and "Shopify" are trademarks of their owners and are used only to say what this works with.
Ask your agent
"How did my ChatGPT ads do last week compared with the week before?"
"Launch a ChatGPT Shopping campaign for my running shoes under $100, 30 dollars a day."
"Make a chat card ad for our new collection page and show me the preview."
"Am I on track to stay under $1,500 on ChatGPT ads this month? What should I pause?"
"Why are half my products missing from my ChatGPT Shopping campaign?"
"Drop the price of these three variants in my OpenAI feed and mark this one out of stock."
"Is my ChatGPT Ads tracking set up correctly?"
"What's my True ROAS on ChatGPT ads from real Shopify orders?"
Related MCP server: chatgpt-ads-manager-mcp
How it works
Two parts, one agent:
Manage ads | Measure results | |
What | A local MCP server that calls OpenAI's Advertiser API | Orders attributed to ChatGPT ads, True ROAS, tracking health |
Needs | Your own Advertiser API key ( | Avada ChatGPT Ads, free, installed with its app embed on |
Where the key lives | On your machine only | In the app; your agent gets a read-only key or OAuth approval |
Tools | 33 | 13 |
OpenAI's numbers say what OpenAI attributed to its ads. The store's numbers say what actually sold. You want both, side by side, in the same currency. Without the app, the measurement tools say exactly what is missing and how to set it up; they never make up a number.
Install (60 seconds)
You need Node.js 20 or later (tested on 22, 24 and 26) and an Advertiser API key: ads.openai.com > Settings > API keys. Put it in your environment, not in a chat:
export OPENAI_ADS_API_KEY=... # add it to your shell profile or a secret managerStatus: v0.2.0, not yet published to npm. Until it is, use the Claude Code plugin (it runs from the repository), or clone and run from source:
git clone https://github.com/Avada-AI/shopify-chatgpt-ads && cd shopify-chatgpt-ads && npm ci, then usenode /path/to/shopify-chatgpt-ads/src/cli.jswherever the examples below saynpx -y shopify-chatgpt-ads-mcp.
Claude Code
As a plugin (MCP server + all skills; it asks for the key and keeps it in your system keychain):
/plugin marketplace add Avada-AI/shopify-chatgpt-ads
/plugin install shopify-chatgpt-ads@avada-aiOr the MCP server alone, reading the key from your environment when it starts:
claude mcp add-json chatgpt-ads --scope user \
'{"command":"npx","args":["-y","shopify-chatgpt-ads-mcp"],"env":{"OPENAI_ADS_API_KEY":"${OPENAI_ADS_API_KEY}"}}'Project config example: examples/claude-code.mcp.json.
Codex
Add to ~/.codex/config.toml (full example):
[mcp_servers.chatgpt-ads]
command = "npx"
args = ["-y", "shopify-chatgpt-ads-mcp"]
env_vars = ["OPENAI_ADS_API_KEY", "AVADA_API_KEY"]AGENTS.md tells Codex and other agents the safety rules. Skills: npx skills add Avada-AI/shopify-chatgpt-ads -a codex.
Cursor
.cursor/mcp.json in your project, or ~/.cursor/mcp.json (example):
{
"mcpServers": {
"chatgpt-ads": {
"command": "npx",
"args": ["-y", "shopify-chatgpt-ads-mcp"],
"env": {"OPENAI_ADS_API_KEY": "${env:OPENAI_ADS_API_KEY}"}
}
}
}Any other MCP client
Run npx -y shopify-chatgpt-ads-mcp over stdio with OPENAI_ADS_API_KEY in its environment (example). Registry metadata: server.json.
Skills only
The skills work with any agent that reads Agent Skills: npx skills add Avada-AI/shopify-chatgpt-ads (the open skills CLI, Node.js 22.20 or later), or copy a folder from skills/ into .claude/skills/ or .agents/skills/.
Add measured orders and True ROAS (free)
Install Avada ChatGPT Ads on your Shopify store and connect your ad account in the app.
Turn on the app embed: Shopify admin > Online Store > Themes > Customize > App embeds > Avada ChatGPT Ads. Without it the store sends no tracked events.
Connect your agent, one of:
API key: in the app, Settings > AI agents > API keys. Then
export AVADA_API_KEY=avk_live_...and restart your agent. Themeasurement_*tools start answering.Hosted MCP server (OAuth): add
https://avada-chatgpt.firebaseapp.com/mcpas a second MCP server and approve it in the app. The Claude Code plugin and the example configs already list it asavada-measurement.
Preview: the Measurement API is being released by the app now. The contract the kit uses is in
docs/measurement-api.md; until it is live for your store, the measurement tools answer "not live yet" with the steps above.
Safety
Paused by default. Every campaign, ad group and ad the kit creates is created
paused, whatever the agent asks. Update tools cannot change status or budget.Spending needs your yes.
activate_campaign, andset_budgetorset_bidwhen they raise spend, first return a dry run: what will run, the budget and currency, preview links, warnings, and aplan_id. The agent must show it to you and call again withconfirm: trueand that exactplan_id. If anything changed in between, the oldplan_idno longer works.Cutting is free. Pausing, lowering a budget or bid, and archiving work directly (archiving is permanent at OpenAI, and the tool says so).
Read-only mode.
CHATGPT_ADS_READ_ONLY=1removes every write tool from the server; the agent cannot even see them.Audit log. Every write is written to
~/.chatgpt-ads-kit/audit.log(JSON lines, readable only by you, no secrets) before it is sent. If the log cannot be written, the write is refused.No duplicate campaigns. Every create sends an
Idempotency-Key; a retried create returns the first object. Writes without one are never retried.Money done carefully. Budgets and bids are converted to OpenAI's micros with decimal arithmetic in your account currency; feed prices go out in ISO 4217 minor units; reported spend is never converted. Amounts in different currencies are never added or compared.
The agent still acts with your key. Read the tool list your client shows, and use read-only mode when you only want reports.
Privacy
Your OpenAI key stays on your machine. It is read from the environment (or your keychain, with the Claude Code plugin), sent only to
api.ads.openai.com, never accepted as a tool argument, never logged, and removed from every answer and error before it reaches the agent.No telemetry. The server talks to OpenAI, and to Avada only when you set
AVADA_API_KEY. Nothing else.What Avada's API returns: aggregates (counts, sums, ratios), campaign and product identifiers, setup and health states for the one store the key belongs to. No customer names, emails or addresses, and never keys or tokens. See
docs/measurement-api.md.Your agent's model provider sees what the tools return, as with any MCP server.
Tools
Tool | Kind |
| read |
| read |
| read |
| write |
| write |
| write |
| write |
| confirm-gated |
| read (Avada) |
Skills
Skill | Ask your agent |
"How did my ChatGPT ads do this week?" | |
"Launch a ChatGPT Shopping campaign for these products" | |
"Keep my ChatGPT ads under $X this month" | |
"Why are my products not showing in ChatGPT ads?" | |
"Is my ChatGPT Ads tracking set up correctly?" (Avada's measured health first, then outside checks) | |
"How much traffic and sales is ChatGPT sending my store?" (Shopify analytics, read-only) | |
"Is my store ready for ChatGPT?" (read-only) |
The last two need no ad account and no server: they use Shopify's own analytics and public pages. Every platform fact the skills and the server rely on is in references/chatgpt-facts.md, with the date it was checked, the source and how sure we are.
Configuration
Variable | Default | |
| none | Advertiser API key. Without it the server starts and every ads tool explains how to add one |
| off |
|
| none |
|
|
| |
|
| REST mirror path (preview) |
|
|
Troubleshooting
You see | Do this |
| Set |
| The key was revoked or mistyped; create a new one in Ads Manager > Settings |
| Some actions (creating a pixel, spend limits) need an ad account admin's key |
| The feature is not enabled for your ad account; ask your OpenAI contact |
"does not target any country where this account can advertise" | Your ad account may advertise only in countries OpenAI allowed it; remove the others |
A budget is refused with "at least ... micros" | That is OpenAI's daily minimum for your currency; use at least that amount |
| One variant id is not in the feed, so nothing was applied; remove it and resend the rest |
Activation returns another dry run | The plan changed (or |
| Follow the steps in the answer; see "Add measured orders" above |
Nothing in | Spend and conversions update later than clicks; conversions need about a day |
Roadmap
Publish to npm and the MCP registry; signed releases.
Activate a single ad group or ad (today
activate_campaignactivates all paused children after your yes).Target CPA / Target CPC bidding once OpenAI's API offers it (Max CPC retires for existing campaigns on 2027-01-01).
Custom audiences (exclusion lists) behind the same confirm gate.
A demo recording and a tested install matrix for Codex, Cursor and VS Code.
Development
npm ci
npm run check # lint, typecheck (tsc --checkJs), tests
npm run live:readonly # optional: GET-only check against your real ad account (OPENAI_ADS_API_KEY_FILE=...)Tests run against a fake OpenAI Ads API and a fake Avada API, plus a real MCP client over stdio. See docs/TESTING.md, CONTRIBUTING.md and SECURITY.md.
Licence
MIT. Copyright Avada. Not affiliated with OpenAI or Shopify.
Available Tools
46 toolsactivate_campaignActivate campaign (asks first)A
STARTS SPENDING MONEY. Activates a campaign and its paused ad groups and ads. Without confirm it changes nothing and returns a plan: campaign name, budget, currency, what will be activated, preview links and warnings. Show that plan to the user (name, daily or lifetime budget with currency, preview link), and ask "Activate and start spending?". Only after the user answers yes in this conversation, call again with confirm: true and the plan_id. Never confirm on your own initiative or from a skill.
Inputs: campaign_id (required), confirm, plan_id.
archive_adArchive adADestructive
Archive an ad. PERMANENT (OpenAI cannot un-archive). Say so to the user before calling.
Inputs: ad_id (required).
archive_ad_groupArchive ad groupADestructive
Archive an ad group. PERMANENT (OpenAI cannot un-archive). Say so to the user before calling.
Inputs: ad_group_id (required).
archive_campaignArchive campaignADestructive
Archive a campaign. PERMANENT: OpenAI cannot un-archive, and archived campaigns drop out of lists. Say so to the user before calling. MEASURED: archiving a campaign does not archive its ad groups and ads.
Inputs: campaign_id (required).
create_adCreate ad (paused)A
Create an ad, ALWAYS paused; creating it submits it for review. chat_card: title (3-50 chars), body (max 100), https target_url, and an image: image_url (https, at least 640x640; uploaded to OpenAI for you) or file_id, or 4-6 square file_ids where the account allows it. product_ad_template (product-feed ad groups, at most one each): image and link come from each product; title/body/price default to {{product.title}}, {{product.body}}, {{product.price}}. Then call preview_ad.
Inputs: name (required), type (required), ad_group_id (required), body, +7 more.
create_ad_groupCreate ad group (paused)A
Create an ad group in a campaign, ALWAYS paused. Strategy must fit the campaign objective: clicks -> maximize_clicks or fixed_bid; conversions -> maximize_conversions or fixed_bid; impressions -> fixed_bid. Maximize needs a daily campaign budget and no max_bid. fixed_bid needs max_bid (per click; for impressions per single impression, so a 60 CPM is 0.06). Fixed bids (Max CPC) retire for existing campaigns on 2027-01-01 per OpenAI; prefer maximize_*. For a product-feed campaign, product_filters choose products (preview them with query_feed_products).
Inputs: name (required), strategy (required), campaign_id (required), max_bid, +3 more.
create_campaignCreate campaign (paused)A
Create a campaign. It is ALWAYS created paused and spends nothing until activate_campaign. Budget is in the ad account currency (get_ad_account); daily is required for Maximize clicks/conversions. A product-feed (Shopping) campaign needs product_feed_id; its feed, objective and mode cannot change later. Daily minimums depend on the currency and OpenAI states them when it refuses. Identical requests return the same campaign (Idempotency-Key).
Inputs: name (required), budget_type (required), budget_amount (required), end_time, +10 more.
get_adGet adCRead-only
One ad with creative, review_status and serving issues.
Inputs: ad_id (required).
get_ad_accountAd accountARead-only
The ad account behind OPENAI_ADS_API_KEY: name, status, review, timezone and currency. Every budget, bid and spend amount in this kit is in this currency. Start here.
Inputs: no named parameters.
get_ad_groupGet ad groupCRead-only
One ad group with serving issues and bid_too_low (a hint that the bid may be too low for reliable delivery, not a block).
Inputs: ad_group_id (required).
get_campaignGet campaignARead-only
One campaign by id, with serving issues. With include_children, also its live ad groups and ads (archived ones left out), which is what you need to explain why a campaign is not serving.
Inputs: campaign_id (required), include_children.
get_insightsPerformance reportARead-only
OpenAI's Insights for the account, a campaign, an ad group or an ad: impressions, clicks, spend, CTR, CPC, CPM and, without a breakdown, conversions, attributed sales and ROAS. Attribution settings are always sent explicitly (defaults 30-day click, 1-day view, ad_event_time, which is what Ads Manager shows). spend/cpc/cpm are MAJOR units of the account currency, not micros. A missing or null metric is unavailable, never zero. Conversions update daily; allow a day. These are OpenAI's attributed numbers; for orders measured in the store use the measurement_* tools.
Inputs: to (required), from (required), id, after, +8 more.
list_ad_groupsList ad groupsARead-only
Ad groups of a campaign with bidding (readable max bid), context hints and serving issues. Archived ad groups are hidden unless asked.
Inputs: campaign_id (required), include_archived.
list_adsList adsBRead-only
Ads of an ad group with creative, status and review_status (in_review, approved, rejected). Archived ads are not listed by OpenAI.
Inputs: ad_group_id (required).
list_audit_logsChange historyBRead-only
OpenAI's record of changes in the ad account, newest first: who changed what and when, with before/after values where OpenAI records them. MEASURED: changes made through an API key are attributed to the key's owner, the same as that person's own Ads Manager changes.
Inputs: ad_id, after, limit, since, +3 more.
list_campaignsList campaignsARead-only
Campaigns in the ad account with status, objective, budget (micros and readable amount) and targeting. Archived campaigns are not listed by OpenAI; read one with get_campaign.
Inputs: after, limit, include_serving_issues.
list_conversion_event_settingsConversion event settingsARead-only
Which events count as conversions (e.g. order_created) and on which data source. A conversions-objective campaign needs one active standard setting id from here.
Inputs: no named parameters.
list_feedsList product feedsARead-only
Product feeds in the ad account (id in feed_id) with countries, currencies, campaign_count and product_count (ingested, ads-eligible products; can read 0 while an upload is processing). There is no get-one-feed endpoint.
Inputs: no named parameters.
list_feed_uploadsFeed upload historyARead-only
Upload history with status (processing, completed, completed_with_errors, skipped, failed), rows accepted / rejected / ads-eligible and diagnostics (missing_required_column, invalid_value, ...). Use it to find rejected products and what to fix in Shopify.
Inputs: feed_id.
list_pixelsList pixelsARead-only
Conversion data sources (web pixels) of the ad account with their pixel_id. A 404 means pixel management is not enabled for this account.
Inputs: no named parameters.
list_recent_conversion_eventsRecent pixel eventsARead-only
Up to 50 conversion events OpenAI received for a pixel in about the last 15 minutes, with event_type and api_channel (pixel_sdk = browser, server_to_server = Conversions API). For testing that tracking arrives, not for reporting. An empty list means none in 15 minutes, not broken tracking. A 404 means the event stream is not enabled for this account.
Inputs: pixel_id (required).
measurement_get_account_overviewMeasured account overviewARead-only
The store, the connected ad account, pixel and Conversions API state and the ready-to-advertise checklist, as Avada sees them. From Avada ChatGPT Ads (preview API, needs AVADA_API_KEY). If it answers unavailable, tell the user the reason and steps; never invent or zero-fill numbers.
Inputs: no named parameters.
measurement_get_ads_breakdownMeasured breakdownARead-only
Delivery by country, device or platform for a date range. From Avada ChatGPT Ads (preview API, needs AVADA_API_KEY). If it answers unavailable, tell the user the reason and steps; never invent or zero-fill numbers.
Inputs: dimension (required), to, from.
measurement_get_ads_reportAds report with True ROASARead-only
OpenAI's totals per campaign and per day beside True ROAS from the store's own Shopify orders. App-side figures are null with a reason when currencies differ or tracking is too new. Amounts are in the currency named in the answer. From Avada ChatGPT Ads (preview API, needs AVADA_API_KEY). If it answers unavailable, tell the user the reason and steps; never invent or zero-fill numbers.
Inputs: to, from, view, basis, +1 more.
measurement_get_campaignCampaign as Avada sees itARead-only
One campaign with its health and measured results. From Avada ChatGPT Ads (preview API, needs AVADA_API_KEY). If it answers unavailable, tell the user the reason and steps; never invent or zero-fill numbers.
Inputs: campaign_id (required).
measurement_get_feed_statusFeed status (Avada)ARead-only
The app's product feed sync to OpenAI: last snapshot, delta updates, quality score. From Avada ChatGPT Ads (preview API, needs AVADA_API_KEY). If it answers unavailable, tell the user the reason and steps; never invent or zero-fill numbers.
Inputs: no named parameters.
measurement_get_product_reportMeasured product reportARead-only
Products that received ad delivery, with measured orders where the app has them. From Avada ChatGPT Ads (preview API, needs AVADA_API_KEY). If it answers unavailable, tell the user the reason and steps; never invent or zero-fill numbers.
Inputs: to, from.
measurement_get_setup_statusMeasurement setup statusARead-only
Is Avada ChatGPT Ads installed, the app embed on, the ad account connected, pixel and Conversions API working. Call this first when measured data is missing. From Avada ChatGPT Ads (preview API, needs AVADA_API_KEY). If it answers unavailable, tell the user the reason and steps; never invent or zero-fill numbers.
Inputs: no named parameters.
measurement_get_spend_pacingSpend pacingARead-only
Month-to-date spend against the target set in the app, with a forecast. From Avada ChatGPT Ads (preview API, needs AVADA_API_KEY). If it answers unavailable, tell the user the reason and steps; never invent or zero-fill numbers.
Inputs: no named parameters.
measurement_get_tracking_healthTracking healthBRead-only
Events by type, the funnel, Conversions API delivery and purchases tracked against real Shopify orders. Counts and sums only. From Avada ChatGPT Ads (preview API, needs AVADA_API_KEY). If it answers unavailable, tell the user the reason and steps; never invent or zero-fill numbers.
Inputs: days.
measurement_list_alertsAlertsARead-only
Open alerts the app raised: tracking stopped, feed failing, campaign not serving, overspend. From Avada ChatGPT Ads (preview API, needs AVADA_API_KEY). If it answers unavailable, tell the user the reason and steps; never invent or zero-fill numbers.
Inputs: no named parameters.
measurement_list_campaign_presetsCampaign presetsBRead-only
Campaign presets the app suggests from the catalogue (bestsellers, new arrivals, ...). From Avada ChatGPT Ads (preview API, needs AVADA_API_KEY). If it answers unavailable, tell the user the reason and steps; never invent or zero-fill numbers.
Inputs: no named parameters.
measurement_list_campaignsCampaigns as Avada sees themARead-only
Campaigns with status, budget and health; include_issues adds ad groups, ads and serving issues (slow). From Avada ChatGPT Ads (preview API, needs AVADA_API_KEY). If it answers unavailable, tell the user the reason and steps; never invent or zero-fill numbers.
Inputs: include_issues.
measurement_list_feed_issuesFeed issues (Avada)BRead-only
Products the last feed snapshot found problems with (missing image, GTIN, price, rejected by OpenAI), one page at a time. From Avada ChatGPT Ads (preview API, needs AVADA_API_KEY). If it answers unavailable, tell the user the reason and steps; never invent or zero-fill numbers.
Inputs: after, limit, severity.
pause_adPause adA
Pause an ad. Safe; no confirmation needed.
Inputs: ad_id (required).
pause_ad_groupPause ad groupA
Pause an ad group. Safe; no confirmation needed.
Inputs: ad_group_id (required).
pause_campaignPause campaignA
Pause a campaign: it stops delivering. Safe; no confirmation needed. Undo with activate_campaign (which asks first).
Inputs: campaign_id (required).
preview_adPreview adARead-only
A link to OpenAI's own preview of an ad as it would appear in ChatGPT. Works for paused ads; the link expires after about 24 hours. A preview shows appearance only, not serving eligibility. Show the link to the user before any activation.
Inputs: ad_id (required).
query_feed_productsQuery feed productsARead-only
Products OpenAI holds in a feed (its copy, not Shopify's), with total_count and matched_count for the filters. Use it to pick products for a campaign and to preview a product set before creating an ad group. MEASURED: results carry no availability or group_id, and filtering on them is refused.
Inputs: feed_id (required), limit, filters.
search_locationsFind location idsARead-only
Look up countries, regions and markets for campaign targeting and get their ids. MEASURED: results are NOT limited to what this ad account may target; an account can target only the countries OpenAI allows it, and a create outside them is refused.
Inputs: query (required), limit.
set_bidSet ad group biddingA
Change how an ad group bids. Lowering a fixed bid applies at once. Raising a bid or switching strategy can spend more: without confirm it returns a plan; show it, get an explicit yes, then call again with confirm: true and the plan_id. Maximize strategies need a daily campaign budget and take no max_bid. Fixed bids (Max CPC) retire for existing campaigns on 2027-01-01 per OpenAI.
Inputs: strategy (required), ad_group_id (required), confirm, max_bid, +1 more.
set_budgetSet campaign budgetA
Set a campaign budget in the ad account currency. Lowering it (same type) applies at once. RAISING it, or switching lifetime to daily, can spend more: without confirm it returns a plan (old and new amount, currency, campaign status); show it to the user, get an explicit yes, then call again with confirm: true and the plan_id. A lifetime budget cannot go below what was already spent, and a daily budget cannot switch back to lifetime.
Inputs: amount (required), campaign_id (required), confirm, plan_id, +1 more.
update_adEdit adA
Change an ad name, its creative (title, body, link, image) or tracking template. Creative fields you do not mention are kept. A creative change sends the ad back to review. Never changes status.
Inputs: ad_id (required), body, name, price, +5 more.
update_ad_groupEdit ad groupA
Change name, description, context hints or the product filters of an ad group. Never changes status or bid (use set_bid). context_hints and product_filters replace the whole list. MEASURED: a list read right after can still show old hints; get_ad_group by id is current.
Inputs: ad_group_id (required), name, description, context_hints, +2 more.
update_campaignEdit campaign settingsA
Change name, description, schedule, targeting or tracking template. Never changes status or budget (use pause_campaign, activate_campaign, set_budget). Targeting you do not mention is kept as it is.
Inputs: campaign_id (required), name, end_time, countries, +6 more.
update_feed_productsUpdate prices and stock (Delta API)A
Change price, availability or title of products ALREADY in an OpenAI feed. MEASURED: this is the only way to change items OpenAI already holds (a re-uploaded file did not update them), changes show in about 60 s, and if ANY variant id is unknown OpenAI rejects the whole request with 422 and applies nothing. product_id is the feed group_id (the item_id when variants are not grouped); variant_id is the item_id. Price is in major units with its currency and sent as minor units. accepted: true does not confirm the ids matched; check with query_feed_products.
Inputs: feed_id (required), products (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 46 tools
The core OpenAI surface (list_campaigns, get_campaign, get_insights, list_feeds) is cleanly separated by resource and action, but the parallel Avada surface creates near-twins: list_campaigns vs measurement_list_campaigns, get_campaign vs measurement_get_campaign, get_insights vs measurement_get_ads_report, list_feed_uploads vs measurement_get_feed_status. Descriptions do draw a real distinction (OpenAI-attributed vs store-measured true ROAS, and the AVADA_API_KEY requirement), which saves it from being a 2, but an agent still has to reason carefully before choosing between two similarly named tools for the same object.
Names are consistently snake_case verb_noun (list_/get_/create_/update_/pause_/archive_/set_), and the app-side tools share a uniform measurement_ namespace prefix, which is a deliberate and predictable convention. Small friction comes from prefix-stacked names like measurement_get_campaign that duplicate the base tool's name, blurring the namespace advantage somewhat.
46 tools for a single ad account surface is heavy, and the count is inflated because two separate backends (the OpenAI Ads API and the Avada measurement app) each get a full parallel tool family. Individual tools are mostly substantive rather than trivial, but the duplication of campaign/feed/reporting tools across two surfaces pushes this well past what an agent can hold in working context.
The lifecycle is broadly covered: campaigns, ad groups and ads all have create/get/list/update/pause/archive plus activation, budget and bid controls, along with feeds, uploads, feed product edits, pixels, conversion event settings, audit logs and insights. Gaps are mostly API-imposed (no un-archive, no single-feed get, no pixel or conversion-setting creation), which agents can work around but leaves a few dead ends.
Maintenance
Related MCP Connectors
OpenAI Ads MCP for ChatGPT Ads campaigns, creatives, audiences, insights, and conversions.
Run Meta Ads and Google Ads for your Shopify store from Claude, ChatGPT or Cursor, with the store's own Shopify, Stripe or Klaviyo revenue next to ad spend. New campaigns are created paused.
Remote MCP for Shopify, Meta Ads, Google Ads and TikTok Ads with human approval for writes
AI agents that manage paid ads on Meta, LinkedIn, and Google Ads from any MCP client.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables management of OpenAI Ads campaigns, ad groups, ads, and insights through MCP, with approval-gated live mutations for safe write operations.127 npmMIT
- AlicenseBqualityCmaintenanceEnables managing ChatGPT Advertiser campaigns from MCP-capable agents, including campaign creation, creative uploads, audience management, conversions setup, and insights retrieval.8938 npmMIT
- FlicenseNot gradedqualityCmaintenanceConnects AI assistants to Google Ads, Meta Ads, ChatGPT Ads, TikTok Ads and LinkedIn Ads so users can query live campaign performance, budgets and audiences in the account's own currency and prepare changes as proposals that only take effect after explicit approval. Reads run immediately, while every write is staged as an approvable proposal with before/after values, and newly created campaigns, ad sets and ads start paused.1-
- AlicenseNot gradedqualityCmaintenanceConnects AI agents to Shopify, Meta Ads, Google Ads, and TikTok Ads for cross-platform reporting, creative management, and approval-gated campaign and store changes.MIT