Skip to main content
Glama
get-mcp-ads

ChatGPT Ads MCP server

ChatGPT Ads MCP server

Bring your ChatGPT Ads account into your MCP client.

Read campaigns, performance and conversions, and prepare changes for the ad account your API key belongs to.

Release CI License: Apache 2.0 Node

Watch the film · What's new · Install · Tool reference · Try hosted getmcpads

Watch the getmcpads film: every ad account in one conversation with your AI assistant

Play the 45-second film

The film shows hosted getmcpads with sample data. Its MCP Apps, from creative galleries and alerts to Google Sheets exports and bulk launches, belong to the hosted product. This repository provides the standalone native API tools.

30 read tools · 28 write tools, disabled by default.

Run locally with your own Advertiser API key and a client that supports stdio MCP, such as Claude Desktop, Claude Code or Cursor. Your requests go directly to the ChatGPT Ads API. For managed connections, including supported ChatGPT setups, use the hosted option.

What's new

v1.0.1: Zod 4 security update · October 26, 2026

  • Update zod to 4.6.7. Every Zod release before 4.6.6 is covered by the high-severity advisory GHSA-mrhx-c7xc-m3w5: validating an oversized constrained collection can exhaust memory, and no Zod 3 release carries the fix. npm audit --omit=dev reports no vulnerability again.

  • Keep the Zod 3 validation behaviour. A parameter default is still validated and completed before use, so an omitted object must still supply its required fields.

  • Keep each parameter's own description when the parameter is optional or has a default. Zod 4 stores a description on the wrapped schema only, so the shared fallback description could otherwise replace it.

  • Tool names, parameters and descriptions published over MCP are unchanged. server-card.json is regenerated with Zod 4's JSON Schema output, which spells some constraints differently.

Earlier releases

Version

Date

Highlights

1.0.0

October 23, 2026

First standalone release

Full changelog · All releases

Source synchronization: SOURCE_SYNC.md.

Upgrade notes

Requires Node.js 22.23.4 or later on the 22 line, 24.22.1 or later on the 24 line, or 26.12.1 or later. These releases carry the October 2026 security fixes, and the server prints a warning on stderr when started on an older runtime. CI covers Node 22, 24 and 26. Writes remain optional and require explicit confirmation. Hosted creative integrations and MCP Apps UI are outside this release.

Related MCP server: OpenAI Ads MCP

Install this release

This is a GitHub source release. npm and MCP Registry versions are published separately. The commands below select this exact version; unpinned npx examples later in this document select the version currently available on npm.

git clone --branch v1.0.1 --depth 1 https://github.com/get-mcp-ads/chatgpt-ads-mcp-server.git
cd chatgpt-ads-mcp-server
npm ci
npm run build

Configure your MCP client to run node with the absolute path to dist/cli.js and the environment variables documented below. With the npm package, a client configuration looks like this:

{
  "mcpServers": {
    "chatgpt-ads": {
      "command": "npx",
      "args": ["-y", "@getmcpads/chatgpt-ads-mcp-server"],
      "env": {
        "OPENAI_ADS_API_KEY": "your-advertiser-api-key",
        "OPENAI_ADS_ACCOUNT_ID": "adacct_your_account"
      }
    }
  }
}

Run npm run doctor to check the configuration without contacting ChatGPT Ads, then call openai_ads_get_account first.

Managed connection. Use ChatGPT Ads with hosted getmcpads. Connect your account, select the data your assistant may access and use the hosted MCP connection. See the site for current features and plans.

Configuration

Provide these environment variables through the client's secret configuration:

Variable

Purpose

OPENAI_ADS_API_KEY

Required. An Advertiser API key created on the Settings page of Ads Manager. Each key is scoped to one ad account. This is not an OpenAI Platform API key.

OPENAI_ADS_ACCOUNT_ID

Required. The adacct_ ID of the account the key belongs to. Every other account ID is refused, and the first request checks that the key matches.

OPENAI_ADS_ENABLE_WRITES

Defaults to false. Only the exact value true registers the write tools.

OPENAI_ADS_ENABLE_ACTIVATION

Defaults to false. true allows activation and changes to status: "active", which can start delivery and spend budget. Requires writes.

You need an ad account in Ads Manager and an Advertiser API key, as described in OpenAI's Advertiser API overview. Some features are enabled per account: the Bulk API is in limited preview, and API partners need pixel management and conversion-optimized bidding enabled for each client account, as described in API Partner Setup. The server returns the native access error when a feature is not enabled. API use is governed by OpenAI's Advertising Terms, which require you to keep API keys confidential.

This package reads a key from the environment. It runs no browser sign-in and writes nothing to disk. To rotate the key, create a new one in Ads Manager, update the variable and restart the server.

Safety and coverage

Writes preview by default. A call without confirm returns the change, the native state it was checked against and a confirmationToken. After the person approves the exact preview, repeat the identical call with confirm: true and that token. Use one requestId UUID per logical change; creations send it as the native Idempotency-Key, which OpenAI uses to avoid creating a duplicate when the same creation is sent again. Before applying, the server reads the native state again and refuses the write if it changed since the preview. After applying, it reads campaigns, ad groups, ads and feed products back and reports whether the change is confirmed. Campaigns, ad groups and ads are created paused. Activation is refused unless OPENAI_ADS_ENABLE_ACTIVATION=true, and previews that can start delivery carry activationMaySpend: true. A write whose outcome is uncertain is recorded as UNKNOWN and never resubmitted. Read the receipt with openai_ads_get_mutation and the native state before deciding anything else. Previews and receipts live in memory and a restart forgets them. Account checks run before every request. Unknown arguments are rejected, and nested request bodies are validated against the pinned native schemas.

Requests go only to api.ads.openai.com with a 30 second timeout and an 8 MiB response bound. Redirects are refused. The key is removed from any provider text, and only validation errors return native messages. The API allows 600 requests per minute per endpoint and 1,200 overall; a throttled request returns RATE_LIMITED without a retry. Budgets and bids use integer micros of the account currency (1,000,000 is one unit). Reported spend, CPC and CPM use major units, CTR and conversion rates are fractions, and missing values stay null. Product feed prices use minor units (7999 is USD 79.99).

This server exposes a reviewed subset of the API. It leaves out API key provisioning, billing and spend limit changes, account administration, partner account creation, custom audience creation and membership uploads, lead sync webhooks and SFTP credentials. New upstream endpoints are not exposed automatically. Use tools/list or server-card.json for exact schemas, openai_ads_get_write_schema for nested request fields, and the official API reference for provider details.

Hosted option

getmcpads for ChatGPT Ads manages the hosted connection and account selection. Hosted and source releases can differ. Contact: hello@getmcpads.com.

Development

npm run typecheck
npm run lint
npm run build
npm test
npm run catalog

All tests run offline with synthetic responses. No live account is read or changed. To refresh the pinned schemas, save the official OpenAPI document and run node scripts/generate-contracts.mjs <path> <date>.

Tools

Every tool is listed below. See server-card.json for complete parameter and output schemas. Every tool takes adAccountId, the account in OPENAI_ADS_ACCOUNT_ID.

Tool

Purpose

openai_ads_get_account

Read the account's name, currency, time zone, status and brand review, and verify that the key belongs to it.

openai_ads_get_campaigns

List one page of campaigns.

openai_ads_get_campaign

Read one campaign with its budget, schedule and targeting.

openai_ads_get_ad_groups

List one page of the ad groups of a campaign.

openai_ads_get_ad_group

Read one ad group with its bidding, context hints and product set.

openai_ads_get_ads

List one page of the ads of an ad group, with creative metadata and review status.

openai_ads_get_ad

Read one ad with its creative and review status.

openai_ads_list_ad_creatives

List chat card creatives with their file IDs and signed image links, refreshing expired links.

openai_ads_get_insights

Read performance by account, campaign, ad group or ad, with one optional country, device or platform breakdown and attribution settings.

openai_ads_search_locations

Search country, region and market location IDs for geographic targeting.

openai_ads_get_audit_logs

List recorded changes to campaigns, ad groups and ads.

openai_ads_get_spend_limits

Read the account's spend limit windows.

openai_ads_get_landing_page_crawl

Read the landing page crawl evidence for an ad's submitted version.

openai_ads_get_conversion_settings

List conversion event settings, the goals a campaign can use.

openai_ads_get_conversion_pixels

List conversion pixels and connected pixel IDs.

openai_ads_get_conversion_events

List recent sampled conversion events, to check that a pixel or server integration sends data.

openai_ads_get_conversion_insights

Read attributed conversion totals or daily values, optionally by country or device.

openai_ads_get_feeds

List product feeds, optionally with product counts.

