ads-mcp
Enables management of Google Ads Search campaigns, including listing campaigns, retrieving campaign structure, creating paused campaigns, managing keywords and negative keywords, updating bid strategies, and controlling campaign status.
Enables management of Meta ad campaigns and ads, including listing campaigns, retrieving ad review status and rejection reasons, listing ads by status (e.g., disapproved), and controlling campaign status.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ads-mcplist all disapproved Meta ads in the account"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ads-mcp
An MCP server wrapping the Google Ads API and Meta Marketing API directly, with no third-party quota or middleman. Point an MCP-compatible client at it and manage Search campaigns, keywords, ads and Meta ad review status straight against Google's and Meta's own APIs.
Every write tool that could spend money is safe by default: google_ads_create_search_campaign always creates campaigns PAUSED, and the only tools that can turn spend on are google_ads_set_campaign_status / meta_ads_set_campaign_status, called explicitly.
Setup
Credentials require logins and business identity only you have; nothing here can be automated.
Google Ads
Google Cloud project + OAuth client: console.cloud.google.com, new (or existing) project, APIs & Services, Credentials, Create OAuth client ID (type: Desktop app). Copy the Client ID/Secret into
.env.Under that OAuth client, add
http://localhost:8787/oauth2callbackas an authorized redirect URI.Developer token: ads.google.com/aw/apicenter, apply for a token. Basic access is free and usually approved within a few days; it allows ~15,000 operations/day. Put it in
.envasGOOGLE_ADS_DEVELOPER_TOKEN.Run
pnpm installthenpnpm google:auth, this opens a browser, you sign in and consent, and it prints a refresh token to paste into.envasGOOGLE_ADS_REFRESH_TOKEN.Set
GOOGLE_ADS_CUSTOMER_IDto the 10-digit account ID (no dashes) these tools should operate on by default. If that account is managed under an MCC account, also setGOOGLE_ADS_LOGIN_CUSTOMER_IDto the MCC's ID.
Meta Ads
Meta App: developers.facebook.com, My Apps, Create App (type: Business). Copy the App ID/Secret from Settings, Basic into
.env.Request the
ads_managementpermission under App Review. This needs Business Verification (documents proving the business is real) and usually a short screen-recording demo of the exact use case. This step is slow, budget for weeks, not days.Once approved, generate a long-lived System User access token (Business Settings, System Users) with
ads_managementscope on the ad account, and put it in.envasMETA_ACCESS_TOKEN.Set
META_AD_ACCOUNT_IDto the numeric account ID (noact_prefix needed, the client adds it).
Related MCP server: PaidSync MCP Server
Running
pnpm install
pnpm dev # runs the MCP server over stdio via tsx, for local testing
pnpm build && pnpm start # compiled versionOnce published to npm, it also runs via npx @gudlab/ads-mcp, no local clone needed. Point an MCP-compatible client at it, e.g. in Claude Code's .mcp.json:
{
"mcpServers": {
"ads-mcp": {
"command": "npx",
"args": ["-y", "@gudlab/ads-mcp"],
"env": {
"GOOGLE_ADS_CLIENT_ID": "...",
"GOOGLE_ADS_CLIENT_SECRET": "...",
"GOOGLE_ADS_DEVELOPER_TOKEN": "...",
"GOOGLE_ADS_REFRESH_TOKEN": "...",
"GOOGLE_ADS_CUSTOMER_ID": "...",
"META_APP_ID": "...",
"META_APP_SECRET": "...",
"META_ACCESS_TOKEN": "...",
"META_AD_ACCOUNT_ID": "..."
}
}
}
}Before that's published, point it at the local build instead: command: "node", args: ["/path/to/ads-mcp/dist/index.js"], or command: "pnpm", args: ["dev"] with cwd set to this directory for local iteration.
First real run: verify before trusting it
The Google Ads and Meta Marketing APIs both shift field/enum names across versions, so before relying on any tool here for real campaign work:
Run
google_ads_list_campaigns/meta_ads_list_campaignsfirst, read-only, the cheapest way to confirm auth and the client libraries are wired correctly.Test
google_ads_create_search_campaignon a throwaway campaign name, then check it directly in the Google Ads UI rather than trusting the tool's own response as proof of correctness.Only after that, use it for real campaign work.
Tool reference
Google Ads (src/google-ads/tools.ts): list_campaigns, get_campaign_structure, create_search_campaign (always PAUSED), add_keywords, set_keyword_status (pause/enable, reversible), remove_keywords (permanent, requires confirm_delete: true), update_bid_strategy, add_negative_keywords, set_campaign_status (the only enable/spend switch).
Meta Ads (src/meta-ads/tools.ts): list_campaigns, get_ad_status (pulls ad_review_feedback/issues_info, the actual rejection reason for a disapproved ad), list_ads_by_status (e.g. pull every DISAPPROVED ad in one call), set_campaign_status (the only enable/spend switch).
Privacy and data handling
All credentials stay in your own .env (never committed, see .gitignore) or your MCP client's own env config, and are used only to call Google's and Meta's APIs directly from your machine. This server sends nothing to any third party: no telemetry, no analytics, no relay service. Every request goes straight from your process to googleads.googleapis.com or graph.facebook.com, using your own developer token and access token.
License
MIT, see LICENSE.
Available Tools
13 toolsgoogle_ads_add_keywordsAdd keywords to a Google Ads ad groupC
Add keywords to an existing ad group
| Name | Required | Description | Default |
|---|---|---|---|
| keywords | Yes | ||
| ad_group_id | Yes | ||
| customer_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=false and destructiveHint=false, which imply a non-read, non-destructive mutation. The description confirms it adds keywords but does not disclose behavioral traits such as whether existing keywords are preserved (vs replaced), whether duplicates are handled, or if there are limits on the number of keywords. It does not contradict annotations, but the description carries the full burden for mutation behavior and provides minimal insight.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, short sentence that is efficient and easy to parse. It has no filler, and the key action is front-loaded. However, it is so brief that it misses necessary details, but conciseness itself is not the problem.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (3 parameters, nested objects for keywords, no output schema), the description is incomplete. It does not explain the structure of the 'keywords' parameter, the meaning of 'match_type' (though the schema has enums), or any required context like the ad_group_id. The openWorldHint suggests the API may accept additional properties, but the description does not elaborate on that either.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for explaining parameters. The description does not mention any parameters at all, leaving the agent to rely solely on the schema. It does not clarify that 'keywords' is an array of objects with 'text' and 'match_type', nor that 'customer_id' is optional context. This is a significant gap given the schema's lack of descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the verb 'add' and the resource 'keywords to an existing ad group', which is clear and specific. However, it does not distinguish itself from the sibling tool 'google_ads_add_negative_keywords', which is a related but distinct operation. The title adds clarity but the description itself is minimal.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. For example, it does not mention that this tool is for positive keywords, whereas 'google_ads_add_negative_keywords' is for negative ones. It also does not mention any prerequisites like needing an existing ad group or customer context, which could be inferred from the parameters but is not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
google_ads_add_negative_keywordsAdd Google Ads negative keywordsC
Add campaign-level negative keywords
| Name | Required | Description | Default |
|---|---|---|---|
| keywords | Yes | ||
| campaign_id | Yes | ||
| customer_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate this is a mutation (readOnlyHint=false) and non-idempotent, but the description adds little behavioral context beyond that. It does not disclose whether keywords are appended or replaced, how duplicates are handled, what effects occur at the campaign level, or what the response contains.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single clear sentence with no wasted wordsholistically. It fronts the key scoping detail ('campaign-level') immediately, but it is too terse to carry the full semantic burden expected for this mutation tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a write operation with no output schema, the description is incomplete. It omits expected side effects, duplicate handling, optional parameter semantics, and any indication of what a successful result looks like. The presence of annotations helps on safety, but not on operational completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for all parameters. It indirectly clarifies campaign_id and keywords by mentioning 'campaign-level negative keywords', but it completely omits customer_id, leaving its purpose unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Add'), resource ('negative keywords'), and scope ('campaign-level'), making the operation unambiguous. It also distinguishes itself from the sibling tool google_ads_add_keywords by explicitly saying 'negative'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided about when to use this tool versus alternatives such as google_ads_add_keywords, google_ads_remove_keywords, or google_ads_set_keyword_status. The agent is left to infer the appropriate selection from the tool name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
google_ads_create_search_campaignCreate Google Ads Search campaign (paused)B
Create a new Search campaign with ad groups, keywords and RSAs. Always created PAUSED.
| Name | Required | Description | Default |
|---|---|---|---|
| language | No | Google language constant resource name, default English | languageConstants/1000 |
| ad_groups | Yes | ||
| locations | Yes | Google geo target constant resource names, e.g. 'geoTargetConstants/2826' for UK | |
| customer_id | No | ||
| daily_budget | Yes | In the account's native currency, e.g. 25 for $25/day | |
| campaign_name | Yes | ||
| negative_keywords | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that this is a mutating but non-destructive operation. The description adds the meaningful behavioral fact 'Always created PAUSED,' which is not in the annotations. However, it does not disclose other behavioral traits such as validation behavior, duplicate handling, or what the created campaign/ad groups look like in return.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences carry all the content: the action, the components, and the paused-state behavior. There is no filler or repetition, and the most operationally important fact (paused) is emphasized separately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is adequate for a create-style tool: it names the resource and the key behavioral guarantee. However, with no output schema and several self-explanatory but undocumented parameters, the description could better prepare an agent on expected inputs, especially given the nested ad_groups structure.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 43%, and the description does not compensate for the undocumented parameters. It mentions 'ad groups, keywords and RSAs' at a high level, but does not clarify customer_id, campaign_name, negative_keywords, or the nested ad_group requirements beyond what the schema already shows.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Create a new Search campaign') and enumerates the core contents ('ad groups, keywords and RSAs'). This clearly differentiates it from the sibling get/update/remove/list tools, all of which signal different operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives like google_ads_update_bid_strategy, google_ads_set_campaign_status, or google_ads_add_keywords. It also omits any prerequisites, such as needing a customer_id or existing account context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
google_ads_get_campaign_structureGet Google Ads campaign structureBRead-onlyIdempotent
Get a campaign's ad groups, keywords, ads, and negatives
| Name | Required | Description | Default |
|---|---|---|---|
| campaign_id | Yes | Campaign ID | |
| customer_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, and idempotentHint=true, covering the safety profile. The description adds the specific components returned (ad groups, keywords, ads, negatives) but does not disclose any additional behavioral details like pagination, error handling, or performance. It is acceptable but minimal given the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no redundancy, front-loading the action and resource. Every word contributes to the meaning, and it is appropriately sized for the tool's simplicity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema and the description is minimal, it lacks parameter clarification and usage context. The description does not explain the role of customer_id or any return format. While annotations cover safety, the description is incomplete for an agent that needs to know how to correctly invoke the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has only 50% coverage (customer_id has no description). The tool description does not mention parameters at all, so it fails to compensate for the gap. An agent gets no help understanding the purpose or usage of customer_id, which is a significant omission.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get' and the resource 'a campaign's ad groups, keywords, ads, and negatives', which is specific and distinguishes it from sibling mutation tools like google_ads_add_keywords or google_ads_remove_keywords. It precisely identifies the scope of the retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It does not mention that it is for a specific campaign versus listing all campaigns, nor does it exclude any scenarios. There is no mention of when to prefer it over google_ads_list_campaigns or other retrieval tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
google_ads_list_campaignsList Google Ads campaignsBRead-onlyIdempotent
List campaigns with status and budget
| Name | Required | Description | Default |
|---|---|---|---|
| customer_id | No | 10-digit account ID, defaults to GOOGLE_ADS_CUSTOMER_ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description adds the useful detail that the list contains status and budget, but it does not disclose other behavioral traits like pagination or account-scoping behavior. This is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler. Every word contributes meaning: the verb, the resource, and the returned attributes. It is appropriately sized for a simple list operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter, read-only, idempotent tool with rich annotations and full schema coverage, the description is largely sufficient. It names the return highlights (status and budget), while the schema covers the optional account ID. It could mention pagination or account default behavior, but the tool's simplicity lowers the bar.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the single optional customer_id parameter is already fully documented with its default-source behavior. The description adds no additional meaning about parameters beyond what the schema provides, meriting the baseline score of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('List campaigns') and names the returned attributes (status and budget), making the action clear. It does not explicitly differentiate from siblings like meta_ads_list_campaigns or google_ads_get_campaign_structure, but the Google Ads scope plus the return-value detail sufficiently orient an agent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to choose this tool over alternatives such as google_ads_get_campaign_structure or meta_ads_list_campaigns. An agent must infer from the sibling names and general list semantics, but there is no explicit when-to-use or when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
google_ads_remove_keywordsPermanently remove Google Ads keywordsBDestructiveIdempotent
Permanently remove keywords. Requires confirm_delete: true.
| Name | Required | Description | Default |
|---|---|---|---|
| ad_group_id | Yes | ||
| customer_id | No | ||
| criterion_ids | Yes | ||
| confirm_delete | Yes | Must be explicitly true — this is permanent. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare destructiveHint=true and readOnlyHint=false, so the description's 'permanently remove' adds modest behavioral context beyond those. It usefully highlights the mandatory confirm_delete safety gate and irreversible framing, but it does not describe downstream effects or what happens to associated data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences front-load the action and then state the required guardrail with no filler. The description is concise and well-ordered, though it leaves some semantic gaps covered by other dimensions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With destructive annotations and the confirm_delete requirement, the description is minimally adequate for a destructive operation. However, there is no output schema and three parameters lack meaningful descriptions, so an agent must infer what criterion_ids and ad_group_id refer to in Google Ads terms.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 25%, so the description needed to compensate for undocumented parameters. It only mentions confirm_delete, which the schema already constrains to true, and adds no meaning for ad_group_id, criterion_ids, or customer_id.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Permanently remove keywords') and identifies the resource, which clearly signals destructive deletion rather than a status change. It differentiates from add-keyword and set-status siblings, though it does not explicitly name them as alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given for when to use this tool versus alternatives such as google_ads_set_keyword_status (for pausing/enabling) or google_ads_add_negative_keywords (for blocking queries). The only usage-related note is the confirm_delete requirement, which is an invocation guardrail rather than a selection criterion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
google_ads_set_campaign_statusEnable or pause a Google Ads campaignAIdempotent
Enable or pause a campaign. The only tool that can turn spend on.
| Name | Required | Description | Default |
|---|---|---|---|
| status | Yes | ||
| campaign_id | Yes | ||
| customer_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate it is a write operation (readOnlyHint=false), idempotent, and not destructive. The description adds the functional effect that it can turn spend on, which is a behavioral consequence beyond the annotations. However, it does not disclose any side effects, auth requirements, or rate limits. Given the annotations, the bar is lower, but the added value is minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no wasted words. It front-loads the primary action and then adds a distinctive differentiator. It is appropriately sized for the tool's simplicity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool that controls campaign spend, the description lacks important context. It does not mention that enabling a campaign will start incurring costs, that pausing stops spend, or any prerequisite like customer_id requirements. It also doesn't mention error handling or verification. The tool is simple but financially impactful, and the description is too thin.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for parameter meaning, but it provides no information about campaign_id, status, or customer_id. The schema itself defines an enum for status and types, but the description adds nothing. For a tool with 0% coverage, this is a significant failure.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: 'Enable or pause a campaign.' It specifies the resource (campaign) and the verb (enable/pause). It also differentiates from siblings by claiming 'The only tool that can turn spend on,' which sets it apart from other Google Ads tools that manage campaigns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: it is for enabling or pausing campaigns, and the unique capability to turn spend on implies this is the go-to tool for that action. It does not name alternatives or explicitly state when not to use it, but the exclusivity claim provides strong guidance. This is a clear context with no explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
google_ads_set_keyword_statusPause or enable Google Ads keywordsBIdempotent
Pause or enable keywords (reversible)
| Name | Required | Description | Default |
|---|---|---|---|
| status | Yes | ||
| ad_group_id | Yes | ||
| customer_id | No | ||
| criterion_ids | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already supply the key behavior: readOnly=false, destructiveHint=false, idempotentHint=true, and openWorldHint=true. The description adds 'reversible,' which reinforces the non-destructive, toggling nature of the operation, but it does not disclose side effects or external-state implications. This is consistent with the annotations but only slightly extends them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise and front-loaded: one short sentence with no filler or repetition beyond the title. It loses a point because the only genuinely new information beyond the title is 'reversible.'
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple reversible status toggle, the schema and annotations provide a minimally viable foundation. However, the lack of an output schema, any description of return values, or explanation of how criterion_ids and ad_group_id relate makes the definition incomplete for a fully informed API call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, but it only maps vaguely to the 'status' parameter. It does not explain ad_group_id, criterion_ids, or customer_id, nor their relationships. The enum values for status do appear in the schema, but the other required parameters are left entirely undocumented in the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the action: pause or enable keywords. The resource is unambiguous from the title, and the action is distinct from sibling tools like google_ads_add_keywords or google_ads_remove_keywords. However, it does not explicitly contrast itself with those alternatives within the description.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance about when to use this tool versus alternatives, no prerequisites mentioned, and no mention of required context such as ad group or customer. The agent must infer the intended usage primarily from the tool name and sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
google_ads_update_bid_strategyUpdate Google Ads bid strategyCIdempotent
Change a campaign's bidding strategy
| Name | Required | Description | Default |
|---|---|---|---|
| strategy | Yes | ||
| campaign_id | Yes | ||
| customer_id | No | ||
| cpc_bid_ceiling | No | Only used with MAXIMIZE_CLICKS, account currency |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already communicate that this is non-read-only, idempotent, and non-destructive, and the description's 'change' is consistent with those hints. However, the description adds no additional behavioral context such as effect on existing campaigns, permission requirements, or API-side constraints. No contradiction exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no fluff and is easy to parse. It is concise, though it largely restates the title rather than adding substantive detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutating tool with no output schema and sparse parameter documentation, the description is too thin to make the tool self-sufficient. It does not mention parameter relationships, the role of customer_id, or expected behavior after the update. Annotations cover safety but not call-construction details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 25%, and the description does not explain campaign_id, customer_id, strategy, or cpc_bid_ceiling semantics. The schema's enum and the cpc_bid_ceiling note carry the only real parameter meaning; the description does not compensate for the under-documented fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a clear action ('change') and a specific target ('a campaign's bidding strategy'), so an agent can tell this is a bid-strategy mutation rather than a status or keyword operation. It is unambiguous against the sibling tools, though it does not explicitly call out a competing alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance about when to use this tool versus related tools, no prerequisites, and no caveats about Google Ads campaign requirements. The only usage signal is the implied purpose in the verb and resource, which is weaker than an explicit 'use this when...' statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
meta_ads_get_ad_statusGet a Meta ad's review statusBRead-onlyIdempotent
Get an ad's review status and rejection reason if any
| Name | Required | Description | Default |
|---|---|---|---|
| ad_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the operation as readOnly and idempotent, so the safety profile is covered. The description adds the behavioral clue that rejection reason is only returned when applicable, but it does not disclose other useful context such as possible status values, invalid ad_id behavior, or response shape.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single focused sentence with no filler. It front-loads the main purpose and adds one useful detail ('rejection reason if any') that goes beyond the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter read-only getter with strong annotations, the description covers the core return concept: review status plus optional rejection reason. It is slightly thin on output details since there is no output schema, but nothing critical seems missing for basic invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not explain the ad_id parameter's format, source, or semantics beyond the resource phrase 'an ad'. The schema only provides the name and type, so the agent gets little help understanding what values are valid.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Get') and the resource ('an ad's review status'), including the additional detail that rejection reason is returned when present. It does not explicitly differentiate from sibling tool meta_ads_list_ads_by_status, which lists ads by status, but the singular focus on a single ad's status is reasonably clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is used when you need a specific ad's review status or rejection reason, but it gives no explicit 'when to use vs alternatives' guidance. There is no mention of prerequisites, limitations, or when to prefer sibling status-related tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
meta_ads_list_ads_by_statusList Meta ads by review statusARead-onlyIdempotent
List ads in an account filtered by effective_status (e.g. DISAPPROVED)
| Name | Required | Description | Default |
|---|---|---|---|
| account_id | No | ||
| effective_status | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, openWorldHint, and idempotentHint, and the description's 'List' is consistent with them. The description adds account scoping and the effective_status filter, but it does not disclose pagination, return shape, or open-world caveats; with annotations present this is a reasonable but not additive profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with the verb and resource front-loaded, followed immediately by the filter dimension. Every part is informative and there is no unnecessary wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple and annotations cover its safety profile, but the description leaves account_id's apparent requirement unclear given that no parameters are marked required in the schema, and there is no output schema or mention of what fields are returned. It is adequate for a basic list tool but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description identifies effective_status as the filter and provides the DISAPPROVED example, adding some meaning beyond the raw schema. However, account_id is only implied by 'in an account', and the status values are already enumerated in the schema, so the description only partially compensates for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource — 'List ads in an account' — and names the filter dimension effective_status with a concrete example. This is clearly distinct from sibling tools like meta_ads_list_campaigns (different resource) and meta_ads_get_ad_status (single ad lookup), even without naming them explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'filtered by effective_status (e.g. DISAPPROVED)' implies the tool is for retrieving ads by review status, but it never states when to prefer this over meta_ads_get_ad_status or mentions exclusions/alternatives. The usage context is present only implicitly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
meta_ads_list_campaignsList Meta Ads campaignsBRead-onlyIdempotent
List Meta campaigns with status and budget
| Name | Required | Description | Default |
|---|---|---|---|
| account_id | No | Numeric ad account ID, no 'act_' prefix. Defaults to META_AD_ACCOUNT_ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and openWorldHint=true, so the safety profile is covered. The description adds that the tool returns status and budget, which is useful, but it does not disclose pagination, default account behavior, or whether the result is a summary or full list. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single short sentence that front-loads the action and resource. It is concise and readable, though it could add a brief note about the optional account_id default without much cost.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list tool with one optional parameter and no output schema, the description is mostly adequate. However, it does not mention pagination, result format, or the fact that account_id defaults to an environment variable, which an agent might need to know for correct invocation. The annotations cover safety, but the description leaves some operational context implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single optional parameter, and the description adds no parameter-specific detail beyond the schema. The baseline of 3 applies because the schema fully documents account_id, including the 'no act_ prefix' and default behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List') and resource ('Meta campaigns') and mentions the key fields returned ('status and budget'). It is clear enough to distinguish from siblings like meta_ads_get_ad_status, though it does not explicitly name a sibling or contrast with meta_ads_list_ads_by_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies a read-only listing use case, and the annotations (readOnlyHint, idempotentHint) reinforce that it is safe to call. However, it does not explicitly state when to use this tool versus alternatives like google_ads_list_campaigns or meta_ads_list_ads_by_status, leaving the agent to infer from the name and platform.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
meta_ads_set_campaign_statusEnable or pause a Meta Ads campaignAIdempotent
Enable or pause a Meta campaign. The only tool that can turn spend on.
| Name | Required | Description | Default |
|---|---|---|---|
| status | Yes | ||
| campaign_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, and destructiveHint=false, and the description does not contradict them. The description adds meaningful behavioral context by warning that this tool controls ad spend — a consequential side effect beyond what annotations express. It does not cover failure modes or timing, but the safety profile is well covered 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler. The action is front-loaded, and the second sentence earns its place by providing an exclusivity and consequence signal that helps tool selection and invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter setter with a clear enum and strong annotations, the description is nearly complete: it states the action, the spend consequence, and why this tool is unique among siblings. It does not describe return values, but with no output schema and a straightforward status-setting operation, that is a minor gap rather than an obstacle.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It partially does: 'Enable or pause' maps directly to the status enum values ACTIVE and PAUSED, and the spend warning clarifies the impact of ACTIVE. However, it does not explain campaign_id format or any edge cases, leaving some semantics to be inferred from parameter names alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb-resource pair ('Enable or pause a Meta campaign') and adds the exclusivity claim 'The only tool that can turn spend on,' which clearly distinguishes it from sibling read/list tools and the Google Ads status setter. An agent can immediately tell what this tool does and how it differs from nearby alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The exclusivity statement 'The only tool that can turn spend on' gives clear routing for the primary use case: activating or pausing a Meta campaign's spend. It does not explicitly name alternatives or state when not to use this tool, but the uniqueness claim is strong enough for an agent to select it over the listed siblings.
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.
13 tool updates
v0.1.1- First observed
google_ads_add_keywords - First observed
google_ads_add_negative_keywords - First observed
google_ads_create_search_campaign - First observed
google_ads_get_campaign_structure - First observed
google_ads_list_campaigns - First observed
google_ads_remove_keywords - First observed
google_ads_set_campaign_status - First observed
google_ads_set_keyword_status - First observed
google_ads_update_bid_strategy - First observed
meta_ads_get_ad_status - First observed
meta_ads_list_ads_by_status - First observed
meta_ads_list_campaigns - First observed
meta_ads_set_campaign_status
TDQS
Scored across 13 tools
Every tool targets a distinct platform-resource-action combination, with clear google_ads_ vs meta_ads_ prefixes separating the two domains. Even the two set_campaign_status tools are disambiguated by the platform prefix and description.
Tool names consistently follow a {platform}_{verb}_{object} pattern in snake_case. Verbs like get, list, create, add, set, remove, update are applied uniformly, making the naming predictable across both platforms.
13 tools is a reasonable scope for an ads management server covering two platforms. The count is neither bloated nor thin, and each tool covers a distinct operation.
The Google Ads side is fairly complete with campaign creation, keyword management, bid strategy updates, and status controls. However, the Meta Ads side lacks any create or edit operations beyond status changes, making the surface significantly incomplete for managing Meta campaigns.
Maintenance
Related MCP Connectors
Manage ad campaigns across Google, Meta, LinkedIn, Reddit, TikTok, and more via AI.
Manage ad campaigns across Google, Meta, LinkedIn, Reddit, TikTok, and more via AI.
Google & Meta Ads management with 100+ tools. Audit, create, and optimize campaigns.
Run ads on Google, Meta, LinkedIn, TikTok and more from AI. 530+ tools across 14 platforms.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables comprehensive management of Google Ads campaigns through natural language, including campaign creation, ad group management, keyword operations, Performance Max campaigns, conversion tracking, and performance insights with support for multiple accounts.4-

PaidSync MCP Serverofficial
AlicenseNot gradedqualityFmaintenanceConnects Google Ads, Meta Ads, and LinkedIn Ads to AI assistants, enabling natural language ad campaign management, reporting, and optimization across platforms.MIT- AlicenseBqualityCmaintenanceEnables full read/write control of Google Ads accounts—managing campaigns, ad groups, ads, keywords, Performance Max, budgets, targeting, and performance reporting through natural language. Supports Search, Display, Video, and Demand Gen campaign types with flexible GAQL querying and comprehensive reporting.471Apache 2.0
- AlicenseNot gradedqualityDmaintenanceEnables complete management of Google Ads, including CRUD operations, dashboards, reporting, and all features from the Google Ads panel.18 npmMIT