#!/usr/bin/env node
/**
* Pre-generate TypeScript APIs from configured MCP servers
*
* This script connects to all configured MCP servers and generates
* TypeScript API files that Claude can read as normal codebase files.
*
* Run this during build or manually: npm run generate-apis
*/
import { MCPOrchestrator } from '../src/orchestrator/MCPOrchestrator.js';
import { TypeScriptGenerator } from '../src/generator/TypeScriptGenerator.js';
import type { MCPServerConfig } from '../src/types/index.js';
// Import the same MCP server configuration
// NOTE: In a production setup, this would be loaded from a config file
const MCP_SERVERS: MCPServerConfig[] = [
{
name: 'context7',
transport: 'stdio',
command: 'npx',
args: ['-y', '@upstash/context7-mcp'],
env: {},
},
{
name: 'playwright',
transport: 'stdio',
command: 'npx',
args: ['@playwright/mcp@latest'],
env: {},
},
{
name: 'bright-data',
transport: 'stdio',
command: 'npx',
args: ['@brightdata/mcp'],
env: {
API_TOKEN: process.env.BRIGHT_DATA_API_TOKEN || '83ca9984ed40d7edc01326acf1c4326c3b09ea906db764a56e1d0f421b1c22d5',
},
},
{
name: 'chrome-devtools',
transport: 'stdio',
command: 'npx',
args: ['chrome-devtools-mcp@latest'],
env: {},
},
{
name: 'firecrawl-mcp',
transport: 'stdio',
command: 'npx',
args: ['-y', 'firecrawl-mcp'],
env: {
FIRECRAWL_API_KEY: process.env.FIRECRAWL_API_KEY || 'fc-418ad2bf8944494dbc52cc8a001feda5',
},
},
{
name: 'shadcn',
transport: 'stdio',
command: 'npx',
args: ['-y', 'mcp-remote', 'https://www.shadcn.io/api/mcp'],
env: {},
},
];
async function main() {
console.error('🔧 Pre-generating TypeScript APIs from MCP servers...\n');
const orchestrator = new MCPOrchestrator();
const generator = new TypeScriptGenerator();
// Connect to all MCP servers
console.error(`📡 Connecting to ${MCP_SERVERS.length} MCP servers...`);
let connectedCount = 0;
for (const serverConfig of MCP_SERVERS) {
try {
console.error(` - Connecting to ${serverConfig.name}...`);
await orchestrator.connectServer(serverConfig);
connectedCount++;
console.error(` ✅ Connected`);
} catch (error) {
console.error(` ❌ Failed: ${error instanceof Error ? error.message : String(error)}`);
console.error(` Continuing without ${serverConfig.name}...`);
}
}
console.error(`\n✅ Connected to ${connectedCount}/${MCP_SERVERS.length} servers\n`);
// Get all tools
const allTools = orchestrator.getAllTools();
console.error(`📋 Found ${allTools.length} tools across all servers\n`);
// Generate TypeScript APIs
if (allTools.length > 0) {
console.error('🔨 Generating TypeScript APIs...');
await generator.generateAPIs(allTools, 'generated');
console.error('✅ TypeScript APIs generated successfully\n');
// Show summary
console.error('📊 Generated APIs Summary:');
const byServer = new Map<string, number>();
for (const tool of allTools) {
const [serverName] = tool.name.split('__');
byServer.set(serverName, (byServer.get(serverName) || 0) + 1);
}
for (const [server, count] of byServer) {
console.error(` - ${server}: ${count} tools`);
}
console.error();
} else {
console.error('⚠️ No tools found - skipping API generation');
}
// Disconnect
await orchestrator.disconnect();
console.error('🎉 API generation complete!\n');
console.error('📁 Generated files are in: generated/servers/');
console.error('👀 Claude can now read these files to understand parameter types!\n');
}
main().catch((error) => {
console.error('❌ Fatal error during API generation:');
console.error(error);
process.exit(1);
});