openai_ads_get_feed_uploads

List recent product feed uploads and their results.

openai_ads_get_feed_settings

Read a feed's display and organic-listing settings.

openai_ads_get_feed_products

List feed products that match ad group product filters.

openai_ads_get_custom_audiences

List custom audiences.

openai_ads_get_custom_audience

Read one custom audience and its matched count.

openai_ads_get_audience_operations

List the accepted operations of a custom audience.

openai_ads_get_audience_operation

Read the state of one custom audience operation.

openai_ads_get_bulk_job

Read the status of a Bulk API job.

openai_ads_get_bulk_job_operations

Read one page of a Bulk API job's operation outcomes.

openai_ads_get_write_schema

Read the pinned native request definitions, upload and bulk limits, and the exclusions.

openai_ads_get_write_context

Read the account, conversion settings and feeds before proposing a campaign, with the supported bid combinations.

openai_ads_get_mutation

Read a write preview or receipt held by this server process.

Disabled by default. Calls preview unless explicitly confirmed. Check the configuration and exact schema before use.

Tool

Purpose

openai_ads_create_campaign

Create a paused campaign with its objective, budget, schedule and targeting.

openai_ads_update_campaign

Update campaign settings such as budget, schedule or targeting.

openai_ads_pause_campaign

Pause a campaign.

openai_ads_activate_campaign

Activate a campaign. Can spend budget; requires OPENAI_ADS_ENABLE_ACTIVATION.

openai_ads_archive_campaign

Archive a campaign.

openai_ads_create_ad_group

Create a paused ad group with its bidding, context hints and product set.

openai_ads_update_ad_group

Update ad group settings such as bidding or context hints.

openai_ads_pause_ad_group

Pause an ad group.

openai_ads_activate_ad_group

Activate an ad group. Can spend budget; requires OPENAI_ADS_ENABLE_ACTIVATION.

openai_ads_archive_ad_group

Archive an ad group.

openai_ads_create_ad

Create a paused ad with a chat card or product template creative, which enters review.

openai_ads_update_ad

Update an ad's name or creative. A creative edit starts a new review.

openai_ads_pause_ad

Pause an ad.

openai_ads_activate_ad

Activate an ad. Can spend budget; requires OPENAI_ADS_ENABLE_ACTIVATION.

openai_ads_archive_ad

Archive an ad.

openai_ads_create_ad_preview

Create a temporary preview of an existing ad.

openai_ads_rename_campaign

Rename a campaign. The name is the only field that changes.

openai_ads_rename_ad_group

Rename an ad group. The name is the only field that changes.

openai_ads_rename_ad

Rename an ad. The name is the only field that changes.

openai_ads_upload_image

Upload PNG, JPEG or WebP bytes of at least 640 x 640 and return a file ID for a chat card.

openai_ads_upload_image_url

Have OpenAI import a public HTTPS image and return a file ID.

openai_ads_create_conversion_setting

Create a conversion event setting for a standard or custom event.

openai_ads_create_conversion_pixel

Create a conversion pixel.

openai_ads_create_feed

Create a product feed.

openai_ads_update_feed_settings

Update a feed's display name and organic-listing settings.

openai_ads_update_feed_products

Update the title, price or availability of up to 500 existing product variants.

openai_ads_archive_feed

Archive a product feed.

openai_ads_submit_bulk_job

Submit a Bulk API job of up to 1,000 operations, validation only by default.

Resource

Content

openai-ads://guide

Account scope, write flow, units, rate limits, supported metrics, levels, breakdowns and attribution options.

License

Apache License 2.0. See NOTICE.

More from getmcpads

Meta Ads · Google Ads · Google Analytics 4 · Google Search Console · TikTok Ads · Pinterest Ads · X Ads

Maintained by Emmanuel at getmcpads. Questions: hello@getmcpads.com.

Available Tools

30 tools
openai_ads_get_accountopenai ads get accountA
Read-onlyIdempotent

Read the configured ChatGPT Ads account: name, currency, time zone, status and brand review. Also verifies that the API key belongs to OPENAI_ADS_ACCOUNT_ID. Run it first.

NameRequiredDescriptionDefault
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, and non-destructive. The description adds that the call validates API key ownership and refuses a mismatched account ID, which is useful context beyond the safety hints, though it doesn't mention rate limits or error shapes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences, front-loaded with the core read action and followed by the verification behavior. Nothing redundant or padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema available, the description needn't explain return structure; it summarizes returned fields and the key verification behavior. Combined with annotations and a fully documented single parameter, an agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the adAccountId pattern and refusal-on-mismatch semantics are already documented in the schema. The description reinforces the single-account scoping but adds no format or syntax details beyond that baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read the configured ChatGPT Ads account') and enumerates what is returned (name, currency, time zone, status, brand review). An agent can distinguish it from the many sibling get_* tools that fetch campaigns, insights, or settings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Run it first' gives explicit ordering guidance, and the note about verifying the API key against OPENAI_ADS_ACCOUNT_ID clarifies its role as a preliminary validation call. It does not name exclusions or alternatives, but the sequencing instruction is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_adopenai ads get adA
Read-onlyIdempotent

Read one ad with its creative and review status. No preview or change is requested.

NameRequiredDescriptionDefault
adIdYesNative ad ID (ad_) in the configured account.
includeNoAdd serving_issues to receive native reasons why this entity cannot serve. A paused state is intentional, not an issue.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds value by specifying the returned content (creative and review status) and explicitly ruling out preview, which is not captured by annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences with zero filler, front-loading the core action and then the exclusion. Every phrase earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given full schema coverage and a present output schema, the description provides enough to call this tool correctly: it states the read-only nature, the resource, and the returned fields. It could be slightly richer by naming the list alternative, but nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and all three parameters are well documented in the schema, including the account scoping and the optional serving_issues include. The description adds no parameter-level meaning beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Read one ad") and what it returns ("creative and review status"), which distinguishes it from the plural list sibling openai_ads_get_ads. It stops short of naming that sibling explicitly, so the differentiation is implied rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"No preview or change is requested" signals this is a pure read and rules out mutation or preview workflows, which is useful context. However, it never says when to choose this over openai_ads_get_ads or openai_ads_list_ad_creatives, nor does it mention prerequisites beyond what the schema already documents.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_ad_groupopenai ads get ad groupA
Read-onlyIdempotent

Read one ad group with its native bidding, context hints and product set.

NameRequiredDescriptionDefault
includeNoAdd serving_issues to receive native reasons why this entity cannot serve. A paused state is intentional, not an issue.
adGroupIdYesNative ad group ID (adgrp_) in the configured account.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so the safety profile is fully covered. The description adds a small amount of value by naming the returned aspects, but says nothing about permissions, errors, or cost beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler; the resource and the returned content are stated immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-by-ID tool with an output schema, full annotation coverage and 100% documented parameters, the description covers the essentials. It could be slightly stronger by naming the list sibling or the serving_issues include option, but nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including the include=serving_issues option and the account-scoping constraint, so the schema does the heavy lifting and baseline 3 applies. The description contributes no additional parameter semantics (it never mentions include or the ID formats).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read one ad group') and names the payload it returns (native bidding, context hints, product set). The singular 'one ad group' implicitly contrasts with the get_ad_groups list sibling, though it never names it explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The when-to-use is only implied by the tool name and singular scope: fetch a single ad group by its adgrp_ ID rather than listing. There is no explicit statement of when to choose this over get_ad_groups or get_campaign, and no prerequisites are mentioned beyond what the schema already says about the scoped account.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_ad_groupsopenai ads get ad groupsA
Read-onlyIdempotent

List one page of ad groups in a campaign. Native ad group IDs start with adgrp_. Follow last_id only when has_more is true.

NameRequiredDescriptionDefault
nameNoReturn only entities whose name matches this text, 3 to 1,000 characters.
afterNoNext-page cursor: the previous page's last_id, only when has_more is true.
limitNoPage size, 1 to 500. Defaults to 100.
orderNoSort by creation time. Defaults to desc, newest first.desc
beforeNoPrevious-page cursor: a first_id returned by a later page.
includeNoAdd serving_issues to receive native reasons why this entity cannot serve. A paused state is intentional, not an issue.
campaignIdYesNative campaign ID (cmpn_) in the configured account.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, openWorld and non-destructive, so safety is covered. The description adds behavior annotations don't: results are returned one page at a time, IDs carry the adgrp_ prefix, and cursors should only be followed when has_more is true. It stops short of noting default page size or rate limits, which the schema covers anyway.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the action and scope, then the two facts an agent needs (ID format, cursor rule). No filler or repetition of schema content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and full annotation coverage, the description does not need to explain return values. It covers pagination behavior, which is the main complexity for an 8-parameter listing tool. Only the absence of any filtering or sorting hint keeps it from being fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter including after, before, limit and order is already documented. The description's mention of last_id and has_more adds useful ties between response fields and the after cursor but nothing beyond that. Baseline 3 applies where the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Uses a specific verb and resource with scope: "List one page of ad groups in a campaign." That clearly separates it from the singular openai_ads_get_ad_group sibling, though it never names the sibling explicitly. Purpose is unambiguous but differentiation is left implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The sentence "Follow last_id only when has_more is true" gives real usage guidance for pagination, which is the main way this tool gets misused. However, it says nothing about when to choose this lister versus openai_ads_get_ad_group or how it relates to openai_ads_get_ads; tool-selection guidance is only implied by the plural/scoped naming.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_adsopenai ads get adsA
Read-onlyIdempotent

