Google Ads MCP server: Developer integration guide

The Model Context Protocol (MCP) is an open standard that lets large language models (LLMs) securely interact with external data and applications. The Google Ads MCP server provides a standardized bridge to the Google Ads API. It lets AI agents retrieve and analyze account data, create assets, upload videos, and manage labels by using natural language.

Community resources and support

Technical overview

Integrating the Google Ads MCP server removes the need to write custom code for Google Ads API authentication, resource fetching, data parsing, and supported asset or label mutations. The server exposes callable tools and reference resources (see Core capabilities) that an LLM can inspect and invoke.

Key specifications

  • Protocol: MCP (Model Context Protocol)
  • Mode: Read and partial mutate (asset creation, video uploads, and label management with propose-and-confirm validation, or configurable read-only mode)
  • Language: Python 3.10 or later
  • Transport: Standard input/output (stdio) or Streamable HTTP (streamable-http on Cloud Run)
  • Authentication: Application Default Credentials (OAuth 2.0 user credentials or service account) for local stdio, or OAuth 2.0 Web application credentials for remote HTTP

How the interaction loop works

  1. Request: You submit a prompt such as "How is my campaign performance this week?" or "Create a callout asset for our summer sale".
  2. Discovery: The LLM inspects its available tools and resources and selects a matching google-ads-mcp tool.
  3. Execution or dry-run validation: Read tools query the Google Ads API directly. Mutate tools first run in propose mode (validate_only=True) to validate inputs without committing changes (see Propose-and-confirm safety workflow).
  4. Context injection: The MCP server returns structured query results, or proposed change_items entries and a verification checksum digest, to the LLM's context window.
  5. Response and confirmation: The LLM presents an answer or asks you to confirm the proposed changes. After you approve, the LLM calls the mutate tool again with validate_only=False and the matching checksum value to commit the change.

Get started

Follow these steps to configure and run the Google Ads MCP server locally. To deploy a shared remote service instead, see Deployment on Google Cloud.

Prerequisites

Before you configure the server, complete the following prerequisites in your local environment and the Google Cloud console:

  • Google Cloud project: Create or select a Google Cloud project with the Google Ads API enabled. Enabling the API grants Test access for testing read and mutate workflows against test accounts. To access production accounts, check the Google Ads API overview page for Explorer, Basic, or Standard access, or apply for one of these access levels. Otherwise, production calls fail with an AuthorizationError.CLOUD_PROJECT_NOT_APPROVED_FOR_PRODUCTION error. Google sunset developer tokens (GOOGLE_ADS_DEVELOPER_TOKEN) on September 9, 2026. The Google Cloud project that owns your OAuth client or service account determines your API access level.
  • Credentials: Local stdio mode authenticates with Application Default Credentials (ADC) from an OAuth 2.0 client secret JSON file or a service account in your Cloud project. Set the GOOGLE_CLOUD_PROJECT environment variable when needed to specify your default quota or ADC project. Remote streamable-http deployments instead require an OAuth 2.0 Web application Client ID and Client secret (see Deploy to Google Cloud Run).
  • Local software (for stdio mode): Install Python 3.10 or later, pipx, and the gcloud command-line tool (used to generate user ADC files).

Configuration

  1. Generate Application Default Credentials (ADC) using an OAuth client from your API-enabled Google Cloud project and include the Google Ads API scope:

    gcloud auth application-default login \
      --scopes=https://www.googleapis.com/auth/adwords,https://www.googleapis.com/auth/cloud-platform \
      --client-id-file=PATH_TO_CLIENT_SECRET_JSON
    

    Replace the following:

    • PATH_TO_CLIENT_SECRET_JSON: the path to your OAuth 2.0 client secret JSON file.

    This command prints Credentials saved to file: [PATH_TO_CREDENTIALS_JSON] (such as ~/.config/gcloud/application_default_credentials.json on Linux and macOS). To authenticate with a service account instead, skip this step and point GOOGLE_APPLICATION_CREDENTIALS to your service account key JSON file, or pass --impersonate-service-account to gcloud auth application-default login.

  2. Add the server to your host's MCP configuration file (such as ~/.gemini/config/mcp_config.json, ~/.gemini/settings.json, or ~/.claude/settings.json):

    {
      "mcpServers": {
        "google-ads-mcp": {
          "command": "pipx",
          "args": [
            "run",
            "--spec",
            "google-ads-mcp==0.0.6",
            "google-ads-mcp"
          ],
          "env": {
            "GOOGLE_CLOUD_PROJECT": "PROJECT_ID",
            "GOOGLE_APPLICATION_CREDENTIALS": "PATH_TO_CREDENTIALS_JSON"
          }
        }
      }
    }
    

    Replace the following:

    • PROJECT_ID: your Google Cloud project ID.
    • PATH_TO_CREDENTIALS_JSON: the path to the ADC JSON file printed in step 1, or to your service account key JSON file. You can omit GOOGLE_APPLICATION_CREDENTIALS when using the default gcloud ADC file location.

    To access client accounts through a manager account, set GOOGLE_ADS_LOGIN_CUSTOMER_ID (10 digits, without hyphens) in env, or pass the login_customer_id parameter on individual tool calls.

