Provides tools for accessing Google Ads Keyword Planner functionality, including keyword discovery, historical metrics analysis, and campaign forecasting capabilities.
Google Ads MCP Server
A Next.js App Router deployment that exposes a Model Context Protocol (MCP) server backed by the Google Ads Keyword Planner. The server provides three tools—get_keyword_ideas
, get_historical_metrics
, and get_forecast
—with secure OAuth, encrypted credential storage, in-flight validation, and lightweight rate limiting. It is optimised for Vercel (Node.js runtime) but runs locally with the same feature set.
Features
Next.js 15 App Router using strict TypeScript, ESLint, and Prettier.
MCP tools for keyword discovery, historical metrics, and forecasts.
Google OAuth 2.0 flow with AES-256-GCM encrypted refresh token storage.
KV persistence via Vercel KV with an automatic in-memory fallback for local development.
Zod validation for every tool input plus environment assertions.
Token bucket rate limiting (10 requests/minute per user/IP).
Structured logging & error mapping for predictable MCP responses.
Requirements
Node.js 18.18 or newer (Next.js 15 canary requires ≥18.18).
pnpm
ornpm
for dependency management.A Google Ads Manager account with API access.
Google Cloud OAuth client (type: Web application) authorised for the deployment URL.
Vercel KV database (or compatible Upstash REST endpoint).
Environment variables
Create a .env
file (or configure Vercel project secrets) that includes all variables from .env.example
.
Variable | Required | Description |
| ✅ | OAuth client ID created in Google Cloud Console. |
| ✅ | OAuth client secret that matches the client ID. |
| ✅ | Google Ads developer token approved for production. |
| ⚪️ | Optional manager account ID used for scoped access. |
| ✅ | Base64 encoded 32-byte key for AES-256-GCM. Generate with
. |
| ⚪️ | Vercel KV REST endpoint. Omit to use in-memory storage locally. |
| ⚪️ | Vercel KV REST token with read/write permissions. |
| ⚪️ | Optional read-only token for GET operations. |
| ✅ | Display name shown on the OAuth confirmation page. |
| ⚪️ | Optional explicit base URL. When omitted the server uses the incoming request origin. |
ℹ️ If any required variable is missing the server throws an explicit error at startup, ensuring you see actionable messages in local development and on Vercel logs.
Project structure
Getting started locally
The development server defaults to http://localhost:3000
. Ensure your Google OAuth client has that origin and callback (http://localhost:3000/api/auth/callback
) added to the authorised redirect URIs.
Running without Vercel KV
If KV_REST_API_URL
or KV_REST_API_TOKEN
is missing the server logs a warning and stores tokens in-memory. This is ideal for local testing but not for production because refresh tokens will be lost on redeploys.
OAuth flow
Direct the browser (or an HTTP client) to
/api/auth/start?userId=<USER>&customerId=<CUSTOMER_ID>
.Google prompts for consent with the
https://www.googleapis.com/auth/adwords
scope.On success Google redirects to
/api/auth/callback
. The server exchanges the code for tokens, encrypts the refresh token with AES-256-GCM, and persists it in KV.The callback endpoint renders a simple confirmation page. Tokens are now available to all MCP tools via the stored
userId
.
The state
parameter is encrypted to prevent tampering and includes the user/customer IDs plus a timestamp.
MCP tools
All tools share the same POST endpoint: POST /api/mcp
with JSON payload {"tool": "<name>", "input": { ... } }
. Responses follow the ToolResponse
shape ({ ok: true, data }
or { ok: false, error }
).
ping
Result:
get_keyword_ideas
get_historical_metrics
get_forecast
All tool inputs are validated by Zod. Errors return HTTP 400 and a structured payload:
Rate limiting & errors
Rate limiting: 10 requests per minute per user (falls back to IP if userId missing). Exceeding the budget returns
429
withcode: RATE_LIMIT_EXCEEDED
.Authentication errors: Missing or corrupt refresh tokens map to
AUTHENTICATION_ERROR
(HTTP 401).Permission issues: Google Ads permission denials map to
PERMISSION_DENIED
(HTTP 403).Quota problems: API quota issues map to
QUOTA_EXCEEDED
(HTTP 429).Unexpected failures: Return
500
withcode: UNKNOWN
but never leak secrets.
Structured logs (via console.log
/ console.error
) include tool name, user ID, duration, and error codes to help diagnose incidents quickly.
Deployment on Vercel
Push the repository to GitHub and create a Vercel project targeting this repo.
Set the production environment variables listed above. Remember to generate a strong
ENCRYPTION_KEY
and configure KV credentials.Deploy. Vercel automatically builds the Next.js app in the Node.js runtime.
After deployment, run the OAuth flow (
https://<app>.vercel.app/api/auth/start?...
) and confirm the callback stores the token (check logs or/api/mcp
ping).Smoke test each tool with
curl
or the MCP client using the production URL.
ChatGPT Developer Mode integration
Add a remote MCP server in ChatGPT using the following configuration:
Server URL:
https://<your-app>.vercel.app/api/mcp
Tools: Automatically discovered (
ping
,get_keyword_ideas
,get_historical_metrics
,get_forecast
).Auth flow: Run
/api/auth/start
in a browser before invoking any tool so the refresh token is available.
Example invocation in ChatGPT (after auth):
Expect a JSON array of keyword ideas with text, competition, and bid ranges.
Troubleshooting
Symptom | Resolution |
error on boot | Verify
matches
and the encryption key is 32 bytes base64. |
returns 400 | Both
and
must be present in the query string. |
Google callback lacks
| Ensure you append
(the start endpoint does this automatically). Remove the app from Google account permissions and retry. |
MCP tools return
| The stored refresh token may be corrupted or encrypted with an old key. Regenerate
, re-run OAuth, and redeploy. |
| Wait until the window resets (~60 seconds) or reduce tool frequency. |
from Google | Confirm the user has access to the specified
and the developer token is approved. |
Acceptance checklist
App Router structure with TypeScript, ESLint, Prettier, and strict mode.
OAuth start/callback routes using AES-256-GCM encrypted refresh tokens.
KV abstraction with Vercel + in-memory modes.
Google Ads helpers for keyword ideas, historical metrics, and forecasts.
MCP tools with validation, rate limiting, and error handling.
README covering setup, usage, deployment, and troubleshooting.
This server cannot be installed
hybrid server
The server is able to function both locally and remotely, depending on the configuration or use case.
Enables interaction with Google Ads through secure OAuth authentication to discover keyword ideas, analyze historical search metrics, and generate forecasts for advertising campaigns. Built as a Next.js application with encrypted credential storage and rate limiting.