discover method

Future<DiscoverResult> discover()

2026-07-28 stateless core: fetch the server's supported versions, capabilities, and optional instructions via server/discover.

Servers MUST implement server/discover; clients MAY call it (version negotiation can also happen inline via per-request _meta). Callable without a prior handshake. As a side effect the parsed ServerCapabilities and server info are cached on this client (serverCapabilities / serverInfo).

Implementation

Future<DiscoverResult> discover() async {
  if (!isConnected) {
    throw McpError('Client is not connected to a transport');
  }
  final response = await _sendRequest('server/discover', {});
  if (response == null) {
    throw McpError('server/discover returned no result');
  }
  final map = Map<String, dynamic>.from(response as Map);

  final versions = (map['supportedVersions'] as List?)
          ?.map((v) => v.toString())
          .toList() ??
      const <String>[];
  final capsData = map['capabilities'];
  final caps = ServerCapabilities.fromJson(
    capsData is Map ? Map<String, dynamic>.from(capsData) : {},
  );
  _serverCapabilities = caps;

  // ResultMetaObject may carry `serverInfo` (2026-07-28).
  final serverInfo = McpRequestMeta.readServerInfo(map['_meta']);
  if (serverInfo != null) {
    _serverInfo = serverInfo;
  }

  return DiscoverResult(
    supportedVersions: versions,
    capabilities: caps,
    instructions: map['instructions'] as String?,
    ttlMs: (map['ttlMs'] as num?)?.toInt(),
    cacheScope: map['cacheScope'] as String?,
    serverInfo: serverInfo,
  );
}