List one page of ads in an ad group with native creative metadata and review status. Follow last_id only when has_more is true.

NameRequiredDescriptionDefault
nameNoReturn only entities whose name matches this text, 3 to 1,000 characters.
afterNoNext-page cursor: the previous page's last_id, only when has_more is true.
limitNoPage size, 1 to 500. Defaults to 100.
orderNoSort by creation time. Defaults to desc, newest first.desc
beforeNoPrevious-page cursor: a first_id returned by a later page.
includeNoAdd serving_issues to receive native reasons why this entity cannot serve. A paused state is intentional, not an issue.
adGroupIdYesNative ad group ID (adgrp_) in the configured account.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, open-world). The description adds real behavioral context: results arrive as a single page and cursors should only be followed when has_more is true. It stops short of stating anything about filtering behavior, the account-scoping constraint, or the effect of include=serving_issues, which the schema carries alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, zero waste, and the primary operation is stated before the pagination caveat. Every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description needn't explain return fields, and the pagination contract is stated. What's missing is a note on the account scoping constraint or how the include parameter changes the response, but those are already covered in the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every one of the eight parameters is already documented, and the baseline of 3 applies. The description mentions cursor semantics but refers to 'last_id' (a response field) rather than the 'after' parameter name, so it adds little usable meaning beyond the schema and risks a naming mismatch.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List one page of ads in an ad group') plus the content returned (native creative metadata and review status). This clearly separates it from openai_ads_get_ad, which fetches a single ad, but it doesn't name that sibling or contrast the two explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The pagination rule ('Follow last_id only when has_more is true') gives clear guidance for paging, which is implied usage. But there is no statement of when to prefer this over openai_ads_get_ad or a creative-listing tool, and nothing about exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_audience_operationopenai ads get audience operationA
Read-onlyIdempotent

Read the lifecycle state of one custom audience operation. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.
operation_idYesExact native operation_id. The entity must belong to the configured ad account.
custom_audience_idYesExact native custom_audience_id. The entity must belong to the configured ad account.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so safety is fully covered. The description adds only 'Native fields and pagination are preserved', a partial note on output fidelity that is largely redundant with the existing output schema. It says nothing about rate limits, eventual consistency of operation state, or what a terminal vs in-progress state looks like.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with the purpose front-loaded; no filler. The final cross-reference sentence is slightly off-target for a read-only tool, but it is brief and does not obscure the main statement.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present the description need not explain return values, and rich annotations carry the safety profile, so the remaining job is purpose plus scoping and both are stated. What is missing is whether the returned lifecycle state can be polled to completion and how it relates to the list-level sibling, which would matter for an operations-status tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and all three required parameters are documented in the schema, including the account-scoping constraint ('another ID is refused'). The description contributes nothing about operation_id or custom_audience_id, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource ('Read the lifecycle state of one custom audience operation'), and the word 'one' plus 'lifecycle state' distinguishes it from the plural sibling openai_ads_get_audience_operations. An agent can pick the right tool without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the singular scope; there is no explicit instruction on when to call this versus openai_ads_get_audience_operations (polling an in-flight op) or openai_ads_get_mutation. The one routing hint given ('see openai_ads_get_write_schema for nested request fields') points at write-side schema, which does not help an agent decide when to read an operation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_audience_operationsopenai ads get audience operationsB
Read-onlyIdempotent

List the accepted operations of a custom audience. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
queryNoDocumented native query parameters. Each call reads one page unless the tool says otherwise.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.
custom_audience_idYesExact native custom_audience_id. The entity must belong to the configured ad account.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so the safety profile is covered. The description adds that operation records are returned in native shape with native pagination preserved, which is genuinely useful since a custom-audience operations endpoint could otherwise be assumed to be normalized. It says nothing about volume, ordering, or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the action and resource. Nothing is padded, though the write-schema pointer is only loosely connected to a read tool and could have been traded for sibling routing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Output schema is present so return values need not be described, and pagination plus native field preservation are disclosed. With 100% schema coverage and clear annotations, the remaining gap is only the missing contrast with the singular get_audience_operation sibling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so adAccountId scoping, the required custom_audience_id, and the limit/cursor query object are already fully documented. The description adds no parameter-level meaning beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: list the accepted operations of a named custom audience. An agent can tell it is a per-audience read. It stops short of distinguishing itself from the singular sibling openai_ads_get_audience_operation, which is the main confusion risk.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus openai_ads_get_audience_operation or openai_ads_get_custom_audience, and no prerequisites or exclusions. The only cross-reference points at openai_ads_get_write_schema for payload shapes, which is about content rather than when to call this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_audit_logsopenai ads get audit logsA
Read-onlyIdempotent

List recorded changes to the account's campaigns, ad groups and ads, optionally filtered by entity, actor or time. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
queryNoDocumented native query parameters. Each call reads one page unless the tool says otherwise.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive and openWorld, so safety is covered. The description adds that native fields and pagination are preserved (one page per call), which is useful context, but says nothing about retention window or volume of results. The trailing reference to openai_ads_get_write_schema is confusing on a read-only log tool and adds no behavioral clarity.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the resource and scope. The final sentence about write schema is the only weak link — it points at a mutation tool from a read tool and slightly dilutes focus.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, annotations are rich, and the parameter schema is fully documented, so the description only needs to establish scope and pagination — which it does. The odd write-schema redirect is the sole incompleteness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all eleven query fields are already documented, including the nested roll-up semantics for campaign_id and ad_group_id and the actor_id caveat. The description only restates the filter axes at a higher level, so it sits at the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — 'List recorded changes to the account's campaigns, ad groups and ads' — which is unmistakably distinct from the get_campaigns/get_ads retrieval siblings. An agent can tell this is the audit-history tool without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It names the filter dimensions (entity, actor, time) which implies when to reach for it, but gives no explicit when-not or alternative routing. The pointer to openai_ads_get_write_schema is a cross-reference for related fields rather than a usage rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_bulk_jobopenai ads get bulk jobA
Read-onlyIdempotent

Read one Bulk API job (limited preview, enabled per account). Only completed, partially_failed and failed are terminal. A completed job still requires reading every operation result and the native entities.

NameRequiredDescriptionDefault
jobIdYesNative bulk job ID, blkmtnjob_ followed by its identifier, returned when the job was submitted.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the safety annotations, the description explicitly details complex behavioral requirements, such as the job states that are terminal. It also enforces a critical next step: even for a completed job, the agent must read every operation result.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description uses two highly dense, well-structured sentences. Both sentences carry maximum information with no wasted words, front-loading constraints and critical operational steps.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that handling bulk API jobs involves state management and subsequent action, the description is entirely complete. It informs the agent about the status lifecycle and the mandatory follow-up step of reading operation results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Since schema coverage is 100%, the description focuses on providing the operational context and lifecycle of the bulk job, rather than redundant parameter explanations. This semantic focus adds significant value beyond the structural schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The purpose is immediately clear: to 'Read one Bulk API job'. It is specifically scoped to a limited preview feature enabled per account, which differentiates it from generic job fetching tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

While it does not specify the exact workflow (when to call it), it provides essential usage context by defining the terminal states of a job (completed, partially_failed, failed). This tells the agent when the tool will be effective.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_bulk_job_operationsopenai ads get bulk job operationsA
Read-onlyIdempotent

Read one page of Bulk API operation outcomes: created, updated, validated, failed or skipped. Pass the last operation_id as after only when has_more is true. A partial failure never rolls back earlier operations; do not resubmit an uncertain job.

