@channel47/google-ads-mcp 1.0.8 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,22 +5,23 @@
5
5
 
6
6
  MCP server for Google Ads API access via GAQL (Google Ads Query Language). Built by a practitioner managing 25+ ad accounts daily — not a demo.
7
7
 
8
- Part of [Channel 47](https://channel47.dev), the open-source ecosystem of profession plugins for Claude Code. [Get the newsletter](https://channel47.dev/subscribe) for weekly skill breakdowns from production use.
8
+ Part of [channel47](https://channel47.dev), the open-source ecosystem of profession plugins for Claude Code. [Get the newsletter](https://channel47.dev/subscribe) for weekly skill breakdowns from production use.
9
9
 
10
- ## Overview
10
+ ## What It Does
11
11
 
12
- This is a Model Context Protocol (MCP) server that provides tools for querying and mutating Google Ads data using GAQL. It's designed to work seamlessly with Claude Code and other MCP-compatible clients.
12
+ - **List accounts** accessible under your MCC or individual credentials
13
+ - **Query anything** with raw GAQL — campaigns, ad groups, keywords, search terms, assets, any resource
14
+ - **Mutate entities** — campaigns, ad groups, ads, keywords, budgets, assets with dry-run safety
15
+ - **Resources and prompts** — bundled GAQL reference docs and operation templates
13
16
 
14
17
  ## Installation
15
18
 
16
19
  ### For Claude Code Plugin Users
17
20
 
18
- This package is bundled with the [media-buyer Claude Code plugin](https://channel47.dev). No manual installation required.
21
+ Bundled with the [media-buyer plugin](https://github.com/channel47/plugins). No manual install required.
19
22
 
20
23
  ### Standalone Use
21
24
 
22
- For use with other MCP clients or standalone testing:
23
-
24
25
  ```bash
25
26
  npx @channel47/google-ads-mcp@latest
26
27
  ```
@@ -34,8 +35,6 @@ google-ads-mcp
34
35
 
35
36
  ## Configuration
36
37
 
37
- Set these environment variables before running:
38
-
39
38
  ### Required
40
39
 
41
40
  | Variable | Description |
@@ -51,6 +50,30 @@ Set these environment variables before running:
51
50
  |----------|-------------|
52
51
  | `GOOGLE_ADS_LOGIN_CUSTOMER_ID` | MCC Account ID (10 digits, no dashes) |
53
52
  | `GOOGLE_ADS_DEFAULT_CUSTOMER_ID` | Default account ID for queries |
53
+ | `GOOGLE_ADS_READ_ONLY` | Set to `true` to hide the mutate tool entirely — query and list only |
54
+
55
+ ### MCP Config Example
56
+
57
+ ```json
58
+ {
59
+ "mcpServers": {
60
+ "google-ads": {
61
+ "command": "npx",
62
+ "args": ["-y", "@channel47/google-ads-mcp@latest"],
63
+ "env": {
64
+ "GOOGLE_ADS_DEVELOPER_TOKEN": "your-developer-token",
65
+ "GOOGLE_ADS_CLIENT_ID": "your-client-id",
66
+ "GOOGLE_ADS_CLIENT_SECRET": "your-client-secret",
67
+ "GOOGLE_ADS_REFRESH_TOKEN": "your-refresh-token",
68
+ "GOOGLE_ADS_LOGIN_CUSTOMER_ID": "1234567890",
69
+ "GOOGLE_ADS_READ_ONLY": "true"
70
+ }
71
+ }
72
+ }
73
+ }
74
+ ```
75
+
76
+ Remove `GOOGLE_ADS_READ_ONLY` or set to `false` to enable the mutate tool.
54
77
 
55
78
  ## Tools
56
79
 
@@ -233,89 +256,28 @@ Campaign creation requires specific fields since Google Ads API v19.2 (September
233
256
  - `target_impression_share` - Target impression share
234
257
  - `bidding_strategy` - Reference to portfolio bidding strategy
235
258
 
236
- ## Resources & Prompts
237
-
238
- The server provides:
239
- - **Resources**: GAQL reference documentation accessible via MCP resources
240
- - **Prompts**: Templates for common Google Ads operations
241
-
242
- ## Usage with Claude Code
243
-
244
- This server is designed to work with the [media-buyer plugin](https://github.com/channel47/channel47), which provides:
245
-
246
- - **Skills** for campaign building, creative testing, and account audits
247
- - **PreToolUse Hook** that validates mutations before execution
248
- - **Reference docs** with GAQL patterns, ad copy formulas, and performance benchmarks
249
-
250
- The plugin ensures Claude consults domain knowledge before executing queries, preventing hallucinated GAQL.
251
-
252
259
  ## Development
253
260
 
254
- ### Prerequisites
255
-
256
- - Node.js 18 or higher
257
- - Google Ads API access (Developer Token)
258
- - OAuth 2.0 credentials from Google Cloud
259
-
260
- ### Setup
261
-
262
261
  ```bash
263
262
  git clone https://github.com/channel47/mcps.git
264
- cd mcps/google-ads
265
- npm install
266
- ```
267
-
268
- ### Testing
269
-
270
- ```bash
271
- npm test
272
- ```
273
-
274
- ### Running Locally
275
-
276
- ```bash
277
- npm start
263
+ cd mcps
264
+ npm install # workspaces — installs all servers
265
+ npm test # runs all server tests
278
266
  ```
279
267
 
280
- ## Architecture
281
-
282
- **Minimal Design:**
283
- - ~200 lines of server code
284
- - 3 core tools (list, query, mutate)
285
- - OAuth 2.0 authentication
286
- - Resources for GAQL reference
287
- - Prompts for common patterns
288
-
289
- **Security:**
290
- - Dry-run mode enabled by default for mutations
291
- - Environment-based credential management
292
- - Input validation for all operations
268
+ 3 core tools. Dry-run by default. OAuth 2.0 with environment-based credentials.
293
269
 
294
- ## Contributing
295
-
296
- Contributions welcome! Please:
297
-
298
- 1. Fork the repository
299
- 2. Create a feature branch
300
- 3. Make your changes with tests
301
- 4. Submit a pull request
270
+ Pairs with the [media-buyer plugin](https://github.com/channel47/plugins), which adds skills, mutation validation hooks, and GAQL reference docs on top of this server.
302
271
 
303
272
  ## Links
304
273
 
305
- - [Channel 47](https://channel47.dev) — open-source profession plugins for Claude Code
306
- - [Build Notes Newsletter](https://channel47.dev/subscribe) — weekly skill breakdowns from production use
307
- - [Media Buyer Plugin](https://github.com/channel47/channel47) — the full paid-search toolkit this MCP powers
274
+ - [channel47](https://channel47.dev) — open-source profession plugins for Claude Code
275
+ - [Build Notes](https://channel47.dev/subscribe) — weekly skill breakdowns from production use
276
+ - [Media Buyer Plugin](https://github.com/channel47/plugins) — the paid-search toolkit this MCP powers
308
277
  - [NPM Package](https://www.npmjs.com/package/@channel47/google-ads-mcp)
309
- - [Google Ads API Documentation](https://developers.google.com/google-ads/api/docs/start)
310
- - [GAQL Reference](https://developers.google.com/google-ads/api/docs/query/overview)
311
- - [Model Context Protocol](https://modelcontextprotocol.io)
278
+ - [Google Ads API](https://developers.google.com/google-ads/api/docs/start) / [GAQL Reference](https://developers.google.com/google-ads/api/docs/query/overview)
279
+ - [X](https://x.com/ctrlswing) / [LinkedIn](https://www.linkedin.com/in/jackson-d-9979a7a0/) / [GitHub](https://github.com/channel47)
312
280
 
313
281
  ## License
314
282
 
315
- MIT - See [LICENSE](LICENSE) file for details.
316
-
317
- ## Support
318
-
319
- For issues or questions:
320
- - Plugin-related: [Plugin Repository Issues](https://github.com/channel47/channel47/issues)
321
- - Server-related: [Server Repository Issues](https://github.com/channel47/mcps/issues)
283
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@channel47/google-ads-mcp",
3
- "version": "1.0.8",
3
+ "version": "1.1.1",
4
4
  "description": "Google Ads MCP Server - Query and mutate Google Ads data using GAQL",
5
5
  "main": "server/index.js",
6
6
  "bin": {
package/server/index.js CHANGED
@@ -26,7 +26,7 @@ import { getPromptsList, renderPrompt } from './prompts/templates.js';
26
26
 
27
27
  // Server metadata
28
28
  const SERVER_NAME = 'google-ads-mcp';
29
- const SERVER_VERSION = '1.0.0';
29
+ const SERVER_VERSION = '1.1.1';
30
30
 
31
31
  // Validate environment on startup
32
32
  const { valid, missing } = validateEnvironment();
@@ -50,8 +50,11 @@ const server = new Server(
50
50
  }
51
51
  );
52
52
 
53
+ // Read-only mode: set GOOGLE_ADS_READ_ONLY=true to disable mutate tool
54
+ const READ_ONLY = process.env.GOOGLE_ADS_READ_ONLY === 'true';
55
+
53
56
  // Tool definitions
54
- const TOOLS = [
57
+ const ALL_TOOLS = [
55
58
  {
56
59
  name: 'list_accounts',
57
60
  description: 'List all accessible Google Ads accounts under the authenticated user or MCC. Use this first to find account IDs before running other tools.',
@@ -143,6 +146,12 @@ For IMAGE/VIDEO assets, use 'image_file_path' or 'video_file_path' with absolute
143
146
  }
144
147
  ];
145
148
 
149
+ const TOOLS = READ_ONLY ? ALL_TOOLS.filter(t => t.name !== 'mutate') : ALL_TOOLS;
150
+
151
+ if (READ_ONLY) {
152
+ console.error('Read-only mode enabled — mutate tool disabled');
153
+ }
154
+
146
155
  // Register list_tools handler
147
156
  server.setRequestHandler(ListToolsRequestSchema, async () => {
148
157
  return { tools: TOOLS };
@@ -161,6 +170,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
161
170
  return await runGaqlQuery(params);
162
171
 
163
172
  case 'mutate':
173
+ if (READ_ONLY) throw new Error('Mutate is disabled in read-only mode (GOOGLE_ADS_READ_ONLY=true)');
164
174
  return await mutate(params);
165
175
 
166
176
  default: