@channel47/google-ads-mcp 1.0.7 → 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 +21 -83
- package/package.json +5 -4
- package/server/index.js +11 -1
package/README.md
CHANGED
|
@@ -3,22 +3,25 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@channel47/google-ads-mcp)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
MCP server for Google Ads API access via GAQL (Google Ads Query Language).
|
|
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
|
-
|
|
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
|
-
|
|
10
|
+
## What It Does
|
|
11
|
+
|
|
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
|
|
11
16
|
|
|
12
17
|
## Installation
|
|
13
18
|
|
|
14
19
|
### For Claude Code Plugin Users
|
|
15
20
|
|
|
16
|
-
|
|
21
|
+
Bundled with the [media-buyer plugin](https://github.com/channel47/channel47). No manual install required.
|
|
17
22
|
|
|
18
23
|
### Standalone Use
|
|
19
24
|
|
|
20
|
-
For use with other MCP clients or standalone testing:
|
|
21
|
-
|
|
22
25
|
```bash
|
|
23
26
|
npx @channel47/google-ads-mcp@latest
|
|
24
27
|
```
|
|
@@ -32,8 +35,6 @@ google-ads-mcp
|
|
|
32
35
|
|
|
33
36
|
## Configuration
|
|
34
37
|
|
|
35
|
-
Set these environment variables before running:
|
|
36
|
-
|
|
37
38
|
### Required
|
|
38
39
|
|
|
39
40
|
| Variable | Description |
|
|
@@ -231,91 +232,28 @@ Campaign creation requires specific fields since Google Ads API v19.2 (September
|
|
|
231
232
|
- `target_impression_share` - Target impression share
|
|
232
233
|
- `bidding_strategy` - Reference to portfolio bidding strategy
|
|
233
234
|
|
|
234
|
-
## Resources & Prompts
|
|
235
|
-
|
|
236
|
-
The server provides:
|
|
237
|
-
- **Resources**: GAQL reference documentation accessible via MCP resources
|
|
238
|
-
- **Prompts**: Templates for common Google Ads operations
|
|
239
|
-
|
|
240
|
-
## Usage with Claude Code
|
|
241
|
-
|
|
242
|
-
This server is designed to work with the [google-ads-specialist plugin](https://marketplace.claude.com/plugins/google-ads-specialist), which provides:
|
|
243
|
-
|
|
244
|
-
- **9 Skill Files**: Progressive disclosure of GAQL patterns and best practices
|
|
245
|
-
- Atomic skills for focused tasks (campaign performance, search terms, wasted spend, etc.)
|
|
246
|
-
- Playbooks for comprehensive workflows (account health audit)
|
|
247
|
-
- Troubleshooting guides for common errors
|
|
248
|
-
- **PreToolUse Hook**: Validates skill references before query/mutate operations
|
|
249
|
-
- **Comprehensive Documentation**: Setup guides and OAuth configuration help
|
|
250
|
-
|
|
251
|
-
The plugin ensures Claude consults domain knowledge before executing queries, preventing hallucinated GAQL.
|
|
252
|
-
|
|
253
235
|
## Development
|
|
254
236
|
|
|
255
|
-
### Prerequisites
|
|
256
|
-
|
|
257
|
-
- Node.js 18 or higher
|
|
258
|
-
- Google Ads API access (Developer Token)
|
|
259
|
-
- OAuth 2.0 credentials from Google Cloud
|
|
260
|
-
|
|
261
|
-
### Setup
|
|
262
|
-
|
|
263
|
-
```bash
|
|
264
|
-
git clone https://github.com/channel47/google-ads-mcp-server.git
|
|
265
|
-
cd google-ads-mcp-server
|
|
266
|
-
npm install
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
### Testing
|
|
270
|
-
|
|
271
|
-
```bash
|
|
272
|
-
npm test
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### Running Locally
|
|
276
|
-
|
|
277
237
|
```bash
|
|
278
|
-
|
|
238
|
+
git clone https://github.com/channel47/mcps.git
|
|
239
|
+
cd mcps
|
|
240
|
+
npm install # workspaces — installs all servers
|
|
241
|
+
npm test # runs all server tests
|
|
279
242
|
```
|
|
280
243
|
|
|
281
|
-
|
|
244
|
+
~200 lines of server code. 3 core tools. Dry-run by default. OAuth 2.0 with environment-based credentials.
|
|
282
245
|
|
|
283
|
-
|
|
284
|
-
- ~200 lines of server code
|
|
285
|
-
- 3 core tools (list, query, mutate)
|
|
286
|
-
- OAuth 2.0 authentication
|
|
287
|
-
- Resources for GAQL reference
|
|
288
|
-
- Prompts for common patterns
|
|
289
|
-
|
|
290
|
-
**Security:**
|
|
291
|
-
- Dry-run mode enabled by default for mutations
|
|
292
|
-
- Environment-based credential management
|
|
293
|
-
- Input validation for all operations
|
|
294
|
-
|
|
295
|
-
## Contributing
|
|
296
|
-
|
|
297
|
-
Contributions welcome! Please:
|
|
298
|
-
|
|
299
|
-
1. Fork the repository
|
|
300
|
-
2. Create a feature branch
|
|
301
|
-
3. Make your changes with tests
|
|
302
|
-
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.
|
|
303
247
|
|
|
304
248
|
## Links
|
|
305
249
|
|
|
250
|
+
- [Channel 47](https://channel47.dev) — open-source profession plugins for Claude Code
|
|
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
|
|
306
253
|
- [NPM Package](https://www.npmjs.com/package/@channel47/google-ads-mcp)
|
|
307
|
-
- [
|
|
308
|
-
- [
|
|
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
|
|
316
|
-
|
|
317
|
-
## Support
|
|
318
|
-
|
|
319
|
-
For issues or questions:
|
|
320
|
-
- Plugin-related: [Plugin Repository Issues](https://github.com/ctrlswing/channel47-marketplace/issues)
|
|
321
|
-
- Server-related: [Server Repository Issues](https://github.com/channel47/google-ads-mcp-server/issues)
|
|
259
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@channel47/google-ads-mcp",
|
|
3
|
-
"version": "1.0
|
|
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": {
|
|
@@ -31,12 +31,13 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"repository": {
|
|
33
33
|
"type": "git",
|
|
34
|
-
"url": "https://github.com/channel47/
|
|
34
|
+
"url": "https://github.com/channel47/mcps.git",
|
|
35
|
+
"directory": "google-ads"
|
|
35
36
|
},
|
|
36
37
|
"bugs": {
|
|
37
|
-
"url": "https://github.com/channel47/
|
|
38
|
+
"url": "https://github.com/channel47/mcps/issues"
|
|
38
39
|
},
|
|
39
|
-
"homepage": "https://github.com/channel47/google-ads
|
|
40
|
+
"homepage": "https://github.com/channel47/mcps/tree/main/google-ads#readme",
|
|
40
41
|
"dependencies": {
|
|
41
42
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
42
43
|
"google-ads-api": "^21.0.1",
|
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
|
|
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:
|