Optional: Equip your agent with skills and the Developer Assistant

The Google Ads MCP server gives your AI client live access to account reporting data along with asset creation, video upload, and label management tools. Pair the MCP server with the following companion tools to help your agent construct valid Google Ads Query Language (GAQL) queries and diagnose account performance shifts. These tools also generate client library code, such as scripts to link created assets to campaigns or perform other unsupported mutations:

  • Google Ads API agent skills: Portable workflow modules (including google-ads-api-mcp-setup, google-ads-api-account-diagnostics, and google-ads-api-quickstart) that help your agent use the Google Ads MCP server with lower token overhead. Run the following command to install them (requires Node.js), or see the Google Ads API agent skills guide for Antigravity, Claude Code, Codex, and Cursor setup:

    npx skills add google/skills/skills/ads
    
  • Google Ads API Developer Assistant: A modular plugin for Google Antigravity and Claude Code that provides local Protobuf schema inspection, GAQL validation, client library code generation, and offline conversion troubleshooting. Read What is the Google Ads API Developer Assistant? or follow the installation guide.

Core capabilities

The following sections describe the server's read tools, partial mutate tools, and reference resources. Starting in v0.0.6, tools register by default with their category namespace prefix (such as search_search). When upgrading prompts or allowlists from unprefixed releases, update tool names or set an empty prefix ("") in tools_config.yaml (see Configure tool namespaces and read-only mode).

Read tools

  • customers_list_accessible_customers (tool list_accessible_customers): Returns the Google Ads customer IDs directly accessible to the authenticated user.
  • search_search (tool search): Builds and runs GAQL SearchStream queries from structured parameters (customer_id, resource, and fields, plus optional conditions, orderings, limit, and login_customer_id) rather than a raw GAQL string. Every query appends PARAMETERS omit_unselected_resource_names=true to fetch resource attributes, metrics, segments, budgets, and status cleanly.
  • metadata_get_resource_metadata (tool get_resource_metadata): Retrieves selectable, filterable, and sortable attributes, metrics, and segments for a Google Ads API resource type (for example, "campaign"). Use this metadata to discover valid query fields—including metrics and segments added in minor releases such as v26.2—before calling the search_search tool.

