mcp-google-ads 1.0.8 → 1.0.10
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/dist/build-info.json +1 -1
- package/dist/errors.js +2 -2
- package/dist/index.js +19 -11
- package/dist/resilience.js +1 -1
- package/package.json +2 -2
package/dist/build-info.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"sha":"
|
|
1
|
+
{"sha":"fd2b513","builtAt":"2026-04-09T21:47:18.505Z"}
|
package/dist/errors.js
CHANGED
|
@@ -12,7 +12,7 @@ export class GoogleAdsAuthError extends Error {
|
|
|
12
12
|
export class GoogleAdsRateLimitError extends Error {
|
|
13
13
|
retryAfterMs;
|
|
14
14
|
constructor(retryAfterMs, cause) {
|
|
15
|
-
super(`
|
|
15
|
+
super(`Google Ads rate limited, retry after ${retryAfterMs}ms`);
|
|
16
16
|
this.retryAfterMs = retryAfterMs;
|
|
17
17
|
this.name = "GoogleAdsRateLimitError";
|
|
18
18
|
this.cause = cause;
|
|
@@ -89,7 +89,7 @@ export function classifyError(error) {
|
|
|
89
89
|
message.includes("refresh token") ||
|
|
90
90
|
code?.authentication_error ||
|
|
91
91
|
code?.authorization_error) {
|
|
92
|
-
return new GoogleAdsAuthError(`
|
|
92
|
+
return new GoogleAdsAuthError(`Google Ads auth failed: ${message}. Check your refresh token and OAuth credentials.`, error);
|
|
93
93
|
}
|
|
94
94
|
// Rate limiting
|
|
95
95
|
if (status === 429 ||
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,10 @@ if (process.argv.includes("--version") || process.argv.includes("-v")) {
|
|
|
34
34
|
console.error(__cliPkg.version);
|
|
35
35
|
process.exit(0);
|
|
36
36
|
}
|
|
37
|
+
// ============================================
|
|
38
|
+
// ENV VAR TRIMMING
|
|
39
|
+
// ============================================
|
|
40
|
+
const envTrimmed = (key) => (process.env[key] || "").trim().replace(/^["']|["']$/g, "");
|
|
37
41
|
function loadConfig() {
|
|
38
42
|
// Try config.json first (for multi-client setups)
|
|
39
43
|
const configPath = join(dirname(new URL(import.meta.url).pathname), "..", "config.json");
|
|
@@ -41,12 +45,12 @@ function loadConfig() {
|
|
|
41
45
|
return JSON.parse(readFileSync(configPath, "utf-8"));
|
|
42
46
|
}
|
|
43
47
|
// Fall back to env vars (single-client mode)
|
|
44
|
-
const clientId =
|
|
45
|
-
const clientSecret =
|
|
46
|
-
const developerToken =
|
|
47
|
-
const refreshToken =
|
|
48
|
-
const customerId =
|
|
49
|
-
const mccId =
|
|
48
|
+
const clientId = envTrimmed("GOOGLE_ADS_CLIENT_ID");
|
|
49
|
+
const clientSecret = envTrimmed("GOOGLE_ADS_CLIENT_SECRET");
|
|
50
|
+
const developerToken = envTrimmed("GOOGLE_ADS_DEVELOPER_TOKEN");
|
|
51
|
+
const refreshToken = envTrimmed("GOOGLE_ADS_REFRESH_TOKEN");
|
|
52
|
+
const customerId = envTrimmed("GOOGLE_ADS_CUSTOMER_ID");
|
|
53
|
+
const mccId = envTrimmed("GOOGLE_ADS_MCC_CUSTOMER_ID");
|
|
50
54
|
if (!clientId || !clientSecret || !developerToken || !refreshToken) {
|
|
51
55
|
throw new Error("No configuration found. Either:\n" +
|
|
52
56
|
" 1. Set env vars: GOOGLE_ADS_CLIENT_ID, GOOGLE_ADS_CLIENT_SECRET, GOOGLE_ADS_DEVELOPER_TOKEN, GOOGLE_ADS_REFRESH_TOKEN, GOOGLE_ADS_CUSTOMER_ID\n" +
|
|
@@ -113,11 +117,11 @@ class GoogleAdsManager {
|
|
|
113
117
|
throw new GoogleAdsAuthError(msg);
|
|
114
118
|
}
|
|
115
119
|
logger.info("Credentials validated: all required env vars present");
|
|
116
|
-
this.defaultRefreshToken =
|
|
120
|
+
this.defaultRefreshToken = envTrimmed("GOOGLE_ADS_REFRESH_TOKEN");
|
|
117
121
|
this.api = new GoogleAdsApi({
|
|
118
|
-
client_id:
|
|
119
|
-
client_secret:
|
|
120
|
-
developer_token:
|
|
122
|
+
client_id: envTrimmed("GOOGLE_ADS_CLIENT_ID"),
|
|
123
|
+
client_secret: envTrimmed("GOOGLE_ADS_CLIENT_SECRET"),
|
|
124
|
+
developer_token: envTrimmed("GOOGLE_ADS_DEVELOPER_TOKEN"),
|
|
121
125
|
});
|
|
122
126
|
}
|
|
123
127
|
getClientForCustomerId(customerId) {
|
|
@@ -1759,6 +1763,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1759
1763
|
error: true,
|
|
1760
1764
|
error_type: error.name,
|
|
1761
1765
|
message: error.message,
|
|
1766
|
+
server: __cliPkg.name,
|
|
1762
1767
|
};
|
|
1763
1768
|
if (error instanceof GoogleAdsAuthError) {
|
|
1764
1769
|
response.action_required = "Re-authenticate: check refresh token in macOS Keychain. Token may be expired or revoked.";
|
|
@@ -1775,11 +1780,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1775
1780
|
response.details = rawError.errors || rawError.stack;
|
|
1776
1781
|
}
|
|
1777
1782
|
return {
|
|
1783
|
+
isError: true,
|
|
1778
1784
|
content: [{
|
|
1779
1785
|
type: "text",
|
|
1780
1786
|
text: JSON.stringify(response, null, 2),
|
|
1781
1787
|
}],
|
|
1782
|
-
isError: true,
|
|
1783
1788
|
};
|
|
1784
1789
|
}
|
|
1785
1790
|
});
|
|
@@ -1818,4 +1823,7 @@ process.on("SIGINT", () => {
|
|
|
1818
1823
|
process.on("SIGPIPE", () => {
|
|
1819
1824
|
// Client disconnected -- expected during shutdown
|
|
1820
1825
|
});
|
|
1826
|
+
process.on("unhandledRejection", (reason) => {
|
|
1827
|
+
console.error("[error] Unhandled promise rejection:", reason);
|
|
1828
|
+
});
|
|
1821
1829
|
main().catch((err) => logger.error({ error: err.message, stack: err.stack }, "Fatal startup error"));
|
package/dist/resilience.js
CHANGED
|
@@ -5,7 +5,7 @@ import pino from "pino";
|
|
|
5
5
|
// ============================================
|
|
6
6
|
export const logger = pino({
|
|
7
7
|
level: process.env.LOG_LEVEL || "info",
|
|
8
|
-
...(process.env.NODE_ENV !== "test" && {
|
|
8
|
+
...(process.env.NODE_ENV !== "test" && process.stderr.isTTY && {
|
|
9
9
|
transport: {
|
|
10
10
|
target: "pino-pretty",
|
|
11
11
|
options: {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-google-ads",
|
|
3
3
|
"mcpName": "io.github.mharnett/google-ads",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.10",
|
|
5
5
|
"description": "MCP server for Google Ads API with MCC support, 35 tools for campaign management, reporting, and optimization. Safe by default — all changes created PAUSED.",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
},
|
|
54
54
|
"homepage": "https://github.com/mharnett/mcp-google-ads#readme",
|
|
55
55
|
"engines": {
|
|
56
|
-
"node": ">=18.
|
|
56
|
+
"node": ">=18.18.0"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@anthropic-ai/sdk": "^0.24.0",
|