diff --git a/lib/src/generated/fai/v1/hub.pb.dart b/lib/src/generated/fai/v1/hub.pb.dart index afcb1b5..af1b326 100644 --- a/lib/src/generated/fai/v1/hub.pb.dart +++ b/lib/src/generated/fai/v1/hub.pb.dart @@ -4539,6 +4539,278 @@ class ClearEventLogResponse extends $pb.GeneratedMessage { void clearChannel() => $_clearField(2); } +class McpClientConfigEntry extends $pb.GeneratedMessage { + factory McpClientConfigEntry({ + $core.String? name, + $core.String? endpoint, + $core.String? apiKeyEnv, + $core.String? description, + }) { + final $result = create(); + if (name != null) { + $result.name = name; + } + if (endpoint != null) { + $result.endpoint = endpoint; + } + if (apiKeyEnv != null) { + $result.apiKeyEnv = apiKeyEnv; + } + if (description != null) { + $result.description = description; + } + return $result; + } + McpClientConfigEntry._() : super(); + factory McpClientConfigEntry.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory McpClientConfigEntry.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'McpClientConfigEntry', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'name') + ..aOS(2, _omitFieldNames ? '' : 'endpoint') + ..aOS(3, _omitFieldNames ? '' : 'apiKeyEnv') + ..aOS(4, _omitFieldNames ? '' : 'description') + ..hasRequiredFields = false + ; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + McpClientConfigEntry clone() => McpClientConfigEntry()..mergeFromMessage(this); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + McpClientConfigEntry copyWith(void Function(McpClientConfigEntry) updates) => super.copyWith((message) => updates(message as McpClientConfigEntry)) as McpClientConfigEntry; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static McpClientConfigEntry create() => McpClientConfigEntry._(); + McpClientConfigEntry createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static McpClientConfigEntry getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static McpClientConfigEntry? _defaultInstance; + + /// Operator-friendly name. Becomes the second segment of + /// every discovered capability id: `mcp..`. + /// Must be unique and not contain dots. + @$pb.TagNumber(1) + $core.String get name => $_getSZ(0); + @$pb.TagNumber(1) + set name($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasName() => $_has(0); + @$pb.TagNumber(1) + void clearName() => $_clearField(1); + + /// Endpoint URL. HTTP(S) for streamable-HTTP servers, + /// `stdio://` for local stdio servers. + @$pb.TagNumber(2) + $core.String get endpoint => $_getSZ(1); + @$pb.TagNumber(2) + set endpoint($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasEndpoint() => $_has(1); + @$pb.TagNumber(2) + void clearEndpoint() => $_clearField(2); + + /// Optional env-var name holding a bearer token. + @$pb.TagNumber(3) + $core.String get apiKeyEnv => $_getSZ(2); + @$pb.TagNumber(3) + set apiKeyEnv($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasApiKeyEnv() => $_has(2); + @$pb.TagNumber(3) + void clearApiKeyEnv() => $_clearField(3); + + /// Optional human-readable description. + @$pb.TagNumber(4) + $core.String get description => $_getSZ(3); + @$pb.TagNumber(4) + set description($core.String v) { $_setString(3, v); } + @$pb.TagNumber(4) + $core.bool hasDescription() => $_has(3); + @$pb.TagNumber(4) + void clearDescription() => $_clearField(4); +} + +class ListMcpClientsResponse extends $pb.GeneratedMessage { + factory ListMcpClientsResponse({ + $core.Iterable? clients, + }) { + final $result = create(); + if (clients != null) { + $result.clients.addAll(clients); + } + return $result; + } + ListMcpClientsResponse._() : super(); + factory ListMcpClientsResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ListMcpClientsResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ListMcpClientsResponse', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) + ..pc(1, _omitFieldNames ? '' : 'clients', $pb.PbFieldType.PM, subBuilder: McpClientStatus.create) + ..hasRequiredFields = false + ; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + ListMcpClientsResponse clone() => ListMcpClientsResponse()..mergeFromMessage(this); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + ListMcpClientsResponse copyWith(void Function(ListMcpClientsResponse) updates) => super.copyWith((message) => updates(message as ListMcpClientsResponse)) as ListMcpClientsResponse; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static ListMcpClientsResponse create() => ListMcpClientsResponse._(); + ListMcpClientsResponse createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static ListMcpClientsResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ListMcpClientsResponse? _defaultInstance; + + /// Every configured server (regardless of last-discovery + /// outcome). + @$pb.TagNumber(1) + $pb.PbList get clients => $_getList(0); +} + +class McpClientStatus extends $pb.GeneratedMessage { + factory McpClientStatus({ + McpClientConfigEntry? config, + $core.int? toolCount, + $core.String? errorKind, + $core.String? message, + }) { + final $result = create(); + if (config != null) { + $result.config = config; + } + if (toolCount != null) { + $result.toolCount = toolCount; + } + if (errorKind != null) { + $result.errorKind = errorKind; + } + if (message != null) { + $result.message = message; + } + return $result; + } + McpClientStatus._() : super(); + factory McpClientStatus.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory McpClientStatus.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'McpClientStatus', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) + ..aOM(1, _omitFieldNames ? '' : 'config', subBuilder: McpClientConfigEntry.create) + ..a<$core.int>(2, _omitFieldNames ? '' : 'toolCount', $pb.PbFieldType.OU3) + ..aOS(3, _omitFieldNames ? '' : 'errorKind') + ..aOS(4, _omitFieldNames ? '' : 'message') + ..hasRequiredFields = false + ; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + McpClientStatus clone() => McpClientStatus()..mergeFromMessage(this); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + McpClientStatus copyWith(void Function(McpClientStatus) updates) => super.copyWith((message) => updates(message as McpClientStatus)) as McpClientStatus; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static McpClientStatus create() => McpClientStatus._(); + McpClientStatus createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static McpClientStatus getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static McpClientStatus? _defaultInstance; + + @$pb.TagNumber(1) + McpClientConfigEntry get config => $_getN(0); + @$pb.TagNumber(1) + set config(McpClientConfigEntry v) { $_setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasConfig() => $_has(0); + @$pb.TagNumber(1) + void clearConfig() => $_clearField(1); + @$pb.TagNumber(1) + McpClientConfigEntry ensureConfig() => $_ensure(0); + + /// Number of tools the last discovery pass returned. 0 + /// before discovery has run or on failure. + @$pb.TagNumber(2) + $core.int get toolCount => $_getIZ(1); + @$pb.TagNumber(2) + set toolCount($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasToolCount() => $_has(1); + @$pb.TagNumber(2) + void clearToolCount() => $_clearField(2); + + /// Empty on success; otherwise the error_kind taxonomy + /// (`invalid_endpoint`, `not_implemented`, `network`, + /// `http`, `server`, `parse`, `env_missing`). + @$pb.TagNumber(3) + $core.String get errorKind => $_getSZ(2); + @$pb.TagNumber(3) + set errorKind($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasErrorKind() => $_has(2); + @$pb.TagNumber(3) + void clearErrorKind() => $_clearField(3); + + /// Human-readable diagnostic. On success "registered N + /// tools"; on failure the error message. + @$pb.TagNumber(4) + $core.String get message => $_getSZ(3); + @$pb.TagNumber(4) + set message($core.String v) { $_setString(3, v); } + @$pb.TagNumber(4) + $core.bool hasMessage() => $_has(3); + @$pb.TagNumber(4) + void clearMessage() => $_clearField(4); +} + +class RemoveMcpClientRequest extends $pb.GeneratedMessage { + factory RemoveMcpClientRequest({ + $core.String? name, + }) { + final $result = create(); + if (name != null) { + $result.name = name; + } + return $result; + } + RemoveMcpClientRequest._() : super(); + factory RemoveMcpClientRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RemoveMcpClientRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'RemoveMcpClientRequest', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'name') + ..hasRequiredFields = false + ; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + RemoveMcpClientRequest clone() => RemoveMcpClientRequest()..mergeFromMessage(this); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + RemoveMcpClientRequest copyWith(void Function(RemoveMcpClientRequest) updates) => super.copyWith((message) => updates(message as RemoveMcpClientRequest)) as RemoveMcpClientRequest; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static RemoveMcpClientRequest create() => RemoveMcpClientRequest._(); + RemoveMcpClientRequest createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RemoveMcpClientRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RemoveMcpClientRequest? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get name => $_getSZ(0); + @$pb.TagNumber(1) + set name($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasName() => $_has(0); + @$pb.TagNumber(1) + void clearName() => $_clearField(1); +} + const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/lib/src/generated/fai/v1/hub.pbgrpc.dart b/lib/src/generated/fai/v1/hub.pbgrpc.dart index f04aab7..0fe42bf 100644 --- a/lib/src/generated/fai/v1/hub.pbgrpc.dart +++ b/lib/src/generated/fai/v1/hub.pbgrpc.dart @@ -203,6 +203,22 @@ class HubAdminClient extends $grpc.Client { '/fai.v1.HubAdmin/DaemonPaths', ($1.Empty value) => value.writeToBuffer(), ($core.List<$core.int> value) => $0.DaemonPathsResponse.fromBuffer(value)); + static final _$listMcpClients = $grpc.ClientMethod<$1.Empty, $0.ListMcpClientsResponse>( + '/fai.v1.HubAdmin/ListMcpClients', + ($1.Empty value) => value.writeToBuffer(), + ($core.List<$core.int> value) => $0.ListMcpClientsResponse.fromBuffer(value)); + static final _$refreshMcpClients = $grpc.ClientMethod<$1.Empty, $0.ListMcpClientsResponse>( + '/fai.v1.HubAdmin/RefreshMcpClients', + ($1.Empty value) => value.writeToBuffer(), + ($core.List<$core.int> value) => $0.ListMcpClientsResponse.fromBuffer(value)); + static final _$addMcpClient = $grpc.ClientMethod<$0.McpClientConfigEntry, $0.ListMcpClientsResponse>( + '/fai.v1.HubAdmin/AddMcpClient', + ($0.McpClientConfigEntry value) => value.writeToBuffer(), + ($core.List<$core.int> value) => $0.ListMcpClientsResponse.fromBuffer(value)); + static final _$removeMcpClient = $grpc.ClientMethod<$0.RemoveMcpClientRequest, $0.ListMcpClientsResponse>( + '/fai.v1.HubAdmin/RemoveMcpClient', + ($0.RemoveMcpClientRequest value) => value.writeToBuffer(), + ($core.List<$core.int> value) => $0.ListMcpClientsResponse.fromBuffer(value)); static final _$systemAiStatus = $grpc.ClientMethod<$1.Empty, $0.SystemAiStatusResponse>( '/fai.v1.HubAdmin/SystemAiStatus', ($1.Empty value) => value.writeToBuffer(), @@ -373,6 +389,36 @@ class HubAdminClient extends $grpc.Client { return $createUnaryCall(_$daemonPaths, request, options: options); } + /// Configured MCP servers + their last-discovery report. + /// Studio's MCP-clients editor renders the result. Mirrors + /// `fai mcp list` on the CLI. + $grpc.ResponseFuture<$0.ListMcpClientsResponse> listMcpClients($1.Empty request, {$grpc.CallOptions? options}) { + return $createUnaryCall(_$listMcpClients, request, options: options); + } + + /// Re-run discovery against every configured MCP server and + /// update the *live* store-index in place. Synthetic entries + /// for tools the server no longer exposes are dropped. + /// Mirrors `fai mcp refresh` but operates on the running + /// daemon — Studio doesn't need to ask the operator to + /// restart anything. + $grpc.ResponseFuture<$0.ListMcpClientsResponse> refreshMcpClients($1.Empty request, {$grpc.CallOptions? options}) { + return $createUnaryCall(_$refreshMcpClients, request, options: options); + } + + /// Persist a new MCP server in `~/.fai/config.yaml` and + /// re-run discovery. Returns the resulting list (same shape + /// as ListMcpClients) so Studio can repaint in one round-trip. + $grpc.ResponseFuture<$0.ListMcpClientsResponse> addMcpClient($0.McpClientConfigEntry request, {$grpc.CallOptions? options}) { + return $createUnaryCall(_$addMcpClient, request, options: options); + } + + /// Remove an MCP server by name and re-run discovery so its + /// synthetic capabilities disappear from the store. + $grpc.ResponseFuture<$0.ListMcpClientsResponse> removeMcpClient($0.RemoveMcpClientRequest request, {$grpc.CallOptions? options}) { + return $createUnaryCall(_$removeMcpClient, request, options: options); + } + /// Read-only system-AI status. Lets Studio render the /// "configure in Settings" affordance when the feature is /// off, and the privacy-mode badge when it is on. @@ -597,6 +643,34 @@ abstract class HubAdminServiceBase extends $grpc.Service { false, ($core.List<$core.int> value) => $1.Empty.fromBuffer(value), ($0.DaemonPathsResponse value) => value.writeToBuffer())); + $addMethod($grpc.ServiceMethod<$1.Empty, $0.ListMcpClientsResponse>( + 'ListMcpClients', + listMcpClients_Pre, + false, + false, + ($core.List<$core.int> value) => $1.Empty.fromBuffer(value), + ($0.ListMcpClientsResponse value) => value.writeToBuffer())); + $addMethod($grpc.ServiceMethod<$1.Empty, $0.ListMcpClientsResponse>( + 'RefreshMcpClients', + refreshMcpClients_Pre, + false, + false, + ($core.List<$core.int> value) => $1.Empty.fromBuffer(value), + ($0.ListMcpClientsResponse value) => value.writeToBuffer())); + $addMethod($grpc.ServiceMethod<$0.McpClientConfigEntry, $0.ListMcpClientsResponse>( + 'AddMcpClient', + addMcpClient_Pre, + false, + false, + ($core.List<$core.int> value) => $0.McpClientConfigEntry.fromBuffer(value), + ($0.ListMcpClientsResponse value) => value.writeToBuffer())); + $addMethod($grpc.ServiceMethod<$0.RemoveMcpClientRequest, $0.ListMcpClientsResponse>( + 'RemoveMcpClient', + removeMcpClient_Pre, + false, + false, + ($core.List<$core.int> value) => $0.RemoveMcpClientRequest.fromBuffer(value), + ($0.ListMcpClientsResponse value) => value.writeToBuffer())); $addMethod($grpc.ServiceMethod<$1.Empty, $0.SystemAiStatusResponse>( 'SystemAiStatus', systemAiStatus_Pre, @@ -749,6 +823,22 @@ abstract class HubAdminServiceBase extends $grpc.Service { return daemonPaths($call, await $request); } + $async.Future<$0.ListMcpClientsResponse> listMcpClients_Pre($grpc.ServiceCall $call, $async.Future<$1.Empty> $request) async { + return listMcpClients($call, await $request); + } + + $async.Future<$0.ListMcpClientsResponse> refreshMcpClients_Pre($grpc.ServiceCall $call, $async.Future<$1.Empty> $request) async { + return refreshMcpClients($call, await $request); + } + + $async.Future<$0.ListMcpClientsResponse> addMcpClient_Pre($grpc.ServiceCall $call, $async.Future<$0.McpClientConfigEntry> $request) async { + return addMcpClient($call, await $request); + } + + $async.Future<$0.ListMcpClientsResponse> removeMcpClient_Pre($grpc.ServiceCall $call, $async.Future<$0.RemoveMcpClientRequest> $request) async { + return removeMcpClient($call, await $request); + } + $async.Future<$0.SystemAiStatusResponse> systemAiStatus_Pre($grpc.ServiceCall $call, $async.Future<$1.Empty> $request) async { return systemAiStatus($call, await $request); } @@ -809,6 +899,10 @@ abstract class HubAdminServiceBase extends $grpc.Service { $async.Future<$0.CheckUpdateResponse> checkUpdate($grpc.ServiceCall call, $1.Empty request); $async.Future<$0.ChannelStatusResponse> channelStatus($grpc.ServiceCall call, $1.Empty request); $async.Future<$0.DaemonPathsResponse> daemonPaths($grpc.ServiceCall call, $1.Empty request); + $async.Future<$0.ListMcpClientsResponse> listMcpClients($grpc.ServiceCall call, $1.Empty request); + $async.Future<$0.ListMcpClientsResponse> refreshMcpClients($grpc.ServiceCall call, $1.Empty request); + $async.Future<$0.ListMcpClientsResponse> addMcpClient($grpc.ServiceCall call, $0.McpClientConfigEntry request); + $async.Future<$0.ListMcpClientsResponse> removeMcpClient($grpc.ServiceCall call, $0.RemoveMcpClientRequest request); $async.Future<$0.SystemAiStatusResponse> systemAiStatus($grpc.ServiceCall call, $1.Empty request); $async.Future<$0.AskAiResponse> askAi($grpc.ServiceCall call, $0.AskAiRequest request); $async.Future<$0.SystemAiStatusResponse> updateSystemAi($grpc.ServiceCall call, $0.UpdateSystemAiRequest request); diff --git a/lib/src/generated/fai/v1/hub.pbjson.dart b/lib/src/generated/fai/v1/hub.pbjson.dart index 156793b..a9525c7 100644 --- a/lib/src/generated/fai/v1/hub.pbjson.dart +++ b/lib/src/generated/fai/v1/hub.pbjson.dart @@ -1002,3 +1002,62 @@ final $typed_data.Uint8List clearEventLogResponseDescriptor = $convert.base64Dec 'ChVDbGVhckV2ZW50TG9nUmVzcG9uc2USFgoGcHVyZ2VkGAEgASgEUgZwdXJnZWQSGAoHY2hhbm' '5lbBgCIAEoCVIHY2hhbm5lbA=='); +@$core.Deprecated('Use mcpClientConfigEntryDescriptor instead') +const McpClientConfigEntry$json = { + '1': 'McpClientConfigEntry', + '2': [ + {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'}, + {'1': 'endpoint', '3': 2, '4': 1, '5': 9, '10': 'endpoint'}, + {'1': 'api_key_env', '3': 3, '4': 1, '5': 9, '10': 'apiKeyEnv'}, + {'1': 'description', '3': 4, '4': 1, '5': 9, '10': 'description'}, + ], +}; + +/// Descriptor for `McpClientConfigEntry`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List mcpClientConfigEntryDescriptor = $convert.base64Decode( + 'ChRNY3BDbGllbnRDb25maWdFbnRyeRISCgRuYW1lGAEgASgJUgRuYW1lEhoKCGVuZHBvaW50GA' + 'IgASgJUghlbmRwb2ludBIeCgthcGlfa2V5X2VudhgDIAEoCVIJYXBpS2V5RW52EiAKC2Rlc2Ny' + 'aXB0aW9uGAQgASgJUgtkZXNjcmlwdGlvbg=='); + +@$core.Deprecated('Use listMcpClientsResponseDescriptor instead') +const ListMcpClientsResponse$json = { + '1': 'ListMcpClientsResponse', + '2': [ + {'1': 'clients', '3': 1, '4': 3, '5': 11, '6': '.fai.v1.McpClientStatus', '10': 'clients'}, + ], +}; + +/// Descriptor for `ListMcpClientsResponse`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List listMcpClientsResponseDescriptor = $convert.base64Decode( + 'ChZMaXN0TWNwQ2xpZW50c1Jlc3BvbnNlEjEKB2NsaWVudHMYASADKAsyFy5mYWkudjEuTWNwQ2' + 'xpZW50U3RhdHVzUgdjbGllbnRz'); + +@$core.Deprecated('Use mcpClientStatusDescriptor instead') +const McpClientStatus$json = { + '1': 'McpClientStatus', + '2': [ + {'1': 'config', '3': 1, '4': 1, '5': 11, '6': '.fai.v1.McpClientConfigEntry', '10': 'config'}, + {'1': 'tool_count', '3': 2, '4': 1, '5': 13, '10': 'toolCount'}, + {'1': 'error_kind', '3': 3, '4': 1, '5': 9, '10': 'errorKind'}, + {'1': 'message', '3': 4, '4': 1, '5': 9, '10': 'message'}, + ], +}; + +/// Descriptor for `McpClientStatus`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List mcpClientStatusDescriptor = $convert.base64Decode( + 'Cg9NY3BDbGllbnRTdGF0dXMSNAoGY29uZmlnGAEgASgLMhwuZmFpLnYxLk1jcENsaWVudENvbm' + 'ZpZ0VudHJ5UgZjb25maWcSHQoKdG9vbF9jb3VudBgCIAEoDVIJdG9vbENvdW50Eh0KCmVycm9y' + 'X2tpbmQYAyABKAlSCWVycm9yS2luZBIYCgdtZXNzYWdlGAQgASgJUgdtZXNzYWdl'); + +@$core.Deprecated('Use removeMcpClientRequestDescriptor instead') +const RemoveMcpClientRequest$json = { + '1': 'RemoveMcpClientRequest', + '2': [ + {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'}, + ], +}; + +/// Descriptor for `RemoveMcpClientRequest`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List removeMcpClientRequestDescriptor = $convert.base64Decode( + 'ChZSZW1vdmVNY3BDbGllbnRSZXF1ZXN0EhIKBG5hbWUYASABKAlSBG5hbWU='); + diff --git a/lib/src/hub_client.dart b/lib/src/hub_client.dart index dc31447..e703cd2 100644 --- a/lib/src/hub_client.dart +++ b/lib/src/hub_client.dart @@ -57,6 +57,9 @@ typedef ClearEventLogResponse = pb.ClearEventLogResponse; typedef DaemonPathsResponse = pb.DaemonPathsResponse; typedef UninstallModuleResponse = pb.UninstallModuleResponse; typedef FetchModuleDocsResponse = pb.FetchModuleDocsResponse; +typedef ListMcpClientsResponse = pb.ListMcpClientsResponse; +typedef McpClientStatus = pb.McpClientStatus; +typedef McpClientConfigEntry = pb.McpClientConfigEntry; typedef ModuleInfoResponse = pb.ModuleInfoResponse; typedef FlowSummary = pb.FlowSummary; typedef StoreEntry = pb.StoreEntry; @@ -236,6 +239,40 @@ class HubClient { return _admin.fetchModuleDocs(pb.FetchModuleDocsRequest(name: name)); } + /// List every configured MCP server with the last-discovery + /// snapshot. Drives Studio's MCP-clients editor. + Future listMcpClients() { + return _admin.listMcpClients(Empty()); + } + + /// Re-run discovery against every configured MCP server and + /// update the running daemon's store-index in place. + Future refreshMcpClients() { + return _admin.refreshMcpClients(Empty()); + } + + /// Persist a new MCP server in `~/.fai/config.yaml` and + /// trigger discovery in one round-trip. + Future addMcpClient({ + required String name, + required String endpoint, + String apiKeyEnv = '', + String description = '', + }) { + return _admin.addMcpClient(pb.McpClientConfigEntry( + name: name, + endpoint: endpoint, + apiKeyEnv: apiKeyEnv, + description: description, + )); + } + + /// Remove an MCP server by name + drop its synthetic + /// capabilities from the running store-index. + Future removeMcpClient(String name) { + return _admin.removeMcpClient(pb.RemoveMcpClientRequest(name: name)); + } + /// Read-only system-AI status. `enabled=false` lets Studio /// render "configure in Settings" without making a request. Future systemAiStatus() { diff --git a/pubspec.yaml b/pubspec.yaml index 51fbc4a..a3f11dd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: fai_dart_sdk description: gRPC client SDK for the F∆I Platform hub. Used by F∆I Studio and Tier-3 domain apps. -version: 0.11.0 +version: 0.12.0 publish_to: 'none' repository: https://git.flemming.ws/fai/dart-sdk