Mutate tools (partial support)

  • assets_create_asset (tool create_asset): Creates standalone Google Ads assets with dedicated parameters for TEXT, IMAGE, YOUTUBE_VIDEO, SITELINK, CALLOUT, and STRUCTURED_SNIPPET asset types. Pass the extra_params dictionary for other mutable AssetService types (such as PRICE, PROMOTION, CALL, or BUSINESS_MESSAGE), and include root-level final_urls alongside sitelink_link_text for SITELINK assets. Local file paths (image_asset_path) work in local stdio mode only. For remote HTTP deployments, pass the base64-encoded image_asset_data parameter with image_asset_mime_type set to IMAGE_PNG, IMAGE_JPEG, or IMAGE_GIF (up to 20 MB).
  • assets_upload_video_asset (tool upload_video_asset): Uploads a local video file (.3gp, .avi, .flv, .mkv, .mov, .mp4, .mpeg, .mpg, .ogg, .webm, or .wmv) to YouTube through the Google Ads API in local stdio mode only. Both video_title and video_description are required parameters, and privacy defaults to UNLISTED (or PUBLIC on advertiser-owned brand channels with user OAuth). This tool returns a Google Ads video_upload_id value (and resource name), not the 11-character YouTube video_id. Query you_tube_video_upload with the search_search tool (filtering by you_tube_video_upload.video_upload_id) until you_tube_video_upload.state = 'PROCESSED'. Then pass you_tube_video_upload.video_id as the youtube_video_id parameter to assets_create_asset (asset_type="YOUTUBE_VIDEO").
  • labels_manage_labels (tool manage_labels): Creates, updates, and removes account labels, including name, description, and hex background color.
  • labels_manage_label_associations (tool manage_label_associations): Supports CREATE and REMOVE label association operations (UPDATE is not supported) on CAMPAIGN, CUSTOMER, AD_GROUP, and AD_GROUP_CRITERION resources. For CUSTOMER resources, resource_id is optional and defaults to customer_id. Pass a composite {ad_group_id}~{criterion_id} ID for AD_GROUP_CRITERION resources, and remove associations by passing either resource_id and label_id or association_resource_name. Ad-level AD_GROUP_AD labels are not supported.

Reference resources

The server exposes four read-only MCP resources that remain mounted regardless of your tools_config.yaml settings:

  • resource://discovery-document: JSON REST discovery overview of Google Ads API resources, service methods, and schemas. It complements the metadata_get_resource_metadata tool, which returns selectable, filterable, and sortable GAQL query fields.
  • resource://metrics: HTML reference documentation for Google Ads API metrics.
  • resource://segments: HTML reference documentation for Google Ads API segments.
  • resource://release-notes: HTML Google Ads API release notes covering version changes and new features.

Propose-and-confirm safety workflow

Every mutate tool (assets_create_asset, assets_upload_video_asset, labels_manage_labels, and labels_manage_label_associations) enforces a two-step propose-and-confirm workflow to help prevent unintended account modifications:

  1. Propose (validate_only=True, default): Validates inputs without committing changes. The asset and label tools execute a live Google Ads API validate_only dry run. Because YouTubeVideoUploadService has no dry-run mode, assets_upload_video_asset instead validates the local file and binds its size and modification timestamp. Each tool returns human-readable change_items entries and a stateless SHA-256 checksum digest bound to the customer_id parameter and request payload.
  2. Confirm (validate_only=False): After presenting the change_items list and receiving your approval, the agent calls the tool again with validate_only=False, the identical customer_id parameter and arguments, and the checksum value from step 1. The server rejects any missing or mismatched checksum before mutating the account.

Configure tool namespaces and read-only mode

The server bundles a default tools_config.yaml file with all five tool categories (customers, search, metadata, labels, and assets) enabled. Customize tools_config.yaml to selectively enable or disable individual tools or namespaces, change or remove namespace prefixes, or enforce a strictly read-only deployment.

At startup, the server resolves tools_config.yaml in the following order:

  1. An explicit path in the GOOGLE_ADS_MCP_TOOLS_CONFIG environment variable (recommended for local stdio hosts, whose working directory can differ from your project folder).
  2. A tools_config.yaml file in the server's current working directory.
  3. The default tools_config.yaml file bundled with the package.

If GOOGLE_ADS_MCP_TOOLS_CONFIG points to a missing file, or if any resolved configuration file is invalid, the server raises an error at startup instead of falling back to defaults.

The following minimal tools_config.yaml file enforces a strictly read-only deployment:

namespaces:
  customers: true
  search: true
  metadata: true
  labels: false
  assets: false

The following tools_config.yaml file customizes prefixes and filters individual tools (for example, exposing the base64 create_asset tool on Cloud Run while disabling the local-only upload_video_asset tool):

namespaces:
  # Default prefix ("customers_list_accessible_customers")
  customers: true

  # Empty prefix mounts unprefixed tool names ("search")
  search: ""

  # Custom prefix ("schema_get_resource_metadata")
  metadata: "schema"

  # Enable only specific tools in a multi-tool category
  assets:
    enabled_tools:
      - create_asset

Sample prompts to start

Try the following prompts in your MCP client after connecting the server.

Ask what the server can do

What can the google-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?
Give me a report of the top spending campaigns split by device category over the last 7 days for account 1234567890

