This repo contains the source code for running an MCP server that interacts with the Google Ads API.
The server uses the Google Ads API to provide several Tools and Resources for use with LLMs and AI agents.
search: Retrieves information about the Google Ads account using GAQL.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.create_asset: Creates Google Ads assets (TEXT, IMAGE, YOUTUBE_VIDEO, SITELINK, CALLOUT, STRUCTURED_SNIPPET, and other asset types via extra_params). Note: image_asset_path is supported in local stdio mode only; use base64 image_asset_data for remote HTTP deployments.upload_video_asset: Uploads a local video file to YouTube via the Google Ads API using a background task so it can be referenced by video assets (supported in local stdio mode only).manage_labels: Creates, updates, and removes account labels.manage_label_associations: Creates and removes label associations on CAMPAIGN, CUSTOMER, AD_GROUP, and AD_GROUP_CRITERION resources.All write/mutate tools (create_asset, upload_video_asset, manage_labels, and manage_label_associations) enforce a two-step Propose & Confirm safety workflow:
validate_only=True, default): Validates the operation (including a Google Ads API validate_only dry run where supported) without committing changes, returning human-readable change_items and a cryptographic checksum bound to the customer ID and parameters.validate_only=False): Requires passing the exact same parameters and customer_id together with the checksum returned in step 1 after explicit user approval. Any missing or mismatched checksum is rejected before mutating the account.The Google Ads MCP server uses 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. For strictly read-only deployments, set labels: false and assets: false in your tools_config.yaml. To customize your installation, the server resolves the configuration in the following order:
GOOGLE_ADS_MCP_TOOLS_CONFIG environment variable.tools_config.yaml file in the current working directory.tools_config.yaml bundled 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.
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: true
# Option 4: Disable write/mutate categories for a strictly read-only server
labels: false
assets: false
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.Setup involves the following steps:
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-mcp
Follow the instructions to enable the following APIs in your Google Cloud project:
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 to http://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, or memory).GOOGLE_ADS_MCP_STORAGE_PATH: (Optional) Directory path for filetree persistent storage.GOOGLE_ADS_MCP_STORAGE_REDIS_URL: (Optional) Redis URL for redis persistent storage.GOOGLE_ADS_MCP_STORAGE_FIRESTORE_PROJECT: (Optional) Google Cloud project for firestore persistent storage. Defaults to the project inferred from Application Default Credentials. Setting it selects the firestore backend even if GOOGLE_ADS_MCP_STORAGE_TYPE is unset.GOOGLE_ADS_MCP_STORAGE_FIRESTORE_DATABASE: (Optional) Firestore database name for firestore persistent 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 to true to 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).
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=all
The 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 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.6,<5) paired with mcp[cli]>=2.0.0,<3. 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 major 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_ads
For 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:
assets_create_assetassets_upload_video_assetcustomers_list_accessible_customerslabels_manage_label_associationslabels_manage_labelsmetadata_get_resource_metadatasearch_searchConfigure 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/adwords
Check out Manage OAuth Clients for how to create an OAuth client.
Here are some sample gcloud commands you might find useful:
YOUR_CLIENT_JSON_FILE.shell
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_FILE
shell
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]
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.
Add the server to your MCP client's configuration. Below are examples for popular clients.
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.
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 serverUrl for a
Streamable HTTP server. Do not use the older httpUrl key. Server-side
credentials belong in the server process, not in this client configuration.
```json
{
"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. 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_JSON with the path you copied in the previous
step.
We also recommend that you add a GOOGLE_CLOUD_PROJECT attribute to the
env object. Replace YOUR_PROJECT_ID in the following example with the
project ID of your
Google Cloud project.
json
{
"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"
}
}
}
}
Option 3: the Python client library method
json
{
"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"
}
}
}
}
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:
json
{
"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_LOGIN_CUSTOMER_ID": "YOUR_MANAGER_CUSTOMER_ID"
}
}
}
}
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).
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).
gcloud CLI installed, authenticated, and active project set.
shell
gcloud config set project YOUR_PROJECT_IDYou can use Cloud Build to build and push the image to Artifact Registry without needing Docker installed locally.
shell
gcloud artifacts repositories create mcp-servers --repository-format=docker --location=us-central1shell
gcloud builds submit --tag us-central1-docker.pkg.dev/YOUR_PROJECT_ID/mcp-servers/google-ads-mcp:latest .
Replace YOUR_PROJECT_ID with your Google Cloud project ID.Make sure to set the required environment variables:
GOOGLE_PROJECT_ID: Your Google Cloud project ID.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 to firestore to use Firestore through Application Default Credentials, which needs no VPC connector, or to redis along with GOOGLE_ADS_MCP_STORAGE_REDIS_URL.Using firestore requires three things: build the image with the extra
installed (change the Dockerfile to uv pip install --system .[firestore]),
create a Firestore database in the project, since one is not provisioned
automatically, and grant the Cloud Run service account roles/datastore.user.
Note that entries are not expired automatically: the store filters expired
entries on read but never deletes them, and expires_at is 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 to 0.0.0.0 to 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_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"
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"
}
}
}
Launch your MCP client. You should see google-ads-mcp listed in the
available servers.
Here are some sample prompts to get you started:
what can the ads-mcp server do?
what customers do I have access to?
How many active campaigns do I have?
How is my campaign performance this week?
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 1234567890
Contributions welcome! See the Contributing Guide. Project maintainers can find the Trusted Publishing and release procedure in the release guide.
| 日期 | 榜单 | 排名 | 周期新增 | 总 STAR |
|---|