NameRequiredDescriptionDefault
jobIdYesNative bulk job ID, blkmtnjob_ followed by its identifier, returned when the job was submitted.
queryNoPage size from 1 to 100 and, for later pages, the last operation_id of the previous page as after.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered; the description instead adds semantics the annotations cannot: partial failures do not roll back earlier operations, paging is gated on has_more, and an uncertain job should not be resubmitted. That's substantive context beyond structured fields, though it doesn't address consistency/latency of the operation log.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences: what it returns, how to page, and how to interpret/handle failure. The paging contract is front-loaded right after the purpose, and no sentence is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-shape explanation is unnecessary, and the description covers the two things that matter for a paginated read of an async job: cursor gating and partial-failure semantics. It stops just short of stating where has_more lives or whether operations are available before the job finishes.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so 3 would be the floor, but the description adds real meaning the schema lacks: the cursor must be the last operation_id and is only valid when has_more is true. That conditional is not present in the 'after' property definition, so the prose genuinely compensates.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource ('Read one page of Bulk API operation outcomes') and even enumerates the outcome types (created, updated, validated, failed, skipped), which is far more than a restatement of the title. It doesn't explicitly contrast itself with the sibling openai_ads_get_bulk_job, so the boundary between 'job status' and 'job operation outcomes' must be inferred from naming.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives one concrete operational rule — pass the last operation_id as after only when has_more is true — plus a caution not to resubmit an uncertain job. What's missing is when to reach for this tool versus openai_ads_get_bulk_job or openai_ads_get_mutation; usage is implied by the paging instruction rather than stated as a selection rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_campaignopenai ads get campaignB
Read-onlyIdempotent

Read one campaign with its native status, budget, schedule and targeting.

NameRequiredDescriptionDefault
includeNoAdd serving_issues to receive native reasons why this entity cannot serve. A paused state is intentional, not an issue.
campaignIdYesNative campaign ID (cmpn_) in the configured account.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds only that fields returned are the "native" ones, without disclosing anything beyond annotations such as the account-scoping refusal or serving-issues behavior (which live in the schema). Given rich annotations, this adds little.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler; every clause contributes to the purpose. It is efficient, though somewhat terse given the available schema detail it could reference.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, rich annotations, and full schema coverage, the description need not explain return values or parameter formats. It is adequate for a simple single-resource read, with only marginal room for added guidance about native-field nuances.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so campaignId, adAccountId and the include flag are all fully documented in the schema, including the serving_issues semantics and the account-scoping restriction. The description adds no parameter detail beyond what the schema already states, meeting the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Read one campaign") and enumerates the data returned (native status, budget, schedule, targeting), which implicitly separates it from the plural get_campaigns sibling. It stops short of naming the sibling explicitly, so it is clear but not maximally differentiating.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The "one campaign" framing implies the single-object use case versus the list tool, but there is no explicit when-to-use, when-not, or prerequisite guidance. Usage is inferable from context rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_campaignsopenai ads get campaignsA
Read-onlyIdempotent

List one page of campaigns in the account. Follow last_id only when has_more is true. Budget amounts use integer account-currency micros.

NameRequiredDescriptionDefault
nameNoReturn only entities whose name matches this text, 3 to 1,000 characters.
afterNoNext-page cursor: the previous page's last_id, only when has_more is true.
limitNoPage size, 1 to 500. Defaults to 100.
orderNoSort by creation time. Defaults to desc, newest first.desc
beforeNoPrevious-page cursor: a first_id returned by a later page.
includeNoAdd serving_issues to receive native reasons why this entity cannot serve. A paused state is intentional, not an issue.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive, open-world behavior, so the bar is lower. The description still adds real value by disclosing that results are paged one page at a time and that budget values are integer micros in account currency, which prevents a common misread of returned numbers.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the verb and scope, then pagination rule, then unit convention. Nothing is padded or repeated from the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be explained, and the description covers pagination and unit conventions. It leaves unmentioned the filtering and sorting capabilities the schema exposes, but nothing required for a correct call is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents every input including the 'after' cursor, limit, order and include. The description reinforces the cursor contract by referring to last_id/has_more, but adds no new meaning for name, limit, order, before or include, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List one page of campaigns in the account'), and 'one page' implicitly contrasts with the singular openai_ads_get_campaign sibling. It stops short of naming the sibling or noting that this returns summary-level campaign objects.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The pagination rule ('Follow last_id only when has_more is true') gives operative guidance for continuation, but there is no explicit statement of when to reach for this list tool versus openai_ads_get_campaign or openai_ads_get_insights.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_conversion_eventsopenai ads get conversion eventsA
Read-onlyIdempotent

List recent sampled conversion events, for checking that a pixel or server integration sends data. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
queryNoDocumented native query parameters. Each call reads one page unless the tool says otherwise.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish that this is a read-only, idempotent, non-destructive, open-world call. The description adds useful behavior beyond that: results are 'recent' and 'sampled,' and native fields plus pagination are preserved, which matters for interpreting the response.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three short sentences, front-loads the core action and purpose, and includes only relevant operational details. The cross-reference to openai_ads_get_write_schema is compact and does not bury the main point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists and the input schema is fully described, the description covers the key remaining gaps: purpose, sampling behavior, and pagination. An agent has enough information to decide when and how to call this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the nested query object documents pid and limit thoroughly. The description adds little parameter-level meaning beyond pointing to openai_ads_get_write_schema for nested request fields, so the schema remains the primary source.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'List recent sampled conversion events.' It also names the concrete diagnostic purpose, checking that a pixel or server integration sends data, which distinguishes it from siblings such as conversion insights, conversion settings, and conversion pixels.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear use case, checking pixel/server integration delivery, but does not explicitly say when to prefer conversion insights or conversion pixels instead. The context is strong enough for most selection decisions, though no exclusions or alternatives are spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_conversion_insightsopenai ads get conversion insightsA
Read-onlyIdempotent

Read attributed conversion totals or daily values, optionally by country or device and with event details. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
bodyYesExact pinned native JSON request body. Nested configuration objects replace their previous contents, so send the complete intended configuration. Money uses integer account-currency micros.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered. The description contributes 'Native fields and pagination are preserved', which usefully signals no result reshaping and paged output, but says nothing about rate limits, result size, or how the pinned native body interacts with reconciliation beyond what the schema states.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core read capability, with no filler. The closing pointer to the write schema is slightly tangential for a read tool but is compact and does not bury the main content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-shape explanation is unnecessary, and the nested body semantics are documented in-schema. Given a nested-object read tool with annotations, the description covers scope, optional dimensions, and pagination adequately; only the sibling differentiation is thin.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents adAccountId scoping, include/event_names dependency, breakdown, and granularity. The description restates the breakdown and event-detail options without adding syntax, defaults, or constraints beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read attributed conversion totals or daily values') plus the supported breakdowns (country/device) and the optional event-detail expansion. It doesn't explicitly contrast itself with the sibling openai_ads_get_insights or openai_ads_get_conversion_events, so the boundary with those tools is left to inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The breakdown and include options imply when this tool is appropriate, but there is no explicit 'use this instead of X when Y' guidance against the many sibling read tools. The only routing pointer is to openai_ads_get_write_schema for nested request fields, which addresses schema discovery rather than tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_conversion_pixelsopenai ads get conversion pixelsB
Read-onlyIdempotent

List the account's conversion pixels and connected pixel IDs. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
queryNoDocumented native query parameters. Each call reads one page unless the tool says otherwise.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered. The description adds that native fields and pagination are preserved, a useful note about response shape, but says nothing further about page size, ordering, or how many pixels a typical account returns. With annotations carrying the safety burden, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with the purpose front-loaded. The trailing write-schema pointer is the one sentence that does not clearly earn its place for a read tool, though it is brief.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists and annotations cover safety, so the core is complete enough to call. However, the description never explains how the returned pixel IDs relate to conversion_events or conversion_settings, and its only external pointer targets the mutation schema, leaving the agent without relational context for a tool that sits in a crowded conversion-related namespace.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% — adAccountId's pattern and account-scoping constraint are fully documented in the schema, as are the query paging parameters. The description adds no parameter-level meaning, so the baseline 3 applies; the cross-reference to openai_ads_get_write_schema does not clarify the read parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — list the account's conversion pixels plus connected pixel IDs — which an agent can distinguish from conversion_events or conversion_settings siblings by name. It stops short of explicitly contrasting with those siblings, but the resource is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to choose this over openai_ads_get_conversion_events or openai_ads_get_conversion_settings, which cover adjacent concepts. The only routing hint points to openai_ads_get_write_schema, a write-oriented sibling, for nested request fields — a confusing pointer for a read-only listing tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_conversion_settingsopenai ads get conversion settingsA
Read-onlyIdempotent

