@channel47/google-ads-mcp 1.0.8 → 1.1.0

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
@@ -7,20 +7,21 @@ MCP server for Google Ads API access via GAQL (Google Ads Query Language). Built
7
7
 
8
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.
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/channel47). 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 |
@@ -233,89 +232,28 @@ Campaign creation requires specific fields since Google Ads API v19.2 (September
233
232
  - `target_impression_share` - Target impression share
234
233
  - `bidding_strategy` - Reference to portfolio bidding strategy
235
234
 
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
235
  ## Development
253
236
 
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
237
  ```bash
263
238
  git clone https://github.com/channel47/mcps.git
264
- cd mcps/google-ads
265
- npm install
239
+ cd mcps
240
+ npm install # workspaces — installs all servers
241
+ npm test # runs all server tests
266
242
  ```
267
243
 
268
- ### Testing
244
+ ~200 lines of server code. 3 core tools. Dry-run by default. OAuth 2.0 with environment-based credentials.
269
245
 
270
- ```bash
271
- npm test
272
- ```
273
-
274
- ### Running Locally
275
-
276
- ```bash
277
- npm start
278
- ```
279
-
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
293
-
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
246
+ Pairs with the [media-buyer plugin](https://github.com/channel47/channel47), which adds skills, mutation validation hooks, and GAQL reference docs on top of this server.
302
247
 
303
248
  ## Links
304
249
 
305
250
  - [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
251
+ - [Build Notes](https://channel47.dev/subscribe) — weekly skill breakdowns from production use
252
+ - [Media Buyer Plugin](https://github.com/channel47/channel47) — the paid-search toolkit this MCP powers
308
253
  - [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)
254
+ - [Google Ads API](https://developers.google.com/google-ads/api/docs/start) / [GAQL Reference](https://developers.google.com/google-ads/api/docs/query/overview)
255
+ - [X](https://x.com/ctrlswing) / [LinkedIn](https://www.linkedin.com/in/jackson-d-9979a7a0/) / [GitHub](https://github.com/channel47)
312
256
 
313
257
  ## License
314
258
 
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)
259
+ 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.0",
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
@@ -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: