@ppcassist/amazon-ads-mcp 1.0.0 → 1.0.1

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/index.js CHANGED
@@ -76,13 +76,35 @@ async function handleRequest(proxy, request) {
76
76
  const result = await proxy.forward(request);
77
77
 
78
78
  if (result.type === "stream") {
79
- // SSE stream: pipe each event line directly to stdout
79
+ // SSE stream: buffer chunks, extract JSON from "data: ..." lines,
80
+ // and write as newline-delimited JSON-RPC for Claude Desktop
81
+ let sseBuf = "";
82
+ result.stream.setEncoding("utf8");
83
+
80
84
  result.stream.on("data", (chunk) => {
81
- process.stdout.write(chunk);
85
+ sseBuf += chunk;
86
+ let lineEnd;
87
+ while ((lineEnd = sseBuf.indexOf("\n")) !== -1) {
88
+ const line = sseBuf.slice(0, lineEnd).trim();
89
+ sseBuf = sseBuf.slice(lineEnd + 1);
90
+ if (line.startsWith("data: ")) {
91
+ const json = line.slice(6);
92
+ if (json) {
93
+ process.stdout.write(json + "\n");
94
+ }
95
+ }
96
+ }
82
97
  });
83
98
 
84
99
  result.stream.on("end", () => {
85
- // SSE streams end naturally; nothing extra needed
100
+ // Flush any remaining data in buffer
101
+ const remaining = sseBuf.trim();
102
+ if (remaining.startsWith("data: ")) {
103
+ const json = remaining.slice(6);
104
+ if (json) {
105
+ process.stdout.write(json + "\n");
106
+ }
107
+ }
86
108
  });
87
109
 
88
110
  result.stream.on("error", (err) => {
package/lib/auth.js CHANGED
@@ -14,7 +14,11 @@ class TokenManager {
14
14
 
15
15
  async init() {
16
16
  await this.refresh();
17
- this.timer = setInterval(() => this.refresh(), REFRESH_INTERVAL_MS);
17
+ this.timer = setInterval(() => {
18
+ this.refresh().catch((err) => {
19
+ process.stderr.write(`[auth] Token refresh failed: ${err.message}\n`);
20
+ });
21
+ }, REFRESH_INTERVAL_MS);
18
22
  this.timer.unref(); // don't keep process alive just for refresh
19
23
  }
20
24
 
package/lib/proxy.js CHANGED
@@ -19,7 +19,20 @@ class McpProxy {
19
19
  this.endpoint = new URL(endpoint);
20
20
  }
21
21
 
22
- async forward(jsonRpcRequest) {
22
+ async forward(jsonRpcRequest, _isRetry) {
23
+ const result = await this._doRequest(jsonRpcRequest);
24
+
25
+ // Retry once on 401 (token expired between refreshes)
26
+ if (!_isRetry && result.statusCode === 401) {
27
+ process.stderr.write("[proxy] Got 401, refreshing token and retrying\n");
28
+ await this.tokenManager.refresh();
29
+ return this.forward(jsonRpcRequest, true);
30
+ }
31
+
32
+ return result;
33
+ }
34
+
35
+ _doRequest(jsonRpcRequest) {
23
36
  const body = JSON.stringify(jsonRpcRequest);
24
37
  const token = this.tokenManager.getToken();
25
38
 
@@ -51,9 +64,8 @@ class McpProxy {
51
64
  res.on("end", () => {
52
65
  const raw = Buffer.concat(chunks).toString();
53
66
  try {
54
- resolve({ type: "json", data: JSON.parse(raw) });
67
+ resolve({ type: "json", data: JSON.parse(raw), statusCode: res.statusCode });
55
68
  } catch {
56
- // Return raw text if not valid JSON (error pages, etc.)
57
69
  resolve({ type: "raw", data: raw, statusCode: res.statusCode });
58
70
  }
59
71
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ppcassist/amazon-ads-mcp",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Local MCP proxy for Amazon Ads API - authenticates and forwards requests to Amazon's official MCP server",
5
5
  "main": "index.js",
6
6
  "bin": {