List the account's conversion event settings, the goals a campaign can use. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
queryNoDocumented native query parameters. Each call reads one page unless the tool says otherwise.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive, and openWorld, so the safety profile is covered. The description adds that native fields and pagination are preserved, which is mild context, but the closing pointer to openai_ads_get_write_schema is confusing for a read-only tool and adds no behavioral clarity.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three compact sentences with the purpose front-loaded and no filler. The trailing write-schema reference is arguably noise for a listing tool, which keeps it just short of a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists and annotations fully describe the safety profile, and the schema documents both parameters. Given that richness, the description supplies exactly the remaining piece — what the resource is and that pagination/native fields are retained.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters (adAccountId, query) are fully documented in the schema, so the description carries little burden. It adds no syntax or scoping detail beyond the schema, and the mention of 'nested request fields' is misleading for a GET tool whose nested object is just a query block.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'List the account's conversion event settings', and adds the purpose ('the goals a campaign can use'). It is reasonably distinguishable from get_conversion_events, though the description never explicitly contrasts the two siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'goals a campaign can use' phrasing implies the use case, but there is no explicit when-to-use guidance, no prerequisites, and no stated alternative for retrieving actual conversion event data versus settings. Usage is only inferable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_custom_audienceopenai ads get custom audienceA
Read-onlyIdempotent

Read one custom audience and its matched count. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
queryNoDocumented native query parameters. Each call reads one page unless the tool says otherwise.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.
custom_audience_idYesExact native custom_audience_id. The entity must belong to the configured ad account.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds beyond that: it discloses that native fields and pagination are preserved, and that a matched count is returned — useful behavioral context the annotations don't carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with the resource and its payload front-loaded; no wasted clauses. The trailing write-schema pointer is arguably dispensable for a read tool but is brief and does not bloat the definition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Output schema exists and schema coverage is 100%, so return shape needn't be explained; the description still covers pagination and matched-count return. The only weakness is the misdirected reference to a write schema, which is not needed to call this read tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and all three parameters (including the nested query.matched_count_granularity) are documented in the schema itself. The description's mention of 'matched count' loosely maps to the granularity param but adds no syntax or format detail beyond what the schema provides; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: 'Read one custom audience and its matched count.' The word 'one' implicitly separates it from the sibling openai_ads_get_custom_audiences (list), though the sibling is never named explicitly. An agent can tell what it fetches, but the singular/plural distinction must be inferred from a single word.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by 'Read one' — no explicit when-to-use, when-not, or alternative named. The one cross-reference ('See openai_ads_get_write_schema for nested request fields') points at a write-schema tool, which is not an obvious alternative for a read operation and adds little routing value.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_custom_audiencesopenai ads get custom audiencesB
Read-onlyIdempotent

List the account's custom audiences. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
queryNoDocumented native query parameters. Each call reads one page unless the tool says otherwise.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so safety is covered. "Native fields and pagination are preserved" adds some behavioral context about pass-through results and paging, but it is vague about page size, cursor semantics, and the fact that each call returns only one page (that detail appears only in the schema).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first two sentences are tight and front-loaded. The third sentence, "See openai_ads_get_write_schema for nested request fields," is a stock cross-reference that is poorly targeted for a read/list operation and spends a full sentence on tangential information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and the adAccountId scoping is handled in the schema. However, for a paginated tool exposing eight query filters (intended_use, custom_audience_ids, policy_revision, etc.), the description says nothing about filtering capability, leaving the agent to discover it from the schema alone.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the nested query object is fully documented in the schema, so the baseline is 3. The description only gestures at pagination and defers filter semantics to another tool, adding little beyond what the schema already states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"List the account's custom audiences" gives a specific verb (list) and resource, which clearly separates it from the singular openai_ads_get_custom_audience in the sibling set. It stops short of naming that sibling explicitly, so the plural-vs-singular distinction is left for the agent to infer from the names.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the word "List" suggests enumeration versus the single-record getter, and the closing pointer redirects to openai_ads_get_write_schema rather than to a competing read tool. There is no explicit statement of when to prefer this over openai_ads_get_custom_audience or when to page instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_feed_productsopenai ads get feed productsB
Read-onlyIdempotent

List products in a feed that match ad group product filters. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
bodyYesExact pinned native JSON request body. Nested configuration objects replace their previous contents, so send the complete intended configuration. Money uses integer account-currency micros.
feed_idYesExact native feed_id. The entity must belong to the configured ad account.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is fully covered elsewhere. The description adds only that 'native fields and pagination are preserved' — a useful but thin note on response shaping, with no mention of the filter semantics (e.g., that product filters come from the ad group) or limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the verb and resource, with no filler. The final cross-reference sentence is terse but arguably misdirects toward a write-schema tool, which slightly weakens an otherwise clean structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the fully-described schema covers all three parameters including the nested body. What remains missing — guidance on choosing this tool over the other feed-related siblings — is a usage gap rather than a completeness gap at the schema level.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already explains adAccountId scoping, feed_id ownership, and the body's complete-configuration semantics including micros currency. The description adds nothing beyond pointing at another tool for 'nested request fields', so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List products in a feed') plus the scoping condition ('that match ad group product filters'), which distinguishes it from sibling listing tools like openai_ads_get_feeds or openai_ads_get_feed_settings. It does not explicitly name those siblings as alternatives, keeping it short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this tool versus openai_ads_get_feeds, openai_ads_get_feed_uploads, or openai_ads_get_feed_settings, and no prerequisites or exclusions. The only routing hint ('See openai_ads_get_write_schema for nested request fields') points at a write-schema tool for what is described as a read/list operation, which is confusing rather than directive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_feedsopenai ads get feedsB
Read-onlyIdempotent

List the account's product feeds, optionally with product counts. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
queryNoDocumented native query parameters. Each call reads one page unless the tool says otherwise.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive, so safety behavior is covered. The description adds that native fields and pagination are preserved, which tells the agent to expect pass-through upstream shapes rather than normalized ones. It says nothing about rate limits, page sizes, or whether counts are expensive to compute.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core action, no filler. The final sentence is the weakest link and could be dropped or corrected without loss.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and parameter coverage is complete in the schema. What is missing is the piece an agent actually needs for selection: how this differs from get_feed_products/get_feed_uploads, and why a read tool would defer nested request detail to a write-schema tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description does hint at the 'include: product_count' option and the pagination parameters, but adds no syntax or constraints beyond what the schema already documents (limit 1-500, after/before cursors, adacct_ ID scoping).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'List the account's product feeds', with an optional enrichment (product counts). It is clearly a feeds listing, not uploads or settings, though it does not explicitly name the neighboring feed tools (get_feed_uploads, get_feed_settings, get_feed_products) to sharpen the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this vs get_feed_products or get_feed_uploads, both of which overlap semantically with 'feeds'. The only routing hint, 'See openai_ads_get_write_schema for nested request fields', points at a write-schema tool for what is a read-only list operation, which is more likely to confuse than help.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_feed_settingsopenai ads get feed settingsA
Read-onlyIdempotent

