@skyramp/mcp 0.0.1 → 0.0.3

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
@@ -15,6 +15,8 @@ import { registerContractTestTool } from "./tools/generateContractRestTool.js";
15
15
  import { registerLoadTestTool } from "./tools/generateLoadRestTool.js";
16
16
  import { registerIntegrationTestTool } from "./tools/generateIntegrationRestTool.js";
17
17
  import { registerEndtoEndTestTool } from "./tools/generateE2ERestTool.js";
18
+ import { registerLoginTool } from "./tools/loginTool.js";
19
+ import { registerLogoutTool } from "./tools/logoutTool.js";
18
20
  const server = new McpServer({
19
21
  name: "Skyramp MCP Server",
20
22
  version: "1.0.0",
@@ -37,6 +39,8 @@ registerIntegrationTestTool(server);
37
39
  registerEndtoEndTestTool(server);
38
40
  registerUITestTool(server);
39
41
  // Register other Skyramp tools
42
+ registerLoginTool(server);
43
+ registerLogoutTool(server);
40
44
  registerExecuteSkyrampTestTool(server);
41
45
  registerTraceTool(server);
42
46
  registerTraceStopTool(server);
@@ -24,8 +24,21 @@ export class TestGenerationService {
24
24
  type: "text",
25
25
  text: `${result}
26
26
 
27
- If the test is successfully created, I can go ahead and refactor your test code to make it modular and reusable?
28
- Reply "yes" to continue, or "no" to skip this step.`,
27
+ If the test was successfully created, I can help refactor your test code to make it more modular and reusable.
28
+ Would you like to proceed with this step?
29
+
30
+ Reply "yes" to continue or "no" to skip.
31
+
32
+ If you reply "yes", I will:
33
+
34
+ Parameterize the test functions into logical groups (e.g., login) to enable reusability for other test scenarios.
35
+
36
+ NOT alter any existing logic, test scenarios, or test cases.
37
+
38
+ NOT add any new logic or classes.
39
+
40
+ Only restructure the code for better modularity and reusability.
41
+ `,
29
42
  },
30
43
  ],
31
44
  isError: false,
@@ -3,13 +3,22 @@ import Docker from "dockerode";
3
3
  import path from "path";
4
4
  import { Writable } from "stream";
5
5
  import { logger } from "../utils/logger.js";
6
+ // Configuration for language-specific file paths
7
+ const LANGUAGE_PATHS = {
8
+ python: "/tmp",
9
+ javascript: "/tmp",
10
+ typescript: "/tmp",
11
+ java: "/app/src",
12
+ };
6
13
  export function registerExecuteSkyrampTestTool(server) {
7
14
  server.registerTool("skyramp_execute_test", {
8
- description: "Execute a Skyramp test",
15
+ description: `Execute a Skyramp test to validate your application using isolated containerized environments.
16
+ Before I can execute the test for you, I need to confirm the following information:
17
+ Authentication: Please provide me with your authentication token (by default we assume a Bearer Token). If you don't require any token for your service please just say: 'No token required'`,
9
18
  inputSchema: {
10
19
  language: z
11
20
  .string()
12
- .describe("Programming language of the test file to execute (e.g., python, javascript, typescript, java). ONLY SUPPORTS PYTHON FOR NOW."),
21
+ .describe("Programming language of the test file to execute (e.g., python, javascript, typescript, java)"),
13
22
  testType: z
14
23
  .string()
15
24
  .describe("Type of the test to execute (e.g., integration, contract, smoke, fuzz, load, e2e, ui). TEST TYPE MUST BE FROM [integration, contract, smoke, fuzz, load, e2e, ui]."),
@@ -18,19 +27,32 @@ export function registerExecuteSkyrampTestTool(server) {
18
27
  .describe("ALWAYS USE ABSOLUTE PATH to the test file to execute"),
19
28
  token: z
20
29
  .string()
21
- .describe("Skyramp authentication token for test execution"),
30
+ .describe("Skyramp authentication token for test execution. Use '' when user confirms 'No token required'"),
22
31
  },
23
32
  annotations: {
24
33
  keywords: ["run test", "execute test"],
25
34
  },
26
35
  }, async (params) => {
27
36
  var docker = new Docker();
28
- var image = "public.ecr.aws/skyramp/rampup/runner:mcp-v0.0.1";
29
- var command = ["./runner.sh", "python", "/tmp/test.py", params.testType];
37
+ var image = "public.ecr.aws/skyramp/rampup/runner:mcp-v0.0.3";
38
+ // Use path.basename for safer filename extraction
39
+ const filename = path.basename(params.testFile);
40
+ if (!filename) {
41
+ throw new Error("Invalid test file path: could not extract filename");
42
+ }
43
+ // Use configurable language paths with fallback
44
+ const basePath = LANGUAGE_PATHS[params.language] || "/tmp";
45
+ const filePath = path.join(basePath, filename);
46
+ var command = [
47
+ "./root/runner.sh",
48
+ params.language,
49
+ filePath,
50
+ params.testType,
51
+ ];
30
52
  const hostConfig = {
31
53
  Mounts: [
32
54
  {
33
- Target: "/tmp/test.py",
55
+ Target: filePath,
34
56
  Source: path.resolve(params.testFile),
35
57
  Type: "bind",
36
58
  },
@@ -50,6 +72,24 @@ export function registerExecuteSkyrampTestTool(server) {
50
72
  var stream = new DockerStream();
51
73
  try {
52
74
  var statusCode = 0;
75
+ // check if image exists
76
+ const images = await docker.listImages();
77
+ const imageExists = images.some((img) => (img.RepoTags && img.RepoTags.includes(image)) ||
78
+ (img.RepoDigests && img.RepoDigests.includes(image)));
79
+ if (!imageExists) {
80
+ // Pull the image if it does not exist
81
+ await new Promise((resolve, reject) => {
82
+ docker.pull(image, (err, stream) => {
83
+ if (err)
84
+ return reject(err);
85
+ docker.modem.followProgress(stream, (err, res) => {
86
+ if (err)
87
+ return reject(err);
88
+ resolve(res);
89
+ });
90
+ });
91
+ });
92
+ }
53
93
  await docker
54
94
  .run(image, command, stream, { Env: env, HostConfig: hostConfig })
55
95
  .then(function (data) {
@@ -0,0 +1,43 @@
1
+ import { SkyrampClient } from "@skyramp/skyramp";
2
+ import { logger } from "../utils/logger.js";
3
+ export function registerLoginTool(server) {
4
+ server.registerTool("skyramp_login", {
5
+ description: "Login to Skyramp platform",
6
+ inputSchema: {},
7
+ annotations: {
8
+ keywords: ["login", "authenticate", "skyramp login"],
9
+ },
10
+ }, async () => {
11
+ const client = new SkyrampClient();
12
+ try {
13
+ logger.info("Attempting to login to Skyramp...");
14
+ const result = await client.login();
15
+ // Strip ANSI codes if result contains them
16
+ const cleanResult = result.replace(/\u001b\[[0-9;]*m/g, "");
17
+ logger.info("Skyramp login successful");
18
+ return {
19
+ content: [
20
+ {
21
+ type: "text",
22
+ text: cleanResult,
23
+ },
24
+ ],
25
+ };
26
+ }
27
+ catch (error) {
28
+ const errorMessage = `Login to Skyramp failed: ${error.message}`;
29
+ logger.error("Skyramp login failed", {
30
+ error: error.message,
31
+ });
32
+ return {
33
+ content: [
34
+ {
35
+ type: "text",
36
+ text: errorMessage,
37
+ },
38
+ ],
39
+ isError: true,
40
+ };
41
+ }
42
+ });
43
+ }
@@ -0,0 +1,43 @@
1
+ import { SkyrampClient } from "@skyramp/skyramp";
2
+ import { logger } from "../utils/logger.js";
3
+ export function registerLogoutTool(server) {
4
+ server.registerTool("skyramp_logout", {
5
+ description: "Logout from Skyramp platform",
6
+ inputSchema: {},
7
+ annotations: {
8
+ keywords: ["logout", "sign out", "skyramp logout"],
9
+ },
10
+ }, async () => {
11
+ const client = new SkyrampClient();
12
+ try {
13
+ logger.info("Attempting to logout from Skyramp...");
14
+ const result = await client.logout();
15
+ // Strip ANSI codes if result contains them
16
+ const cleanResult = result.replace(/\u001b\[[0-9;]*m/g, "");
17
+ logger.info("Skyramp logout successful");
18
+ return {
19
+ content: [
20
+ {
21
+ type: "text",
22
+ text: cleanResult,
23
+ },
24
+ ],
25
+ };
26
+ }
27
+ catch (error) {
28
+ const errorMessage = `Logout from Skyramp failed: ${error.message}`;
29
+ logger.error("Skyramp logout failed", {
30
+ error: error.message,
31
+ });
32
+ return {
33
+ content: [
34
+ {
35
+ type: "text",
36
+ text: errorMessage,
37
+ },
38
+ ],
39
+ isError: true,
40
+ };
41
+ }
42
+ });
43
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyramp/mcp",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "main": "build/index.js",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@modelcontextprotocol/sdk": "^1.11.4",
45
- "@skyramp/skyramp": "^1.2.7",
45
+ "@skyramp/skyramp": "^1.2.9",
46
46
  "dockerode": "^4.0.6",
47
47
  "zod": "^3.25.3"
48
48
  },
@@ -58,4 +58,4 @@
58
58
  "engines": {
59
59
  "node": ">=18"
60
60
  }
61
- }
61
+ }