google-ads-mcp
OfficialThe server is an MCP interface to the Google Ads API that lets LLMs query account data, discover API structure, and manage access to Google Ads accounts.
Search Google Ads data: Run GAQL-style searches (
search_search) on resources like campaigns and ad groups, with fields, conditions, ordering, and limits.Discover resource metadata: Use
metadata_get_resource_metadatato find selectable, filterable, and sortable fields for resources such ascampaignorad_groupbefore constructing queries.List accessible customers: Use
customers_list_accessible_customersto get customer IDs directly accessible to the authenticated user.Access API reference resources: Retrieve the Google Ads API discovery document, available metrics, segments, and release notes.
Authenticate flexibly: Supports Application Default Credentials, OAuth proxy/Streamable HTTP, and
google-ads.yaml-based credentials.Configure tool availability: Use
tools_config.yamlto enable/disable tools, customize namespaces, and fine-tune tool exposure.Support manager accounts: Pass a
login_customer_idper call or viaGOOGLE_ADS_LOGIN_CUSTOMER_IDfor manager-account access.
Provides tools and resources for interacting with the Google Ads API, enabling AI agents to search account data, retrieve resource metadata, list accessible customers, and access discovery documents, metrics, segments, and release notes.
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-mcpSearch for my active campaigns"
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 Server
This repo contains the source code for running an MCP server that interacts with the Google Ads API.
Tools
The server uses the Google Ads API to provide several Tools and Resources for use with LLMs and AI agents.
Tools available
search: Retrieves information about the Google Ads account.get_resource_metadata: Retrieves metadata about a Google Ads API resource type, for example "campaign". This is useful to understand the structure of the data and what fields are available for querying.list_accessible_customers: Returns ids of customers directly accessible by the user authenticating the call.
Configuring and Namespacing Tools
The Google Ads MCP server uses the tools_config.yaml to let you selectively enable or disable individual tools or tool categories (namespaces) and customize their namespace prefixes.
A default tools_config.yaml with all tools enabled is bundled with the package, so the server works out of the box with no extra setup. To customize your installation, the server resolves the configuration in the following order:
An explicit path set via the
GOOGLE_ADS_MCP_TOOLS_CONFIGenvironment variable.A
tools_config.yamlfile in the current working directory.The default
tools_config.yamlbundled with the package.
If an explicitly requested configuration file (via the environment variable) is missing, or any resolved file is invalid, the server raises an error and fails to start.
Configuration Example:
namespaces:
# Option 1: Enable category 'customers' with default prefix -> "customers_list_accessible_customers"
customers: true
# Option 2: Enable category 'search' with a custom prefix -> "query_search"
search: "query"
# Option 3: Fine-grained control over tools in a category
metadata:
enabled: true
prefix: "metadata"
enabled_tools:
- get_resource_metadata: trueResources available
discovery-document: Retrieve the Google Ads API discovery document. Provides the discovery document for the latest version of the Google Ads API, which describes the API surface, including resources, methods, and schemas. Host LLMs should access this resource to understand the structure of the Google Ads API and discover available features.metrics: Retrieve information about the metrics available for reporting in the Google Ads API.segments: Retrieve information about the segments available for reporting in the Google Ads API.release-notes: Retrieve the release notes for the latest version of the Google Ads API.
Related MCP server: gads
Notes
The MCP Server will expose your data to the Agent or LLM that you connect to it.
If you have technical issues, please use the GitHub issue tracker.
To help us collect usage data, you will notice an extra header has been added to your API calls: this data is used to improve the product.
Setup instructions
Setup involves the following steps:
Configure Python.
Configure Developer Token.
Enable APIs in your project
Configure Credentials.
Configure your MCP client.
Configure Python
After a version has been published to PyPI, you can run that exact version instead of following the latest repository state:
pipx run --spec "google-ads-mcp==X.Y.Z" google-ads-mcpConfigure Developer Token (Optional)
If your setup requires a developer token, follow the instructions for Obtaining a Developer Token.
Your developer token must have at least Explorer access to query production accounts. New tokens may be automatically upgraded to Explorer access; if not, you can apply through the API Center. See the access levels documentation for details.
If you see the error "The developer token is only approved for use with test accounts", your token does not yet have access to production accounts. See the access levels documentation for how to request the access level you need.
Enable APIs in your project
Follow the instructions to enable the following APIs in your Google Cloud project:
Configure Credentials
Option 1: Using FastMCP OAuth Proxy
The server supports FastMCP's OAuth proxy feature for dynamic user authentication. This is useful when running the server as a web service.
To enable it, set the following environment variables:
GOOGLE_ADS_MCP_OAUTH_CLIENT_ID: Your Google Cloud OAuth 2.0 Client ID.GOOGLE_ADS_MCP_OAUTH_CLIENT_SECRET: Your Google Cloud OAuth 2.0 Client Secret.GOOGLE_ADS_MCP_BASE_URL: (Optional) The base URL where the server is accessible (defaults tohttp://localhost:8080).GOOGLE_ADS_MCP_JWT_SIGNING_KEY: (Optional) Secret key used to sign FastMCP JWT tokens across multiple server instances or deployments.GOOGLE_ADS_MCP_STORAGE_TYPE: (Optional) Storage backend for OAuth state (filetree,redis,firestore, ormemory).GOOGLE_ADS_MCP_STORAGE_PATH: (Optional) Directory path forfiletreepersistent storage.GOOGLE_ADS_MCP_STORAGE_REDIS_URL: (Optional) Redis URL forredispersistent storage.GOOGLE_ADS_MCP_STORAGE_FIRESTORE_PROJECT: (Optional) Google Cloud project forfirestorepersistent storage. Defaults to the project inferred from Application Default Credentials. Setting it selects thefirestorebackend even ifGOOGLE_ADS_MCP_STORAGE_TYPEis unset.GOOGLE_ADS_MCP_STORAGE_FIRESTORE_DATABASE: (Optional) Firestore database name forfirestorepersistent storage. Defaults to(default).GOOGLE_ADS_MCP_STORAGE_ENCRYPTION_KEY: (Optional) Encryption key for stored OAuth tokens.GOOGLE_ADS_MCP_STORAGE_DISABLE_ENCRYPTION: (Optional) Set totrueto disable token encryption.
The redis and firestore backends need their storage library installed
alongside the server: pip install py-key-value-aio[redis] and
pip install google-ads-mcp[firestore] respectively.
Once this is enabled, you can authenticate to the API through your MCP client.
When these variables are set, the server automatically switches to the
streamable-http transport instead of stdio.
You will need to run the server as a separate process and configure your MCP
client to connect to the Streamable HTTP endpoint (for example,
http://localhost:8080/mcp).
Local WSL and Podman deployment
This deployment has been tested with rootless Podman in WSL and exposes a single
Streamable HTTP endpoint at http://localhost:8080/mcp. Build the image from
the repository inside WSL:
podman build --tag localhost/google-ads-mcp:latest --file Dockerfile .Keep server credentials out of MCP client configuration. The tested Quadlet
loads Google Ads and OAuth settings from a private host-side file through
EnvironmentFile= and uses a separate named volume for persistent encrypted
OAuth state:
[Container]
Image=localhost/google-ads-mcp:latest
PublishPort=127.0.0.1:8080:8080
EnvironmentFile=/absolute/host/path/google-ads-mcp.env
Volume=google-ads-mcp-oauth.volume:/var/lib/google-ads-mcp:rw
ReadOnly=true
NoNewPrivileges=true
DropCapability=allThe environment file and the OAuth-state volume serve different purposes: the
volume does not contain the .env file. Keep the environment file outside the
repository, restrict it to the service owner, and never commit it. Antigravity
and Codex then need only the MCP endpoint and their own OAuth authorization;
they do not need the server's Google Ads developer token, OAuth client secret,
or signing and storage keys. Publish port 8080 only on the loopback interface
when the server is intended for local agents.
The endpoint deliberately keeps stateful Streamable HTTP enabled. It supports
legacy MCP 2025 clients that use Mcp-Session-Id and GET SSE as well as MCP
2026 clients that use sessionless POST requests and subscriptions/listen.
Do not enable FastMCP's stateless_http option on this shared endpoint; doing
so removes the legacy GET channel.
The server runs on FastMCP 4 (fastmcp>=4.0.3) paired with mcp[cli]==2.0.0. The Docker build also applies a version-guarded
OAuth metadata workaround for Codex CLI 0.146. It stops advertising the RFC
9207 authorization-response iss parameter as mandatory while FastMCP still
includes it in redirects. The build fails if the expected FastMCP version or
patch location changes, so upgrades require explicit interoperability tests.
For Codex, configure and authenticate the server as described in the official Codex MCP documentation:
codex mcp add google_ads --url http://localhost:8080/mcp
codex mcp login google_adsFor Antigravity, configure the same URL as serverUrl in its MCP configuration.
This key is required for Streamable HTTP in Antigravity 2.8.1 and Antigravity
IDE 2.5.5; httpUrl is not accepted by those versions. After authentication,
both clients should list these namespaced tools:
customers_list_accessible_customersmetadata_get_resource_metadatasearch_search
Option 2: Configure credentials using Application Default Credentials
Configure your Application Default Credentials (ADC). Make sure the credentials are for a user with access to your Google Ads accounts or properties.
Credentials must include the Google Ads API scope:
https://www.googleapis.com/auth/adwordsCheck out Manage OAuth Clients for how to create an OAuth client.
Here are some sample gcloud commands you might find useful:
Set up ADC using user credentials and an OAuth desktop or web client after downloading the client JSON to
YOUR_CLIENT_JSON_FILE.gcloud auth application-default login \ --scopes https://www.googleapis.com/auth/adwords,https://www.googleapis.com/auth/cloud-platform \ --client-id-file=YOUR_CLIENT_JSON_FILESet up ADC using service account impersonation.
gcloud auth application-default login \ --impersonate-service-account=SERVICE_ACCOUNT_EMAIL \ --scopes=https://www.googleapis.com/auth/adwords,https://www.googleapis.com/auth/cloud-platform
When the gcloud auth application-default command completes, copy the
PATH_TO_CREDENTIALS_JSON file location printed to the console in the
following message. You will need this for a later step!
Credentials saved to file: [PATH_TO_CREDENTIALS_JSON]Option 3: Configure credentials using the Google Ads API Python client library.
Follow the instructions to setup and configure the Google Ads API Python client library
If you have already done this and have a working google-ads.yaml , you can reuse this file!
In the utils.py file, change get_googleads_client() to use the load_from_storage() method.
Configure your MCP client
Add the server to your MCP client's configuration. Below are examples for popular clients.
Antigravity / Antigravity IDE
Install Antigravity or Antigravity IDE.
Configure your server. Refer to the docs at https://antigravity.google/docs/mcp for details on setting up MCP servers.
Option 1: Using FastMCP OAuth Proxy (Streamable HTTP)
You can run the server as a separate process and configure your MCP client to connect to the Streamable HTTP endpoint (for example,
http://localhost:8080/mcp). This also allows using FastMCP's OAuth proxy feature for dynamic user authentication.Antigravity 2.8.1 and Antigravity IDE 2.5.5 require
serverUrlfor a Streamable HTTP server. Do not use the olderhttpUrlkey. Server-side credentials belong in the server process, not in this client configuration.{ "mcpServers": { "google-ads-mcp": { "serverUrl": "http://localhost:8080/mcp" } } }Option 2: the Application Default Credentials method
This remains a supported alternative, but it provides less credential isolation than the server-managed Streamable HTTP deployment above. The MCP client starts the server and its configuration contains the ADC file path and Google Ads developer token. Prefer the Quadlet deployment when several local clients share the same server or client configuration may be copied, synchronized, or inspected by other tools.
Replace
PATH_TO_CREDENTIALS_JSONwith the path you copied in the previous step.We also recommend that you add a
GOOGLE_CLOUD_PROJECTattribute to theenvobject. ReplaceYOUR_PROJECT_IDin the following example with the project ID of your Google Cloud project.{ "mcpServers": { "google-ads-mcp": { "command": "pipx", "args": [ "run", "--spec", "git+https://github.com/googleads/google-ads-mcp.git", "google-ads-mcp" ], "env": { "GOOGLE_APPLICATION_CREDENTIALS": "PATH_TO_CREDENTIALS_JSON", "GOOGLE_PROJECT_ID": "YOUR_PROJECT_ID", "GOOGLE_ADS_DEVELOPER_TOKEN": "YOUR_DEVELOPER_TOKEN" } } } }Option 3: the Python client library method
{ "mcpServers": { "google-ads-mcp": { "command": "pipx", "args": [ "run", "--spec", "git+https://github.com/googleads/google-ads-mcp.git", "google-ads-mcp" ], "env": { "GOOGLE_PROJECT_ID": "YOUR_PROJECT_ID", "GOOGLE_ADS_DEVELOPER_TOKEN": "YOUR_DEVELOPER_TOKEN" } } } }
Login Customer Id
If your access to the customer account is through a manager account, you can
either provide the manager account's customer ID per tool call via the optional
login_customer_id parameter, or set GOOGLE_ADS_LOGIN_CUSTOMER_ID in the
settings file as a default (the per-call login_customer_id parameter takes
precedence when specified).
See here for details.
The final file will look like this:
{
"mcpServers": {
"google-ads-mcp": {
"command": "pipx",
"args": [
"run",
"--spec",
"git+https://github.com/googleads/google-ads-mcp.git",
"google-ads-mcp"
],
"env": {
"GOOGLE_APPLICATION_CREDENTIALS": "PATH_TO_CREDENTIALS_JSON",
"GOOGLE_PROJECT_ID": "YOUR_PROJECT_ID",
"GOOGLE_ADS_DEVELOPER_TOKEN": "YOUR_DEVELOPER_TOKEN",
"GOOGLE_ADS_LOGIN_CUSTOMER_ID": "YOUR_MANAGER_CUSTOMER_ID"
}
}
}
}Other MCP clients (Claude Code, Cursor, VS Code, etc.)
The mcpServers block format is the same across all MCP clients. Add the configuration shown above to the appropriate settings file for your client (e.g., ~/.claude/settings.json for Claude Code, .cursor/mcp.json for Cursor, .vscode/mcp.json for VS Code with Copilot).
Deployment to Google Cloud Platform
Instead of hosting this MCP server locally, you can host it on Google Cloud Run or on any other cloud-based infrastructure. This is useful if you want to share the server across different agents or run it as a web service.
Note that this only supports authentication with an OAuth Client ID and Client Secret pair through the OAuth proxy (Option #1 above).
Prerequisites
A Google Cloud project.
The
gcloudCLI installed, authenticated, and active project set.gcloud config set project YOUR_PROJECT_ID
Step 1: Build and Push Docker Image
You can use Cloud Build to build and push the image to Artifact Registry without needing Docker installed locally.
Create a repository in Artifact Registry:
gcloud artifacts repositories create mcp-servers --repository-format=docker --location=us-central1Build and submit the image:
gcloud builds submit --tag us-central1-docker.pkg.dev/YOUR_PROJECT_ID/mcp-servers/google-ads-mcp:latest .Replace
YOUR_PROJECT_IDwith your Google Cloud project ID.
Step 2: Deploy to Google Cloud Run
Make sure to set the required environment variables:
GOOGLE_PROJECT_ID: Your Google Cloud project ID.GOOGLE_ADS_DEVELOPER_TOKEN: (Optional) The developer token you want the MCP server to use (see above).GOOGLE_ADS_MCP_OAUTH_CLIENT_ID: The OAuth Client ID you want the MCP server to use.GOOGLE_ADS_MCP_OAUTH_CLIENT_SECRET: The OAuth Client secret you want the MCP server to use.GOOGLE_ADS_MCP_BASE_URL: The base URL where your MCP server is accessible: this will be automatically assigned by Google Cloud Run after your first deployment. You can update the environment variables after deployment.GOOGLE_ADS_MCP_JWT_SIGNING_KEY: (Recommended for production) Persistent JWT signing key across Cloud Run instances.GOOGLE_ADS_MCP_STORAGE_TYPE: (Recommended for production) Storage backend to persist OAuth tokens across instances. Set it tofirestoreto use Firestore through Application Default Credentials, which needs no VPC connector, or toredisalong withGOOGLE_ADS_MCP_STORAGE_REDIS_URL.Using
firestorerequires three things: build the image with the extra installed (change the Dockerfile touv pip install --system .[firestore]), create a Firestore database in the project, since one is not provisioned automatically, and grant the Cloud Run service accountroles/datastore.user. Note that entries are not expired automatically: the store filters expired entries on read but never deletes them, andexpires_atis written as a string, so a Firestore TTL policy cannot collect them either. Plan on a periodic cleanup job for long-running deployments. Redis expires entries on its own.FASTMCP_HOST: Set this to0.0.0.0to allow FastMCP to accept connections from all IP addresses.GOOGLE_ADS_LOGIN_CUSTOMER_ID: Required if your access to the customer account is through a manager account. Set it to the customer ID of the manager account. See Login Customer Id above for details.
gcloud run deploy google-ads-mcp \
--image us-central1-docker.pkg.dev/YOUR_PROJECT_ID/mcp-servers/google-ads-mcp:latest \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--set-env-vars="GOOGLE_PROJECT_ID=YOUR_PROJECT_ID,GOOGLE_ADS_DEVELOPER_TOKEN=YOUR_DEVELOPER_TOKEN,GOOGLE_ADS_MCP_OAUTH_CLIENT_ID=YOUR_CLIENT_ID,GOOGLE_ADS_MCP_OAUTH_CLIENT_SECRET=YOUR_CLIENT_SECRET,GOOGLE_ADS_MCP_BASE_URL=YOUR_BASE_URL,GOOGLE_ADS_MCP_JWT_SIGNING_KEY=YOUR_JWT_SIGNING_KEY,GOOGLE_ADS_MCP_STORAGE_TYPE=firestore,FASTMCP_HOST=0.0.0.0"Step 3: Configure MCP Client
Once deployed, update your MCP client configuration (refer to the docs at https://antigravity.google/docs/mcp) to use the Cloud Run URL.
{
"mcpServers": {
"google-ads-mcp": {
"httpUrl": "https://your-cloud-run-url.a.run.app/mcp"
}
}
}Try it out
Launch your MCP client. You should see google-ads-mcp listed in the
available servers.
Here are some sample prompts to get you started:
Ask what the server can do:
what can the ads-mcp server do?Ask about customers:
what customers do I have access to?Ask about campaigns
How many active campaigns do I have?How is my campaign performance this week?
Note about Customer ID
Your agent will need and ask for a customer id for most prompts. If you are moving between multiple customers, including the customer ID in the prompt may be simpler.
How many active campaigns do I have for customer id 1234567890Contributing
Contributions welcome! See the Contributing Guide. Project maintainers can find the Trusted Publishing and release procedure in the release guide.
Available Tools
3 toolscustomers_list_accessible_customersCustomers 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 declare readOnlyHint=true, which aligns with the description's read-only nature. The description adds value beyond annotations by noting that it returns only directly accessible customershare, implying a permission filter, and that the output is a list of IDs (though this is also in the output schema). It does not contradict 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 concise, with a brief purpose statement and a usage hint, followed by a return type section. It is front-loaded with the key action and avoids unnecessary 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 parameterless tool with a simple output (a list of strings), the description is fully sufficient. It explains what the tool does, when to use it, and what it returns. The output schema already documents the return type, so no additional return 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?
The tool has zero parameters, so there is no parameter semantics to clarify. The description correctly focuses on the output and usage context, which is appropriate for a parameterless tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns IDs of customers directly accessible by the authenticated user, with a specific verb ('Returns') and resource ('customers'). It is distinct from siblings like search_search and metadata_get_resource_metadata, as it lists customer IDs rather than performing search or fetching metadata.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent to use this tool first to discover customer IDs if the user hasn't provided one, and notes that most other tools require a valid customer ID. It does not explicitly mention when not to use it or name alternatives, but the guidance is clear enough for this context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
metadata_get_resource_metadataMetadata 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'). | |
| login_customer_id | No | Optional manager customer ID to use as the login-customer-id header. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation readOnlyHint=true already covers the safety profile, and the description complements it by disclosing the response contents (fields, metrics, segments) and the naming convention for metrics/segments. It also adds an operational trait: 'responses ... should be cached, as they don't change frequently'. 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 front-loaded with the core purpose and adds concise, actionable guidance. There is minor redundancy: the first sentence says 'including compatible metrics and segments' and the third sentence repeats that metrics and segments can be selected. Still, it is well-structured and every section adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a metadata-lookup tool with an output schema and readOnlyHint annotation, the description covers everything an agent needs: what the tool returns, naming conventions, mandatory usage before querying, and caching guidance. No significant gaps remain for correct 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?
The input schema already describes both parameters comprehensively (100% coverage), so the description need not repeat them. It adds a small amount of extra context with examples like 'campaign', 'ad_group', but this does not significantly exceed what the schema provides. 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 uses a specific verb ('Retrieves') and names a clear resource: the selectable, filterable, and sortable fields for a Google Ads resource, including metrics and segments. This clearly distinguishes the tool from the siblings: search_search executes queries, while this tool provides metadata for building them.
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 states when to use the tool: before constructing a query for the `search` tool, and it warns 'Do not guess fields, you MUST use this tool to discover them'. This gives the agent an unambiguous directive and contextual placement relative to the sibling search tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_searchSearch SearchCRead-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 | |
| login_customer_id | No | Optional manager customer ID to use as the login-customer-id header. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The only annotation is readOnlyHint=true, which already tells the agent this is a safe read operation. The description adds no additional behavioral context—nothing about pagination, limits, error handling, or response format. It fails to enrich the annotation-provided information.
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 only one sentence and is technically concise, but it is under-specified to the point of being nearly useless. It does not front-load critical information or structure the content in a way that helps an agent understand the tool's scope. The brevity is a deficiency, not a virtue.
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?
This is a 7-parameter tool with 3 required parameters, yet the description provides no context about what the tool actually accomplishes beyond a generic 'search'. It lacks any explanation of the query syntax, the relationship between fields and resource, or expected output. Given the complexity, the description is grossly incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, meaning all parameters have descriptions in the schema. The description adds no extra meaning beyond what the schema already provides, so the baseline of 3 applies. It does not compensate with any additional clarifications about parameter relationships or formatting.
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 verb ('Fetches data') and a resource ('Google Ads API') but is extremely vague about what kind of data or which resources are searchable. It does not differentiate from sibling tools like metadata_get_resource_metadata or customers_list_accessible_customers, making it unclear when this tool is the right choice.
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 on when to use this tool versus the siblings. No mention of alternatives, exclusions, or prerequisites. An agent has to infer that this is a general search tool, but the description gives no contextual hints about when it should be preferred.
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.
2 tool updates
v0.0.4- Changed
metadata_get_resource_metadata1 field changed- added
Input schema / properties / login_customer_idAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Optional manager customer ID to use as the login-customer-id header." +}
- Changed
search_search1 field changed- added
Input schema / properties / login_customer_idAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Optional manager customer ID to use as the login-customer-id header." +}
3 tool updates
v0.0.3- First observed
customers_list_accessible_customers - First observed
metadata_get_resource_metadata - First observed
search_search
TDQS
Scored across 3 tools
Each tool maps to a distinct concern: customer discovery, schema/metadata discovery, and data retrieval. There is no overlap in purpose or output type.
All names are snake_case and generally follow a {namespace}_{verb}_{object} pattern, but `search_search` is redundant and lacks an object, while the others include explicit objects. This is a minor inconsistency rather than a chaotic mix.
Three tools is the minimal viable set for a read-only Google Ads query server: list customers, discover fields, and run queries. Each tool is essential and there are no filler or redundant tools.
The core workflow is fully covered: get customer IDs, discover valid fields via metadata, then search using those fields. For a query-focused MCP server there are no dead ends; mutation endpoints are outside the apparent scope.
Maintenance
Related MCP Connectors
Google Ads MCP server — manage campaigns, keywords, and metrics.
MCP server for querying and analyzing data from ad platforms, analytics tools, and spreadsheets
Google Ads MCP server: 16 tools for reporting, campaigns, keywords, assets. Writes preview first.
Hosted MCP server for GA4, Google Ads and Search Console. Google OAuth, nothing to install.
Related MCP Servers
- AlicenseAqualityFmaintenanceA read-write MCP server for managing Google Ads campaigns, ad groups, keywords, and ads via natural language.122-
- FlicenseNot gradedqualityDmaintenanceA Google Ads API MCP server that enables searching and listing accessible customers via natural language queries.2-
- 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
- AlicenseNot gradedqualityBmaintenanceMCP server for Google Ads API that enables LLMs to search and query Google Ads accounts, retrieve resource metadata, and generate keyword ideas.Apache 2.0