OpenAI Ads MCP
This server provides an MCP interface for OpenAI Ads, allowing AI assistants to safely inspect, manage, and interact with advertising accounts.
Account Management
Retrieve account details (id, name, timezone, currency, settings) and verify API key functionality.
Campaign, Ad Group & Ad Management
List, get, create, update, and set state (activate/pause) for campaigns, ad groups, and ads.
Performance Insights
Query performance data at account, campaign, ad group, or ad scope with filtering, sorting, segmentation (product/country/device), time ranges, granularity (hourly/daily/monthly), and cursor pagination.
Creatives
Upload image URLs or local image files to create ad creatives.
Audiences & Geo Targeting
List, get, and manage custom audiences; search for geographical targeting locations.
Conversions
Send conversion events and manage conversion definitions, with built-in validation.
Campaign Building & Drafting
Deterministically draft
context_hintsfor ad group targeting and build entire paused campaign structures (campaign, ad group, ads) in a guarded workflow.
Safety Features
All create operations default to paused entities.
Enforces budget ceilings (e.g., $100) with explicit confirmation required for overrides.
A
readonlymode (set viaOPENAI_ADS_MCP_READONLY) disables all write operations.Separate activation tools prevent accidental spending.
Allows interaction with OpenAI Ads, ChatGPT Ads, and OpenAI's Advertiser API, providing tools for managing ad accounts, campaigns, ad groups, ads, creatives, audiences, and conversion events.
openai-ads-mcp
Trakkr tracks the full AI-visibility funnel, organic and paid. This is the open-source paid-side companion.
openai-ads-mcp is a typed Model Context Protocol server for OpenAI Ads, ChatGPT Ads, and OpenAI's Advertiser API. It lets Claude, Cursor, Codex, VS Code, and other MCP clients inspect Ads accounts, read performance insights, build paused campaigns, upload creatives, manage audiences, and send conversion events.
People often search for this as a ChatGPT Ads MCP because the ads appear in ChatGPT. The package keeps the OpenAI Ads MCP name because ChatGPT Ads are managed through OpenAI Ads, Ads Manager, and the OpenAI Advertiser API.
Current public release: 0.1.7.
It ships in two runtimes with the same tool names, arguments, defaults, safety model, and vendored OpenAPI reference:
Runtime | Best install | Package path |
Python |
|
|
Node |
|
|
The goal is simple: make OpenAI Ads workable from an AI assistant without making spend easy to trigger by accident.
Install
Python with uvx:
export OPENAI_ADS_API_KEY="..."
export OPENAI_ADS_MCP_READONLY=1
uvx openai-ads-mcpPython with pip:
python -m pip install openai-ads-mcp
export OPENAI_ADS_API_KEY="..."
export OPENAI_ADS_MCP_READONLY=1
openai-ads-mcpNode with npx:
export OPENAI_ADS_API_KEY="..."
export OPENAI_ADS_MCP_READONLY=1
npx -y openai-ads-mcpNode with npm:
npm install -g openai-ads-mcp
export OPENAI_ADS_API_KEY="..."
export OPENAI_ADS_MCP_READONLY=1
openai-ads-mcpFor local development from this monorepo:
cd services/openai-ads-mcp/python
python -m pip install -e .
python -m openai_ads_mcp
cd ../typescript
npm install
npm run build
node dist/index.jsRelated MCP server: OpenAI Ads MCP Server
Configuration
Create an Ads API key in OpenAI Ads Manager, then pass it as an environment variable.
export OPENAI_ADS_API_KEY="..."Recommended first connection:
export OPENAI_ADS_MCP_READONLY=1
uvx openai-ads-mcpOr with Node:
export OPENAI_ADS_MCP_READONLY=1
npx -y openai-ads-mcpReadonly mode hides every write tool. They are absent from tools/list and cannot be called. Once you have confirmed the account and inspected data, unset OPENAI_ADS_MCP_READONLY to enable writes.
Optional environment variables:
Variable | Purpose |
| Required bearer key for |
| Optional HTTPS override for tests or proxies. |
| Set to |
| Optional budget guard. Default |
Discovery Metadata
This repo includes server.json for the official MCP Registry and downstream MCP directories. The canonical registry name is:
io.github.trakkr-aisearch/openai-ads-mcpThe Node package includes the matching mcpName, and the Python package README includes the matching mcp-name marker for PyPI ownership verification.
The registry metadata also advertises the hosted read-only Streamable HTTP endpoint:
https://openai-ads-mcp.trakkr.ai/mcpThat hosted endpoint is for discovery and read-only usage. It does not store or use a Trakkr-owned OpenAI Ads API key.
The hosted endpoint allows anonymous initialize and tools/list; Ads API tool calls require the caller to send X-OpenAI-Ads-API-Key.
MCP client examples
Claude Code, Python runtime
claude mcp add openai-ads \
-e OPENAI_ADS_API_KEY=your_ads_key_here \
-e OPENAI_ADS_MCP_READONLY=1 \
-- uvx openai-ads-mcpClaude Code, Node runtime
claude mcp add openai-ads \
-e OPENAI_ADS_API_KEY=your_ads_key_here \
-e OPENAI_ADS_MCP_READONLY=1 \
-- npx -y openai-ads-mcpCursor or Claude Desktop
{
"mcpServers": {
"openai-ads": {
"command": "uvx",
"args": ["openai-ads-mcp"],
"env": {
"OPENAI_ADS_API_KEY": "your_ads_key_here",
"OPENAI_ADS_MCP_READONLY": "1"
}
}
}
}Use "command": "npx" and "args": ["-y", "openai-ads-mcp"] for the Node runtime.
Codex CLI
[mcp_servers.openai_ads]
command = "uvx"
args = ["openai-ads-mcp"]
env = { OPENAI_ADS_API_KEY = "your_ads_key_here", OPENAI_ADS_MCP_READONLY = "1" }MCP Registry
Registry-compatible clients should discover this server by name:
io.github.trakkr-aisearch/openai-ads-mcpThe registry metadata lists npm, PyPI, and the hosted Streamable HTTP endpoint. The hosted endpoint does not require an API key for discovery, but it does require X-OpenAI-Ads-API-Key for Ads API tool calls.
Docker
The repository includes production Dockerfiles for hosted Streamable HTTP deployments:
docker build -t openai-ads-mcp .
docker run --rm -p 8080:8080 \
-e OPENAI_ADS_MCP_HOSTED_PUBLIC=1 \
-e OPENAI_ADS_MCP_TELEMETRY_SALT="local-test-salt" \
openai-ads-mcpThe narrower typescript/Dockerfile is used by the Cloud Run deploy script. For local stdio use, prefer uvx openai-ads-mcp or npx -y openai-ads-mcp.
Streamable HTTP
The Node runtime can also serve MCP over Streamable HTTP for hosted or team deployments:
export OPENAI_ADS_MCP_HTTP_TOKEN="choose_a_long_random_token"
export OPENAI_ADS_MCP_READONLY=1
npx -y openai-ads-mcp --httpDefaults:
URL:
http://127.0.0.1:8080/mcplocally, orhttps://your-host/mcpbehind a proxy.Health checks:
GET /healthz,GET /health, andGET /ready.Remote mode forces
OPENAI_ADS_MCP_READONLY=1unlessOPENAI_ADS_MCP_HTTP_ALLOW_WRITES=1is set.OPENAI_ADS_MCP_HTTP_TOKENprotects the MCP endpoint withAuthorization: Bearer <token>.Clients may send
X-OpenAI-Ads-API-Keyper request, or the server can use a server-sideOPENAI_ADS_API_KEY.
Useful hosted env vars:
Variable | Purpose |
| HTTP port. Default |
| MCP path. Default |
| Health path. Default |
| Optional bearer token required by hosted clients. |
| Set to |
| Optional CORS origin. Default |
For public hosted endpoints, keep writes disabled and require users to bring their own Ads API key per request. Do not put a shared Ads API key in browser-visible config.
Public hosted mode
For a public discovery endpoint, use:
export OPENAI_ADS_MCP_HOSTED_PUBLIC=1
export OPENAI_ADS_MCP_TELEMETRY_SALT="long_random_value"
npx -y openai-ads-mcp --httpHosted public mode:
forces readonly mode
refuses to start if
OPENAI_ADS_MCP_HTTP_ALLOW_WRITES=1refuses to start if
OPENAI_ADS_API_KEYis presentrejects
X-OpenAI-Ads-API-Base-Urlallows anonymous initialize and
tools/listrequires
X-OpenAI-Ads-API-Keyfor Ads API tool callsrate-limits discovery and tool calls
logs only redacted summaries, hashes, counts, status, latency, and client metadata
The production runbook is in HOSTED_DEPLOY.md.
Tool Surface
The Python and Node runtimes expose the same 27 tools.
Group | Tools |
Account |
|
Campaigns |
|
AdGroups |
|
Ads |
|
Insights |
|
Audiences |
|
Conversions |
|
Helpers |
|
High-use tools
Tool | What it does |
| Gets the ad account and confirms the API key works. |
| Reads account, campaign, ad group, or ad insights with fields, filters, sort, segments, and cursor pagination. |
| Creates a paused campaign with a guarded lifetime budget, including conversion-optimized campaigns with one event setting. |
| Uploads an image URL or local image file and returns |
| Creates a paused ad. |
| Creates one paused campaign, one paused ad group, and paused ads in a guarded workflow. |
| Deterministically drafts API-shaped |
| Sends conversion events to |
get_insights accepts the current tagged time-range shape, for example:
{"type":"unix_range","start":1764547200,"end":1765152000}The older nested shape is normalized for backward compatibility.
For conversion optimization, pass bidding_type="conversions" and exactly one
conversion_event_setting_ids value to create_campaign. The campaign cannot
use product-feed mode, and child ad groups must bill by click. build_campaign
offers the same path through its singular conversion_event_setting_id helper
argument. The bid is a CPA input even though OpenAI bills the child ad group per
click.
OpenAI's Bulk API remains a limited preview and is not exposed as a general MCP tool. Product-feed campaign objects are supported, but feed connection and catalog upload still happen in Ads Manager or through OpenAI's supported SFTP flow.
Safety Model
This server can affect real ad spend, so the defaults are deliberately cautious.
Create tools default to paused.
build_campaigncreates every object paused.Activations are separate tools:
set_campaign_state,set_ad_group_state, andset_ad_state.Budget-setting paths enforce
OPENAI_ADS_BUDGET_CEILING_USD, default100.To exceed the ceiling, pass
confirm_budget=True.OPENAI_ADS_MCP_READONLY=1hides every write tool entirely.Conversion ingest validates at most 1000 events per call, timestamps no older than 7 days, and timestamps no more than 10 minutes in the future.
Use
validate_only=trueto validate a conversion batch without ingesting it.The server never logs API keys or conversion user data.
MCP annotations are set on every tool. Read tools use readOnlyHint. Write tools use readOnlyHint=false. Activation and budget-changing tools are marked destructive and open-world so hosts can prompt before running them.
Worked Example
First, connect safely:
export OPENAI_ADS_API_KEY="..."
export OPENAI_ADS_MCP_READONLY=1
uvx openai-ads-mcpAsk your assistant:
Call get_account and list_campaigns. Confirm the Ads key works and show me what already exists.Then restart without readonly mode and build a paused campaign:
Use draft_context_hints for "AI visibility monitoring software" aimed at growth teams with comparison intent.
Then call build_campaign with:
- name: "AI visibility category test"
- budget_usd: 50
- ad_group: name "Growth teams", billing_event "click", max_bid_usd 1.25, context_hints from the draft
- ads: two chat_card variants using my uploaded file_id
Do not activate anything.Review the returned campaign, ad group, ads, budget, targeting, and review status. When you are ready to go live, activate each layer explicitly:
Call set_campaign_state with state="activate".
Call set_ad_group_state with state="activate".
Call set_ad_state for the approved ad with state="activate".The Organic Half
Paid placements answer: where did you buy attention?
Trakkr answers: where does your brand show up organically across ChatGPT, Perplexity, Gemini, Claude, Google AI Overviews, Reddit, citations, rankings, competitors, sentiment, prompts, reports, and actions?
Track the organic side at trakkr.ai. Use the Trakkr generator at trakkr.ai/create when you want to turn AI-search gaps into content briefs.
This MCP also exposes one optional resource:
openai-ads://trakkr-visibilityIt returns a short paste-ready briefing that connects buying ChatGPT ad placements with tracking organic ChatGPT visibility. It is never injected into tool results.
Development
Python:
cd services/openai-ads-mcp/python
python -m pytest -q
python -c "import openai_ads_mcp; print('ok')"Node:
cd services/openai-ads-mcp/typescript
npm install
npm run build
npm test
OPENAI_ADS_MCP_READONLY=1 node dist/index.jsOpenAPI drift check:
cd services/openai-ads-mcp/typescript
npm run check:openapi
npm run check:docsThe scheduled workflow runs both checks weekly. The OpenAPI comparison catches
schema drift. The guide check covers current behavior documented outside the
downloadable schema, including tagged insight ranges, obref, mobile app
events, conversion optimization, advertiser readiness, required chat-card
images, and the limited-preview Bulk API.
Release Status
0.1.7 is the current public beta release for npm, PyPI, the hosted endpoint, and the live MCP Registry entry. Registry metadata versions are immutable, so registry-only corrections in this repo should ship with the next package release version. Release work is synced to the dedicated public repository before publishing. See RELEASING.md.
License
MIT, copyright Trakkr.
Available Tools
12 toolsdraft_context_hintsCRead-onlyIdempotentInspect
Draft deterministic context_hints for an ad group from product, audience, intent, and keywords.
| Name | Required | Description | Default |
|---|---|---|---|
| product | Yes | ||
| audience | No | ||
| intent | No | ||
| keywords | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey read-only, idempotent, and non-destructive behavior. The description adds 'deterministic', reinforcing idempotency. However, it does not explain what 'drafting' entails operationally, whether the results are cached, or any side effects of repeated calls. Given the strong annotation coverage, the description adds some but not extensive behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that is concise and to the point. It efficiently communicates the core purpose and inputs. However, it omits necessary detail (e.g., output description, parameter formats) that could be added without significant verbosity. The structure is acceptable for a simple tool but front-loads the essential information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 4 parameters, 0% schema description coverage, and no output schema, the description is insufficient. It does not explain what 'context_hints' are, how they relate to an ad group, or what the tool returns. A user would likely need additional documentation to understand the tool's full behavior and inputs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It lists the four parameter names (product, audience, intent, keywords) but provides no additional semantics: no data types, formats, allowed values, or examples. 'keywords' has an empty JSON schema type (likely an object) but is not clarified. The parameter names are somewhat self-explanatory, but the description fails to add meaningful detail beyond the names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The verb 'draft' and resource 'context_hints' clearly indicate the action and output. The description specifies inputs from product, audience, intent, and keywords, making the core function unambiguous. However, it does not differentiate from sibling tools like 'get_ad_group' or 'manage_conversions', though the scope is distinct enough.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. The description lacks context about prerequisites, typical workflows, or scenarios where drafting context hints is appropriate. Sibling tools exist (e.g., 'get_ad_group', 'manage_conversions') but no comparisons are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_accountARead-onlyIdempotentInspect
Get the authenticated OpenAI Ads account. Use this first to verify that OPENAI_ADS_API_KEY works and to read account id, name, timezone, currency, and settings.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only and idempotent hints, but the description adds valuable context: the tool verifies the API key and reads specific fields (account id, name, timezone, currency, settings). This goes beyond the annotations without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no unnecessary words. Front-loaded with the verb and resource, then provides usage instructions. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, no-output-schema tool, the description is complete: it names the action, the purpose, and the specific returned fields. No gaps given the simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist, and schema coverage is 100% (0 parameters). The description compensates by listing the returned fields, which adds meaning beyond the empty schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it retrieves the authenticated OpenAI Ads account, specifying the verb 'Get' and the resource 'account'. It distinguishes well from sibling tools like get_ad, get_campaign, etc., which target different resources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises to use this tool first to verify the API key works, providing clear usage context. No alternatives exist since it's the only account retrieval tool, but the guidance on when to use is specific and helpful.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_adARead-onlyIdempotentInspect
Get one ad by id, including review_status and creative metadata.
| Name | Required | Description | Default |
|---|---|---|---|
| ad_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true, so safety profile is clear. The description adds value by detailing included fields (review_status, creative metadata), which is beyond basic retrieval.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no wasted words. Directly communicates purpose and output content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-ID tool with one parameter and no output schema, the description is mostly complete: it states what it does and what fields are returned. Could mention response format but not critical.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It states the parameter is the ad's ID, which is minimal. No format, constraints, or source information provided, but for a single string parameter, this meets the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verb 'Get' and resource 'ad' with scope 'one ad by id', clearly distinguishing from sibling tools like list_ads. It also specifies included content (review_status, creative metadata).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use case: to retrieve a single ad by ID. It doesn't explicitly mention when not to use or name alternatives, but the sibling tool list_ads provides a clear contrasting use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_ad_groupBRead-onlyIdempotentInspect
Get one ad group by id.
| Name | Required | Description | Default |
|---|---|---|---|
| ad_group_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true, which cover safety and idempotency. The description adds no behavioral context beyond what annotations provide, but does not conflict. Missing info on error behavior (e.g., what if id not found).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no extraneous words. Every word serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and no output schema, the description is minimally adequate. However, it lacks details on return values or edge cases, which would be helpful for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, and the description does not explain the 'ad_group_id' parameter (e.g., format, example, or meaning). It adds no value beyond the schema's type and required flag.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('get'), the resource ('ad group'), and the identifier method ('by id'). It distinguishes from sibling tools like list_ad_groups (which returns multiple) and get_ad (different resource).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives (e.g., list_ad_groups for multiple ad groups). It lacks exclusions or context for appropriate use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_audienceBRead-onlyIdempotentInspect
Get one custom audience by id.
| Name | Required | Description | Default |
|---|---|---|---|
| audience_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide strong behavioral hints (readOnlyHint, destructiveHint, idempotentHint). The description adds no additional behavioral context beyond what the annotations convey, such as what the response contains or authorization requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence with no wasted words. However, it is somewhat under-specified for the required parameter, costing a point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-id tool with strong annotations, the description is adequate. However, it lacks mention of return value structure or any context about where the audience ID originates, leaving some gaps for an AI agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. However, it only says 'by id' without explaining the format, source, or constraints of the audience_id parameter. This adds minimal value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Get one custom audience by id' clearly specifies the verb (Get), the resource (custom audience), and the selection criteria (by id). It distinguishes from sibling tools like list_audiences (which retrieves multiple) and get_account (different entity).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when you have an audience ID and need its details, but does not provide explicit guidance on when to use this tool versus alternatives (e.g., list_audiences) or when not to use it. No exclusions or prerequisites are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_campaignBRead-onlyIdempotentInspect
Get one campaign by id.
| Name | Required | Description | Default |
|---|---|---|---|
| campaign_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint, idempotentHint, and openWorldHint. The description adds no behavioral context beyond what annotations provide, but it does not contradict them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very concise, using only 5 words in one sentence. However, it is almost too brief and could benefit from slightly more detail without becoming verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of the tool (one parameter, no output schema, many siblings), the description is minimal. It does not explain return values, error handling, or how it differs from similar retrieval tools like get_ad.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage for the only parameter (campaign_id) is 0%, and the description does not explain parameter meaning, format, or constraints. It adds no value beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get', the resource 'campaign', and the method 'by id'. It is specific and distinguishes from sibling tools like list_campaigns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives such as list_campaigns or search_geo. The description does not mention when not to use it or any prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_insightsARead-onlyIdempotentInspect
Get performance insights for account, campaign, ad group, or ad scope. Supports fields, filters, sort, product/country/device segments, time ranges, and cursor pagination.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | Yes | ||
| entity_id | No | ||
| time_granularity | No | daily | |
| time_range | No | ||
| segments | No | ||
| fields | No | ||
| filters | No | ||
| sort | No | ||
| limit | No | ||
| after | No | ||
| before | No | ||
| response_format | No | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint, idempotentHint, so description does not need to repeat safety. It adds value by disclosing supported features (fields, filters, sort, segments, time ranges, cursor pagination), which goes beyond annotations. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence that efficiently lists features. Could be improved with bullet points for readability, but minimal waste. Appropriate length for the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 12 parameters, no output schema, and 0% schema descriptions, the description provides high-level context but lacks details on output structure, parameter formats, or required scope usage. Sufficient for basic understanding but not for precise invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage for 12 parameters, the description mentions several capabilities (fields, filters, segments, etc.) but does not map to parameter names or explain formats (e.g., how to specify time_range or segments). Partially compensates but leaves many parameters undefined.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Get performance insights' and lists scopes (account, campaign, ad group, ad), which distinguishes it from sibling tools that retrieve single entities. However, it could be more specific about the type of insights (e.g., metrics).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for aggregated performance data vs. entity retrieval, but does not explicitly state when to use or not use this tool compared to alternatives like get_account or list_campaigns. No exclusion criteria or prerequisites provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_ad_groupsBRead-onlyIdempotentInspect
List ad groups, optionally filtered to a campaign.
| Name | Required | Description | Default |
|---|---|---|---|
| campaign_id | No | ||
| limit | No | ||
| after | No | ||
| before | No | ||
| order | No | desc |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint, idempotentHint, openWorldHint. Description adds no behavioral context beyond the filter option mentioned in schema. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single short sentence, front-loaded with purpose. However, given the tool has 5 parameters including pagination, the description is underspecified and could benefit from more structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, and description does not hint at what the response contains (e.g., list of ad group objects). Missing pagination context for after/before parameters, which are crucial for list operations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%. Description only references 'campaign_id' implicitly. Does not explain pagination parameters (limit, after, before) or ordering (order). Fails to compensate for lack of schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb (list), resource (ad groups), and condition (optionally filtered to a campaign). Distinguishes from sibling tools like list_ads or list_campaigns by specifying the resource type.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implied usage: use to list ad groups. No explicit guidance on when to use vs alternatives, no exclusions or prerequisites mentioned. Adequate but minimal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_adsCRead-onlyIdempotentInspect
List ads in an ad group.
| Name | Required | Description | Default |
|---|---|---|---|
| ad_group_id | Yes | ||
| limit | No | ||
| after | No | ||
| before | No | ||
| order | No | desc |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds no behavioral context beyond 'list ads', such as sorting, filtering, or pagination behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no waste, but it lacks critical information, making it under-informative rather than appropriately concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 5 parameters, no output schema, and annotations present, the description is incomplete. It omits pagination, ordering, and limit behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%. The description fails to explain any of the 5 parameters (ad_group_id, limit, after, before, order). No additional meaning provided.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb (list) and resource (ads) with a specific scope (in an ad group). It effectively distinguishes from sibling tools like get_ad (single ad) and list_ad_groups.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives (e.g., get_ad, get_ad_group). No mention of prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_audiencesCRead-onlyIdempotentInspect
List custom audiences for the authenticated ad account.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| after | No | ||
| before | No | ||
| order | No | desc |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true. Description adds the authentication scope but does not disclose pagination behavior, data freshness, or any side effects beyond what annotations imply. Minimal extra value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Very short sentence, no wasted words. However, it lacks important details about parameters and usage, making it under-specified for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, so description should explain what is returned (e.g., list of audience objects) but does not. Missing pagination behavior and ordering semantics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description provides no explanation for parameters (limit, after, before, order). Agent must rely solely on parameter names and types without semantic clues.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'list', resource 'custom audiences', and scope 'for the authenticated ad account'. It is specific and distinguishes from sibling 'get_audience' by implying a list operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool vs siblings like 'get_audience'. Does not mention when not to use or prerequisites. The agent must infer usage from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_campaignsARead-onlyIdempotentInspect
List campaigns in the authenticated ad account with cursor pagination.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| after | No | ||
| before | No | ||
| order | No | desc |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only and idempotent behavior. The description adds cursor pagination detail, which is a behavioral trait not in annotations. Missing information about rate limits or authentication details, but annotations cover safety.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence of 10 words, front-loaded with the action and resource. Every word adds value; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, no parameter descriptions. The description only gives high-level purpose and pagination method. For a 4-parameter list tool, return fields and default behavior are not described, leaving gaps for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% (no descriptions in schema). The description implies after/before are cursor tokens via 'cursor pagination', but does not explain any parameter explicitly. With low coverage, the description should compensate but does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists campaigns in the authenticated ad account. The mention of cursor pagination adds specificity. It distinguishes from sibling tools like get_campaign (single) and list_ads/list_ad_groups (different resource).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives like get_campaign for a single campaign or search tools. The description is purely declarative without usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_geoARead-onlyIdempotentInspect
Search geo targets for targeting.locations.include and return ids usable in campaign targeting.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide behavioral traits: readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds that the tool returns IDs usable in campaign targeting, which is useful context but does not significantly expand beyond the annotations. There is no contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence of about 15 words, no unnecessary information. It is front-loaded with the tool's purpose. However, it could be slightly more efficient or structured, but it is generally concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has one parameter, no output schema, and annotations covering safety, the description is minimally adequate. It explains the tool's purpose and output usage but lacks details on query format, possible response, or types of geo targets. For a straightforward search tool, it is barely sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has one parameter 'query' with 0% coverage (no description). The tool description does not specify what the query should contain (e.g., a location name, coordinate, or code). This leaves the agent with little guidance on how to form a valid query, despite the low schema coverage burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches geo targets for the specific purpose of obtaining IDs for campaign targeting's targeting.locations.include. It uses a specific verb 'Search' and resource 'geo targets', and the output is explicitly stated as 'ids usable in campaign targeting'. This distinguishes it from sibling tools which focus on different resources like accounts, ads, and audiences.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool: when you need geo target IDs for targeting.locations.include in campaign targeting. However, it does not explicitly state when not to use it or provide alternative tools. The sibling tools are all different in purpose, so the context is clear but lacks exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
12 tool updates
v0.1.5- First observed
draft_context_hints - First observed
get_account - First observed
get_ad - First observed
get_ad_group - First observed
get_audience - First observed
get_campaign - First observed
get_insights - First observed
list_ad_groups - First observed
list_ads - First observed
list_audiences - First observed
list_campaigns - First observed
search_geo
TDQS
Scored across 12 tools
Each tool has a clearly distinct purpose: get_* and list_* target specific entities, draft_context_hints is a unique creation action, search_geo handles geo targeting, and get_insights covers analytics. No overlap or ambiguity.
All tool names follow a consistent verb_noun pattern with lowercase and underscores, e.g., get_account, list_campaigns, draft_context_hints, search_geo. The naming is predictable and uniform.
With 12 tools, the set is slightly on the higher side but still well-scoped for an ads platform's essential operations (read entities, insights, geo search, drafting). No unnecessary tools.
The tool surface is missing critical CRUD operations for campaigns, ad groups, ads, and audiences. Agents can only read and list, plus draft hints, which is a significant gap for managing ads campaigns.
Maintenance
Related MCP Connectors
Google Ads MCP server — manage campaigns, keywords, and metrics.
Marketo MCP server for AI. 130 tools to operate Marketo from Claude, Cursor, or ChatGPT.
MCP server that lets AI assistants use all OneSchema features exposed via the public API.
Google Ads, Meta Ads & GA4 MCP server - 250+ tools for campaigns, creatives, audiences & reports.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceUnofficial MCP server implementation for Facebook Business API. Enables LLMs to manage ad campaigns and ads via natural language.2MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that exposes the ChatGPT Ads API as tools an LLM host can call.4MIT
- AlicenseNot gradedqualityDmaintenanceEnables management of OpenAI Ads campaigns, ad groups, ads, and insights through MCP, with approval-gated live mutations for safe write operations.33 npmMIT
- AlicenseAqualityDmaintenanceAn MCP server for the OpenAI Ads (ChatGPT Ads) Advertiser API, providing tools for agent-led performance marketing such as finding dead ads, auditing near-duplicate copy, and auditing ad-group context hints.18MIT