run static method

void run(
  1. List<String> args
)

Parses args, validates the --db path, and starts the server on stdio.

Exits with code 1 if --db is missing, the file cannot be read, or the database version does not match kDbVersion.

Implementation

static void run(List<String> args) {
  final parser = ArgParser()
    ..addOption(
      'db',
      help: 'Path to the sqlite3 documentation database file.',
      valueHelp: 'path',
    )
    ..addFlag(
      'help',
      abbr: 'h',
      negatable: false,
      help: 'Print usage information.',
    )
    ..addFlag(
      'version',
      negatable: false,
      help: 'Print the server version and exit.',
    )
    ..addFlag(
      'db-version',
      negatable: false,
      help: 'Print the version of the --db database file and exit.',
    );

  late ArgResults results;
  try {
    results = parser.parse(args);
  } on FormatException catch (e) {
    io.stderr.writeln(e.message);
    io.stderr.writeln(parser.usage);
    io.exit(1);
  }

  if (results.flag('help')) {
    io.stdout.writeln(
      'Usage: flutterdocs_mcp --db <path>\n\n${parser.usage}',
    );
    return;
  }

  if (results.flag('version')) {
    io.stdout.writeln(kVersion);
    return;
  }

  final dbPath = results.option('db');
  final dbFile = dbPath != null ? io.File(dbPath) : null;

  if (results.flag('db-version')) {
    if (dbPath == null) {
      io.stderr.writeln('Error: --db is required with --db-version.');
      io.stderr.writeln(parser.usage);
      io.exit(1);
    }
    if (!dbFile!.existsSync()) {
      io.stderr.writeln('Error: database file not found: $dbPath');
      io.exit(1);
    }
    late int userVersion;
    try {
      userVersion = DocDatabase.readUserVersion(dbPath);
    } catch (e) {
      io.stderr.writeln('Error: failed to read database version: $e');
      io.exit(1);
    }
    if (userVersion == 0) {
      io.stderr.writeln('Error: database has no version information.');
      io.exit(1);
    }
    io.stdout.writeln(_dbVersionToSemver(userVersion));
    return;
  }

  if (dbPath == null) {
    io.stderr.writeln('Error: --db is required.');
    io.stderr.writeln(parser.usage);
    io.exit(1);
  }
  if (!dbFile!.existsSync()) {
    io.stderr.writeln('Error: database file not found: $dbPath');
    io.exit(1);
  }

  late int dbUserVersion;
  try {
    dbUserVersion = DocDatabase.readUserVersion(dbPath);
  } catch (e) {
    io.stderr.writeln('Error: failed to read database version: $e');
    io.exit(1);
  }
  if (dbUserVersion != kDbVersion) {
    io.stderr.writeln(
      'Error: database version mismatch: '
      'server expects ${_dbVersionToSemver(kDbVersion)}, '
      'database has ${_dbVersionToSemver(dbUserVersion)}.',
    );
    io.exit(1);
  }

  late DocDatabase db;
  try {
    db = DocDatabase(dbPath);
  } catch (e) {
    io.stderr.writeln('Error: failed to open database: $e');
    io.exit(1);
  }

  FlutterDocsMcpServer.fromChannel(
    stdioChannel(input: io.stdin, output: io.stdout),
    db,
  );
}