Skip to main content
Glama

Enhanced MCP MSSQL Server

by michaelyuwh
test-ci.cjs8.82 kB
#!/usr/bin/env node /** * CI-friendly test script for the MCP MSSQL Server * Tests compilation, imports, and basic functionality without database connection */ const fs = require('fs'); const path = require('path'); class CITester { constructor() { this.passed = 0; this.failed = 0; } log(message, type = 'info') { const timestamp = new Date().toISOString(); const prefix = { 'info': '📋', 'success': '✅', 'error': '❌', 'warning': '⚠️' }[type] || '📋'; console.log(`${prefix} [${timestamp}] ${message}`); } assert(condition, message) { if (condition) { this.passed++; this.log(`PASS: ${message}`, 'success'); } else { this.failed++; this.log(`FAIL: ${message}`, 'error'); } } async testFileStructure() { this.log('Testing project file structure...', 'info'); // Check essential files exist const essentialFiles = [ 'package.json', 'tsconfig.json', 'src/index.ts', 'dist/index.js', 'dist/index.d.ts', 'README.md', 'LICENSE' ]; for (const file of essentialFiles) { const exists = fs.existsSync(path.join(process.cwd(), file)); this.assert(exists, `Essential file exists: ${file}`); } } async testPackageJson() { this.log('Testing package.json configuration...', 'info'); try { const packagePath = path.join(process.cwd(), 'package.json'); const packageContent = JSON.parse(fs.readFileSync(packagePath, 'utf8')); this.assert(packageContent.name === 'mcp-mssql-server', 'Package name is correct'); this.assert(packageContent.type === 'module', 'Package type is ES module'); this.assert(packageContent.main === 'dist/index.js', 'Main entry point is correct'); // Check dependencies const deps = packageContent.dependencies || {}; this.assert('@modelcontextprotocol/sdk' in deps, 'MCP SDK dependency exists'); this.assert('mssql' in deps, 'MSSQL dependency exists'); this.assert('zod' in deps, 'Zod dependency exists'); // Check scripts const scripts = packageContent.scripts || {}; this.assert('build' in scripts, 'Build script exists'); this.assert('test' in scripts, 'Test script exists'); this.assert('start' in scripts, 'Start script exists'); } catch (error) { this.assert(false, `Package.json parsing: ${error.message}`); } } async testTypeScriptCompilation() { this.log('Testing TypeScript compilation...', 'info'); try { // Check if dist files were created const distExists = fs.existsSync(path.join(process.cwd(), 'dist')); this.assert(distExists, 'Dist directory exists'); const indexJsExists = fs.existsSync(path.join(process.cwd(), 'dist/index.js')); this.assert(indexJsExists, 'Compiled JavaScript exists'); const indexDtsExists = fs.existsSync(path.join(process.cwd(), 'dist/index.d.ts')); this.assert(indexDtsExists, 'TypeScript declarations exist'); // Check if compiled JS is valid if (indexJsExists) { const compiledContent = fs.readFileSync(path.join(process.cwd(), 'dist/index.js'), 'utf8'); this.assert(compiledContent.includes('import') || compiledContent.includes('export'), 'Compiled code uses ES modules'); this.assert(compiledContent.length > 1000, 'Compiled code has substantial content'); } } catch (error) { this.assert(false, `TypeScript compilation check: ${error.message}`); } } async testImports() { this.log('Testing module imports...', 'info'); try { // Check if package.json dependencies are installed const nodeModulesExists = fs.existsSync(path.join(process.cwd(), 'node_modules')); this.assert(nodeModulesExists, 'node_modules directory exists'); if (nodeModulesExists) { const mcpSdkExists = fs.existsSync(path.join(process.cwd(), 'node_modules/@modelcontextprotocol')); this.assert(mcpSdkExists, 'MCP SDK package is installed'); const mssqlExists = fs.existsSync(path.join(process.cwd(), 'node_modules/mssql')); this.assert(mssqlExists, 'MSSQL package is installed'); const zodExists = fs.existsSync(path.join(process.cwd(), 'node_modules/zod')); this.assert(zodExists, 'Zod package is installed'); } // Check if the compiled code imports these modules const distPath = path.join(process.cwd(), 'dist/index.js'); if (fs.existsSync(distPath)) { const distContent = fs.readFileSync(distPath, 'utf8'); this.assert(distContent.includes('@modelcontextprotocol/sdk'), 'Compiled code imports MCP SDK'); this.assert(distContent.includes('mssql'), 'Compiled code imports MSSQL'); this.assert(distContent.includes('zod'), 'Compiled code imports Zod'); } } catch (error) { this.assert(false, `Import test: ${error.message}`); } } async testConfigFiles() { this.log('Testing configuration files...', 'info'); // Test .env.example const envExampleExists = fs.existsSync(path.join(process.cwd(), '.env.example')); this.assert(envExampleExists, '.env.example file exists'); if (envExampleExists) { const envContent = fs.readFileSync(path.join(process.cwd(), '.env.example'), 'utf8'); this.assert(envContent.includes('MSSQL_SERVER'), '.env.example contains MSSQL_SERVER'); this.assert(envContent.includes('MSSQL_DATABASE'), '.env.example contains MSSQL_DATABASE'); } // Test tsconfig.json try { const tsconfigPath = path.join(process.cwd(), 'tsconfig.json'); const tsconfigContent = JSON.parse(fs.readFileSync(tsconfigPath, 'utf8')); this.assert(tsconfigContent.compilerOptions, 'tsconfig.json has compilerOptions'); this.assert(tsconfigContent.compilerOptions.target, 'tsconfig.json specifies target'); this.assert(tsconfigContent.compilerOptions.outDir === './dist', 'tsconfig.json outDir is dist'); } catch (error) { this.assert(false, `tsconfig.json parsing: ${error.message}`); } } async testDocumentation() { this.log('Testing documentation...', 'info'); const docFiles = [ 'README.md', 'CONTRIBUTING.md', 'ENHANCEMENTS.md' ]; for (const docFile of docFiles) { const exists = fs.existsSync(path.join(process.cwd(), docFile)); this.assert(exists, `Documentation file exists: ${docFile}`); if (exists) { const content = fs.readFileSync(path.join(process.cwd(), docFile), 'utf8'); this.assert(content.length > 100, `${docFile} has substantial content`); } } } async testGitHubWorkflows() { this.log('Testing GitHub workflows...', 'info'); const workflowDir = path.join(process.cwd(), '.github/workflows'); const workflowExists = fs.existsSync(workflowDir); this.assert(workflowExists, '.github/workflows directory exists'); if (workflowExists) { const workflows = fs.readdirSync(workflowDir).filter(f => f.endsWith('.yml')); this.assert(workflows.length > 0, 'At least one workflow file exists'); for (const workflow of workflows) { const workflowPath = path.join(workflowDir, workflow); const content = fs.readFileSync(workflowPath, 'utf8'); this.assert(content.includes('name:'), `${workflow} has proper YAML structure`); this.assert(content.includes('on:'), `${workflow} has trigger configuration`); this.assert(content.includes('jobs:'), `${workflow} defines jobs`); } } } async runAllTests() { this.log('🧪 Starting CI-friendly MCP MSSQL Server tests...', 'info'); try { await this.testFileStructure(); await this.testPackageJson(); await this.testTypeScriptCompilation(); await this.testImports(); await this.testConfigFiles(); await this.testDocumentation(); await this.testGitHubWorkflows(); this.log('📊 Test Results Summary:', 'info'); this.log(`✅ Passed: ${this.passed}`, 'success'); this.log(`❌ Failed: ${this.failed}`, this.failed > 0 ? 'error' : 'info'); const success = this.failed === 0; this.log(`🎯 Overall Result: ${success ? 'SUCCESS' : 'FAILURE'}`, success ? 'success' : 'error'); process.exit(this.failed === 0 ? 0 : 1); } catch (error) { this.log(`💥 Fatal error during testing: ${error.message}`, 'error'); console.error(error.stack); process.exit(1); } } } // Run tests if this script is executed directly if (require.main === module) { const tester = new CITester(); tester.runAllTests().catch(error => { console.error('💥 Unhandled error:', error); process.exit(1); }); } module.exports = { CITester };

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/michaelyuwh/mcp-mssql-connector'

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