import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { getDb, closeDb } from './db/connection.js';
import { runMigrations } from './db/migrations.js';
import { SqliteVectorStore } from './services/sqlite-vector-store.js';
import { SemanticCache } from './services/semantic-cache.js';
import { ProxyManager } from './services/proxy-manager.js';
import { UserManager } from './services/user-manager.js';
import { SessionManager } from './services/session-manager.js';
import { MetricsSnapshotter } from './services/metrics-snapshotter.js';
import { createMcpServer } from './server/mcp-server.js';
import { createExpressApp, startServer } from './server/transport.js';
import { logger } from './utils/logger.js';
import { config } from './config.js';
async function main(): Promise<void> {
const isStdio = process.argv.includes('--stdio');
// Initialize database
const db = getDb();
runMigrations(db);
logger.info('Database initialized');
// Initialize services
const vectorStore = new SqliteVectorStore(db);
const cache = new SemanticCache();
const proxyManager = new ProxyManager();
const userManager = new UserManager(db);
const sessionManager = new SessionManager(db);
const snapshotter = new MetricsSnapshotter(db);
// Seed default dashboard user
await userManager.seedDefaultUser(config.dashboard.username, config.dashboard.password);
// Create MCP server
const mcpServer = createMcpServer({ db, vectorStore, cache, proxyManager });
if (isStdio) {
// Stdio mode for local testing
const transport = new StdioServerTransport();
await mcpServer.connect(transport);
logger.info('MCP Context Hub running in stdio mode');
await transport.start();
} else {
// Start metrics snapshotter
snapshotter.start();
// HTTP mode
const app = createExpressApp(mcpServer, {
db,
cache,
proxyManager,
sessionManager,
userManager,
snapshotter,
});
const httpServer = startServer(app);
// Graceful shutdown
const shutdown = async () => {
logger.info('Shutting down...');
snapshotter.stop();
httpServer.close();
await proxyManager.closeAll();
closeDb();
logger.info('Shutdown complete');
process.exit(0);
};
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
}
}
main().catch((err) => {
logger.fatal({ err }, 'Failed to start MCP Context Hub');
process.exit(1);
});