UNPKG

@skyramp/mcp

Version:

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

144 lines (134 loc) 6.09 kB
import { z } from "zod"; import { TestDiscoveryService } from "../../services/TestDiscoveryService.js"; import { logger } from "../../utils/logger.js"; import { StateManager, } from "../../utils/AnalysisStateManager.js"; import * as path from "path"; import { AnalyticsService } from "../../services/AnalyticsService.js"; const TOOL_NAME = "skyramp_discover_tests"; /** * Register the Skyramp test discovery tool with the MCP server * * This tool scans a repository for test files generated by Skyramp, * extracts metadata from each test, and returns a comprehensive list * of all discovered tests with their properties. */ export function registerDiscoverTestsTool(server) { server.registerTool("skyramp_discover_tests", { description: ` ⚠️ MANDATORY FIRST STEP - DISPLAY THIS WARNING: Before ANY other response text, you MUST output this exact message: "** This tool is currently in Early Preview stage. Please verify the results. **" DO NOT proceed with tool calls until you have displayed this warning in your response. ❌ WRONG: Calling this tool without first displaying the warning message to the user ✅ CORRECT: First display the warning message in plain text, THEN call this tool EXPECTED FLOW: 1. System displays: "** This tool is currently in Early Preview stage..." 2. System calls: skyramp_discover_tests(...) 3. System processes results Discover all Skyramp-generated tests in a repository. This tool scans the specified repository for test files that were generated by Skyramp. It identifies tests across multiple languages (Python, JavaScript, TypeScript, Java) and extracts comprehensive metadata in the unified TestAnalysisResult format. **WORKFLOW:** This is an OPTIONAL first step if you need to find all tests. If you already know which tests to analyze, you can skip this and go directly to drift analysis. **STATE FILE MODE:** - Saves results to filesystem state file - Returns summary + stateFile path (reduces token usage by 98%+) - Pass stateFile to next tool in chain **NEXT STEP:** Call \`skyramp_analyze_test_drift\` with stateFile **Output:** {summary, stateFile, sessionId, stateFileSize, message}`, inputSchema: { repositoryPath: z .string() .describe("Absolute path to the repository to scan for Skyramp tests (e.g., /Users/dev/my-project)"), sessionId: z .string() .optional() .describe("Optional session ID for state file. Auto-generated if not provided."), }, }, async (args) => { let errorResult; try { logger.info(`Discovering Skyramp tests in repository: ${args.repositoryPath}`); // Validate input if (!args.repositoryPath) { errorResult = { content: [ { type: "text", text: JSON.stringify({ error: "repositoryPath is required", }, null, 2), }, ], isError: true, }; return errorResult; } // Resolve to absolute path const absolutePath = path.resolve(args.repositoryPath); // Step 1: Discover tests const testDiscoveryService = new TestDiscoveryService(); const discoveryResult = await testDiscoveryService.discoverTests(absolutePath); logger.info(`Test discovery completed. Found ${discoveryResult.tests.length} Skyramp tests`); // Transform to unified TestAnalysisResult format const testAnalysisResults = discoveryResult.tests.map((test) => ({ testFile: test.testFile, testType: test.testType, language: test.language, framework: test.framework, apiSchema: test.apiSchema, generatedAt: test.generatedAt, apiEndpoint: test.apiEndpoint, // drift and execution will be added in subsequent steps })); // Save to state file const stateManager = new StateManager("analysis", args.sessionId); await stateManager.writeData({ tests: testAnalysisResults }, { repositoryPath: absolutePath, step: "discovery", }); const stateSize = await stateManager.getSizeFormatted(); logger.info(`Saved ${testAnalysisResults.length} tests to state file: ${stateManager.getStatePath()} (${stateSize})`); const responseData = { summary: { totalTests: testAnalysisResults.length, repositoryPath: absolutePath, }, stateFile: stateManager.getStatePath(), sessionId: stateManager.getSessionId(), stateFileSize: stateSize, message: `Discovery complete. Found ${testAnalysisResults.length} tests. Pass stateFile to skyramp_analyze_test_drift.`, generatedAt: new Date().toISOString(), }; return { content: [ { type: "text", text: JSON.stringify(responseData, null, 2), }, ], }; } catch (error) { logger.error(`Test discovery failed: ${error.message}`, error); errorResult = { content: [ { type: "text", text: JSON.stringify({ error: error.message, details: error.stack, }, null, 2), }, ], isError: true, }; return errorResult; } finally { AnalyticsService.pushMCPToolEvent(TOOL_NAME, errorResult, {}); } }); }