@myspec/mcp-server 1.1.1-next.173 → 1.1.1-next.174

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.
Files changed (2) hide show
  1. package/dist/index.js +59 -28
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2048,6 +2048,51 @@ var ConsoleLogger = class {
2048
2048
  };
2049
2049
 
2050
2050
  // ../../packages/platform-client/shared/http-base.ts
2051
+ var CONNECT_ERROR_CODES = /* @__PURE__ */ new Set([
2052
+ "ECONNREFUSED",
2053
+ "ENOTFOUND",
2054
+ "EAI_AGAIN",
2055
+ "EHOSTUNREACH",
2056
+ "ENETUNREACH",
2057
+ "UND_ERR_CONNECT_TIMEOUT"
2058
+ ]);
2059
+ function errorCode(value) {
2060
+ const code = value?.code;
2061
+ return typeof code === "string" ? code : void 0;
2062
+ }
2063
+ function failedBeforeConnecting(error) {
2064
+ const cause = error.cause;
2065
+ const errors = cause?.errors;
2066
+ if (Array.isArray(errors) && errors.length > 0) {
2067
+ return errors.every((e) => CONNECT_ERROR_CODES.has(errorCode(e) ?? ""));
2068
+ }
2069
+ return CONNECT_ERROR_CODES.has(errorCode(cause) ?? errorCode(error) ?? "");
2070
+ }
2071
+ function classifyAttemptFailure(error) {
2072
+ if (error.name === "AbortError") {
2073
+ return { kind: "timeout" };
2074
+ }
2075
+ const status = error.status;
2076
+ if (status !== void 0) {
2077
+ return { kind: "status", status, quota: isPlatformQuotaError(error) };
2078
+ }
2079
+ if (error.message.includes("fetch") || error.message.includes("network")) {
2080
+ return failedBeforeConnecting(error) ? { kind: "connect" } : { kind: "network" };
2081
+ }
2082
+ return { kind: "other" };
2083
+ }
2084
+ var retryTransientFailures = (_method, failure) => {
2085
+ switch (failure.kind) {
2086
+ case "status":
2087
+ return !failure.quota && RETRYABLE_STATUS_CODES.includes(failure.status);
2088
+ case "timeout":
2089
+ case "connect":
2090
+ case "network":
2091
+ return true;
2092
+ case "other":
2093
+ return false;
2094
+ }
2095
+ };
2051
2096
  var DEFAULT_HTTP_CONFIG = {
2052
2097
  timeout: 3e4,
2053
2098
  retryConfig: DEFAULT_RETRY_CONFIG
@@ -2059,11 +2104,13 @@ var STANDARD_HEADERS = {
2059
2104
  var BaseHttpClient = class {
2060
2105
  config;
2061
2106
  logger;
2107
+ retryDecision;
2062
2108
  constructor(config) {
2063
2109
  this.logger = config.logger ?? new ConsoleLogger();
2110
+ this.retryDecision = config.shouldRetry ?? retryTransientFailures;
2064
2111
  this.config = {
2065
- ...DEFAULT_HTTP_CONFIG,
2066
- ...config,
2112
+ baseUrl: config.baseUrl,
2113
+ timeout: config.timeout ?? DEFAULT_HTTP_CONFIG.timeout,
2067
2114
  retryConfig: config.retryConfig ?? DEFAULT_HTTP_CONFIG.retryConfig
2068
2115
  };
2069
2116
  }
@@ -2116,7 +2163,7 @@ var BaseHttpClient = class {
2116
2163
  const result = await withRetry(
2117
2164
  () => this.executeRequest(method, path4, body, jwt, options),
2118
2165
  this.config.retryConfig,
2119
- this.shouldRetry.bind(this)
2166
+ (error) => this.shouldRetry(method, error)
2120
2167
  );
2121
2168
  if (!result.success) {
2122
2169
  const error = result.error ?? new Error("Unknown error");
@@ -2193,31 +2240,15 @@ var BaseHttpClient = class {
2193
2240
  }
2194
2241
  return headers;
2195
2242
  }
2196
- /**
2197
- * Determines if a failed request should be retried.
2198
- */
2199
- shouldRetry(error) {
2200
- if (error.name === "AbortError") {
2201
- this.logger.debug("Retrying after abort/timeout", { error: error.message });
2202
- return true;
2203
- }
2204
- if (isPlatformQuotaError(error)) {
2205
- this.logger.debug("Not retrying quota rejection", { status: 429 });
2206
- return false;
2207
- }
2208
- const httpError = error;
2209
- if (httpError.status !== void 0) {
2210
- const shouldRetry = RETRYABLE_STATUS_CODES.includes(httpError.status);
2211
- if (shouldRetry) {
2212
- this.logger.debug("Retrying after HTTP error", { status: httpError.status });
2213
- }
2214
- return shouldRetry;
2215
- }
2216
- if (error.message.includes("fetch") || error.message.includes("network")) {
2217
- this.logger.debug("Retrying after network error", { error: error.message });
2218
- return true;
2219
- }
2220
- return false;
2243
+ /** Whether a failed attempt is sent again: the configured decision on the classified failure. */
2244
+ shouldRetry(method, error) {
2245
+ const failure = classifyAttemptFailure(error);
2246
+ const retry = this.retryDecision(method, failure);
2247
+ this.logger.debug(retry ? "Retrying after a failed attempt" : "Not retrying a failed attempt", {
2248
+ method,
2249
+ failure
2250
+ });
2251
+ return retry;
2221
2252
  }
2222
2253
  };
2223
2254
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myspec/mcp-server",
3
- "version": "1.1.1-next.173",
3
+ "version": "1.1.1-next.174",
4
4
  "description": "MySpec MCP server — exposes MySpec platform projects, files and attachments to MCP-aware clients via OAuth-authenticated access tokens.",
5
5
  "type": "module",
6
6
  "repository": {