connect method

  1. @override
Future<KernelClientConnection> connect({
  1. required String id,
  2. required KernelTransportKind transport,
  3. String? endpoint,
  4. Map<String, dynamic>? options,
})
override

Open a connection to a remote MCP server. The connection is identified by id (host-assigned URL, label, or other handle).

Implementation

@override
Future<KernelClientConnection> connect({
  required String id,
  required KernelTransportKind transport,
  String? endpoint,
  Map<String, dynamic>? options,
}) async {
  final existing = _connections[id];
  if (existing != null && existing.isConnected) return existing;

  final client = cli.Client(
    name: name,
    version: version,
    capabilities: const cli.ClientCapabilities(),
  );

  final cli.ClientTransport wire = await _openTransport(
    transport: transport,
    endpoint: endpoint,
    options: options ?? const <String, dynamic>{},
  );
  // Bounded on purpose. Building a transport does not touch the endpoint —
  // the handshake is the first thing that does — so an unreachable target
  // only shows up here, and a caller that never gets an answer cannot report
  // one. `options.connectTimeoutMs` raises it for a slow target.
  final timeoutMs = (options?['connectTimeoutMs'] as num?)?.toInt() ?? 15000;
  try {
    await client.connect(wire).timeout(Duration(milliseconds: timeoutMs));
  } on TimeoutException {
    client.disconnect();
    throw StateError(
      'connect timed out after ${timeoutMs}ms: $id '
      '(${endpoint ?? transport.name})',
    );
  }

  final conn = _McpClientConnection(id: id, client: client);
  _connections[id] = conn;
  return conn;
}