feat: MCP-client federation surface (v0.12.0)
Picks up the four new HubAdmin RPCs that drive Studio's MCP-clients editor: - `listMcpClients()` — config + last-discovery snapshot. - `refreshMcpClients()` — re-run discovery against the live daemon. - `addMcpClient(name, endpoint, apiKeyEnv?, description?)` — persist + refresh in one round-trip. - `removeMcpClient(name)` — drop persisted entry and live synthetic capabilities. Typedefs for `ListMcpClientsResponse`, `McpClientStatus`, `McpClientConfigEntry` so callers don't import generated/. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
a893361ff9
commit
776e3c0221
5 changed files with 463 additions and 1 deletions
|
|
@ -4539,6 +4539,278 @@ class ClearEventLogResponse extends $pb.GeneratedMessage {
|
||||||
void clearChannel() => $_clearField(2);
|
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<McpClientConfigEntry> createRepeated() => $pb.PbList<McpClientConfigEntry>();
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static McpClientConfigEntry getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<McpClientConfigEntry>(create);
|
||||||
|
static McpClientConfigEntry? _defaultInstance;
|
||||||
|
|
||||||
|
/// Operator-friendly name. Becomes the second segment of
|
||||||
|
/// every discovered capability id: `mcp.<name>.<tool>`.
|
||||||
|
/// 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://<command>` 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<McpClientStatus>? 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<McpClientStatus>(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<ListMcpClientsResponse> createRepeated() => $pb.PbList<ListMcpClientsResponse>();
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static ListMcpClientsResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ListMcpClientsResponse>(create);
|
||||||
|
static ListMcpClientsResponse? _defaultInstance;
|
||||||
|
|
||||||
|
/// Every configured server (regardless of last-discovery
|
||||||
|
/// outcome).
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$pb.PbList<McpClientStatus> 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<McpClientConfigEntry>(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<McpClientStatus> createRepeated() => $pb.PbList<McpClientStatus>();
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static McpClientStatus getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<McpClientStatus>(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<RemoveMcpClientRequest> createRepeated() => $pb.PbList<RemoveMcpClientRequest>();
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static RemoveMcpClientRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RemoveMcpClientRequest>(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 _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
|
||||||
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');
|
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,22 @@ class HubAdminClient extends $grpc.Client {
|
||||||
'/fai.v1.HubAdmin/DaemonPaths',
|
'/fai.v1.HubAdmin/DaemonPaths',
|
||||||
($1.Empty value) => value.writeToBuffer(),
|
($1.Empty value) => value.writeToBuffer(),
|
||||||
($core.List<$core.int> value) => $0.DaemonPathsResponse.fromBuffer(value));
|
($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>(
|
static final _$systemAiStatus = $grpc.ClientMethod<$1.Empty, $0.SystemAiStatusResponse>(
|
||||||
'/fai.v1.HubAdmin/SystemAiStatus',
|
'/fai.v1.HubAdmin/SystemAiStatus',
|
||||||
($1.Empty value) => value.writeToBuffer(),
|
($1.Empty value) => value.writeToBuffer(),
|
||||||
|
|
@ -373,6 +389,36 @@ class HubAdminClient extends $grpc.Client {
|
||||||
return $createUnaryCall(_$daemonPaths, request, options: options);
|
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
|
/// Read-only system-AI status. Lets Studio render the
|
||||||
/// "configure in Settings" affordance when the feature is
|
/// "configure in Settings" affordance when the feature is
|
||||||
/// off, and the privacy-mode badge when it is on.
|
/// off, and the privacy-mode badge when it is on.
|
||||||
|
|
@ -597,6 +643,34 @@ abstract class HubAdminServiceBase extends $grpc.Service {
|
||||||
false,
|
false,
|
||||||
($core.List<$core.int> value) => $1.Empty.fromBuffer(value),
|
($core.List<$core.int> value) => $1.Empty.fromBuffer(value),
|
||||||
($0.DaemonPathsResponse value) => value.writeToBuffer()));
|
($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>(
|
$addMethod($grpc.ServiceMethod<$1.Empty, $0.SystemAiStatusResponse>(
|
||||||
'SystemAiStatus',
|
'SystemAiStatus',
|
||||||
systemAiStatus_Pre,
|
systemAiStatus_Pre,
|
||||||
|
|
@ -749,6 +823,22 @@ abstract class HubAdminServiceBase extends $grpc.Service {
|
||||||
return daemonPaths($call, await $request);
|
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 {
|
$async.Future<$0.SystemAiStatusResponse> systemAiStatus_Pre($grpc.ServiceCall $call, $async.Future<$1.Empty> $request) async {
|
||||||
return systemAiStatus($call, await $request);
|
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.CheckUpdateResponse> checkUpdate($grpc.ServiceCall call, $1.Empty request);
|
||||||
$async.Future<$0.ChannelStatusResponse> channelStatus($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.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.SystemAiStatusResponse> systemAiStatus($grpc.ServiceCall call, $1.Empty request);
|
||||||
$async.Future<$0.AskAiResponse> askAi($grpc.ServiceCall call, $0.AskAiRequest request);
|
$async.Future<$0.AskAiResponse> askAi($grpc.ServiceCall call, $0.AskAiRequest request);
|
||||||
$async.Future<$0.SystemAiStatusResponse> updateSystemAi($grpc.ServiceCall call, $0.UpdateSystemAiRequest request);
|
$async.Future<$0.SystemAiStatusResponse> updateSystemAi($grpc.ServiceCall call, $0.UpdateSystemAiRequest request);
|
||||||
|
|
|
||||||
|
|
@ -1002,3 +1002,62 @@ final $typed_data.Uint8List clearEventLogResponseDescriptor = $convert.base64Dec
|
||||||
'ChVDbGVhckV2ZW50TG9nUmVzcG9uc2USFgoGcHVyZ2VkGAEgASgEUgZwdXJnZWQSGAoHY2hhbm'
|
'ChVDbGVhckV2ZW50TG9nUmVzcG9uc2USFgoGcHVyZ2VkGAEgASgEUgZwdXJnZWQSGAoHY2hhbm'
|
||||||
'5lbBgCIAEoCVIHY2hhbm5lbA==');
|
'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=');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,9 @@ typedef ClearEventLogResponse = pb.ClearEventLogResponse;
|
||||||
typedef DaemonPathsResponse = pb.DaemonPathsResponse;
|
typedef DaemonPathsResponse = pb.DaemonPathsResponse;
|
||||||
typedef UninstallModuleResponse = pb.UninstallModuleResponse;
|
typedef UninstallModuleResponse = pb.UninstallModuleResponse;
|
||||||
typedef FetchModuleDocsResponse = pb.FetchModuleDocsResponse;
|
typedef FetchModuleDocsResponse = pb.FetchModuleDocsResponse;
|
||||||
|
typedef ListMcpClientsResponse = pb.ListMcpClientsResponse;
|
||||||
|
typedef McpClientStatus = pb.McpClientStatus;
|
||||||
|
typedef McpClientConfigEntry = pb.McpClientConfigEntry;
|
||||||
typedef ModuleInfoResponse = pb.ModuleInfoResponse;
|
typedef ModuleInfoResponse = pb.ModuleInfoResponse;
|
||||||
typedef FlowSummary = pb.FlowSummary;
|
typedef FlowSummary = pb.FlowSummary;
|
||||||
typedef StoreEntry = pb.StoreEntry;
|
typedef StoreEntry = pb.StoreEntry;
|
||||||
|
|
@ -236,6 +239,40 @@ class HubClient {
|
||||||
return _admin.fetchModuleDocs(pb.FetchModuleDocsRequest(name: name));
|
return _admin.fetchModuleDocs(pb.FetchModuleDocsRequest(name: name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// List every configured MCP server with the last-discovery
|
||||||
|
/// snapshot. Drives Studio's MCP-clients editor.
|
||||||
|
Future<ListMcpClientsResponse> listMcpClients() {
|
||||||
|
return _admin.listMcpClients(Empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Re-run discovery against every configured MCP server and
|
||||||
|
/// update the running daemon's store-index in place.
|
||||||
|
Future<ListMcpClientsResponse> refreshMcpClients() {
|
||||||
|
return _admin.refreshMcpClients(Empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Persist a new MCP server in `~/.fai/config.yaml` and
|
||||||
|
/// trigger discovery in one round-trip.
|
||||||
|
Future<ListMcpClientsResponse> 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<ListMcpClientsResponse> removeMcpClient(String name) {
|
||||||
|
return _admin.removeMcpClient(pb.RemoveMcpClientRequest(name: name));
|
||||||
|
}
|
||||||
|
|
||||||
/// Read-only system-AI status. `enabled=false` lets Studio
|
/// Read-only system-AI status. `enabled=false` lets Studio
|
||||||
/// render "configure in Settings" without making a request.
|
/// render "configure in Settings" without making a request.
|
||||||
Future<SystemAiStatusResponse> systemAiStatus() {
|
Future<SystemAiStatusResponse> systemAiStatus() {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
name: fai_dart_sdk
|
name: fai_dart_sdk
|
||||||
description: gRPC client SDK for the F∆I Platform hub. Used by F∆I Studio and Tier-3 domain apps.
|
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'
|
publish_to: 'none'
|
||||||
repository: https://git.flemming.ws/fai/dart-sdk
|
repository: https://git.flemming.ws/fai/dart-sdk
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue