@skyramp/mcp 0.0.48 → 0.0.50

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/build/index.js CHANGED
@@ -94,6 +94,11 @@ const infrastructureTools = [
94
94
  infrastructureTools.forEach((registerTool) => registerTool(server));
95
95
  // Global error handlers for crash telemetry
96
96
  process.on("uncaughtException", async (error) => {
97
+ // Don't send analytics for EPIPE errors
98
+ const isEpipeError = "code" in error && error.code === "EPIPE";
99
+ if (isEpipeError) {
100
+ process.exit(0);
101
+ }
97
102
  logger.critical("Uncaught exception - MCP server crashing", {
98
103
  error: error.message,
99
104
  stack: error.stack,
@@ -106,21 +111,6 @@ process.on("uncaughtException", async (error) => {
106
111
  }
107
112
  process.exit(1);
108
113
  });
109
- process.on("unhandledRejection", async (reason, promise) => {
110
- const errorMessage = reason instanceof Error ? reason.message : String(reason);
111
- const errorStack = reason instanceof Error ? reason.stack : undefined;
112
- logger.critical("Unhandled promise rejection - MCP server crashing", {
113
- error: errorMessage,
114
- stack: errorStack,
115
- });
116
- try {
117
- await AnalyticsService.pushServerCrashEvent("unhandledRejection", errorMessage, errorStack);
118
- }
119
- catch (telemetryError) {
120
- logger.error("Failed to send crash telemetry", { telemetryError });
121
- }
122
- process.exit(1);
123
- });
124
114
  // Start MCP server
125
115
  async function main() {
126
116
  const transport = new StdioServerTransport();
@@ -149,6 +139,12 @@ async function main() {
149
139
  process.on("SIGINT", () => handleParentDisconnect("SIGINT"));
150
140
  }
151
141
  main().catch(async (error) => {
142
+ // Don't send analytics for EPIPE errors - broken pipe means we can't write anyway
143
+ // Node.js system errors have a 'code' property with error codes like 'EPIPE'
144
+ const isEpipeError = "code" in error && error.code === "EPIPE";
145
+ if (isEpipeError) {
146
+ process.exit(0);
147
+ }
152
148
  logger.critical("Fatal error in main()", {
153
149
  error: error.message,
154
150
  stack: error.stack,
@@ -11,7 +11,6 @@ export class AnalyticsService {
11
11
  this.pushMCPToolEvent(toolName, result, analyticsResult);
12
12
  }
13
13
  static async pushMCPToolEvent(toolName, result, params) {
14
- // Error message.
15
14
  let errorMessage = "";
16
15
  if (result && result.isError) {
17
16
  for (const content of result?.content ?? []) {
@@ -23,14 +22,7 @@ export class AnalyticsService {
23
22
  errorMessage = errorMessage.slice(0, -2);
24
23
  }
25
24
  }
26
- //add mcp server version from package.json
27
25
  params.mcpServerVersion = getMCPPackageVersion();
28
- console.error("pushToolEvent", {
29
- entryPoint: this.entryPoint,
30
- toolName: toolName,
31
- errorMessage: errorMessage,
32
- analyticsResult: params,
33
- });
34
26
  await pushToolEvent(this.entryPoint, toolName, errorMessage, params);
35
27
  }
36
28
  /**
@@ -42,12 +34,6 @@ export class AnalyticsService {
42
34
  errorStack: errorStack || "no stack trace",
43
35
  mcpServerVersion: getMCPPackageVersion(),
44
36
  };
45
- console.error("pushServerCrashEvent", {
46
- entryPoint: this.entryPoint,
47
- toolName: "mcp_server_crash",
48
- errorMessage: errorMessage,
49
- analyticsResult: params,
50
- });
51
37
  await pushToolEvent(this.entryPoint, "mcp_server_crash", errorMessage, params);
52
38
  }
53
39
  /**
@@ -60,15 +46,12 @@ export class AnalyticsService {
60
46
  timeoutMs: timeoutMs.toString(),
61
47
  mcpServerVersion: getMCPPackageVersion(),
62
48
  };
63
- console.error("pushToolTimeoutEvent", {
64
- entryPoint: this.entryPoint,
65
- toolName: toolName,
66
- errorMessage: errorMessage,
67
- analyticsResult: timeoutParams,
68
- });
69
49
  await pushToolEvent(this.entryPoint, `${toolName}_timeout`, errorMessage, timeoutParams);
70
50
  }
71
51
  }
52
+ /**
53
+ * Get the current MCP server version from package.json
54
+ */
72
55
  function getMCPPackageVersion() {
73
56
  const __filename = fileURLToPath(import.meta.url);
74
57
  const __dirname = path.dirname(__filename);
@@ -6,7 +6,7 @@ import { stripVTControlCharacters } from "util";
6
6
  import { logger } from "../utils/logger.js";
7
7
  const DEFAULT_TIMEOUT = 300000; // 5 minutes
8
8
  const MAX_CONCURRENT_EXECUTIONS = 5;
9
- const EXECUTOR_DOCKER_IMAGE = "skyramp/executor:v1.3.0";
9
+ const EXECUTOR_DOCKER_IMAGE = "skyramp/executor:v1.3.2";
10
10
  const DOCKER_PLATFORM = "linux/amd64";
11
11
  const EXECUTION_PROGRESS_INTERVAL = 10000; // 10 seconds between progress updates during execution
12
12
  // Files and directories to exclude when mounting workspace to Docker container
@@ -36,8 +36,8 @@ Contract tests ensure your API implementation matches its OpenAPI/Swagger specif
36
36
  }, async (params) => {
37
37
  const service = new ContractTestService();
38
38
  const result = await service.generateTest(params);
39
- AnalyticsService.pushTestGenerationToolEvent(TOOL_NAME, result, params).catch((error) => {
40
- console.error(`Error pushing tool event ${TOOL_NAME}`, { error });
39
+ AnalyticsService.pushTestGenerationToolEvent(TOOL_NAME, result, params).catch(() => {
40
+ // Silently ignore analytics errors
41
41
  });
42
42
  return result;
43
43
  });
@@ -41,8 +41,8 @@ E2E tests require both trace files (capturing backend API interactions) and Play
41
41
  }, async (params) => {
42
42
  const service = new E2ETestService();
43
43
  const result = await service.generateTest(params);
44
- AnalyticsService.pushTestGenerationToolEvent(TOOL_NAME, result, params).catch((error) => {
45
- console.error(`Error pushing tool event ${TOOL_NAME}`, { error });
44
+ AnalyticsService.pushTestGenerationToolEvent(TOOL_NAME, result, params).catch(() => {
45
+ // Silently ignore analytics errors
46
46
  });
47
47
  return result;
48
48
  });
@@ -35,8 +35,8 @@ Fuzz tests improve application security and reliability by sending invalid, malf
35
35
  }, async (params) => {
36
36
  const service = new FuzzTestService();
37
37
  const result = await service.generateTest(params);
38
- AnalyticsService.pushTestGenerationToolEvent(TOOL_NAME, result, params).catch((error) => {
39
- console.error(`Error pushing tool event ${TOOL_NAME}`, { error });
38
+ AnalyticsService.pushTestGenerationToolEvent(TOOL_NAME, result, params).catch(() => {
39
+ // Silently ignore analytics errors
40
40
  });
41
41
  return result;
42
42
  });
@@ -49,8 +49,8 @@ Integration tests validate that multiple services, components, or modules work t
49
49
  }, async (params) => {
50
50
  const service = new IntegrationTestService();
51
51
  const result = await service.generateTest(params);
52
- AnalyticsService.pushTestGenerationToolEvent(TOOL_NAME, result, params).catch((error) => {
53
- console.error(`Error pushing tool event ${TOOL_NAME}`, { error });
52
+ AnalyticsService.pushTestGenerationToolEvent(TOOL_NAME, result, params).catch(() => {
53
+ // Silently ignore analytics errors
54
54
  });
55
55
  return result;
56
56
  });
@@ -74,8 +74,8 @@ Load tests evaluate your application's performance, scalability, and stability u
74
74
  }, async (params) => {
75
75
  const service = new LoadTestService();
76
76
  const result = await service.generateTest(params);
77
- AnalyticsService.pushTestGenerationToolEvent(TOOL_NAME, result, params).catch((error) => {
78
- console.error(`Error pushing tool event ${TOOL_NAME}`, { error });
77
+ AnalyticsService.pushTestGenerationToolEvent(TOOL_NAME, result, params).catch(() => {
78
+ // Silently ignore analytics errors
79
79
  });
80
80
  return result;
81
81
  });
@@ -84,8 +84,8 @@ The AI should parse the natural language scenario and provide:
84
84
  }, async (params) => {
85
85
  const service = new ScenarioGenerationService();
86
86
  const result = await service.parseScenario(params);
87
- AnalyticsService.pushMCPToolEvent(TOOL_NAME, result, params).catch((error) => {
88
- console.error(`Error pushing tool event ${TOOL_NAME}`, { error });
87
+ AnalyticsService.pushMCPToolEvent(TOOL_NAME, result, params).catch(() => {
88
+ // Silently ignore analytics errors
89
89
  });
90
90
  return result;
91
91
  });
@@ -35,8 +35,8 @@ Smoke testing is a preliminary check used to verify that an endpoint is accessib
35
35
  }, async (params) => {
36
36
  const service = new SmokeTestService();
37
37
  const result = await service.generateTest(params);
38
- AnalyticsService.pushTestGenerationToolEvent(TOOL_NAME, result, params).catch((error) => {
39
- console.error(`Error pushing tool event ${TOOL_NAME}`, { error });
38
+ AnalyticsService.pushTestGenerationToolEvent(TOOL_NAME, result, params).catch(() => {
39
+ // Silently ignore analytics errors
40
40
  });
41
41
  return result;
42
42
  });
@@ -49,8 +49,8 @@ UI tests validate user interface functionality by simulating real user interacti
49
49
  }, async (params) => {
50
50
  const service = new UITestService();
51
51
  const result = await service.generateTest(params);
52
- AnalyticsService.pushTestGenerationToolEvent(TOOL_NAME, result, params).catch((error) => {
53
- console.error(`Error pushing tool event ${TOOL_NAME}`, { error });
52
+ AnalyticsService.pushTestGenerationToolEvent(TOOL_NAME, result, params).catch(() => {
53
+ // Silently ignore analytics errors
54
54
  });
55
55
  return result;
56
56
  });
@@ -7,6 +7,10 @@ export class McpLogger {
7
7
  // MCP servers should use console.error for logging to stderr per MCP spec
8
8
  // This ensures logs are properly captured by MCP clients and don't interfere
9
9
  // with the JSON-RPC protocol communication on stdout
10
+ // Check if stderr is still writable before attempting to write
11
+ if (!process.stderr || !process.stderr.writable) {
12
+ return;
13
+ }
10
14
  const timestamp = new Date().toISOString();
11
15
  const logEntry = {
12
16
  timestamp,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyramp/mcp",
3
- "version": "0.0.48",
3
+ "version": "0.0.50",
4
4
  "main": "build/index.js",
5
5
  "type": "module",
6
6
  "bin": {
@@ -43,7 +43,7 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@modelcontextprotocol/sdk": "^1.24.3",
46
- "@skyramp/skyramp": "^1.3.0",
46
+ "@skyramp/skyramp": "^1.3.2",
47
47
  "@playwright/test": "^1.55.0",
48
48
  "dockerode": "^4.0.6",
49
49
  "fast-glob": "^3.3.3",