@cesteral/gads-mcp
v1.3.0
Published
Google Ads MCP Server - Campaign entity management and reporting via Google Ads REST API v23
Maintainers
Readme
@cesteral/gads-mcp
Google Ads MCP Server - Campaign entity management and reporting via Google Ads REST API v23.
Purpose
Management and reporting server for Google Ads. Provides full CRUD operations on Google Ads campaign entities (campaigns, ad groups, ads, keywords, assets, budgets) and arbitrary GAQL query execution. Designed for AI agents to manage Google Ads campaigns programmatically through the Model Context Protocol.
Choose Your Path
- Self-host this connector when you want direct control of credentials, infrastructure, and Google Ads API access.
- Use Cesteral Intelligence when the workflow needs approvals before spend commits, credential brokering, auditability, and cross-platform execution.
Self-host quickstart | Compare OSS vs Cesteral Intelligence | Book a workflow demo
Features
- Per-session authentication via
SessionServiceStorepattern - OAuth2 refresh token auth using
X-GAds-*headers (developer token, client ID, client secret, refresh token) - OpenTelemetry instrumentation for traces and metrics
- Rate limiting via shared
RateLimiterclass - MCP protocol with Streamable HTTP transport (Hono)
- Structured output with
outputSchemaon all tools - GAQL query support for flexible read operations
MCP Tools
Read Tools
1. gads_gaql_search
Execute arbitrary GAQL queries against the Google Ads API.
Parameters:
customerId(string): Google Ads customer ID (no dashes)query(string): GAQL query stringpageSize(number, optional): Deprecated. UsemaxRowsinstead.pageToken(string, optional): Cursor for the next upstream page (different fromoffsetwhich slices the in-memory buffer)mode,columns,maxRows(optional): Bounded report-view params —modeis"summary"(default — headers + counts + 10-row preview) or"rows"(paginated rows page);columnsprojects to selected columns;maxRowscaps page size (default 10/50; hard cap 200).offsetis not supported here — paginate viapageToken.
2. gads_list_accounts
List all Google Ads customer accounts accessible to the authenticated user.
Parameters: None
3. gads_get_entity
Get a single Google Ads entity by type and ID.
Parameters:
entityType(string): Type of entity to retrievecustomerId(string): Google Ads customer IDentityId(string): The entity ID
4. gads_list_entities
List entities with optional GAQL filters and pagination.
Parameters:
entityType(string): Type of entities to listcustomerId(string): Google Ads customer IDfilters(object, optional): GAQL filter conditionspageSize(number, optional): Results per page (default 100, max 10000)pageToken(string, optional): Pagination tokenorderBy(string, optional): GAQL ORDER BY clause
5. gads_get_insights
Get performance insights for Google Ads entities using preset parameters. Convenience wrapper around GAQL.
Parameters:
customerId(string): Google Ads customer IDentityType(string): Entity type (campaign,adGroup,ad,keyword)entityId(string, optional): Filter to a specific entitydateRange(string): Date range preset (TODAY,YESTERDAY,LAST_7_DAYS,LAST_30_DAYS,THIS_MONTH,LAST_MONTH,LAST_90_DAYS)metrics(string[], optional): Custom metrics (defaults to impressions, clicks, cost_micros, conversions, ctr, average_cpc)limit(number, optional): Deprecated. UsemaxRowsinstead.mode,columns,offset,maxRows(optional): Bounded report-view params —modeis"summary"(default) or"rows";columnsprojects to selected columns;offsetpaginates;maxRowscaps page size (default 10/50; hard cap 200).
Write Tools
6. gads_create_entity
Create a new Google Ads entity via the :mutate API.
Parameters:
entityType(string): Type of entity to createcustomerId(string): Google Ads customer IDdata(object): Entity data fields
7. gads_update_entity
Update an existing entity with updateMask discipline.
Parameters:
entityType(string): Type of entity to updatecustomerId(string): Google Ads customer IDentityId(string): The entity IDdata(object): Fields to updateupdateMask(string): Comma-separated list of fields to update
8. gads_remove_entity
Remove an entity via the :mutate API (sets status to REMOVED).
Parameters:
entityType(string): Type of entity to removecustomerId(string): Google Ads customer IDentityId(string): The entity ID
9. gads_bulk_mutate
Execute multiple create/update/remove operations in a single API call.
Parameters:
entityType(string): Type of entities to mutatecustomerId(string): Google Ads customer IDoperations(array): Array of mutate operation objectspartialFailure(boolean, optional): Allow partial success (default: false)
10. gads_bulk_update_status
Batch update statuses for multiple entities.
Parameters:
entityType(string): Type of entities to updatecustomerId(string): Google Ads customer IDentityIds(string[]): Entity IDs to update (max 100)status(string):ENABLED,PAUSED, orREMOVED
11. gads_adjust_bids
Batch adjust ad group bids with safe read-modify-write pattern.
Parameters:
customerId(string): Google Ads customer IDadjustments(array): Array of bid adjustments (max 50), each withadGroupIdand optionalcpcBidMicros/cpmBidMicrosreason(string, optional): Reason for the bid adjustment (for audit trail)
Validate Tools
12. gads_validate_entity
Dry-run validate an entity payload via the Google Ads API with validateOnly: true.
Parameters:
entityType(string): Type of entity to validatecustomerId(string): Google Ads customer IDmode(string):createorupdatedata(object): Entity data to validateentityId(string, optional): Required for update modeupdateMask(string, optional): Required for update mode
Supported Entity Types
| Entity Type | GAQL Resource | Mutate Endpoint | Notes |
| ---------------- | -------------------- | ------------------------ | ----------------------------------------- |
| campaign | campaign | campaigns:mutate | Requires campaignBudget reference |
| adGroup | ad_group | adGroups:mutate | Requires campaign reference |
| ad | ad_group_ad | adGroupAds:mutate | Composite ID: {adGroupId}~{adId} |
| keyword | ad_group_criterion | adGroupCriteria:mutate | Composite ID: {adGroupId}~{criterionId} |
| campaignBudget | campaign_budget | campaignBudgets:mutate | Create before campaign |
| asset | asset | assets:mutate | Reusable text/image/sitelink/callout |
Entity Hierarchy: Customer > Campaign Budget > Campaign > Ad Group > Ad / Keyword
Current Status
Phase: Production-Ready
All tools are fully implemented using Google Ads REST API v23. Entity CRUD, GAQL queries, and bulk operations are operational via OAuth2 refresh token authentication.
Development
# Install dependencies
pnpm install
# Run in development mode
pnpm run dev:http
# Build
pnpm run build
# Start production server
pnpm run start
# Type check
pnpm run typecheck
# Run tests
pnpm run testEnvironment Variables
GADS_MCP_PORT: Server port (default: 3004)GADS_DEVELOPER_TOKEN: Google Ads developer token (required for stdio mode)GADS_CLIENT_ID: OAuth2 client ID (required for stdio mode)GADS_CLIENT_SECRET: OAuth2 client secret (required for stdio mode)GADS_REFRESH_TOKEN: OAuth2 refresh token (required for stdio mode)GADS_LOGIN_CUSTOMER_ID: Manager account ID (optional, for stdio mode)MCP_AUTH_MODE: Authentication mode -gads-headers(default),jwt, ornoneMCP_AUTH_SECRET_KEY: Required whenMCP_AUTH_MODE=jwt
Architecture
Key Components
GAdsHttpClient- HTTP client for Google Ads API v23 with retry logic and error parsingGAdsService- GAQL queries, account listing, and generic CRUD via :mutate APIGAdsRefreshTokenAuthAdapter- OAuth2 token caching with mutex for concurrent requestsGAdsHeadersAuthStrategy- Reads credentials from request headersSessionServiceStore- Per-session service instances keyed by session ID
Key Gotchas
customerIdmust be numeric with no dashes (e.g.,1234567890not123-456-7890)- Budget amounts are in micros (e.g.,
1000000= $1.00) campaignBudgetmust be created before the campaign that references itREMOVEDstatus is permanent — equivalent to deletegads_validate_entitycalls the real API withvalidateOnly: true(not client-side only)- Composite IDs for ads:
{adGroupId}~{adId}, for keywords:{adGroupId}~{criterionId}
Transport
- Streamable HTTP: MCP protocol via Hono +
@hono/mcp - Health check:
/healthendpoint
Contributing
See root CLAUDE.md for development guidelines, build system details, and monorepo conventions. See the root README for full architecture context.
Get Started
Self-host: Follow the deployment guide to run this server on your own infrastructure.
Cesteral Intelligence: Request access -- governed execution with credential brokering, approvals, audit, and multi-tenant access.
Book a workflow demo: See it in action with your own ad accounts.
Compare options: OSS connectors vs Cesteral Intelligence
License
Apache License 2.0 — see LICENSE for details. This package is part of Cesteral's open-source connector layer; managed hosting and higher-level governance features live outside this repository.