Create assets, upload videos, and manage labels

Create a callout asset with the text "Free Shipping" for account 1234567890
Upload /path/to/promo.mp4 with title "Summer Sale" and description "Summer promo video" for account 1234567890
Create a label named "Q4 Promo" with background color #34A853 and apply it to campaign 9876543210 in account 1234567890

Deployment on Google Cloud

To share the MCP server across multiple agents or run it as a web service, host it on Google Cloud Run or another cloud infrastructure provider instead of running it locally.

Prerequisites

  1. A Google Cloud project with the Google Ads API enabled (see Prerequisites for production access requirements).
  2. The gcloud command-line tool installed, authenticated, and configured with an active project:

    gcloud config set project PROJECT_ID
    

    Replace the following:

    • PROJECT_ID: your Google Cloud project ID.

Build and push a Docker image

Use Cloud Build to build and push the container image to Artifact Registry without installing Docker locally:

  1. Create a repository in Artifact Registry:

    gcloud artifacts repositories create mcp-servers \
      --repository-format=docker --location=us-central1
    
  2. Build and submit the image from a release tag in the GitHub repository (or from . in a local checkout if you customized Dockerfile or tools_config.yaml):

    gcloud builds submit https://github.com/googleads/google-ads-mcp \
      --git-source-revision=v0.0.6 \
      --tag=us-central1-docker.pkg.dev/PROJECT_ID/mcp-servers/google-ads-mcp:v0.0.6
    

    Replace the following:

    • PROJECT_ID: your Google Cloud project ID.

    Rebuild and redeploy the image whenever you update google-ads-mcp or upgrade the bundled google-ads Python client library for new Google Ads API releases (such as v26.2).

Deploy to Google Cloud Run

