metheus-governance-mcp-cli 0.2.229 → 0.2.230

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.
@@ -1,6 +1,48 @@
1
1
  import http from "node:http";
2
2
  import https from "node:https";
3
3
 
4
+ function sleep(ms) {
5
+ return new Promise((resolve) => setTimeout(resolve, ms));
6
+ }
7
+
8
+ function isTransientGatewayTransportError(err) {
9
+ const code = String(err?.code || "").trim().toUpperCase();
10
+ const text = String(err?.message || err || "").toLowerCase();
11
+ if ([
12
+ "ECONNRESET",
13
+ "EPIPE",
14
+ "ETIMEDOUT",
15
+ "ECONNABORTED",
16
+ "EAI_AGAIN",
17
+ ].includes(code)) {
18
+ return true;
19
+ }
20
+ return [
21
+ "timeout",
22
+ "socket hang up",
23
+ "bad record mac",
24
+ "decryption failed",
25
+ "tls_get_more_records",
26
+ ].some((item) => text.includes(item));
27
+ }
28
+
29
+ async function withTransientGatewayRetry(operation) {
30
+ const maxAttempts = 3;
31
+ let lastError = null;
32
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
33
+ try {
34
+ return await Promise.resolve(operation(attempt));
35
+ } catch (err) {
36
+ lastError = err;
37
+ if (attempt >= maxAttempts || !isTransientGatewayTransportError(err)) {
38
+ throw err;
39
+ }
40
+ await sleep(250 * attempt);
41
+ }
42
+ }
43
+ throw lastError || new Error("gateway transport failed");
44
+ }
45
+
4
46
  function safeObject(value) {
5
47
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
6
48
  return value;
@@ -32,7 +74,7 @@ export function parseToolEnvelopeFromRPCResult(resultObj, deps) {
32
74
  }
33
75
 
34
76
  export async function postJSON(urlText, timeoutSeconds, token, payload) {
35
- return new Promise((resolve, reject) => {
77
+ return withTransientGatewayRetry(() => new Promise((resolve, reject) => {
36
78
  const url = new URL(urlText);
37
79
  const body = Buffer.from(JSON.stringify(payload));
38
80
  const transport = url.protocol === "http:" ? http : https;
@@ -74,11 +116,11 @@ export async function postJSON(urlText, timeoutSeconds, token, payload) {
74
116
  req.on("error", reject);
75
117
  req.write(body);
76
118
  req.end();
77
- });
119
+ }));
78
120
  }
79
121
 
80
122
  export function getJSONWithAuthHeaders(urlText, timeoutSeconds, token, extraHeaders = {}) {
81
- return new Promise((resolve, reject) => {
123
+ return withTransientGatewayRetry(() => new Promise((resolve, reject) => {
82
124
  const url = new URL(urlText);
83
125
  const transport = url.protocol === "http:" ? http : https;
84
126
  const req = transport.request(
@@ -121,7 +163,7 @@ export function getJSONWithAuthHeaders(urlText, timeoutSeconds, token, extraHead
121
163
  });
122
164
  req.on("error", reject);
123
165
  req.end();
124
- });
166
+ }));
125
167
  }
126
168
 
127
169
  export function getJSONWithAuth(urlText, timeoutSeconds, token) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metheus-governance-mcp-cli",
3
- "version": "0.2.229",
3
+ "version": "0.2.230",
4
4
  "description": "Metheus Governance MCP CLI (setup + stdio proxy)",
5
5
  "type": "module",
6
6
  "files": [