Google Ads MCP Admin
This server extends Google's official Google Ads MCP with confirmed campaign administration across managed client accounts, providing read-only querying plus a safe, approval-gated mutation workflow.
Read/Discovery:
List accessible customers (
customers_list_accessible_customers): Discover all customer/account IDs directly accessible to the authenticated user.Get resource metadata (
metadata_get_resource_metadata): Retrieve selectable, filterable, and sortable fields, metrics, and segments for any Google Ads resource (e.g.,campaign,ad_group).Search/query (
search_search): Fetch data from the Google Ads API using structured field selections, filters, orderings, and row limits.
Safe Mutation Workflow (no live data affected until final apply):
Plan mutations (
mutations_plan_mutations): Validate operations and generate an immutable, previewed mutation plan (old/new values, risk level, warnings, plan ID, expiration) — no actual writes.Get mutation plan (
mutations_get_mutation_plan): Retrieve a previously created plan's stored preview and current state.Cancel mutation plan (
mutations_cancel_mutation_plan): Invalidate a pending plan by ID and hash without touching Google Ads.Acknowledge high-risk plan (
mutations_acknowledge_high_risk_plan): First of two required approvals for high-risk operations (enabling campaigns, creating budgets, increasing budgets >25%, removing 10+ resources in one batch).Apply mutation plan (
mutations_apply_mutation_plan): Execute exactly one previously previewed and approved plan, after interactive approval, with manager-access revalidation, replay protection, and post-write verification.
Supported Writable Resources: campaign_budget, campaign, ad_group, ad_group_ad, ad_group_criterion (keywords), and campaign_criterion (targeting) — with create, update (explicit update_mask), and remove actions.
Safety: Plans are immutable, single-use, expire after 15 minutes, and the client hierarchy is revalidated immediately before any write.
Provides tools for administering Google Ads campaigns, ad groups, budgets, and criteria across manager accounts, with a mutation workflow requiring planning, approval, and verification.
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., "@Google Ads MCP AdminPause campaign 8888888888 in account 1234567890"
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.
Google Ads MCP Admin
An extension of Google's official Google Ads MCP that adds confirmed campaign administration across client accounts managed by a Google Ads manager account.
Website: jomiferse.com
Read tools run directly. Every persistent write requires an immutable plan, a preview, interactive approval, and post-write verification. High-risk changes require two independent approvals.
Safety model
Mutation plans are immutable, expire after 15 minutes, and can be applied only once.
The server revalidates the client hierarchy immediately before a write.
Normal writes require approval for
mutations_apply_mutation_plan.High-risk writes first require
mutations_acknowledge_high_risk_plan, followed by a separate apply approval.Ambiguous API responses are never retried automatically.
Audit records contain metadata and request IDs, not credentials or complete payloads.
Related MCP server: adsmith
Prerequisites
macOS, Windows, or Linux.
Python 3.11 or later.
uv.Google Cloud CLI (
gcloud).A Google Cloud project with the Google Ads API enabled.
A Desktop OAuth client authorized for a Google user who can access the target manager account.
An approved Google Ads API developer token.
Install the pinned dependencies:
uv sync --extra devConfigure Codex
Copy the public configuration template and replace its cwd value with the absolute path to this repository:
cp .codex/config.toml.example .codex/config.tomlThe local .codex/config.toml file is ignored by Git. Provide these non-secret variables to the Codex process. POSIX shell:
export GOOGLE_CLOUD_PROJECT="your-google-cloud-project"
export GOOGLE_ADS_LOGIN_CUSTOMER_ID="1234567890"PowerShell:
$env:GOOGLE_CLOUD_PROJECT = "your-google-cloud-project"
$env:GOOGLE_ADS_LOGIN_CUSTOMER_ID = "1234567890"Google Ads account IDs must contain digits only, without hyphens. GOOGLE_APPLICATION_CREDENTIALS is optional when Application Default Credentials are stored in the standard gcloud location.
You may place non-secret local values in the ignored configuration instead:
[mcp_servers.google_ads_admin.env]
GOOGLE_CLOUD_PROJECT = "your-google-cloud-project"
GOOGLE_ADS_LOGIN_CUSTOMER_ID = "1234567890"Never place the developer token, OAuth client secret, or ADC refresh token in this repository.
Configure OAuth
Create a Desktop OAuth client in Google Auth Platform and download its JSON file outside the repository. On macOS or Linux, run the optional helper:
export GOOGLE_CLOUD_PROJECT="your-google-cloud-project"
scripts/configure-google-ads-oauth.sh "/absolute/path/to/oauth-client.json"On Windows PowerShell, run the equivalent Google Cloud CLI commands:
$env:GOOGLE_CLOUD_PROJECT = "your-google-cloud-project"
gcloud services enable googleads.googleapis.com --project $env:GOOGLE_CLOUD_PROJECT
gcloud auth application-default login `
--scopes="https://www.googleapis.com/auth/adwords,https://www.googleapis.com/auth/cloud-platform" `
--client-id-file="C:\absolute\path\to\oauth-client.json"The helper enables googleads.googleapis.com and requests only these scopes:
https://www.googleapis.com/auth/adwordshttps://www.googleapis.com/auth/cloud-platform, required for Application Default Credentials
The resulting ADC file is stored outside the repository by gcloud.
Store the developer token
Store or replace the token with a hidden prompt:
uv run google-ads-mcp-admin-credentials setThe command uses the native credential store selected by Python keyring:
macOS Keychain.
Windows Credential Locker.
Linux Secret Service or KWallet when a compatible backend is available.
Check which source is active without displaying the token:
uv run google-ads-mcp-admin-credentials statusDelete only the native credential with:
uv run google-ads-mcp-admin-credentials deleteOn desktop Linux, install the Secret Service or KWallet packages recommended by your distribution and run the application in an active D-Bus session. keyring diagnose reports the selected backend. Headless Linux, CI, and containers can use the environment fallback instead.
POSIX shell fallback:
export GOOGLE_ADS_DEVELOPER_TOKEN="your-developer-token"PowerShell fallback:
$env:GOOGLE_ADS_DEVELOPER_TOKEN = "your-developer-token"The native credential has priority when both sources are configured. Never place the token in .codex/config.toml, .env, command arguments, or this repository.
Migration from the macOS-only release
Run uv run google-ads-mcp-admin-credentials set and paste the existing token into the hidden prompt. After status reports native, remove the legacy codex-google-ads-developer-token item with the Keychain Access application. Automatic migration is intentionally not performed.
Start the MCP server
Set the manager account and start the server manually to verify startup:
export GOOGLE_ADS_LOGIN_CUSTOMER_ID="1234567890"
uv run google-ads-mcp-adminPowerShell:
$env:GOOGLE_ADS_LOGIN_CUSTOMER_ID = "1234567890"
uv run google-ads-mcp-adminAfter editing .codex/config.toml:
Restart Codex or reopen the project.
Open
/mcpand confirm thatgoogle_ads_adminis available.Confirm that the official read tools and the five
mutations_*tools are present.
Do not weaken the write approval policies when the server can access production accounts.
Read-only verification
Offline checks require no credentials:
uv run pytest -m "not integration" -qAfter OAuth and credential setup, run the opt-in live read test. The test resolves the native token first and uses the environment fallback when needed:
export GOOGLE_ADS_LOGIN_CUSTOMER_ID="1234567890"
GOOGLE_ADS_RUN_INTEGRATION=1 \
uv run pytest tests/integration/test_google_ads_read.py -vThe test discovers enabled, non-manager client accounts and queries one of them without writing.
Mutation workflow
Call
mutations_plan_mutationswith a ten-digitcustomer_idand structured operations.Review
preview,old_values,new_values,warnings,risk,plan_id,plan_hash, and expiration.Approve
mutations_apply_mutation_planin Codex for a normal-risk plan.The server revalidates manager access, claims the plan to prevent replay, dispatches it once, and reads the resulting resources.
Review
request_idsandverification.
Use mutations_cancel_mutation_plan with the plan ID and hash to invalidate a pending plan. Plans are held only in memory and disappear when the server restarts.
High-risk changes
The following operations are high risk:
Enabling a campaign.
Creating a budget.
Increasing a budget by more than 25 percent.
Removing ten or more resources in one batch.
First approve mutations_acknowledge_high_risk_plan. Codex then requests a separate approval for mutations_apply_mutation_plan. Neither call can replace or alter the saved operations.
Supported resources
campaign_budgetcampaignad_groupad_group_adad_group_criterion, including keywordscampaign_criterion, including targeting
Supported actions are create, update with an explicit update_mask, and remove. Google Ads removal commonly changes status to REMOVED; it is not physical deletion and may be irreversible.
First persistent write
Complete these checks before any persistent write:
uv run ruff check .uv run pytest -m "not integration" -qThe live read-only integration test.
validate_onlyagainst a dedicated test account:
export GOOGLE_ADS_TEST_CUSTOMER_ID="1234567890"
GOOGLE_ADS_RUN_INTEGRATION=1 \
uv run pytest tests/integration/test_google_ads_validate_only.py -vThe first persistent test should create a PAUSED campaign with the minimum practical budget in a test account. Review and approve its plan, verify the resources, then create and approve a separate removal plan.
If no test account is available, stop after validate_only. A first write to production requires separate explicit authorization and should be limited to one paused resource with minimal financial impact.
Recovery and auditing
Expired or cancelled plan: create a new plan; it cannot be reactivated.
Revoked OAuth grant: rerun
scripts/configure-google-ads-oauth.sh.Replaced developer token: run
uv run google-ads-mcp-admin-credentials setagain.Ambiguous write response: do not retry; query state once and preserve the returned request ID.
Quota, permission, or policy error: preserve the Google Ads request ID for diagnosis.
Client removed from the manager hierarchy: the pre-write revalidation rejects the operation.
Local audit events are written to audit/google_ads_mcp.jsonl, rotate at 5 MiB, and contain account, plan, resource counts, result, and request IDs. They do not contain complete mutation payloads or credentials.
Development
uv run ruff check .
uv run pytest -m "not integration" -v
uv build
git diff --checkThe official server dependency is pinned to upstream commit f48a6b85e1f43ebd44a72531c9611e2b7265ca28. Review upstream changes, rerun all checks, and inspect MCP tool annotations before updating it.
License
Licensed under the Apache License, Version 2.0. See LICENSE.
Available Tools
8 toolscustomers_list_accessible_customersARead-only
Returns ids of customers directly accessible by the user authenticating the call.
Use this tool first to discover available customer IDs if the user hasn't provided one. Most other tools require a valid customer ID as input.
Returns: List[str]: A list of customer IDs.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, and the description adds context that IDs are 'directly accessible by the user authenticating the call' and that this is a discovery tool. This goes beyond the annotation by specifying scope and workflow, though it does not cover all potential behaviors (e.g., pagination).
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 three short lines with no filler. Each sentence adds value: it states what the tool does, when to use it, and what it returns. The structure is front-loaded with the primary purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple parameterless tool with an output schema, the description is complete. It covers the purpose, the return type, and the workflow context (other tools need a customer ID). The existing output schema handles the return specification, so no further detail is needed.
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 zero parameters, the schema fully documents any inputs (none needed). The baseline for 0 params is 4, and the description correctly avoids adding parameter details that don't exist.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns customer IDs accessible by the user, using a specific verb ('Returns') and resource (customer IDs). It distinguishes from sibling tools by focusing on 'directly accessible' customers and noting its role as a discovery step.
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?
Explicit guidance is provided: 'Use this tool first to discover available customer IDs if the user hasn't provided one. Most other tools require a valid customer ID as input.' This clearly states when to use it and why it is the appropriate first step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
metadata_get_resource_metadataARead-only
Retrieves the selectable, filterable, and sortable fields for a specific Google Ads resource, including compatible metrics and segments.
Use this tool to find out which fields you can select, filter by, or sort by when querying a specific resource (e.g., 'campaign', 'ad_group'). This tool also returns metrics and segments that can be selected with the resource. Their names start with 'metrics.' and 'segments.' respectively.
Do not guess fields, you MUST use this tool to discover them before constructing a query for the
search tool.
The responses of this tool should be cached, as they don't change frequently.
| Name | Required | Description | Default |
|---|---|---|---|
| resource_name | Yes | The name of the Google Ads resource (e.g., 'campaign', 'ad_group'). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations include readOnlyHint=true, so safety is covered. The description adds context about field naming conventions ('metrics.' and 'segments.' prefixes) and that responses should be cached as they don't change frequently. This adds behavioral context beyond the annotation without contradicting it.
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 four sentences, with the main purpose in the first sentence and supporting details following. There is no fluff—every sentence contributes either functional purpose, usage guidance, or caching advice.
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 an output schema exists, there's no need to explain return values. The description covers scope, usage, mandatory invocation, field naming, and caching. For a single-parameter tool with rich schema/annotations, this is complete and self-sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 100% coverage for the single parameter, which already explains it as 'The name of the Google Ads resource (e.g., 'campaign', 'ad_group').' The description repeats this with examples but doesn't add substantially new semantic detail, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves selectable, filterable, and sortable fields for a specific Google Ads resource, including compatible metrics and segments. It uses a specific verb ('Retrieves') and resource, distinguishing it from siblings like search and mutation tools.
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 explicitly tells when to use it: to discover fields before constructing a query for the `search` tool. It also provides a strong exclusion: 'Do not guess fields, you MUST use this tool to discover them.' This is clear guidance on when this tool is required vs alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mutations_acknowledge_high_risk_planB
Record the first interactive approval required for a high-risk plan.
| Name | Required | Description | Default |
|---|---|---|---|
| plan_id | Yes | ||
| plan_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already state readOnlyHint=false and destructiveHint=false, so the mutation nature is known. The description adds the nuanced context of 'first interactive approval,' implying a workflow step, but does not disclose side effects, idempotency, or failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, front-loaded with the action verb, zero filler. Appropriate length, and every word contributes to the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present but no param descriptions, no usage guidance, and only one contextual hint about high-risk plans, the description is insufficient for an agent to confidently integrate this tool into a mutation workflow.
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 elaborate on plan_id or plan_hash. There is no added meaning beyond parameter names; an agent must guess the hash's purpose.
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 'Record' and identifies the resource as a 'high-risk plan' with the scope 'first interactive approval required.' This clearly distinguishes it from sibling mutation tools like apply, cancel, or plan mutations.
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 mutations_plan_mutations, mutations_cancel_mutation_plan, or mutations_apply_mutation_plan. It does not mention prerequisites, workflow position, or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mutations_apply_mutation_planADestructive
Apply exactly one previously previewed plan after interactive approval.
| Name | Required | Description | Default |
|---|---|---|---|
| plan_id | Yes | ||
| plan_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=false, so the description's job is to add context beyond that. It adds the requirement of interactive approval and exactly one plan, which are useful safety constraints, but does not disclose what happens to the plan after application (e.g., whether it is consumed) or any rollback possibilities.
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?
One sentence with no fluff, every word adds value: 'Apply exactly one' sets scope, 'previously previewed' sets precondition, 'after interactive approval' sets workflow. Description is front-loaded with the core action.
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 low parameter count, presence of an output schema, and clear annotations, the description covers the essential purpose and constraints. It could clarify the exact nature of 'interactive approval' (e.g., whether it blocks or expires), but this is minor because the workflow is implied by sibling tools.
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 describes parameters as plan_id and plan_hash (both required strings) but has 0% description coverage. The description does not mention either parameter or explain the meaning or relationship (e.g., why hash is needed, how to obtain them). The tool name implies they identify a plan, but no additional semantics are provided.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Apply'), the resource ('mutation plan'), and specific constraints (exactly one, previously previewed, after interactive approval). This distinguishes it from sibling tools like mutations_get_mutation_plan (retrieving) and mutations_cancel_mutation_plan (canceling).
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 'after interactive approval' and 'previously previewed plan' clearly indicates when this tool should be used: only after preview and approval. It implies the workflow but does not explicitly name alternatives or exclusions, though sibling tools make it obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mutations_cancel_mutation_planBRead-only
Invalidate a pending local plan without changing Google Ads.
| Name | Required | Description | Default |
|---|---|---|---|
| plan_id | Yes | ||
| plan_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description contradicts the annotations: it says 'Invalidate a pending local plan' (a mutation) while annotations declare readOnlyHint: true. This is a direct contradiction, and the description does not reconcile this by explaining that it only affects local state. Annotation contradiction is present.
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 that immediately conveys the core function. Every word adds value, and there is no unnecessary filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having an output schema, the description is too minimal to fully support an agent. It omits any explanation of parameters, side effects, or how it relates to the mutation plan lifecycle. The contradiction with annotations further reduces its reliability, making it incomplete for a tool that invalidates a plan.
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 what 'plan_id' and 'plan_hash' are or how they relate to the invalidation. With two required parameters and no added context, the description fails to compensate for 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 clearly states the verb 'Invalidate' and the specific resource 'a pending local plan', and adds the scope 'without changing Google Ads', which distinguishes it from apply/acknowledge siblings. It is concise and unambiguous about what the tool does.
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 clear context: this tool is for invalidating a pending local plan, implying it should be used instead of applying or acknowledging it. However, it does not explicitly name alternatives or state when not to use it, so it falls short of a perfect score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mutations_get_mutation_planARead-only
Return the stored immutable preview and current local plan state.
| Name | Required | Description | Default |
|---|---|---|---|
| plan_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true and destructiveHint=false, which covers the safety profile. The description adds context by mentioning 'immutable preview' and 'current local plan state', but does not disclose additional behavioral traits like error conditions or authorization needs. Credit for adding some context beyond annotations, but not substantial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that front-loads the key action and object. It wastes no words and is appropriately sized for a simple read-only getter.
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 with one parameter and an existing output schema, the description is mostly complete. It clarifies the two components of the return value ('stored immutable preview' and 'current local plan state'). However, it could be slightly richer by explicitly mentioning plan_id as the input, but given the schema and output schema, the description is sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%; the description does not mention the 'plan_id' parameter at all. The schema only provides the name and type, leaving the agent to guess what a valid plan_id is. With 0% coverage, the description fails to compensate, resulting in minimal semantic guidance for the parameter.
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 'Return the stored immutable preview and current local plan state' states a specific verb ('Return') and resource ('mutation plan'), and clearly distinguishes this getter from sibling tools like apply, cancel, and acknowledge which modify or act on plans. It precisely describes what the tool returns.
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 verb 'Return' implies usage for retrieving plan state, but there is no explicit when-to-use guidance or mention of alternatives. Context from sibling names suggests this is the read-only getter among mutation plan operations, but the description does not state when to prefer this over other tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mutations_plan_mutationsARead-only
Validate operations and return an immutable preview; makes no Ads write.
| Name | Required | Description | Default |
|---|---|---|---|
| operations | Yes | ||
| customer_id | Yes | ||
| partial_failure | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds context by specifying 'return an immutable preview' and reinforcing 'makes no Ads write.' This goes slightly beyond the annotations by clarifying the nature of the returned data (immutable preview) rather than just the safety 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?
The description is a single sentence that is front-loaded with the verb and directly states the tool's purpose. Every word adds value, and there is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema and strong annotations, the description adequately conveys the tool's primary role as a non-writing validation/preview step. However, it misses details about partial_failure handling and could benefit from explicit differentiation from the many sibling mutation tools, leaving a slight gap.
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 only mentions 'operations' as the subject of validation, leaving customer_id and partial_failure completely unexplained. The description fails to provide essential parameter context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Validate operations and return an immutable preview' and explicitly notes it 'makes no Ads write.' This distinguishes it from sibling tools like mutations_apply_mutation_plan, which applies plans, and mutations_get_mutation_plan, which retrieves plans.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for previewing/validation ('return an immutable preview'; 'makes no Ads write') but does not explicitly state when to use it over alternatives like mutations_apply_mutation_plan or mutations_get_mutation_plan. No exclusions or explicit alternative references are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_searchARead-only
Fetches data from the Google Ads API using the search method
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | The maximum number of rows to return | |
| fields | Yes | The fields to fetch | |
| resource | Yes | The resource to return fields from | |
| orderings | No | How the data is ordered | |
| conditions | No | List of conditions to filter the data, combined using AND clauses | |
| customer_id | Yes | The id of the customer |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already signals this is a safe read operation. The description confirms the fetching behavior and adds the 'search method' detail, but does not disclose additional traits like pagination, rate limits, or error handling. No contradiction with annotations 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 sentence that immediately states the action and method. Every word is meaningful, with no fluff or repetition of schema details.
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 has moderate complexity, but the schema fully covers parameters and an output schema exists. The description is adequate but minimal; it does not explain the GAQL/search method context or provide operational guidance beyond the basic purpose. Given the richness of structured data, this is a passable but not exceptional description.
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?
Input schema has 100% coverage with descriptions for all six parameters. The tool description itself adds no parameter-level meaning, so per the rubric baseline of 3 for high schema coverage, this score is appropriate.
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 ('Fetches data'), the resource ('Google Ads API'), and the method ('search method'), making it distinct from sibling mutation and metadata tools. The verb is specific and the resource is clearly identified.
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 usage guidance is provided. The description does not mention when to use this tool versus alternatives, nor does it name sibling tools or list exclusions. The intended read-only use is only implied by the annotations and the word 'fetches', not explicitly stated.
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.
8 tool updates
v0.1.0- First observed
customers_list_accessible_customers - First observed
metadata_get_resource_metadata - First observed
mutations_acknowledge_high_risk_plan - First observed
mutations_apply_mutation_plan - First observed
mutations_cancel_mutation_plan - First observed
mutations_get_mutation_plan - First observed
mutations_plan_mutations - First observed
search_search
TDQS
Scored across 8 tools
Each tool serves a distinct purpose: customer discovery, metadata lookup, data search, and mutation plan lifecycle. The only mild ambiguity is between 'plan_mutations' and 'get_mutation_plan', as both return previews, but their roles (create vs retrieve) are clarified in descriptions.
Tools follow a consistent [domain]_[action] pattern with snake_case, such as customers_list_accessible_customers and mutations_apply_mutation_plan. The name 'search_search' is slightly awkward (resource and verb identical), but overall the pattern is predictable and coherent.
Eight tools is well-scoped for the Google Ads admin domain, covering customer access, metadata/field discovery, search, and a complete mutation planning workflow. No redundant or excessive tools.
The mutation plan lifecycle is well covered (plan, get, cancel, acknowledge, apply), and search is supported by metadata discovery. Minor gaps include no way to list all mutation plans and no single-customer detail endpoint, but these are edge cases rather than core dead ends.
Maintenance
Related MCP Connectors
Google Ads MCP with 20,000+ account peer context and staged approve-then-execute writes.
Google Ads MCP server — manage campaigns, keywords, and metrics.
Hosted Google Ads MCP with OAuth, bounded reads, and prepare/confirm writes.
Google Ads, Meta Ads & GA4 MCP server - 250+ tools for campaigns, creatives, audiences & reports.
Related MCP Servers
- AlicenseAqualityBmaintenanceExtends the official Google Ads MCP with a safe write layer for creating paused-by-default Search campaigns and an account auditor, all running locally with no hosted dependencies.131Apache 2.0
- AlicenseNot gradedqualityAmaintenanceA Google Ads MCP server that enables safe, auditable management of ad accounts through natural language, including proposing, reviewing, applying, and rolling back changes with guardrails and dry-runs.MIT
- AlicenseNot gradedqualityCmaintenanceMCP server for managing Google Ads campaigns through the official Google Ads API, covering accounts, campaigns, budgets, keywords, search terms, and keyword ideas. It provides tools for both reading and mutating live ads data, such as pausing campaigns, updating budgets, and adding keywords.MIT
- AlicenseAqualityAmaintenanceAn MCP server that provides read and write access to Google Ads, allowing natural language management of campaigns, budgets, ad groups, bids, and keywords, with dry-run validation for safety.18MIT