Skip to main content
Glama

MCP API Server

by fikri2992
ai-parsing.test.ts11.7 kB
import { AIParser, createAIParser, DEFAULT_AI_PARSER_CONFIG } from '../src/ai/index.js'; import { CurlAnalyzer } from '../src/ai/curl-analyzer.js'; import { OpenAIClient } from '../src/ai/openai-client.js'; // Test data const SAMPLE_MARKDOWN = `# User Management API This API provides endpoints for managing users in the system. ## Get User Retrieve a user by ID: \`\`\`bash curl -X GET "https://api.example.com/users/123" \\ -H "Authorization: Bearer your-token-here" \\ -H "Content-Type: application/json" \`\`\` ## Create User Create a new user: \`\`\`bash curl -X POST "https://api.example.com/users" \\ -H "Authorization: Bearer your-token-here" \\ -H "Content-Type: application/json" \\ -d '{ "name": "John Doe", "email": "john@example.com", "role": "user" }' \`\`\` ## Update User Update an existing user: \`\`\`bash curl -X PUT "https://api.example.com/users/123" \\ -H "Authorization: Bearer your-token-here" \\ -H "Content-Type: application/json" \\ -d '{ "name": "John Smith", "email": "johnsmith@example.com" }' \`\`\` `; const SIMPLE_MARKDOWN = `# Simple API \`\`\`bash curl -X GET "https://api.test.com/data" \`\`\` `; const MALFORMED_MARKDOWN = `# Broken API \`\`\`bash curl -X GET \`\`\` \`\`\`bash not-a-curl-command \`\`\` `; // Mock OpenAI responses for testing const mockOpenAIResponse = { apis: [ { name: "Get User", description: "Retrieve a user by ID", method: "GET", url: "https://api.example.com/users/123", headers: { "Authorization": "Bearer your-token-here", "Content-Type": "application/json" }, parameters: [ { name: "id", type: "string" as const, required: true, location: "path" as const, description: "User ID" } ] } ], metadata: { name: "User Management API", baseUrl: "https://api.example.com", authentication: { type: "bearer" as const, location: "header" as const, name: "Authorization" } }, confidence: 0.9, warnings: [] }; class TestRunner { private testCount = 0; private passedTests = 0; private failedTests = 0; async runTest(name: string, testFn: () => Promise<void>): Promise<void> { this.testCount++; try { await testFn(); console.log(`✅ ${name}`); this.passedTests++; } catch (error) { console.log(`❌ ${name}: ${error instanceof Error ? error.message : 'Unknown error'}`); this.failedTests++; } } printSummary(): void { console.log(`\n📊 Test Summary:`); console.log(`Total: ${this.testCount}`); console.log(`Passed: ${this.passedTests}`); console.log(`Failed: ${this.failedTests}`); console.log(`Success Rate: ${((this.passedTests / this.testCount) * 100).toFixed(1)}%`); } } // Test utilities function assert(condition: boolean, message: string): void { if (!condition) { throw new Error(message); } } function assertExists<T>(value: T | null | undefined, message: string): T { if (value == null) { throw new Error(message); } return value; } // Mock OpenAI client for testing class MockOpenAIClient extends OpenAIClient { constructor() { super({ apiKey: 'test-key' }); } async parseMarkdownToAPISpecs(): Promise<any> { return mockOpenAIResponse; } async analyzeCurlCommand(): Promise<any> { return mockOpenAIResponse.apis[0]; } async optimizeAPISpec(apiSpec: any): Promise<any> { return { ...apiSpec, optimized: true }; } } async function runTests(): Promise<void> { const runner = new TestRunner(); console.log('🧪 Running AI Parsing Tests\n'); // Test CurlAnalyzer await runner.runTest('CurlAnalyzer - Extract curl commands from markdown', async () => { const mockClient = new MockOpenAIClient(); const analyzer = new CurlAnalyzer(mockClient); const commands = analyzer.extractCurlCommands(SAMPLE_MARKDOWN); assert(commands.length === 3, `Expected 3 curl commands, got ${commands.length}`); assert(commands[0].raw.includes('GET'), 'First command should be GET'); assert(commands[1].raw.includes('POST'), 'Second command should be POST'); assert(commands[2].raw.includes('PUT'), 'Third command should be PUT'); }); await runner.runTest('CurlAnalyzer - Handle simple curl command', async () => { const mockClient = new MockOpenAIClient(); const analyzer = new CurlAnalyzer(mockClient); const commands = analyzer.extractCurlCommands(SIMPLE_MARKDOWN); assert(commands.length === 1, `Expected 1 curl command, got ${commands.length}`); assert(commands[0].raw.includes('GET'), 'Command should be GET'); }); await runner.runTest('CurlAnalyzer - Handle malformed markdown', async () => { const mockClient = new MockOpenAIClient(); const analyzer = new CurlAnalyzer(mockClient); const commands = analyzer.extractCurlCommands(MALFORMED_MARKDOWN); // Should still extract the partial curl command assert(commands.length >= 1, 'Should extract at least one command'); }); // Test AIParser configuration await runner.runTest('AIParser - Create with default config', async () => { const config = { ...DEFAULT_AI_PARSER_CONFIG, apiKey: 'test-key' }; const parser = createAIParser(config); const safeConfig = parser.getConfig(); assert(safeConfig.model === 'gpt-4', 'Should use gpt-4 model'); assert(safeConfig.temperature === 0.1, 'Should use low temperature'); }); await runner.runTest('AIParser - Update configuration', async () => { const parser = createAIParser({ apiKey: 'test-key' }); parser.updateConfig({ model: 'gpt-3.5-turbo', temperature: 0.5 }); const config = parser.getConfig(); assert(config.model === 'gpt-3.5-turbo', 'Model should be updated'); assert(config.temperature === 0.5, 'Temperature should be updated'); }); // Test input validation await runner.runTest('AIParser - Validate input - empty markdown', async () => { const parser = createAIParser({ apiKey: 'test-key' }); try { await parser.parseMarkdown(''); assert(false, 'Should throw error for empty markdown'); } catch (error) { assert(error instanceof Error, 'Should throw Error instance'); assert((error as Error).message.includes('empty'), 'Error should mention empty content'); } }); await runner.runTest('AIParser - Validate input - no curl commands', async () => { const parser = createAIParser({ apiKey: 'test-key' }); try { await parser.parseMarkdown('# API\n\nThis is just text with no curl commands.'); assert(false, 'Should throw error for no curl commands'); } catch (error) { assert(error instanceof Error, 'Should throw Error instance'); assert((error as Error).message.includes('curl'), 'Error should mention curl commands'); } }); await runner.runTest('AIParser - Validate input - too large', async () => { const parser = createAIParser({ apiKey: 'test-key' }); const largeMarkdown = 'curl -X GET "https://api.com"' + 'x'.repeat(100000); try { await parser.parseMarkdown(largeMarkdown); assert(false, 'Should throw error for large content'); } catch (error) { assert(error instanceof Error, 'Should throw Error instance'); assert((error as Error).message.includes('large'), 'Error should mention large content'); } }); // Test context inference await runner.runTest('AIParser - Infer context from markdown', async () => { const parser = createAIParser({ apiKey: 'test-key' }); // Use reflection to access private method for testing const inferContext = (parser as any).inferContextFromMarkdown.bind(parser); const context = inferContext(SAMPLE_MARKDOWN); assert(context.apiName === 'User Management API', 'Should infer API name from title'); assert(context.baseUrl === 'https://api.example.com', 'Should infer base URL'); assert(context.expectedEndpoints === 3, 'Should count curl commands'); }); // Test result validation await runner.runTest('AIParser - Validate successful result', async () => { const parser = createAIParser({ apiKey: 'test-key' }); const result = { success: true, apis: [ { name: 'Test API', method: 'GET', url: 'https://api.test.com/data' } ], metadata: { name: 'Test' }, confidence: 0.8, warnings: [], errors: [], processingStats: { totalCurlCommands: 1, successfullyParsed: 1, failedToParse: 0, averageConfidence: 0.8 }, processingTime: 1000 }; const validation = parser.validateResult(result); assert(validation.isValid, 'Valid result should pass validation'); assert(validation.issues.length === 0, 'Valid result should have no issues'); }); await runner.runTest('AIParser - Validate failed result', async () => { const parser = createAIParser({ apiKey: 'test-key' }); const result = { success: false, apis: [], metadata: { name: 'Failed' }, confidence: 0.2, warnings: [], errors: ['Test error'], processingStats: { totalCurlCommands: 0, successfullyParsed: 0, failedToParse: 1, averageConfidence: 0 }, processingTime: 500 }; const validation = parser.validateResult(result); assert(!validation.isValid, 'Failed result should not pass validation'); assert(validation.issues.length > 0, 'Failed result should have issues'); }); // Test error handling await runner.runTest('AIParser - Handle API errors gracefully', async () => { // Create parser with invalid API key to simulate API errors const parser = createAIParser({ apiKey: 'invalid-key' }); const result = await parser.parseMarkdown(SIMPLE_MARKDOWN); assert(!result.success, 'Should fail with invalid API key'); assert(result.errors.length > 0, 'Should have error messages'); assert(result.processingTime > 0, 'Should track processing time'); }); // Test confidence scoring await runner.runTest('CurlAnalyzer - Calculate confidence scores', async () => { const mockClient = new MockOpenAIClient(); const analyzer = new CurlAnalyzer(mockClient); // Test with well-formed curl command const goodCommand = { raw: 'curl -X GET "https://api.example.com/users" -H "Authorization: Bearer token"' }; const goodResult = await analyzer.analyzeCurlCommand(goodCommand); assert(goodResult.confidence > 0.7, 'Well-formed command should have high confidence'); // Test with minimal curl command const minimalCommand = { raw: 'curl https://api.com' }; const minimalResult = await analyzer.analyzeCurlCommand(minimalCommand); assert(minimalResult.confidence < goodResult.confidence, 'Minimal command should have lower confidence'); }); // Test warning generation await runner.runTest('CurlAnalyzer - Generate appropriate warnings', async () => { const mockClient = new MockOpenAIClient(); const analyzer = new CurlAnalyzer(mockClient); const incompleteCommand = { raw: 'curl -X GET' }; const result = await analyzer.analyzeCurlCommand(incompleteCommand); assert(result.warnings.length > 0, 'Incomplete command should generate warnings'); assert(result.warnings.some(w => w.includes('URL')), 'Should warn about missing URL'); }); runner.printSummary(); } // Run tests if this file is executed directly // Note: This check is disabled for TypeScript compatibility export { runTests };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/fikri2992/mcp0'

If you have feedback or need assistance with the MCP directory API, please join our Discord server