mcp-bing-ads 1.0.7 → 1.0.9
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 +13 -5
- package/dist/resilience.js +1 -1
- package/package.json +2 -2
package/dist/build-info.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"sha":"
|
|
1
|
+
{"sha":"9c3433f","builtAt":"2026-04-09T21:47:25.221Z"}
|
package/dist/errors.js
CHANGED
|
@@ -12,7 +12,7 @@ export class BingAdsAuthError extends Error {
|
|
|
12
12
|
export class BingAdsRateLimitError extends Error {
|
|
13
13
|
retryAfterMs;
|
|
14
14
|
constructor(retryAfterMs, cause) {
|
|
15
|
-
super(`
|
|
15
|
+
super(`Bing Ads rate limited, retry after ${retryAfterMs}ms`);
|
|
16
16
|
this.retryAfterMs = retryAfterMs;
|
|
17
17
|
this.name = "BingAdsRateLimitError";
|
|
18
18
|
this.cause = cause;
|
|
@@ -47,7 +47,7 @@ export function classifyError(error) {
|
|
|
47
47
|
message.includes("OAuth token refresh failed") ||
|
|
48
48
|
message.includes("AuthenticationTokenExpired") ||
|
|
49
49
|
message.includes("InvalidCredentials")) {
|
|
50
|
-
return new BingAdsAuthError(`
|
|
50
|
+
return new BingAdsAuthError(`Bing Ads auth failed: ${message}. Refresh token may be expired. Re-authenticate and update Keychain.`, error);
|
|
51
51
|
}
|
|
52
52
|
if (status === 429 || message.includes("RateLimit") || message.includes("CallRateExceeded")) {
|
|
53
53
|
const retryMs = 60_000;
|
package/dist/index.js
CHANGED
|
@@ -33,6 +33,10 @@ if (process.argv.includes("--version") || process.argv.includes("-v")) {
|
|
|
33
33
|
console.error(__cliPkg.version);
|
|
34
34
|
process.exit(0);
|
|
35
35
|
}
|
|
36
|
+
// ============================================
|
|
37
|
+
// ENV VAR TRIMMING
|
|
38
|
+
// ============================================
|
|
39
|
+
const envTrimmed = (key) => (process.env[key] || "").trim().replace(/^["']|["']$/g, "");
|
|
36
40
|
function loadConfig() {
|
|
37
41
|
const configPath = join(dirname(new URL(import.meta.url).pathname), "..", "config.json");
|
|
38
42
|
if (!existsSync(configPath)) {
|
|
@@ -69,14 +73,14 @@ class BingAdsManager {
|
|
|
69
73
|
throw new BingAdsAuthError(msg);
|
|
70
74
|
}
|
|
71
75
|
console.error("[startup] Credentials validated: all required env vars present");
|
|
72
|
-
this.developerToken =
|
|
73
|
-
this.refreshToken =
|
|
76
|
+
this.developerToken = envTrimmed("BING_ADS_DEVELOPER_TOKEN");
|
|
77
|
+
this.refreshToken = envTrimmed("BING_ADS_REFRESH_TOKEN");
|
|
74
78
|
// Allow env vars to override config for OAuth
|
|
75
79
|
if (process.env.BING_ADS_CLIENT_ID) {
|
|
76
|
-
this.config.oauth.client_id =
|
|
80
|
+
this.config.oauth.client_id = envTrimmed("BING_ADS_CLIENT_ID");
|
|
77
81
|
}
|
|
78
82
|
if (process.env.BING_ADS_CLIENT_SECRET) {
|
|
79
|
-
this.config.oauth.client_secret =
|
|
83
|
+
this.config.oauth.client_secret = envTrimmed("BING_ADS_CLIENT_SECRET");
|
|
80
84
|
}
|
|
81
85
|
}
|
|
82
86
|
async getAccessToken() {
|
|
@@ -738,6 +742,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
738
742
|
error: true,
|
|
739
743
|
error_type: error.name,
|
|
740
744
|
message: error.message,
|
|
745
|
+
server: __cliPkg.name,
|
|
741
746
|
};
|
|
742
747
|
if (error instanceof BingAdsAuthError) {
|
|
743
748
|
response.action_required = "Re-authenticate: refresh token may be expired. Update Keychain entry BING_ADS_REFRESH_TOKEN.";
|
|
@@ -753,11 +758,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
753
758
|
response.details = rawError.stack;
|
|
754
759
|
}
|
|
755
760
|
return {
|
|
761
|
+
isError: true,
|
|
756
762
|
content: [{
|
|
757
763
|
type: "text",
|
|
758
764
|
text: JSON.stringify(response, null, 2),
|
|
759
765
|
}],
|
|
760
|
-
isError: true,
|
|
761
766
|
};
|
|
762
767
|
}
|
|
763
768
|
});
|
|
@@ -788,4 +793,7 @@ process.on("SIGINT", () => {
|
|
|
788
793
|
process.on("SIGPIPE", () => {
|
|
789
794
|
// Client disconnected -- expected during shutdown
|
|
790
795
|
});
|
|
796
|
+
process.on("unhandledRejection", (reason) => {
|
|
797
|
+
console.error("[error] Unhandled promise rejection:", reason);
|
|
798
|
+
});
|
|
791
799
|
main().catch(console.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-bing-ads",
|
|
3
3
|
"mcpName": "io.github.mharnett/bing-ads",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.9",
|
|
5
5
|
"description": "MCP server for Microsoft Advertising (Bing Ads) API with campaign, ad group, keyword, and performance reporting. First comprehensive open-source Bing Ads MCP.",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
},
|
|
49
49
|
"homepage": "https://github.com/mharnett/mcp-bing-ads#readme",
|
|
50
50
|
"engines": {
|
|
51
|
-
"node": ">=18.
|
|
51
|
+
"node": ">=18.18.0"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@modelcontextprotocol/sdk": "^0.5.0",
|