cli.ts•2.68 kB
#!/usr/bin/env node
import { Command } from 'commander'
import { readFileSync } from 'fs'
import { join } from 'path'
import { Config } from './core/config'
import { MCPServer } from './server'
// Read version from package.json
const packageJson = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'))
const VERSION = packageJson.version
// Catch any uncaught errors
process.on('uncaughtException', (error) => {
  console.error('Uncaught Exception:', error)
  process.exit(1)
})
process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled Rejection at:', promise, 'reason:', reason)
  process.exit(1)
})
const program = new Command()
program
  .name('min-kb-mcp')
  .description('A minimalist, file-based knowledge base server (MCP) for LLMs')
  .version(VERSION)
program
  .command('start')
  .description('Start the MCP server')
  .requiredOption('--kb <name>', 'Name of the knowledge base')
  .option('--port <number>', 'Port number for HTTP transport')
  .option('--host <hostname>', 'Host for HTTP transport')
  .action(async (options) => {
    let server: MCPServer | undefined
    const isDebugMode = process.env.DEBUG === '*' || process.env.NODE_ENV === 'development'
    const cleanup = async () => {
      if (server) {
        if (isDebugMode) {
          console.log('\nShutting down MCP server...')
        }
        await server.stop()
        process.exit(0)
      }
    }
    // Handle graceful shutdown
    process.on('SIGINT', cleanup)
    process.on('SIGTERM', cleanup)
    try {
      // Create config with transport options
      const config = new Config(options.kb, options.port ? parseInt(options.port, 10) : undefined)
      if (isDebugMode) {
        console.log('Config created:', {
          kb: options.kb,
          transport: config.transport,
          httpPort: config.httpPort,
        })
      }
      server = new MCPServer(config)
      await server.start()
      if (isDebugMode || config.transport === 'http') {
        console.log(`MCP server started for knowledge base: ${options.kb}`)
        if (config.transport === 'http') {
          console.log(`HTTP transport listening on port ${config.httpPort}`)
        }
      }
    } catch (error) {
      console.error(
        'Failed to start server:',
        error instanceof Error ? error.message : String(error)
      )
      if (error instanceof Error && error.stack) {
        console.error('Stack trace:', error.stack)
      }
      process.exit(1)
    }
  })
// Since we use async actions, we need to use parseAsync
program.parseAsync().catch((error) => {
  console.error('Failed to parse CLI:', error)
  process.exit(1)
})