Skip to main content
Glama
index.js•8.38 kB
#!/usr/bin/env node import { Command } from 'commander'; import chalk from 'chalk'; import { IncrementalImpactAnalyzer } from './IncrementalImpactAnalyzer.js'; import { ReportGenerator } from './ReportGenerator.js'; import fs from 'fs/promises'; const program = new Command(); const reportGenerator = new ReportGenerator(); program .name('mcp-token-analyzer') .description('Precise token counting and context efficiency analysis for MCP servers') .version('1.0.0'); program .command('analyze') .description('Perform complete MCP token analysis') .option('-o, --output <file>', 'Output file for detailed results (JSON)') .option('-r, --report <file>', 'Output file for formatted report (TXT)') .option('-c, --csv <file>', 'Output file for CSV data') .option('-q, --quiet', 'Suppress console output except errors') .option('-s, --summary', 'Show only quick summary') .action(async (options) => { try { const analyzer = new IncrementalImpactAnalyzer(); if (!options.quiet) { console.log(chalk.cyan.bold('šŸ” MCP Token Analyzer v1.0.0')); console.log(chalk.gray('Analyzing MCP server token consumption...\n')); } // Perform analysis const results = await analyzer.performCompleteAnalysis(); if (results.error) { console.error(chalk.red('āŒ Analysis failed:'), results.error); if (results.configPaths) { console.log(chalk.gray('Checked configuration paths:')); results.configPaths.forEach(path => console.log(chalk.gray(` • ${path}`))); } process.exit(1); } // Generate outputs if (options.output) { await fs.writeFile(options.output, JSON.stringify(results, null, 2)); if (!options.quiet) console.log(chalk.green(`šŸ“„ Detailed results saved to ${options.output}`)); } if (options.report) { const report = reportGenerator.generateCompleteReport(results); await fs.writeFile(options.report, report); if (!options.quiet) console.log(chalk.green(`šŸ“‹ Report saved to ${options.report}`)); } if (options.csv) { const csvData = reportGenerator.generateCSVExport(results); await fs.writeFile(options.csv, csvData); if (!options.quiet) console.log(chalk.green(`šŸ“Š CSV data saved to ${options.csv}`)); } // Console output if (!options.quiet) { if (options.summary) { console.log('\n' + reportGenerator.generateQuickSummary(results)); } else { console.log('\n' + reportGenerator.generateCompleteReport(results)); } } } catch (error) { console.error(chalk.red('āŒ Analysis failed:'), error.message); if (process.env.DEBUG) { console.error(error.stack); } process.exit(1); } }); program .command('config') .description('Show MCP configuration information') .action(async () => { try { const { MCPConfigurationAnalyzer } = await import('./MCPConfigurationAnalyzer.js'); const analyzer = new MCPConfigurationAnalyzer(); console.log(chalk.cyan.bold('šŸ“‹ MCP Configuration Analysis\n')); const config = await analyzer.analyzeConfiguration(); if (!config.hasConfiguration) { console.log(chalk.yellow('āš ļø No MCP configuration found')); console.log(chalk.gray('Checked paths:')); analyzer.configPaths.forEach(path => console.log(chalk.gray(` • ${path}`))); return; } console.log(chalk.green(`āœ… Configuration found: ${config.configPath}`)); console.log(`Total servers: ${config.totalServers}`); if (config.servers.length > 0) { console.log('\n' + chalk.cyan('Configured Servers:')); config.servers.forEach(server => { const status = server.disabled ? chalk.red('DISABLED') : chalk.green('ACTIVE'); console.log(` • ${server.name} (${server.configType}) - ${status}`); }); } } catch (error) { console.error(chalk.red('āŒ Configuration analysis failed:'), error.message); process.exit(1); } }); program .command('quick') .description('Quick token estimation (no server connection)') .action(async () => { try { const { MCPConfigurationAnalyzer } = await import('./MCPConfigurationAnalyzer.js'); const { TokenMeasurementEngine } = await import('./TokenMeasurementEngine.js'); const configAnalyzer = new MCPConfigurationAnalyzer(); const tokenEngine = new TokenMeasurementEngine(); console.log(chalk.cyan.bold('⚔ Quick Token Estimation\n')); const config = await configAnalyzer.analyzeConfiguration(); if (!config.hasConfiguration) { console.log(chalk.yellow('āš ļø No MCP configuration found')); return; } const activeServers = config.servers.filter(s => !s.disabled); const baseline = tokenEngine.measureBaselineTokens(); // Rough estimation without connecting to servers const estimatedTokensPerServer = 1500; // Conservative estimate based on research const estimatedMcpTokens = activeServers.length * estimatedTokensPerServer; const totalEstimated = baseline.totalBuiltInTokens + estimatedMcpTokens; const percentageEstimated = (totalEstimated / 200000) * 100; console.log(`Built-in tools: ${baseline.totalBuiltInTokens} tokens`); console.log(`Active MCP servers: ${activeServers.length}`); console.log(`Estimated MCP tokens: ${estimatedMcpTokens.toLocaleString()} tokens`); console.log(`Total estimated overhead: ${totalEstimated.toLocaleString()} tokens`); console.log(`Estimated context usage: ${percentageEstimated.toFixed(1)}%`); if (percentageEstimated > 10) { console.log(chalk.yellow('\nāš ļø High estimated overhead detected')); console.log(chalk.gray('Run full analysis for detailed recommendations')); } else { console.log(chalk.green('\nāœ… Overhead appears reasonable')); } } catch (error) { console.error(chalk.red('āŒ Quick estimation failed:'), error.message); process.exit(1); } }); program .command('doctor') .description('Validate analyzer setup and dependencies') .action(async () => { console.log(chalk.cyan.bold('🩺 MCP Token Analyzer Doctor\n')); const checks = []; // Check Node.js version const nodeVersion = process.version; checks.push({ name: 'Node.js Version', status: true, message: nodeVersion }); // Check for MCP configuration try { const { MCPConfigurationAnalyzer } = await import('./MCPConfigurationAnalyzer.js'); const analyzer = new MCPConfigurationAnalyzer(); const config = await analyzer.analyzeConfiguration(); checks.push({ name: 'MCP Configuration', status: config.hasConfiguration, message: config.hasConfiguration ? `Found: ${config.configPath}` : 'Not found' }); } catch (error) { checks.push({ name: 'MCP Configuration', status: false, message: `Error: ${error.message}` }); } // Check write permissions try { await fs.writeFile('test-write.tmp', 'test'); await fs.unlink('test-write.tmp'); checks.push({ name: 'File System Access', status: true, message: 'Write permissions OK' }); } catch (error) { checks.push({ name: 'File System Access', status: false, message: `Cannot write files: ${error.message}` }); } // Display results checks.forEach(check => { const icon = check.status ? chalk.green('āœ…') : chalk.red('āŒ'); console.log(`${icon} ${check.name}: ${check.message}`); }); const allPassed = checks.every(check => check.status); console.log('\n' + (allPassed ? chalk.green('šŸŽ‰ All checks passed! Analyzer is ready to use.') : chalk.yellow('āš ļø Some checks failed. See messages above.') )); }); // Handle unknown commands program.on('command:*', () => { console.error(chalk.red('āŒ Unknown command. Use --help for available commands.')); process.exit(1); }); // Default action if (process.argv.length === 2) { program.help(); } program.parse();

Latest Blog Posts

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/cordlesssteve/token-analyzer-mcp'

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