@skyramp/mcp
Version:
Skyramp MCP (Model Context Protocol) Server - AI-powered test generation and execution
139 lines (132 loc) • 6.63 kB
JavaScript
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,
});
}
});
}