Skip to main content
Glama

MCP API Server

by fikri2992
code-generator-integration.test.ts9.42 kB
import { describe, it, expect } from 'vitest'; import { CodeGenerator } from '../src/generator/code-generator.js'; import { ParsedAPICollection } from '../src/parser/types.js'; import * as path from 'path'; import * as fs from 'fs'; import * as os from 'os'; describe('CodeGenerator Integration', () => { const sampleAPICollection: ParsedAPICollection = { name: 'Test API', description: 'Test API collection for integration testing', baseUrl: 'https://api.example.com', apis: [ { name: 'Get User', method: 'GET', url: 'https://api.example.com/users/{id}', description: 'Get user by ID', parameters: [ { name: 'id', type: 'string', required: true, description: 'User ID', location: 'path', }, ], sourceLocation: { lineNumber: 1 }, }, { name: 'Create User', method: 'POST', url: 'https://api.example.com/users', description: 'Create new user', body: { name: 'John Doe', email: 'john@example.com' }, parameters: [ { name: 'name', type: 'string', required: true, description: 'User name', location: 'body', }, { name: 'email', type: 'string', required: true, description: 'User email', location: 'body', }, ], sourceLocation: { lineNumber: 10 }, }, ], curlCommands: [], rawMarkdown: '# Test API\n\n## Get User\n\n## Create User', metadata: { fileName: 'test-api.md', parsedAt: new Date().toISOString(), headings: ['Test API', 'Get User', 'Create User'], codeBlocks: 2, curlCommandsFound: 2, }, }; it('should generate complete MCP server from API collection', async () => { // Create temporary directory for output const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mcp-generator-test-')); try { const generator = new CodeGenerator({ outputDir: tempDir, debug: false, overwrite: true, server: { name: 'Test API Server', version: '1.0.0', description: 'Generated test server', packageName: 'test-api-server', author: 'Test Author', license: 'MIT', }, toolGeneration: { includeDescriptions: true, strictValidation: true, toolNamePrefix: 'api_', }, validationGeneration: { strictValidation: true, includeCustomErrors: true, runtimeTypeChecking: true, }, }); const result = await generator.generateFromAPICollection(sampleAPICollection); // Debug: log errors if any if (result.errors.length > 0) { console.log('Generation errors:', result.errors); } if (result.warnings.length > 0) { console.log('Generation warnings:', result.warnings); } // Verify generation results expect(result.stats.toolsGenerated).toBe(2); expect(result.stats.apisProcessed).toBe(2); expect(result.stats.errors).toBe(0); expect(result.tools).toHaveLength(2); // Verify server structure expect(result.server.name).toBe('Test API Server'); expect(result.server.tools).toHaveLength(2); expect(result.server.apis).toHaveLength(2); // Verify tools const getUserTool = result.tools.find(t => t.name === 'api_get_get_user'); expect(getUserTool).toBeDefined(); expect(getUserTool!.httpMethod).toBe('GET'); expect(getUserTool!.hasBody).toBe(false); const createUserTool = result.tools.find(t => t.name === 'api_post_create_user'); expect(createUserTool).toBeDefined(); expect(createUserTool!.httpMethod).toBe('POST'); expect(createUserTool!.hasBody).toBe(true); // Verify validation generation expect(result.validation.stats.schemasGenerated).toBe(2); expect(result.validation.stats.rulesGenerated).toBeGreaterThan(0); expect(result.validation.validationCode).toContain('ValidationError'); expect(result.validation.typeDefinitions).toContain('interface'); // Verify files would be generated (we're not actually writing files in this test) // but we can check that the generation process completed successfully expect(result.errors).toHaveLength(0); } finally { // Clean up temporary directory fs.rmSync(tempDir, { recursive: true, force: true }); } }); it('should handle API collection with validation errors gracefully', async () => { const invalidAPICollection: ParsedAPICollection = { name: 'Invalid API', apis: [ { name: '', // Invalid: empty name method: 'GET', url: 'invalid-url', // Invalid: not a proper URL sourceLocation: { lineNumber: 1 }, }, ], curlCommands: [], rawMarkdown: '# Invalid API', metadata: { parsedAt: new Date().toISOString(), headings: ['Invalid API'], codeBlocks: 0, curlCommandsFound: 0, }, }; const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mcp-generator-error-test-')); try { const generator = new CodeGenerator({ outputDir: tempDir, debug: false, server: { name: 'Invalid API Server', }, }); const result = await generator.generateFromAPICollection(invalidAPICollection); // Should handle errors gracefully - either errors or warnings should be generated const hasIssues = result.stats.errors > 0 || result.errors.length > 0 || result.warnings.length > 0; expect(hasIssues).toBe(true); // Should still generate some output even with invalid input expect(result.tools.length).toBeGreaterThanOrEqual(0); } finally { fs.rmSync(tempDir, { recursive: true, force: true }); } }); it('should generate proper template context', async () => { const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mcp-generator-context-test-')); try { const generator = new CodeGenerator({ outputDir: tempDir, debug: false, server: { name: 'Context Test Server', version: '2.0.0', author: 'Context Test Author', }, }); // Update the server generator config to use the correct version generator['serverGenerator'].updateConfig({ serverVersion: '2.0.0', }); const result = await generator.generateFromAPICollection(sampleAPICollection); // Verify template context structure expect(result.server.metadata.generatedBy).toBe('MCP Builder CLI'); expect(result.server.metadata.toolCount).toBe(2); expect(result.server.metadata.apiCount).toBe(2); expect(result.server.version).toBe('2.0.0'); // Verify dependencies are included expect(result.server.dependencies.length).toBeGreaterThan(0); expect(result.server.dependencies.some(dep => dep.name === '@modelcontextprotocol/sdk')).toBe(true); expect(result.server.dependencies.some(dep => dep.name === 'zod')).toBe(true); // Verify imports and exports expect(result.server.imports.length).toBeGreaterThan(0); expect(result.server.exports.length).toBeGreaterThan(0); } finally { fs.rmSync(tempDir, { recursive: true, force: true }); } }); it('should generate warnings for potential issues', async () => { const problematicAPICollection: ParsedAPICollection = { name: 'Problematic API', apis: [ { name: 'Complex Endpoint', method: 'POST', url: 'https://api.example.com/complex', // Many parameters to trigger warning parameters: Array.from({ length: 12 }, (_, i) => ({ name: `param${i}`, type: 'string' as const, required: i < 6, description: `Parameter ${i}`, location: 'query' as const, })), sourceLocation: { lineNumber: 1 }, }, { name: 'Another Endpoint', method: 'GET', url: 'https://api.example.com/another', // No description to trigger warning sourceLocation: { lineNumber: 10 }, }, ], curlCommands: [], rawMarkdown: '# Problematic API', metadata: { parsedAt: new Date().toISOString(), headings: ['Problematic API'], codeBlocks: 0, curlCommandsFound: 0, }, }; const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mcp-generator-warnings-test-')); try { const generator = new CodeGenerator({ outputDir: tempDir, debug: false, server: { name: 'Problematic API Server', }, }); const result = await generator.generateFromAPICollection(problematicAPICollection); // Should generate warnings expect(result.warnings.length).toBeGreaterThan(0); expect(result.warnings.some(w => w.includes('more than'))).toBe(true); expect(result.warnings.some(w => w.includes('missing descriptions'))).toBe(true); } finally { fs.rmSync(tempDir, { recursive: true, force: true }); } }); });

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