Configure the following environment variables and secrets for your Cloud Run service:

  • GOOGLE_ADS_MCP_OAUTH_CLIENT_ID: The OAuth 2.0 Web application Client ID from your API-enabled Google Cloud project for application-level OAuth authentication. Complete the following OAuth configuration steps:
    • Add the authorized redirect URIs for any AI clients that you plan to connect (such as https://claude.ai/api/mcp/auth_callback, https://chatgpt.com/connector_platform_oauth_redirect, or https://antigravity.google/oauth-callback).
    • Add the https://www.googleapis.com/auth/adwords scope to the OAuth consent screen under APIs & Services > OAuth consent screen > Data Access (Add or remove scopes).
    • If your OAuth consent screen publishing status is set to Testing (the default), add the Google Accounts connecting to the MCP server as Test users under APIs & Services > OAuth consent screen > Audience (Test users > + Add users).
  • GOOGLE_ADS_MCP_OAUTH_CLIENT_SECRET: The OAuth Client secret corresponding to your OAuth Client ID.
  • GOOGLE_ADS_MCP_BASE_URL: The public base URL of your MCP server (for example, https://google-ads-mcp-xyz-uc.a.run.app). Cloud Run assigns this URL during initial deployment, so deploy without this variable first and update the service afterward.
  • GOOGLE_ADS_MCP_JWT_SIGNING_KEY (recommended for multi-instance Cloud Run): A persistent secret that signs FastMCP JWTs across container restarts and horizontal scaling.
  • GOOGLE_ADS_MCP_STORAGE_TYPE (recommended for multi-instance Cloud Run): Persistent backend for OAuth client registrations and tokens (redis with GOOGLE_ADS_MCP_STORAGE_REDIS_URL, or firestore). Because the stock v0.0.6 Dockerfile installs only the in-memory backend, install py-key-value-aio[redis] or .[firestore] in a custom Dockerfile first. Using firestore also requires a Firestore database and the roles/datastore.user IAM role on the Cloud Run service account. For single-instance testing with in-memory storage, pass --max-instances=1.
  • GOOGLE_ADS_LOGIN_CUSTOMER_ID (optional): Default 10-digit manager customer ID (without hyphens) used when tool calls omit the login_customer_id parameter.
  • GOOGLE_ADS_MCP_TOOLS_CONFIG (optional): Container path to a custom tools_config.yaml file (for example, mounted from Secret Manager at /etc/mcp/tools_config.yaml to enforce read-only mode without rebuilding the image). See Configure tool namespaces and read-only mode.

Store GOOGLE_ADS_MCP_OAUTH_CLIENT_SECRET and GOOGLE_ADS_MCP_JWT_SIGNING_KEY in Secret Manager and deploy the service to Google Cloud Run:

gcloud run deploy google-ads-mcp \
  --image=us-central1-docker.pkg.dev/PROJECT_ID/mcp-servers/google-ads-mcp:v0.0.6 \
  --platform=managed \
  --region=us-central1 \
  --allow-unauthenticated \
  --set-env-vars="GOOGLE_ADS_MCP_OAUTH_CLIENT_ID=CLIENT_ID" \
  --set-secrets="GOOGLE_ADS_MCP_OAUTH_CLIENT_SECRET=MCP_OAUTH_CLIENT_SECRET:latest,GOOGLE_ADS_MCP_JWT_SIGNING_KEY=MCP_JWT_SIGNING_KEY:latest"

After Cloud Run completes the deployment, retrieve the assigned service URL and update the service with the GOOGLE_ADS_MCP_BASE_URL environment variable:

gcloud run services update google-ads-mcp \
  --region=us-central1 \
  --update-env-vars="GOOGLE_ADS_MCP_BASE_URL=https://CLOUD_RUN_SERVICE_URL"

Replace the following:

  • PROJECT_ID: your Google Cloud project ID.
  • CLIENT_ID: your OAuth 2.0 Web application Client ID.
  • MCP_OAUTH_CLIENT_SECRET: the Secret Manager secret name storing your OAuth 2.0 Client secret.
  • MCP_JWT_SIGNING_KEY: the Secret Manager secret name storing your JWT signing key.
  • CLOUD_RUN_SERVICE_URL: the hostname assigned to your Cloud Run service (for example, google-ads-mcp-xyz-uc.a.run.app).

Authentication and security model

Deploying with --allow-unauthenticated disables Cloud Run's infrastructure IAM check (roles/run.invoker) so external AI clients can connect without Google Cloud service account tokens. Authentication is delegated to the application layer instead:

  • When GOOGLE_ADS_MCP_OAUTH_CLIENT_ID and GOOGLE_ADS_MCP_OAUTH_CLIENT_SECRET are set, the server enforces Google OAuth 2.0 on every request and returns a 401 Unauthorized HTTP status code to unauthenticated callers. Every tool call executes under the authenticated caller's OAuth identity.
  • Omitting --allow-unauthenticated requires callers to pass Google Cloud OIDC identity tokens with every request. Standard AI clients (such as Claude and ChatGPT) use end-user OAuth rather than Google Cloud IAM tokens, so direct connections require --allow-unauthenticated paired with application-level OAuth.

Configure the MCP client

After deployment, configure your MCP client with the Cloud Run service URL. Because the server enforces OAuth 2.0, your client must support the MCP OAuth flow or supply an authorized Bearer token:

  • OAuth-enabled clients: In clients that support MCP OAuth discovery (such as Antigravity), connecting triggers a Google sign-in prompt to grant the https://www.googleapis.com/auth/adwords scope (shown as .../auth/adwords in the Google Cloud console).
  • Third-party AI platforms (Claude, ChatGPT): In your client's connector settings, add a custom connector pointing to your service URL with the /mcp path (for example, https://google-ads-mcp-xyz-uc.a.run.app/mcp). Select OAuth 2.0 authentication with your OAuth Client ID and Client secret, and confirm that the client's callback URI is in your OAuth client's authorized redirect URIs.
  • Clients without OAuth support: Clients that don't support HTTP OAuth flows receive a 401 Unauthorized HTTP status code. For those clients, use the local stdio configuration instead.

The following example configures the gemini command-line tool in ~/.gemini/settings.json (for Google Antigravity in ~/.gemini/config/mcp_config.json, replace "httpUrl" with "serverUrl" or "url"):

{
  "mcpServers": {
    "google-ads-mcp": {
      "httpUrl": "https://CLOUD_RUN_SERVICE_URL/mcp"
    }
  }
}

Replace the following:

  • CLOUD_RUN_SERVICE_URL: the hostname assigned to your Cloud Run service (for example, google-ads-mcp-xyz-uc.a.run.app).

Next steps