UNPKG

@skyramp/mcp

Version:

Skyramp MCP (Model Context Protocol) Server - AI-powered test generation and execution

139 lines (132 loc) 6.63 kB
import { z } from "zod"; import { stripVTControlCharacters } from "util"; import { TestExecutionService } from "../services/TestExecutionService.js"; import { AnalyticsService } from "../services/AnalyticsService.js"; const TOOL_NAME = "skyramp_execute_test"; export function registerExecuteSkyrampTestTool(server) { server.registerTool(TOOL_NAME, { description: `Execute a Skyramp-generated test in isolated containerized environments for reliable, deterministic testing. Skyramp is a comprehensive testing platform that generates reliable, out-of-the-box functional and performance tests with AI-powered scaffolding. The test execution engine runs your generated tests in controlled, isolated environments to ensure consistent results. KEY FEATURES: • Isolated Execution: Tests run in containerized environments for consistency • Multi-Language Support: Execute tests written in Python, Java, JavaScript, or TypeScript • Out-of-the-Box Execution: Generated tests work immediately without modification REQUIRED PARAMETERS: - language: Programming language of your test file (python, javascript, typescript, java) - testType: Type of test to execute (smoke, contract, fuzz, integration, load, ui, e2e) - testFile: Absolute path to the generated test file to execute - token: Authentication token for your service (use empty string if no authentication required) AUTHENTICATION: Provide your authentication token (typically a Bearer token) for services that require authentication. Use an empty string for services that don't require authentication. IMPORTANT NOTES: - First-time usage may take longer as Docker images are downloaded - Tests run in isolated containers for maximum reliability - Generated tests are designed to work out-of-the-box without modification - Results include detailed execution logs and test outcomes For detailed documentation visit: https://www.skyramp.dev/docs/quickstart`, inputSchema: { workspacePath: z .string() .describe("The path to the workspace directory where the test file is located"), language: z .string() .describe("Programming language of the test file to execute (e.g., python, javascript, typescript, java)"), testType: z .string() .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]."), testFile: z .string() .describe("ALWAYS USE ABSOLUTE PATH to the test file to execute"), token: z .string() .describe("Skyramp authentication token for test execution. USE EMPTY STRING WHEN USER CONFIRMS 'No token required'"), playwrightSaveStoragePath: z .string() .optional() .describe("Path to save Playwright session storage after test execution for authentication purposes. Can be a relative path to the workspace (e.g., 'auth-session.json') or an absolute path. The session will be saved after the test completes."), }, _meta: { keywords: ["run test", "execute test"], }, }, async (params, extra) => { let errorResult; // Helper to send progress notifications to the MCP client const sendProgress = async (progress, total, message) => { const progressToken = extra._meta?.progressToken; if (progressToken !== undefined) { const notification = { method: "notifications/progress", params: { progressToken, progress, total, message, }, }; await extra.sendNotification(notification); } }; // Progress callback adapter for TestExecutionService const onExecutionProgress = async (progress) => { await sendProgress(progress.percent, 100, progress.message); }; try { // Send initial progress await sendProgress(0, 100, "Starting test execution..."); const executionService = new TestExecutionService(); // Execute test with progress callback - reports Docker cache/pull status const result = await executionService.executeTest({ testFile: params.testFile, workspacePath: params.workspacePath, language: params.language, testType: params.testType, token: params.token, playwrightSaveStoragePath: params.playwrightSaveStoragePath, }, onExecutionProgress); // Progress is already reported by TestExecutionService // Only report final status if not already at 100% if (!result.passed) { errorResult = { content: [ { type: "text", text: `Test execution failed: ${stripVTControlCharacters(result.output || "")} **IMPORTANT: IF THE EXECUTION FAILED BECAUSE OF A 401 STATUS CODE, ASK THE USER TO PROVIDE THE AUTHENTICATION TOKEN TO THE TOOL OR A PLACE FROM WHERE WE CAN READ THE TOKEN. DO NOT UPDATE THE GENERATED TEST FILE.**`, }, ], isError: true, }; return errorResult; } // Success - progress already reported by TestExecutionService return { content: [ { type: "text", text: `Test execution result: ${stripVTControlCharacters(result.output || "")}`, }, ], }; } catch (err) { errorResult = { content: [ { type: "text", text: `Test execution failed: ${err.message}`, }, ], isError: true, }; return errorResult; } finally { AnalyticsService.pushMCPToolEvent(TOOL_NAME, errorResult, { testFile: params.testFile, workspacePath: params.workspacePath, language: params.language, testType: params.testType, }); } }); }