@ai-ecoverse/mcpcat 0.15.0 → 0.15.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.
@@ -8343,6 +8343,16 @@ var McpAuthError = class extends Error {
8343
8343
  this.target = target;
8344
8344
  }
8345
8345
  };
8346
+ var TransportRefusalError = class extends Error {
8347
+ status;
8348
+ reason;
8349
+ constructor(status, reason) {
8350
+ super(reason);
8351
+ this.name = "TransportRefusalError";
8352
+ this.status = status;
8353
+ this.reason = reason;
8354
+ }
8355
+ };
8346
8356
  var AuthRetryableError = class extends Error {
8347
8357
  response;
8348
8358
  constructor(response) {
@@ -8485,6 +8495,15 @@ async function createStatelessConnection(options) {
8485
8495
  return h;
8486
8496
  }
8487
8497
  async function handleErrorStatus(res, method) {
8498
+ if (res.status === 403) {
8499
+ const wwwAuth = res.headers.get("www-authenticate") ?? "";
8500
+ if (!wwwAuth) {
8501
+ const body = await res.text();
8502
+ if (body && !body.includes("insufficient_scope")) {
8503
+ throw new TransportRefusalError(403, body.split("\n")[0].slice(0, 200));
8504
+ }
8505
+ }
8506
+ }
8488
8507
  if ((res.status === 401 || res.status === 403) && authProvider)
8489
8508
  throw new AuthRetryableError(res);
8490
8509
  if (res.status === 401 || res.status === 403) throw new McpAuthError(res.status, url);
@@ -9018,6 +9037,7 @@ async function connect(platform2, options) {
9018
9037
  const isMethodNotFound = err instanceof StatelessRpcError && err.code === -32601 || err instanceof StatelessHttpError && err.status >= 400 && err.status < 500;
9019
9038
  if (options.protocolVersion?.startsWith("2026")) throw err;
9020
9039
  if (err instanceof McpAuthError || err instanceof AuthStepUpError) throw err;
9040
+ if (err instanceof TransportRefusalError) throw err;
9021
9041
  if (err.name === "McpOAuthAuthorizationRequiredError") throw err;
9022
9042
  if (isMethodNotFound) {
9023
9043
  return createPiConnection({
@@ -14449,7 +14469,10 @@ async function sealSecret(platform2, name, value, options) {
14449
14469
  }
14450
14470
  const response = JSON.parse(responseText);
14451
14471
  if (response.error) {
14452
- throw Object.assign(new Error(response.error), { sealErrno: response.errno ?? "EACCES" });
14472
+ const isStructured = typeof response.error === "object" && response.error !== null && response.error.code;
14473
+ const errno = isStructured ? response.error.code : response.errno ?? "EACCES";
14474
+ const message = isStructured ? response.error.message : response.error;
14475
+ throw Object.assign(new Error(String(message)), { sealErrno: errno });
14453
14476
  }
14454
14477
  return { placeholder: response.placeholder };
14455
14478
  }
@@ -14461,6 +14484,7 @@ function sealErrorMessage(errno, name) {
14461
14484
  if (errno === "EEXIST") return `a non-bridge secret named ${name} already exists`;
14462
14485
  if (errno === "ENOTCONN") return "no vault available; use --bearer '${VAR}' or --no-auth";
14463
14486
  if (errno === "EACCES") return "vault locked; use --bearer '${VAR}' or --no-auth";
14487
+ if (errno === "ETIMEDOUT") return "vault did not respond in time";
14464
14488
  return `vault error: ${errno}`;
14465
14489
  }
14466
14490
 
@@ -16088,6 +16112,9 @@ function classifyError(err) {
16088
16112
  if (err instanceof InputRequiredError) {
16089
16113
  return { code: EXIT_INPUT_REQUIRED, kind: "input_required", msg: err.requestJson };
16090
16114
  }
16115
+ if (err instanceof TransportRefusalError) {
16116
+ return { code: EXIT_CONNECTION, kind: "connection", msg: err.reason };
16117
+ }
16091
16118
  if (err instanceof McpTimeoutError2) {
16092
16119
  return { code: EXIT_TIMEOUT, kind: "timeout", msg: err.message };
16093
16120
  }
@@ -16144,6 +16171,14 @@ async function resolveAuthProvider(platform2, hasAuthHeader, url, target, config
16144
16171
  return { provider, credentialSecrets };
16145
16172
  }
16146
16173
  function classifyConnectionError(err, target, interrupted) {
16174
+ if (err instanceof TransportRefusalError) {
16175
+ const hint = "in seven, reach the host via http://host.slicc.internal:<port>; in tests, enable the transport's hostLoopback";
16176
+ return {
16177
+ code: EXIT_CONNECTION,
16178
+ kind: "connection",
16179
+ msg: `${err.reason} (${hint})`
16180
+ };
16181
+ }
16147
16182
  if (err instanceof McpAuthError || err instanceof AuthStepUpError || err instanceof JerkSignInRequiredError) {
16148
16183
  return classifyError(err);
16149
16184
  }
@@ -16649,5 +16684,5 @@ try {
16649
16684
  });
16650
16685
  } catch {
16651
16686
  }
16652
- var code = await run(platform, "0.15.0", args);
16687
+ var code = await run(platform, "0.15.1", args);
16653
16688
  process.exit(code);
@@ -7964,6 +7964,16 @@ var McpAuthError = class extends Error {
7964
7964
  this.target = target;
7965
7965
  }
7966
7966
  };
7967
+ var TransportRefusalError = class extends Error {
7968
+ status;
7969
+ reason;
7970
+ constructor(status, reason) {
7971
+ super(reason);
7972
+ this.name = "TransportRefusalError";
7973
+ this.status = status;
7974
+ this.reason = reason;
7975
+ }
7976
+ };
7967
7977
  var AuthRetryableError = class extends Error {
7968
7978
  response;
7969
7979
  constructor(response) {
@@ -8106,6 +8116,15 @@ async function createStatelessConnection(options) {
8106
8116
  return h;
8107
8117
  }
8108
8118
  async function handleErrorStatus(res, method) {
8119
+ if (res.status === 403) {
8120
+ const wwwAuth = res.headers.get("www-authenticate") ?? "";
8121
+ if (!wwwAuth) {
8122
+ const body = await res.text();
8123
+ if (body && !body.includes("insufficient_scope")) {
8124
+ throw new TransportRefusalError(403, body.split("\n")[0].slice(0, 200));
8125
+ }
8126
+ }
8127
+ }
8109
8128
  if ((res.status === 401 || res.status === 403) && authProvider)
8110
8129
  throw new AuthRetryableError(res);
8111
8130
  if (res.status === 401 || res.status === 403) throw new McpAuthError(res.status, url);
@@ -8639,6 +8658,7 @@ async function connect(platform2, options) {
8639
8658
  const isMethodNotFound = err instanceof StatelessRpcError && err.code === -32601 || err instanceof StatelessHttpError && err.status >= 400 && err.status < 500;
8640
8659
  if (options.protocolVersion?.startsWith("2026")) throw err;
8641
8660
  if (err instanceof McpAuthError || err instanceof AuthStepUpError) throw err;
8661
+ if (err instanceof TransportRefusalError) throw err;
8642
8662
  if (err.name === "McpOAuthAuthorizationRequiredError") throw err;
8643
8663
  if (isMethodNotFound) {
8644
8664
  return createPiConnection({
@@ -14070,7 +14090,10 @@ async function sealSecret(platform2, name, value, options) {
14070
14090
  }
14071
14091
  const response = JSON.parse(responseText);
14072
14092
  if (response.error) {
14073
- throw Object.assign(new Error(response.error), { sealErrno: response.errno ?? "EACCES" });
14093
+ const isStructured = typeof response.error === "object" && response.error !== null && response.error.code;
14094
+ const errno = isStructured ? response.error.code : response.errno ?? "EACCES";
14095
+ const message = isStructured ? response.error.message : response.error;
14096
+ throw Object.assign(new Error(String(message)), { sealErrno: errno });
14074
14097
  }
14075
14098
  return { placeholder: response.placeholder };
14076
14099
  }
@@ -14082,6 +14105,7 @@ function sealErrorMessage(errno, name) {
14082
14105
  if (errno === "EEXIST") return `a non-bridge secret named ${name} already exists`;
14083
14106
  if (errno === "ENOTCONN") return "no vault available; use --bearer '${VAR}' or --no-auth";
14084
14107
  if (errno === "EACCES") return "vault locked; use --bearer '${VAR}' or --no-auth";
14108
+ if (errno === "ETIMEDOUT") return "vault did not respond in time";
14085
14109
  return `vault error: ${errno}`;
14086
14110
  }
14087
14111
 
@@ -15709,6 +15733,9 @@ function classifyError(err) {
15709
15733
  if (err instanceof InputRequiredError) {
15710
15734
  return { code: EXIT_INPUT_REQUIRED, kind: "input_required", msg: err.requestJson };
15711
15735
  }
15736
+ if (err instanceof TransportRefusalError) {
15737
+ return { code: EXIT_CONNECTION, kind: "connection", msg: err.reason };
15738
+ }
15712
15739
  if (err instanceof McpTimeoutError2) {
15713
15740
  return { code: EXIT_TIMEOUT, kind: "timeout", msg: err.message };
15714
15741
  }
@@ -15765,6 +15792,14 @@ async function resolveAuthProvider(platform2, hasAuthHeader, url, target, config
15765
15792
  return { provider, credentialSecrets };
15766
15793
  }
15767
15794
  function classifyConnectionError(err, target, interrupted) {
15795
+ if (err instanceof TransportRefusalError) {
15796
+ const hint = "in seven, reach the host via http://host.slicc.internal:<port>; in tests, enable the transport's hostLoopback";
15797
+ return {
15798
+ code: EXIT_CONNECTION,
15799
+ kind: "connection",
15800
+ msg: `${err.reason} (${hint})`
15801
+ };
15802
+ }
15768
15803
  if (err instanceof McpAuthError || err instanceof AuthStepUpError || err instanceof JerkSignInRequiredError) {
15769
15804
  return classifyError(err);
15770
15805
  }
@@ -16313,7 +16348,7 @@ async function main(ctx) {
16313
16348
  packageDir: "/node_modules/@ai-ecoverse/mcpcat"
16314
16349
  });
16315
16350
  const args = ctx.argv.slice(1);
16316
- return run(platform2, "0.15.0", args);
16351
+ return run(platform2, "0.15.1", args);
16317
16352
  }
16318
16353
  export {
16319
16354
  main as default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/mcpcat",
3
- "version": "0.15.0",
3
+ "version": "0.15.1",
4
4
  "description": "A curl for the Model Context Protocol",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -56,7 +56,7 @@
56
56
  "trust:dry": "npx fledgling sync --dry-run -y --skip-publish"
57
57
  },
58
58
  "devDependencies": {
59
- "@ai-ecoverse/slicc-kernel": "1.83.0",
59
+ "@ai-ecoverse/slicc-kernel": "1.85.0",
60
60
  "@ai-ecoverse/slicc-shared-web": "1.13.1",
61
61
  "@biomejs/biome": "2.5.15",
62
62
  "@earendil-works/pi-codemode": "1.2.0",