@channel47/google-ads-mcp 1.1.1 → 1.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@channel47/google-ads-mcp",
3
- "version": "1.1.1",
3
+ "version": "1.2.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/auth.js CHANGED
@@ -61,14 +61,15 @@ export function initializeGoogleAdsClient() {
61
61
  /**
62
62
  * Get authenticated customer client for a specific account
63
63
  * @param {string} customerId - Google Ads account ID (without dashes)
64
+ * @param {string} [loginCustomerId] - MCC account ID to authenticate through (overrides env var)
64
65
  * @returns {Customer}
65
66
  */
66
- export function getCustomerClient(customerId) {
67
+ export function getCustomerClient(customerId, loginCustomerId) {
67
68
  const client = initializeGoogleAdsClient();
68
69
 
69
70
  return client.Customer({
70
71
  customer_id: customerId,
71
72
  refresh_token: process.env.GOOGLE_ADS_REFRESH_TOKEN,
72
- login_customer_id: process.env.GOOGLE_ADS_LOGIN_CUSTOMER_ID,
73
+ login_customer_id: loginCustomerId || process.env.GOOGLE_ADS_LOGIN_CUSTOMER_ID,
73
74
  });
74
75
  }
package/server/index.js CHANGED
@@ -61,6 +61,10 @@ const ALL_TOOLS = [
61
61
  inputSchema: {
62
62
  type: 'object',
63
63
  properties: {
64
+ login_customer_id: {
65
+ type: 'string',
66
+ description: 'MCC account ID to authenticate through (overrides GOOGLE_ADS_LOGIN_CUSTOMER_ID env var). Use when accessing accounts under a different MCC than the default.'
67
+ },
64
68
  include_manager_accounts: {
65
69
  type: 'boolean',
66
70
  description: 'Include manager (MCC) accounts in results',
@@ -79,6 +83,10 @@ const ALL_TOOLS = [
79
83
  type: 'string',
80
84
  description: 'Google Ads account ID (optional, uses default if not specified)'
81
85
  },
86
+ login_customer_id: {
87
+ type: 'string',
88
+ description: 'MCC account ID to authenticate through (overrides GOOGLE_ADS_LOGIN_CUSTOMER_ID env var). Use when accessing accounts under a different MCC than the default.'
89
+ },
82
90
  query: {
83
91
  type: 'string',
84
92
  description: 'Full GAQL query string (SELECT only)'
@@ -123,6 +131,10 @@ For IMAGE/VIDEO assets, use 'image_file_path' or 'video_file_path' with absolute
123
131
  type: 'string',
124
132
  description: 'Google Ads customer ID (optional, uses default if not specified)'
125
133
  },
134
+ login_customer_id: {
135
+ type: 'string',
136
+ description: 'MCC account ID to authenticate through (overrides GOOGLE_ADS_LOGIN_CUSTOMER_ID env var). Use when accessing accounts under a different MCC than the default.'
137
+ },
126
138
  operations: {
127
139
  type: 'array',
128
140
  description: 'Array of mutation operations. Supports standard format ({ create/update/remove: ... }) or Opteo format ({ entity, operation, resource }).',
@@ -63,7 +63,7 @@ export async function runGaqlQuery(params = {}) {
63
63
  }
64
64
  }
65
65
 
66
- const customer = getCustomerClient(customerId);
66
+ const customer = getCustomerClient(customerId, params.login_customer_id);
67
67
 
68
68
  // Execute query
69
69
  const startTime = Date.now();
@@ -12,18 +12,20 @@ export async function listAccounts(params = {}) {
12
12
  try {
13
13
  const includeManagers = params.include_manager_accounts || false;
14
14
 
15
- // Use login customer ID or default customer ID
16
- const customerId = process.env.GOOGLE_ADS_LOGIN_CUSTOMER_ID ||
17
- process.env.GOOGLE_ADS_DEFAULT_CUSTOMER_ID;
15
+ // Resolve MCC to enumerate broader fallback than query/mutate because
16
+ // list_accounts always needs an MCC, while the others target specific accounts
17
+ const loginCustomerId = params.login_customer_id ||
18
+ process.env.GOOGLE_ADS_LOGIN_CUSTOMER_ID ||
19
+ process.env.GOOGLE_ADS_DEFAULT_CUSTOMER_ID;
18
20
 
19
- if (!customerId) {
21
+ if (!loginCustomerId) {
20
22
  throw new Error(
21
- 'Either GOOGLE_ADS_LOGIN_CUSTOMER_ID or GOOGLE_ADS_DEFAULT_CUSTOMER_ID must be set'
23
+ 'Either login_customer_id parameter, GOOGLE_ADS_LOGIN_CUSTOMER_ID, or GOOGLE_ADS_DEFAULT_CUSTOMER_ID must be set'
22
24
  );
23
25
  }
24
26
 
25
- // Get customer client
26
- const customer = getCustomerClient(customerId);
27
+ // Get customer client — login_customer_id serves as both the query target and auth MCC
28
+ const customer = getCustomerClient(loginCustomerId, loginCustomerId);
27
29
 
28
30
  // Build query with optional manager filter
29
31
  const filters = includeManagers ? '' : "WHERE customer_client.manager = false";
@@ -17,6 +17,7 @@ import { normalizeOperations } from '../utils/operation-transform.js';
17
17
  export async function mutate(params) {
18
18
  const {
19
19
  customer_id = process.env.GOOGLE_ADS_CUSTOMER_ID,
20
+ login_customer_id,
20
21
  operations,
21
22
  partial_failure = true,
22
23
  dry_run = true
@@ -31,7 +32,7 @@ export async function mutate(params) {
31
32
  return formatError(new Error('operations array is required and must contain at least one operation'));
32
33
  }
33
34
 
34
- const customer = getCustomerClient(customer_id);
35
+ const customer = getCustomerClient(customer_id, login_customer_id);
35
36
  let response;
36
37
  let partialFailureErrors = [];
37
38