Read a feed's display and organic-listing settings. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
feed_idYesExact native feed_id. The entity must belong to the configured ad account.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the safety profile is covered. The description adds useful context beyond the annotations: raw native fields are preserved and pagination is maintained, which tells the agent what shape the response will take.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, no filler, and the core read action is front-loaded. The trailing pointer to the write schema is a little questionable in a read context, but the description is tight overall.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values needn't be described, and both required parameters are covered by rich schema descriptions. The description supplies the essential behavior (raw native fields and pagination preserved) and a cross-reference, leaving only minor gaps around when to prefer this over sibling read tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both required parameters (feed_id and adAccountId) are fully documented in the schema, including the adacct_ pattern and account scoping. The description adds no parameter-level detail, which is acceptable given the schema does the work, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Read') and resource ('a feed's display and organic-listing settings'), which is distinguishable from list tools like openai_ads_get_feeds and related item tools like openai_ads_get_feed_products. The exact nature of 'display and organic-listing settings' remains slightly abstract, but the scope is clear enough to choose the tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the verb 'Read' plus the resource suggests fetching settings for a known feed, and the pointer to openai_ads_get_write_schema hints at related workflows. There is no explicit 'use this when…' or exclusion against siblings such as openai_ads_get_feeds or openai_ads_get_feed_products, and referring to a write schema in a read tool is confusing rather than helpful.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_feed_uploadsopenai ads get feed uploadsA
Read-onlyIdempotent

List recent product feed uploads and their processing results. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
queryNoDocumented native query parameters. Each call reads one page unless the tool says otherwise.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare this is a safe, read-only, idempotent operation. The description complements this by adding functional context that the results include processing status, which is critical for the user's understanding of the return value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is brief, uses active language, and organizes the information logically: what it does, how it paginates, and where to find advanced request details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the excellent structured data (annotations and 100% schema coverage), the description successfully fills the gaps by addressing specific operational behaviors like pagination preservation and the scope of the results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, satisfying the minimum requirement (score 3). The description adds semantic value by detailing the scope of the data returned—'processing results'—which gives the parameters a higher operational meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the resource being acted upon ('product feed uploads') and the action ('List') while specifying the inclusion of 'processing results.' This precisely distinguishes it from sibling tools like openai_ads_get_feeds or openai_ads_get_ad_creatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides practical usage context by stating that 'native fields and pagination are preserved.' It also guides the user to a specific sibling tool (openai_ads_get_write_schema) for complex nested request definitions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_insightsopenai ads get insightsA
Read-onlyIdempotent

Read performance by account, campaign, ad group or ad over inclusive account-local dates. One optional country, device or platform breakdown supports delivery metrics only; use openai_ads_get_conversion_insights for conversions by country or device. Attribution defaults to 30-day click, 1-day view and ad_event_time. CTR and CVR are fractions; money uses major units of the account currency. Pages are followed up to maxRows and truncation is explicit.

NameRequiredDescriptionDefault
levelNoAggregation level: ad_account, campaign, ad_group or ad. Defaults to campaign.campaign
sinceYesFirst day of the report, YYYY-MM-DD, in the account's time zone. Inclusive.
untilYesLast day of the report, YYYY-MM-DD, in the account's time zone. Inclusive. At most 365 days after since.
maxRowsNoMaximum rows to collect across pages, 1 to 10,000. truncated is true when more rows exist.
metricsNoNative metrics to return. Defaults to spend, impressions and clicks.
breakdownNoOne delivery breakdown per request: country, device or platform. Supports impressions, clicks, spend, ctr, cpc and cpm. Omit for entity totals.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.
attributionNoReport attribution only: attribution_window_days 7, 14 or 30, view_through_attribution_window_days 0 or 1, attribution_time_basis ad_event_time or conversion_time. Campaign goals are unchanged.
timeGranularityNodaily returns one row per day; none returns period totals.daily

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only/non-destructive/idempotent, but the description adds genuinely new behavior: pagination is followed up to maxRows with explicit truncation, attribution defaults to 30-day click and 1-day view on ad_event_time, CTR/CVR are fractions, and money is in major units of account currency. These conventions prevent real misinterpretation of results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four dense sentences, front-loaded with the read scope and followed by exclusions, semantics, and pagination. No filler, though some clauses (attribution defaults, unit conventions) are compressed into a very jargon-heavy run-on that takes a careful read.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 9 parameters, nested attribution, and an output schema present, the description covers everything the schema does not carry: cross-metric/breakdown compatibility, unit conventions, attribution default semantics, and pagination/truncation behavior. Nothing needed for a correct call is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description does add some meaning beyond the schema (breakdown restricted to delivery metrics, attribution defaults, inclusive date range), but it mostly summarizes defaults already documented per-parameter rather than deepening them.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Read performance' at four named aggregation levels over inclusive account-local dates. It immediately distinguishes itself from openai_ads_get_conversion_insights by naming that sibling and its domain, so an agent can route correctly without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing rule: use openai_ads_get_conversion_insights for conversions by country or device. It also states the in-tool constraint that a single breakdown supports delivery metrics only, which tells the agent when not to combine breakdown with conversion metrics.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_landing_page_crawlopenai ads get landing page crawlA
Read-onlyIdempotent

Read the saved landing page crawl evidence for an ad's submitted version. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
ad_idYesExact native ad_id. The entity must belong to the configured ad account.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds that native fields and pagination are preserved, which is useful behavioral context, but says nothing about rate limits or response shape beyond that.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core action. The final reference to openai_ads_get_write_schema for 'nested request fields' is slightly odd for a read-only tool and may not earn its place, but overall the text is tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and annotations cover safety. The description supplies the essential scope ('saved crawl evidence for an ad's submitted version') and pagination note; only the write_schema pointer is confusing, but nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (ad_id, adAccountId) are fully documented in the schema, including the account-scoping constraint. The description adds no parameter-level meaning beyond what the schema already provides, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: reading saved landing page crawl evidence for an ad's submitted version. This is clearly distinguishable from the many get_* siblings which fetch ads, campaigns, insights, etc. It stops short of explaining what 'submitted version' means, which leaves some ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies usage context (retrieving crawl evidence for a specific ad) but gives no explicit when-to-use/when-not guidance or alternatives among siblings. The cross-reference to openai_ads_get_write_schema is presented without a condition that selects it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_mutationopenai ads get mutationA
Read-onlyIdempotent

Read a write preview or receipt held by this server process: its state, the native state it was approved against and the result. Receipts live in memory and a restart forgets them. Never resubmit a write whose state is UNKNOWN or APPLYING.

NameRequiredDescriptionDefault
mutationIdYesThe confirmationToken or mutationId returned by a write preview or receipt.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by disclosing durability ('Receipts live in memory and a restart forgets them') and the specific state semantics that matter operationally (UNKNOWN/APPLYING must not be resubmitted). The readOnly/idempotent hints are already in the annotations, so this added context is exactly the kind that earns credit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with what the tool reads, then the durability caveat, then the operational warning. Every sentence carries information an agent would otherwise have to discover by failure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present it is fair not to enumerate the returned structure, and the description still summarizes it plus the memory volatility caveat. What it omits is how the enumerated states relate to each other (what to do after APPLYING resolves), leaving a small but real gap for a status-polling tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters carry their own descriptions, so the baseline is 3. The description adds a little meaning by tying 'preview' and 'receipt' to the two possible identifiers, but it gives no format or lookup details beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Read a write preview or receipt held by this server process,' and enumerates the payload (state, approved-against native state, result). Among the many get_* siblings it is unmistakably the only mutation/receipt reader, though it never names a sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Context for use is clear: this is how you check on a preview or receipt you already hold, and 'Never resubmit a write whose state is UNKNOWN or APPLYING' gives a concrete decision rule for the polling loop. It stops short of naming alternatives such as openai_ads_get_bulk_job or openai_ads_get_write_context, so the routing is not fully explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_spend_limitsopenai ads get spend limitsA
Read-onlyIdempotent

Read the account's spend limit windows and daily recurrence rules. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so safety is covered. The description adds that native fields and pagination are preserved, a modest note on return shape, but says nothing about account-scoping refusals or rate limits beyond what the schema already states.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the purpose front-loaded and no redundancy. The trailing pointer to openai_ads_get_write_schema ('nested request fields') is boilerplate that doesn't apply to a read tool with a flat one-field schema, costing a little precision.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and annotations cover safety. However, the 'pagination is preserved' claim is unverifiable in a schema with no pagination parameters, and the write-schema reference is a misdirection — enough gaps to keep this at minimum-viable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter and schema coverage is 100% — the adAccountId pattern and the API-key scoping/refusal behavior are fully documented in the schema itself. The description adds no parameter-level meaning beyond that, which matches the baseline-3 expectation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Read') and a specific resource ('the account's spend limit windows and daily recurrence rules'), which no sibling tool covers. An agent can distinguish it from openai_ads_get_account or openai_ads_get_insights without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The purpose implies when it applies (fetching spend limits), but there is no explicit when/when-not guidance and no alternative named. The only cross-reference points at openai_ads_get_write_schema, which is a write-path helper unrelated to this read-only tool, so it doesn't route the agent usefully.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_write_contextopenai ads get write contextA
Read-onlyIdempotent

Read the account, its conversion settings and its product feeds before proposing a campaign. Lists the native objective, billing and bid strategy combinations and the missing prerequisites. It grants no eligibility and creates nothing.

NameRequiredDescriptionDefault
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, so the description is not carrying the safety burden alone — yet it still adds real behavioral context: the tool aggregates several resources and surfaces 'missing prerequisites'. The explicit disclaimer "grants no eligibility and creates nothing" usefully preempts an agent misreading the composite read as an entitlement check.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences: the trigger and scope come first, then what is returned, then the negative capability disclaimer. No filler and nothing that could be cut without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be spelled out, and annotations cover the safety profile; the description supplies the one thing they cannot — when in the workflow to call it. The only gap is that it does not relate itself to the adjacent write-schema/pre-write sibling, leaving the agent to infer that pairing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Single parameter with 100% schema description coverage, including the adacct_ pattern and the API-key scoping rule. The description adds nothing about adAccountId, so the baseline of 3 for fully-documented schemas applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (read) and a specific composite resource (account, conversion settings, product feeds) plus the two things it returns: valid objective/billing/bid-strategy combinations and missing prerequisites. It is distinguishable from single-resource siblings like get_account or get_feeds by being an aggregating pre-flight read, although it never names those siblings explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"before proposing a campaign" gives a clear trigger condition, and "creates nothing" sets the boundary against write tools. No alternatives or exclusions are named (e.g. when to call get_conversion_settings alone instead), so it stops just short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_get_write_schemaopenai ads get write schemaA
Read-onlyIdempotent

Read the pinned native request definitions, paths and parameters of every operation, the upload and bulk limits, and what this server leaves out. Schema support does not imply that the account is eligible for a feature.

NameRequiredDescriptionDefault
toolNameNoOptional tool name, such as openai_ads_create_campaign, to return only that operation. Omit for all.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish that this is a read-only, idempotent, non-destructive operation. The description adds meaningful scope details: it returns paths, parameters, limits, and explicitly documents what the server leaves out, plus a caveat about feature eligibility. It stops short of describing return structure, but an output schema exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loads the core action and returned content. The eligibility caveat is worth including, though the sentence is somewhat dense and could be split for faster scanning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a fully described input schema, an output schema, and rich annotations, the description supplies the remaining necessary context: returned content categories, limits, omissions, and an eligibility caveat. An agent has enough information to decide whether to call it and what to expect.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already fully documented in the input schema. The description adds no additional meaning about adAccountId or the optional toolName filter, which is acceptable given the high schema coverage baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Read') and clearly identifies the resource: pinned native request definitions, paths, parameters, upload/bulk limits, and omissions. It is more specific than the title and differentiates at a high level from typical data-fetching siblings, though it does not explicitly contrast with close metadata siblings like openai_ads_get_write_context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this is for looking up write-operation schemas and limits, but it gives no explicit when-to-use guidance, prerequisites, or comparison to alternatives such as openai_ads_get_write_context. The caveat that schema support does not imply account eligibility is useful context but not usage routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_list_ad_creativesopenai ads list ad creativesA
Read-onlyIdempotent

List chat card creatives of the account or of one ad group, 20 ads per page, or read up to 60 exact adIds. Each item has the native file_id, signed image_url, title, body, destination and review status. An expired image link is refreshed with one ad read. Follow nextCursor when hasMore.

NameRequiredDescriptionDefault
adIdsNoUp to 60 exact ad IDs to read. Cannot be combined with adGroupId or after.
afterNoThe nextCursor of the previous page, only when hasMore is true.
limitNoAds per page, 1 to 20. Defaults to 20.
adGroupIdNoOptional ad group (adgrp_) to list. Omit to list ads across the account.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive/openWorld, so the safety profile is covered and the description spends its budget on real behavior: 20 items per page, a 60-id batch ceiling, sequential paging via nextCursor/hasMore, and the fact that an expired signed image_url is refreshed by a single ad read. That last detail is non-obvious side-effect disclosure an agent would otherwise not know.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three densely packed sentences, front-loaded with the core listing scope, and each one carries actionable information about paging, return fields, or link refresh. The enumeration of return fields is marginally redundant given an output schema exists, but it is compact enough not to waste space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present the description needn't document return shape, and it still adds pagination termination rules and the batch-read mode that the schema alone would not make obvious. Account scoping is left to the schema's adAccountId text, so the description is complete but not exhaustive for a 5-parameter listing tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3; the description goes further by tying pagination to concrete values ("20 ads per page") and by explaining that after should be followed from nextCursor when hasMore is true, plus the 60-id cap on adIds. It adds page-size and paging-loop semantics beyond the field-level schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb plus resource ("List chat card creatives") and enumerates the three access modes: account-wide, one ad group, or up to 60 exact adIds. An agent immediately knows the scope and shape of the call. It does not explicitly distinguish itself from the sibling openai_ads_get_ads / openai_ads_get_ad, which is the only thing keeping it from a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"List ... of the account or of one ad group, ... or read up to 60 exact adIds" clearly frames the mutually exclusive invocation modes, and the schema reinforces that adIds cannot combine with adGroupId or after. There is no explicit when-not guidance or named alternative among the large set of sibling listing tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openai_ads_search_locationsopenai ads search locationsA
Read-onlyIdempotent

Search country, region and market location IDs for campaign geographic targeting. Native fields and pagination are preserved. See openai_ads_get_write_schema for nested request fields.

NameRequiredDescriptionDefault
queryNoDocumented native query parameters. Each call reads one page unless the tool says otherwise.
adAccountIdYesThe adacct_ ID configured in OPENAI_ADS_ACCOUNT_ID. The API key is scoped to this one account; another ID is refused.

Output Schema

NameRequiredDescription
resultYesOriginal tool result: parsed JSON when the text is JSON, otherwise the text or multiple MCP content blocks. Provider fields depend on the selected query.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructive:false, so the safety profile is covered. 'Native fields and pagination are preserved' is the only added behavioral claim and is too vague to act on – it hints at raw-API passthrough and paging without saying what paging looks like or how large result sets are handled.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with the search action front-loaded and no padding. The write-schema cross-reference is the one sentence that does not clearly earn its place on a read-only location search.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema and full annotation coverage, little else is required; the description names the resource and the filtering domain. The odd reference to get_write_schema slightly muddies rather than completes the picture, and query-matching semantics remain unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the adAccountId entry already explains the adacct_ scoping and refusal behavior. The description adds nothing about the nested query object — how `q` matches (prefix vs substring, case sensitivity) or what `limit` defaults to — so it sits at the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (search) plus a precise resource (country, region and market location IDs) and the reason for it (campaign geographic targeting). That is enough to separate it from every get_*-style sibling, though it never explicitly says 'use this instead of X'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'for campaign geographic targeting' clause implies when the tool applies, but there is no explicit when-not, no prerequisites, and no named alternative. The closing pointer to openai_ads_get_write_schema is a cross-reference, not usage routing, and is puzzling on a read-only lookup tool.

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.

  1. 30 tool updates
    • Changedopenai_ads_get_account1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_ad1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_ad_group1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_ad_groups1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_ads1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_audience_operation1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_audience_operations1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_audit_logs4 fields changed
      • addedInput schema / properties / query / properties / order / anyOf
        Added value: +[
        +  {
        +    "const": "asc",
        +    "type": "string"
        +  },
        +  {
        +    "const": "desc",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / query / properties / order / enum
        Removed value: -[
        -  "asc",
        -  "desc"
        -]
      • removedInput schema / properties / query / properties / order / type
        Removed value: -"string"
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_bulk_job1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_bulk_job_operations1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_campaign1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_campaigns1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_conversion_events2 fields changed
      • changedInput schema / required
        Previous value: -[
        -  "adAccountId",
        -  "query"
        -]New value: +[
        +  "adAccountId"
        +]
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_conversion_insights12 fields changed
      • addedInput schema / properties / body / properties / attribution_time_basis / anyOf
        Added value: +[
        +  {
        +    "const": "conversion_time",
        +    "type": "string"
        +  },
        +  {
        +    "const": "ad_event_time",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / body / properties / attribution_time_basis / enum
        Removed value: -[
        -  "conversion_time",
        -  "ad_event_time"
        -]
      • removedInput schema / properties / body / properties / attribution_time_basis / type
        Removed value: -"string"
      • changedInput schema / properties / body / properties / attribution_window_days / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      7,
        -      14,
        -      30
        -    ],
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "const": 7,
        +        "type": "number"
        +      },
        +      {
        +        "const": 14,
        +        "type": "number"
        +      },
        +      {
        +        "const": 30,
        +        "type": "number"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / body / properties / breakdown / anyOf
        Added value: +[
        +  {
        +    "const": "device",
        +    "type": "string"
        +  },
        +  {
        +    "const": "country",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / body / properties / breakdown / enum
        Removed value: -[
        -  "device",
        -  "country"
        -]
      • removedInput schema / properties / body / properties / breakdown / type
        Removed value: -"string"
      • addedInput schema / properties / body / properties / time_granularity / anyOf
        Added value: +[
        +  {
        +    "const": "none",
        +    "type": "string"
        +  },
        +  {
        +    "const": "daily",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / body / properties / time_granularity / enum
        Removed value: -[
        -  "none",
        -  "daily"
        -]
      • removedInput schema / properties / body / properties / time_granularity / type
        Removed value: -"string"
      • changedInput schema / properties / body / properties / view_through_attribution_window_days / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      0,
        -      1
        -    ],
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "const": 0,
        +        "type": "number"
        +      },
        +      {
        +        "const": 1,
        +        "type": "number"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_conversion_pixels4 fields changed
      • addedInput schema / properties / query / properties / order / anyOf
        Added value: +[
        +  {
        +    "const": "asc",
        +    "type": "string"
        +  },
        +  {
        +    "const": "desc",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / query / properties / order / enum
        Removed value: -[
        -  "asc",
        -  "desc"
        -]
      • removedInput schema / properties / query / properties / order / type
        Removed value: -"string"
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_conversion_settings4 fields changed
      • addedInput schema / properties / query / properties / order / anyOf
        Added value: +[
        +  {
        +    "const": "asc",
        +    "type": "string"
        +  },
        +  {
        +    "const": "desc",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / query / properties / order / enum
        Removed value: -[
        -  "asc",
        -  "desc"
        -]
      • removedInput schema / properties / query / properties / order / type
        Removed value: -"string"
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_custom_audience1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_custom_audiences7 fields changed
      • addedInput schema / properties / query / properties / intended_use / anyOf
        Added value: +[
        +  {
        +    "const": "inclusion",
        +    "type": "string"
        +  },
        +  {
        +    "const": "exclusion",
        +    "type": "string"
        +  },
        +  {
        +    "const": "bid_multiplier",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / query / properties / intended_use / enum
        Removed value: -[
        -  "inclusion",
        -  "exclusion",
        -  "bid_multiplier"
        -]
      • removedInput schema / properties / query / properties / intended_use / type
        Removed value: -"string"
      • addedInput schema / properties / query / properties / order / anyOf
        Added value: +[
        +  {
        +    "const": "asc",
        +    "type": "string"
        +  },
        +  {
        +    "const": "desc",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / query / properties / order / enum
        Removed value: -[
        -  "asc",
        -  "desc"
        -]
      • removedInput schema / properties / query / properties / order / type
        Removed value: -"string"
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_feed_products4 fields changed
      • addedInput schema / properties / body / properties / filters / items / properties / operator / anyOf
        Added value: +[
        +  {
        +    "const": "in",
        +    "type": "string"
        +  },
        +  {
        +    "const": "not_in",
        +    "type": "string"
        +  },
        +  {
        +    "const": "gt",
        +    "type": "string"
        +  },
        +  {
        +    "const": "gte",
        +    "type": "string"
        +  },
        +  {
        +    "const": "lt",
        +    "type": "string"
        +  },
        +  {
        +    "const": "lte",
        +    "type": "string"
        +  },
        +  {
        +    "const": "contains",
        +    "type": "string"
        +  },
        +  {
        +    "const": "not_contains",
        +    "type": "string"
        +  },
        +  {
        +    "const": "starts_with",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / body / properties / filters / items / properties / operator / enum
        Removed value: -[
        -  "in",
        -  "not_in",
        -  "gt",
        -  "gte",
        -  "lt",
        -  "lte",
        -  "contains",
        -  "not_contains",
        -  "starts_with"
        -]
      • removedInput schema / properties / body / properties / filters / items / properties / operator / type
        Removed value: -"string"
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_feed_settings1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_feed_uploads1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_feeds1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_insights10 fields changed
      • addedInput schema / properties / attribution / properties / attribution_window_days / anyOf
        Added value: +[
        +  {
        +    "const": 7,
        +    "type": "number"
        +  },
        +  {
        +    "const": 14,
        +    "type": "number"
        +  },
        +  {
        +    "const": 30,
        +    "type": "number"
        +  }
        +]
      • removedInput schema / properties / attribution / properties / attribution_window_days / enum
        Removed value: -[
        -  7,
        -  14,
        -  30
        -]
      • removedInput schema / properties / attribution / properties / attribution_window_days / type
        Removed value: -"number"
      • addedInput schema / properties / attribution / properties / view_through_attribution_window_days / anyOf
        Added value: +[
        +  {
        +    "const": 0,
        +    "type": "number"
        +  },
        +  {
        +    "const": 1,
        +    "type": "number"
        +  }
        +]
      • removedInput schema / properties / attribution / properties / view_through_attribution_window_days / enum
        Removed value: -[
        -  0,
        -  1
        -]
      • removedInput schema / properties / attribution / properties / view_through_attribution_window_days / type
        Removed value: -"number"
      • removedInput schema / properties / until / $ref
        Removed value: -"#/properties/since"
      • addedInput schema / properties / until / pattern
        Added value: +"^\\d{4}-\\d{2}-\\d{2}$"
      • addedInput schema / properties / until / type
        Added value: +"string"
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_landing_page_crawl1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_mutation2 fields changed
      • addedInput schema / properties / mutationId / pattern
        Added value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_spend_limits1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_write_context1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_get_write_schema3 fields changed
      • addedInput schema / properties / toolName / format
        Added value: +"starts_with"
      • changedInput schema / properties / toolName / pattern
        Previous value: -"^openai\\_ads\\_"New value: +"^openai_ads_.*"
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_list_ad_creatives1 field changed
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedopenai_ads_search_locations2 fields changed
      • changedInput schema / required
        Previous value: -[
        -  "adAccountId",
        -  "query"
        -]New value: +[
        +  "adAccountId"
        +]
      • changedOutput schema / properties / result / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": true,
        -    "properties": {},
        -    "type": "object"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {},
        +    "properties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {},
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
  2. 30 tool updatesv1.0.0
    • First observedopenai_ads_get_account
    • First observedopenai_ads_get_ad
    • First observedopenai_ads_get_ad_group
    • First observedopenai_ads_get_ad_groups
    • First observedopenai_ads_get_ads
    • First observedopenai_ads_get_audience_operation
    • First observedopenai_ads_get_audience_operations
    • First observedopenai_ads_get_audit_logs
    • First observedopenai_ads_get_bulk_job
    • First observedopenai_ads_get_bulk_job_operations
    • First observedopenai_ads_get_campaign
    • First observedopenai_ads_get_campaigns
    • First observedopenai_ads_get_conversion_events
    • First observedopenai_ads_get_conversion_insights
    • First observedopenai_ads_get_conversion_pixels
    • First observedopenai_ads_get_conversion_settings
    • First observedopenai_ads_get_custom_audience
    • First observedopenai_ads_get_custom_audiences
    • First observedopenai_ads_get_feed_products
    • First observedopenai_ads_get_feed_settings
    • First observedopenai_ads_get_feed_uploads
    • First observedopenai_ads_get_feeds
    • First observedopenai_ads_get_insights
    • First observedopenai_ads_get_landing_page_crawl
    • First observedopenai_ads_get_mutation
    • First observedopenai_ads_get_spend_limits
    • First observedopenai_ads_get_write_context
    • First observedopenai_ads_get_write_schema
    • First observedopenai_ads_list_ad_creatives
    • First observedopenai_ads_search_locations

TDQS

A3.5/5.0

Scored across 30 tools

Disambiguation4/5

Each tool targets a distinct resource or report (campaigns vs ad groups vs ads vs feeds vs audiences vs bulk jobs), and the insights vs conversion_insights split is explicitly documented. The main friction is the large set of near-neighbor tools (get_custom_audiences / get_custom_audience / get_audience_operations / get_audience_operation, and get_write_schema / get_write_context / get_mutation) where an agent must read carefully, plus get_* names that sometimes list and sometimes read one entity.

Naming Consistency4/5

All names share the openai_ads_ prefix and a verb_noun shape, so the set is predictable. However the verb usage is loose: get_ is used for both list operations (get_campaigns, get_ads, get_feeds) and single-entity reads, while list_ and search_ appear only once each, which weakens the pattern's signal.

Tool Count3/5

30 tools is heavy for a single MCP server and sits above the comfortable 15-tool band, even though the domain (campaigns, creatives, conversions, feeds, audiences, audit, bulk) is genuinely broad. Several read-only sub-resources (audience operations, feed uploads, feed settings, landing page crawl) could reasonably be folded into parent tools to slim the surface.

Completeness3/5

Read coverage is deep and coherent across the ad lifecycle, including diagnostics and bulk job result inspection. But the surface is read-heavy: get_write_schema, get_write_context and get_mutation reference write previews and receipts while no tool actually submits a mutation, leaving a dangling step in the advertised lifecycle and no create/update/delete operations.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables management of OpenAI Ads campaigns, ad groups, ads, and insights through MCP, with approval-gated live mutations for safe write operations.
    128 npm
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    Typed MCP server for OpenAI Ads and ChatGPT Ads via the Advertiser API. Supports account, campaign, ad group, ad, creative, audience, insight, and conversion tools with readonly mode and guarded writes.
    12
    4
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables management of Google Ads accounts via MCP, providing read and write tools for campaigns, ad groups, keywords, assets, and more, with support for reporting and mutations.
    -
  • A
    license
    B
    quality
    C
    maintenance
    Enables managing ChatGPT Advertiser campaigns from MCP-capable agents, including campaign creation, creative uploads, audience management, conversions setup, and insights retrieval.
    89
    24 npm
    MIT