Skip to main content
Glama

Financial Modeling Prep MCP Server

Apache 2.0
17
59
  • Linux
  • Apple
verify-registry-submission.ts12 kB
#!/usr/bin/env tsx /** * Registry submission verification script * Tests all installation methods and validates registry entry functionality */ import { execSync, spawn } from 'child_process'; import { readFileSync, existsSync, mkdirSync, rmSync } from 'fs'; import { join } from 'path'; interface VerificationResult { success: boolean; message: string; details?: string; } /** * Safely extracts error message from unknown error type. * @param error - The error to extract message from. * @returns The error message string. */ function getErrorMessage(error: unknown): string { return error instanceof Error ? error.message : String(error); } /** * Executes a shell command and returns the output. * @param command - The command to execute. * @param options - Execution options. * @returns The command output as a string. */ function executeCommand(command: string, options: { silent?: boolean; cwd?: string; timeout?: number } = {}): string { try { const result = execSync(command, { encoding: 'utf-8', stdio: options.silent ? 'pipe' : 'inherit', cwd: options.cwd || process.cwd(), timeout: options.timeout || 30000 }); return typeof result === 'string' ? result : ''; } catch (error: any) { throw new Error(`Command failed: ${command}\n${error.message}`); } } /** * Verifies NPM package publication and metadata. * @returns Promise resolving to verification result. */ async function verifyNpmPackage(): Promise<VerificationResult> { console.log('🔍 Verifying NPM package publication...'); try { const packageJson = JSON.parse(readFileSync('package.json', 'utf-8')); const packageName = packageJson.name; const packageVersion = packageJson.version; const mcpName = packageJson.mcpName; // Check if package exists on NPM const npmInfo = executeCommand(`npm view ${packageName}@${packageVersion} --json`, { silent: true }); const npmData = JSON.parse(npmInfo); // Verify version matches if (npmData.version !== packageVersion) { return { success: false, message: 'NPM package version mismatch', details: `Expected ${packageVersion}, found ${npmData.version}` }; } // Verify mcpName field exists if (npmData.mcpName !== mcpName) { return { success: false, message: 'NPM package missing or incorrect mcpName field', details: `Expected ${mcpName}, found ${npmData.mcpName || 'undefined'}` }; } // Verify required fields const requiredFields = ['name', 'version', 'description', 'main', 'bin']; for (const field of requiredFields) { if (!npmData[field]) { return { success: false, message: `NPM package missing required field: ${field}` }; } } console.log(` ✅ Package ${packageName}@${packageVersion} verified on NPM`); console.log(` ✅ MCP name: ${mcpName}`); return { success: true, message: 'NPM package verification successful' }; } catch (error) { return { success: false, message: 'NPM package verification failed', details: getErrorMessage(error) }; } } /** * Verifies NPM package installation readiness. * @returns Promise resolving to verification result. */ async function verifyInstallationReadiness(): Promise<VerificationResult> { console.log('📦 Verifying NPM package installation readiness...'); try { const packageJson = JSON.parse(readFileSync('package.json', 'utf-8')); // Verify binary configuration if (!packageJson.bin || !packageJson.bin['fmp-mcp']) { return { success: false, message: 'NPM package missing binary configuration' }; } // Verify main entry point if (!packageJson.main) { return { success: false, message: 'NPM package missing main entry point' }; } // Verify files array includes dist if (!packageJson.files || !packageJson.files.includes('dist')) { return { success: false, message: 'NPM package files array missing dist directory' }; } // Verify built files exist if (!existsSync('dist/index.js')) { return { success: false, message: 'Built JavaScript files not found in dist directory' }; } console.log(' ✅ Binary configuration: fmp-mcp -> dist/index.js'); console.log(' ✅ Main entry point: dist/index.js'); console.log(' ✅ Distribution files present'); console.log(' ✅ Package ready for installation via NPM/NPX'); return { success: true, message: 'NPM package installation readiness verified' }; } catch (error) { return { success: false, message: 'Installation readiness verification failed', details: getErrorMessage(error) }; } } /** * Validates server.json schema and content. * @returns Promise resolving to verification result. */ async function validateServerJson(): Promise<VerificationResult> { console.log('📋 Validating server.json schema and content...'); try { if (!existsSync('server.json')) { return { success: false, message: 'server.json file not found' }; } const serverConfig = JSON.parse(readFileSync('server.json', 'utf-8')); const packageJson = JSON.parse(readFileSync('package.json', 'utf-8')); // Validate required fields const requiredFields = ['name', 'description', 'version', 'packages']; for (const field of requiredFields) { if (!serverConfig[field]) { return { success: false, message: `server.json missing required field: ${field}` }; } } // Validate version consistency if (serverConfig.version !== packageJson.version) { return { success: false, message: 'Version mismatch between server.json and package.json', details: `server.json: ${serverConfig.version}, package.json: ${packageJson.version}` }; } // Validate package configuration if (!Array.isArray(serverConfig.packages) || serverConfig.packages.length === 0) { return { success: false, message: 'server.json packages array is empty or invalid' }; } const npmPackage = serverConfig.packages.find((pkg: any) => pkg.registry_type === 'npm'); if (!npmPackage) { return { success: false, message: 'server.json missing NPM package configuration' }; } // Validate NPM package fields const requiredPackageFields = ['identifier', 'version', 'transport']; for (const field of requiredPackageFields) { if (!npmPackage[field]) { return { success: false, message: `server.json NPM package missing required field: ${field}` }; } } console.log(' ✅ server.json schema validation passed'); console.log(` ✅ MCP name: ${serverConfig.name}`); console.log(` ✅ Version: ${serverConfig.version}`); console.log(` ✅ NPM package: ${npmPackage.identifier}@${npmPackage.version}`); return { success: true, message: 'server.json validation successful' }; } catch (error) { return { success: false, message: 'server.json validation failed', details: getErrorMessage(error) }; } } /** * Tests HTTP transport functionality. * @returns Promise resolving to verification result. */ async function testHttpTransport(): Promise<VerificationResult> { console.log('🌐 Testing HTTP transport functionality...'); try { const serverConfig = JSON.parse(readFileSync('server.json', 'utf-8')); const npmPackage = serverConfig.packages.find((pkg: any) => pkg.registry_type === 'npm'); if (!npmPackage?.transport?.url) { return { success: false, message: 'No HTTP transport URL found in server.json' }; } const transportUrl = npmPackage.transport.url; console.log(` Testing transport URL: ${transportUrl}`); // Test HTTP endpoint availability (basic connectivity) try { executeCommand(`curl -s -o /dev/null -w "%{http_code}" "${transportUrl}"`, { silent: true, timeout: 10000 }); console.log(' ✅ HTTP transport endpoint is accessible'); } catch (error) { console.log(' ⚠️ HTTP transport endpoint test skipped (curl not available or endpoint not responding)'); } return { success: true, message: 'HTTP transport configuration validated' }; } catch (error) { return { success: false, message: 'HTTP transport test failed', details: getErrorMessage(error) }; } } /** * Runs all verification tests. */ async function runAllVerifications(): Promise<void> { console.log('🚀 Starting registry submission verification...\n'); const tests = [ { name: 'NPM Package Verification', test: verifyNpmPackage }, { name: 'server.json Validation', test: validateServerJson }, { name: 'Installation Readiness Check', test: verifyInstallationReadiness }, { name: 'HTTP Transport Test', test: testHttpTransport } ]; const results: Array<{ name: string; result: VerificationResult }> = []; for (const { name, test } of tests) { console.log(`\n📋 Running: ${name}`); try { const result = await test(); results.push({ name, result }); if (result.success) { console.log(`✅ ${name}: ${result.message}`); } else { console.log(`❌ ${name}: ${result.message}`); if (result.details) { console.log(` Details: ${result.details}`); } } } catch (error) { const failedResult: VerificationResult = { success: false, message: 'Test execution failed', details: getErrorMessage(error) }; results.push({ name, result: failedResult }); console.log(`❌ ${name}: ${failedResult.message}`); console.log(` Details: ${failedResult.details}`); } } // Summary console.log('\n📊 Verification Summary:'); console.log('=' .repeat(50)); const passed = results.filter(r => r.result.success).length; const total = results.length; results.forEach(({ name, result }) => { const status = result.success ? '✅ PASS' : '❌ FAIL'; console.log(`${status} ${name}`); }); console.log('=' .repeat(50)); console.log(`Total: ${passed}/${total} tests passed`); if (passed === total) { console.log('\n🎉 All verifications passed! Registry submission is successful.'); console.log('\n📋 Registry Entry Details:'); const packageJson = JSON.parse(readFileSync('package.json', 'utf-8')); const serverConfig = JSON.parse(readFileSync('server.json', 'utf-8')); console.log(` MCP Name: ${serverConfig.name}`); console.log(` NPM Package: ${packageJson.name}@${packageJson.version}`); console.log(` Description: ${serverConfig.description}`); console.log(` Repository: ${packageJson.repository?.url || 'N/A'}`); console.log('\n📦 Installation Methods Verified:'); console.log(' • Global NPM: npm install -g financial-modeling-prep-mcp-server'); console.log(' • Local NPM: npm install financial-modeling-prep-mcp-server'); console.log(' • NPX: npx financial-modeling-prep-mcp-server'); } else { console.log('\n❌ Some verifications failed. Please review the errors above.'); process.exit(1); } } // Run verifications if this script is executed directly if (import.meta.url === `file://${process.argv[1]}`) { runAllVerifications().catch((error) => { console.error('❌ Verification script failed:', getErrorMessage(error)); process.exit(1); }); } export { runAllVerifications };

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/imbenrabi/Financial-Modeling-Prep-MCP-Server'

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