mmt-mcp 1.43.3 → 1.44.0-pre

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/server.cjs CHANGED
@@ -14223,7 +14223,12 @@ var apiToJSfunc = async (ctx) => {
14223
14223
  const entries = Object.entries(ctx.api.inputs ?? {});
14224
14224
  for (const [name, value] of entries) {
14225
14225
  const quoted = new RegExp(`"\\$\\{${name}\\}"`, "g");
14226
- if (typeof value === "string") {
14226
+ if (reqFormat2 === "json" && typeof value !== "string") {
14227
+ formattedBody = formattedBody.replace(
14228
+ quoted,
14229
+ () => "${JSON.stringify(" + name + ")}"
14230
+ );
14231
+ } else if (typeof value === "string") {
14227
14232
  formattedBody = formattedBody.replace(quoted, '"${' + name + '}"');
14228
14233
  } else {
14229
14234
  formattedBody = formattedBody.replace(quoted, "${" + name + "}");
@@ -27662,8 +27667,40 @@ function trackSocketForAgent(socket, host, protocol) {
27662
27667
  });
27663
27668
  socket.once("end", () => {
27664
27669
  connectionTracker.close(connId, "server");
27670
+ if (!socket._httpMessage) {
27671
+ destroySocketQuietly(socket);
27672
+ }
27665
27673
  });
27666
27674
  }
27675
+ function destroySocketQuietly(socket) {
27676
+ if (!socket || socket.destroyed) {
27677
+ return;
27678
+ }
27679
+ try {
27680
+ socket.removeAllListeners("error");
27681
+ socket.on("error", () => {
27682
+ });
27683
+ socket.destroy();
27684
+ } catch {
27685
+ }
27686
+ }
27687
+ function requestSocket(source) {
27688
+ return source?.request?.socket || source?.response?.request?.socket || source?.socket;
27689
+ }
27690
+ function dropKeepAliveSocket(source) {
27691
+ destroySocketQuietly(requestSocket(source));
27692
+ }
27693
+ function isDeadKeepAliveError(err) {
27694
+ if (!err || err.response) {
27695
+ return false;
27696
+ }
27697
+ const code = err.code || err.cause?.code;
27698
+ if (code === "ECONNRESET" || code === "EPIPE") {
27699
+ return true;
27700
+ }
27701
+ const message = typeof err.message === "string" ? err.message.toLowerCase() : "";
27702
+ return message.includes("socket hang up") || message.includes("econnreset");
27703
+ }
27667
27704
  function createHttpsAgentWithCertificates(hostname, port, protocol, config, opts) {
27668
27705
  const skipValidation = opts?.skipCertificateValidation ?? false;
27669
27706
  const agentKey = getHttpsAgentKey(hostname, port, protocol, config, opts);
@@ -28125,6 +28162,9 @@ async function sendHttpRequest(req, config) {
28125
28162
  };
28126
28163
  const toError = (err, warning) => {
28127
28164
  const duration = Date.now() - start;
28165
+ if (err?.response && Number(err.response.status) >= 400) {
28166
+ dropKeepAliveSocket(err);
28167
+ }
28128
28168
  if (err?.response) {
28129
28169
  const headers = normalizeAxiosHeaders(err.response.headers);
28130
28170
  return {
@@ -28179,8 +28219,18 @@ async function sendHttpRequest(req, config) {
28179
28219
  const response = await executeRequest(false);
28180
28220
  return toSuccess(response);
28181
28221
  } catch (err) {
28182
- if (canRetrySelfSigned && isSelfSignedTlsError(err)) {
28183
- const warning = formatSelfSignedWarning(err);
28222
+ let responseErr = err;
28223
+ if (isDeadKeepAliveError(err)) {
28224
+ dropKeepAliveSocket(err);
28225
+ try {
28226
+ const retryResponse = await executeRequest(false);
28227
+ return toSuccess(retryResponse);
28228
+ } catch (retryErr) {
28229
+ responseErr = retryErr;
28230
+ }
28231
+ }
28232
+ if (canRetrySelfSigned && isSelfSignedTlsError(responseErr)) {
28233
+ const warning = formatSelfSignedWarning(responseErr);
28184
28234
  try {
28185
28235
  const retryResponse = await executeRequest(true);
28186
28236
  return toSuccess(retryResponse, warning);
@@ -28188,7 +28238,7 @@ async function sendHttpRequest(req, config) {
28188
28238
  return toError(retryErr, warning);
28189
28239
  }
28190
28240
  }
28191
- if (parsedUrl.protocol === "https:" && isClientCertificateRequiredTlsError(err)) {
28241
+ if (parsedUrl.protocol === "https:" && isClientCertificateRequiredTlsError(responseErr)) {
28192
28242
  const retryClient = getCertificateRequiredRetryClient(
28193
28243
  config,
28194
28244
  hostname,
@@ -28207,7 +28257,7 @@ async function sendHttpRequest(req, config) {
28207
28257
  }
28208
28258
  }
28209
28259
  }
28210
- if (parsedUrl.protocol === "https:" && isClientCertificateRequiredHttpResponse(err)) {
28260
+ if (parsedUrl.protocol === "https:" && isClientCertificateRequiredHttpResponse(responseErr)) {
28211
28261
  const retryClient = getCertificateRequiredRetryClient(
28212
28262
  config,
28213
28263
  hostname,
@@ -28233,7 +28283,7 @@ async function sendHttpRequest(req, config) {
28233
28283
  }
28234
28284
  }
28235
28285
  }
28236
- return toError(err);
28286
+ return toError(responseErr);
28237
28287
  }
28238
28288
  }
28239
28289
  function toNetworkError(err, config, duration, warning) {
package/dist/server.js CHANGED
@@ -14223,7 +14223,12 @@ var apiToJSfunc = async (ctx) => {
14223
14223
  const entries = Object.entries(ctx.api.inputs ?? {});
14224
14224
  for (const [name, value] of entries) {
14225
14225
  const quoted = new RegExp(`"\\$\\{${name}\\}"`, "g");
14226
- if (typeof value === "string") {
14226
+ if (reqFormat2 === "json" && typeof value !== "string") {
14227
+ formattedBody = formattedBody.replace(
14228
+ quoted,
14229
+ () => "${JSON.stringify(" + name + ")}"
14230
+ );
14231
+ } else if (typeof value === "string") {
14227
14232
  formattedBody = formattedBody.replace(quoted, '"${' + name + '}"');
14228
14233
  } else {
14229
14234
  formattedBody = formattedBody.replace(quoted, "${" + name + "}");
@@ -27662,8 +27667,40 @@ function trackSocketForAgent(socket, host, protocol) {
27662
27667
  });
27663
27668
  socket.once("end", () => {
27664
27669
  connectionTracker.close(connId, "server");
27670
+ if (!socket._httpMessage) {
27671
+ destroySocketQuietly(socket);
27672
+ }
27665
27673
  });
27666
27674
  }
27675
+ function destroySocketQuietly(socket) {
27676
+ if (!socket || socket.destroyed) {
27677
+ return;
27678
+ }
27679
+ try {
27680
+ socket.removeAllListeners("error");
27681
+ socket.on("error", () => {
27682
+ });
27683
+ socket.destroy();
27684
+ } catch {
27685
+ }
27686
+ }
27687
+ function requestSocket(source) {
27688
+ return source?.request?.socket || source?.response?.request?.socket || source?.socket;
27689
+ }
27690
+ function dropKeepAliveSocket(source) {
27691
+ destroySocketQuietly(requestSocket(source));
27692
+ }
27693
+ function isDeadKeepAliveError(err) {
27694
+ if (!err || err.response) {
27695
+ return false;
27696
+ }
27697
+ const code = err.code || err.cause?.code;
27698
+ if (code === "ECONNRESET" || code === "EPIPE") {
27699
+ return true;
27700
+ }
27701
+ const message = typeof err.message === "string" ? err.message.toLowerCase() : "";
27702
+ return message.includes("socket hang up") || message.includes("econnreset");
27703
+ }
27667
27704
  function createHttpsAgentWithCertificates(hostname, port, protocol, config, opts) {
27668
27705
  const skipValidation = opts?.skipCertificateValidation ?? false;
27669
27706
  const agentKey = getHttpsAgentKey(hostname, port, protocol, config, opts);
@@ -28125,6 +28162,9 @@ async function sendHttpRequest(req, config) {
28125
28162
  };
28126
28163
  const toError = (err, warning) => {
28127
28164
  const duration = Date.now() - start;
28165
+ if (err?.response && Number(err.response.status) >= 400) {
28166
+ dropKeepAliveSocket(err);
28167
+ }
28128
28168
  if (err?.response) {
28129
28169
  const headers = normalizeAxiosHeaders(err.response.headers);
28130
28170
  return {
@@ -28179,8 +28219,18 @@ async function sendHttpRequest(req, config) {
28179
28219
  const response = await executeRequest(false);
28180
28220
  return toSuccess(response);
28181
28221
  } catch (err) {
28182
- if (canRetrySelfSigned && isSelfSignedTlsError(err)) {
28183
- const warning = formatSelfSignedWarning(err);
28222
+ let responseErr = err;
28223
+ if (isDeadKeepAliveError(err)) {
28224
+ dropKeepAliveSocket(err);
28225
+ try {
28226
+ const retryResponse = await executeRequest(false);
28227
+ return toSuccess(retryResponse);
28228
+ } catch (retryErr) {
28229
+ responseErr = retryErr;
28230
+ }
28231
+ }
28232
+ if (canRetrySelfSigned && isSelfSignedTlsError(responseErr)) {
28233
+ const warning = formatSelfSignedWarning(responseErr);
28184
28234
  try {
28185
28235
  const retryResponse = await executeRequest(true);
28186
28236
  return toSuccess(retryResponse, warning);
@@ -28188,7 +28238,7 @@ async function sendHttpRequest(req, config) {
28188
28238
  return toError(retryErr, warning);
28189
28239
  }
28190
28240
  }
28191
- if (parsedUrl.protocol === "https:" && isClientCertificateRequiredTlsError(err)) {
28241
+ if (parsedUrl.protocol === "https:" && isClientCertificateRequiredTlsError(responseErr)) {
28192
28242
  const retryClient = getCertificateRequiredRetryClient(
28193
28243
  config,
28194
28244
  hostname,
@@ -28207,7 +28257,7 @@ async function sendHttpRequest(req, config) {
28207
28257
  }
28208
28258
  }
28209
28259
  }
28210
- if (parsedUrl.protocol === "https:" && isClientCertificateRequiredHttpResponse(err)) {
28260
+ if (parsedUrl.protocol === "https:" && isClientCertificateRequiredHttpResponse(responseErr)) {
28211
28261
  const retryClient = getCertificateRequiredRetryClient(
28212
28262
  config,
28213
28263
  hostname,
@@ -28233,7 +28283,7 @@ async function sendHttpRequest(req, config) {
28233
28283
  }
28234
28284
  }
28235
28285
  }
28236
- return toError(err);
28286
+ return toError(responseErr);
28237
28287
  }
28238
28288
  }
28239
28289
  function toNetworkError(err, config, duration, warning) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mmt-mcp",
3
- "version": "1.43.3",
3
+ "version": "1.44.0-pre",
4
4
  "description": "Multimeter MCP server for Cursor, Copilot, and Claude. Scaffold, validate, format, and run YAML .mmt API tests. Do not invent .mmt syntax.",
5
5
  "mcpName": "io.github.mshobeyri/multimeter",
6
6
  "type": "module",