Implement mcp purge command for registry cleanup

Add PurgeComponent RPC to the agent service that removes stale registry
entries for components that are both gone (observed state is removed,
unknown, or exited) and unwanted (not in any current service definition).
Refuses to purge components with running or stopped containers. When all
components of a service are purged, the service row is deleted too.
Supports --dry-run to preview without modifying the database.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-26 22:30:45 -07:00
parent 1afbf5e1f6
commit 1e58dcce27
8 changed files with 1001 additions and 36 deletions

View File

@@ -1865,6 +1865,193 @@ func (x *NodeStatusResponse) GetUptimeSince() *timestamppb.Timestamp {
return nil
}
type PurgeRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Service name (empty = all services).
Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
// Component name (empty = all eligible in service).
Component string `protobuf:"bytes,2,opt,name=component,proto3" json:"component,omitempty"`
// Preview only, do not modify registry.
DryRun bool `protobuf:"varint,3,opt,name=dry_run,json=dryRun,proto3" json:"dry_run,omitempty"`
// Currently-defined service/component pairs (e.g., "mcns/mcns").
// The agent uses this to determine what is "not in any service definition".
DefinedComponents []string `protobuf:"bytes,4,rep,name=defined_components,json=definedComponents,proto3" json:"defined_components,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *PurgeRequest) Reset() {
*x = PurgeRequest{}
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[33]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *PurgeRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PurgeRequest) ProtoMessage() {}
func (x *PurgeRequest) ProtoReflect() protoreflect.Message {
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[33]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PurgeRequest.ProtoReflect.Descriptor instead.
func (*PurgeRequest) Descriptor() ([]byte, []int) {
return file_proto_mcp_v1_mcp_proto_rawDescGZIP(), []int{33}
}
func (x *PurgeRequest) GetService() string {
if x != nil {
return x.Service
}
return ""
}
func (x *PurgeRequest) GetComponent() string {
if x != nil {
return x.Component
}
return ""
}
func (x *PurgeRequest) GetDryRun() bool {
if x != nil {
return x.DryRun
}
return false
}
func (x *PurgeRequest) GetDefinedComponents() []string {
if x != nil {
return x.DefinedComponents
}
return nil
}
type PurgeResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Results []*PurgeResult `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *PurgeResponse) Reset() {
*x = PurgeResponse{}
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[34]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *PurgeResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PurgeResponse) ProtoMessage() {}
func (x *PurgeResponse) ProtoReflect() protoreflect.Message {
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[34]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PurgeResponse.ProtoReflect.Descriptor instead.
func (*PurgeResponse) Descriptor() ([]byte, []int) {
return file_proto_mcp_v1_mcp_proto_rawDescGZIP(), []int{34}
}
func (x *PurgeResponse) GetResults() []*PurgeResult {
if x != nil {
return x.Results
}
return nil
}
type PurgeResult struct {
state protoimpl.MessageState `protogen:"open.v1"`
Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
Component string `protobuf:"bytes,2,opt,name=component,proto3" json:"component,omitempty"`
// true if removed (or would be, in dry-run).
Purged bool `protobuf:"varint,3,opt,name=purged,proto3" json:"purged,omitempty"`
// Why eligible, or why refused.
Reason string `protobuf:"bytes,4,opt,name=reason,proto3" json:"reason,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *PurgeResult) Reset() {
*x = PurgeResult{}
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[35]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *PurgeResult) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PurgeResult) ProtoMessage() {}
func (x *PurgeResult) ProtoReflect() protoreflect.Message {
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[35]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PurgeResult.ProtoReflect.Descriptor instead.
func (*PurgeResult) Descriptor() ([]byte, []int) {
return file_proto_mcp_v1_mcp_proto_rawDescGZIP(), []int{35}
}
func (x *PurgeResult) GetService() string {
if x != nil {
return x.Service
}
return ""
}
func (x *PurgeResult) GetComponent() string {
if x != nil {
return x.Component
}
return ""
}
func (x *PurgeResult) GetPurged() bool {
if x != nil {
return x.Purged
}
return false
}
func (x *PurgeResult) GetReason() string {
if x != nil {
return x.Reason
}
return ""
}
var File_proto_mcp_v1_mcp_proto protoreflect.FileDescriptor
const file_proto_mcp_v1_mcp_proto_rawDesc = "" +
@@ -1988,7 +2175,19 @@ const file_proto_mcp_v1_mcp_proto_rawDesc = "" +
"\x11memory_free_bytes\x18\t \x01(\x04R\x0fmemoryFreeBytes\x12*\n" +
"\x11cpu_usage_percent\x18\n" +
" \x01(\x01R\x0fcpuUsagePercent\x12=\n" +
"\fuptime_since\x18\v \x01(\v2\x1a.google.protobuf.TimestampR\vuptimeSince2\x80\a\n" +
"\fuptime_since\x18\v \x01(\v2\x1a.google.protobuf.TimestampR\vuptimeSince\"\x8e\x01\n" +
"\fPurgeRequest\x12\x18\n" +
"\aservice\x18\x01 \x01(\tR\aservice\x12\x1c\n" +
"\tcomponent\x18\x02 \x01(\tR\tcomponent\x12\x17\n" +
"\adry_run\x18\x03 \x01(\bR\x06dryRun\x12-\n" +
"\x12defined_components\x18\x04 \x03(\tR\x11definedComponents\">\n" +
"\rPurgeResponse\x12-\n" +
"\aresults\x18\x01 \x03(\v2\x13.mcp.v1.PurgeResultR\aresults\"u\n" +
"\vPurgeResult\x12\x18\n" +
"\aservice\x18\x01 \x01(\tR\aservice\x12\x1c\n" +
"\tcomponent\x18\x02 \x01(\tR\tcomponent\x12\x16\n" +
"\x06purged\x18\x03 \x01(\bR\x06purged\x12\x16\n" +
"\x06reason\x18\x04 \x01(\tR\x06reason2\xbf\a\n" +
"\x0fMcpAgentService\x127\n" +
"\x06Deploy\x12\x15.mcp.v1.DeployRequest\x1a\x16.mcp.v1.DeployResponse\x12F\n" +
"\vStopService\x12\x1a.mcp.v1.StopServiceRequest\x1a\x1b.mcp.v1.StopServiceResponse\x12I\n" +
@@ -1999,6 +2198,7 @@ const file_proto_mcp_v1_mcp_proto_rawDesc = "" +
"\x10GetServiceStatus\x12\x1f.mcp.v1.GetServiceStatusRequest\x1a .mcp.v1.GetServiceStatusResponse\x12@\n" +
"\tLiveCheck\x12\x18.mcp.v1.LiveCheckRequest\x1a\x19.mcp.v1.LiveCheckResponse\x12R\n" +
"\x0fAdoptContainers\x12\x1e.mcp.v1.AdoptContainersRequest\x1a\x1f.mcp.v1.AdoptContainersResponse\x12=\n" +
"\x0ePurgeComponent\x12\x14.mcp.v1.PurgeRequest\x1a\x15.mcp.v1.PurgeResponse\x12=\n" +
"\bPushFile\x12\x17.mcp.v1.PushFileRequest\x1a\x18.mcp.v1.PushFileResponse\x12=\n" +
"\bPullFile\x12\x17.mcp.v1.PullFileRequest\x1a\x18.mcp.v1.PullFileResponse\x12C\n" +
"\n" +
@@ -2016,7 +2216,7 @@ func file_proto_mcp_v1_mcp_proto_rawDescGZIP() []byte {
return file_proto_mcp_v1_mcp_proto_rawDescData
}
var file_proto_mcp_v1_mcp_proto_msgTypes = make([]protoimpl.MessageInfo, 33)
var file_proto_mcp_v1_mcp_proto_msgTypes = make([]protoimpl.MessageInfo, 36)
var file_proto_mcp_v1_mcp_proto_goTypes = []any{
(*ComponentSpec)(nil), // 0: mcp.v1.ComponentSpec
(*ServiceSpec)(nil), // 1: mcp.v1.ServiceSpec
@@ -2051,7 +2251,10 @@ var file_proto_mcp_v1_mcp_proto_goTypes = []any{
(*PullFileResponse)(nil), // 30: mcp.v1.PullFileResponse
(*NodeStatusRequest)(nil), // 31: mcp.v1.NodeStatusRequest
(*NodeStatusResponse)(nil), // 32: mcp.v1.NodeStatusResponse
(*timestamppb.Timestamp)(nil), // 33: google.protobuf.Timestamp
(*PurgeRequest)(nil), // 33: mcp.v1.PurgeRequest
(*PurgeResponse)(nil), // 34: mcp.v1.PurgeResponse
(*PurgeResult)(nil), // 35: mcp.v1.PurgeResult
(*timestamppb.Timestamp)(nil), // 36: google.protobuf.Timestamp
}
var file_proto_mcp_v1_mcp_proto_depIdxs = []int32{
0, // 0: mcp.v1.ServiceSpec.components:type_name -> mcp.v1.ComponentSpec
@@ -2063,44 +2266,47 @@ var file_proto_mcp_v1_mcp_proto_depIdxs = []int32{
1, // 6: mcp.v1.SyncDesiredStateRequest.services:type_name -> mcp.v1.ServiceSpec
13, // 7: mcp.v1.SyncDesiredStateResponse.results:type_name -> mcp.v1.ServiceSyncResult
16, // 8: mcp.v1.ServiceInfo.components:type_name -> mcp.v1.ComponentInfo
33, // 9: mcp.v1.ComponentInfo.started:type_name -> google.protobuf.Timestamp
36, // 9: mcp.v1.ComponentInfo.started:type_name -> google.protobuf.Timestamp
15, // 10: mcp.v1.ListServicesResponse.services:type_name -> mcp.v1.ServiceInfo
33, // 11: mcp.v1.EventInfo.timestamp:type_name -> google.protobuf.Timestamp
36, // 11: mcp.v1.EventInfo.timestamp:type_name -> google.protobuf.Timestamp
15, // 12: mcp.v1.GetServiceStatusResponse.services:type_name -> mcp.v1.ServiceInfo
19, // 13: mcp.v1.GetServiceStatusResponse.drift:type_name -> mcp.v1.DriftInfo
20, // 14: mcp.v1.GetServiceStatusResponse.recent_events:type_name -> mcp.v1.EventInfo
15, // 15: mcp.v1.LiveCheckResponse.services:type_name -> mcp.v1.ServiceInfo
25, // 16: mcp.v1.AdoptContainersResponse.results:type_name -> mcp.v1.AdoptResult
33, // 17: mcp.v1.NodeStatusResponse.uptime_since:type_name -> google.protobuf.Timestamp
2, // 18: mcp.v1.McpAgentService.Deploy:input_type -> mcp.v1.DeployRequest
5, // 19: mcp.v1.McpAgentService.StopService:input_type -> mcp.v1.StopServiceRequest
7, // 20: mcp.v1.McpAgentService.StartService:input_type -> mcp.v1.StartServiceRequest
9, // 21: mcp.v1.McpAgentService.RestartService:input_type -> mcp.v1.RestartServiceRequest
11, // 22: mcp.v1.McpAgentService.SyncDesiredState:input_type -> mcp.v1.SyncDesiredStateRequest
14, // 23: mcp.v1.McpAgentService.ListServices:input_type -> mcp.v1.ListServicesRequest
18, // 24: mcp.v1.McpAgentService.GetServiceStatus:input_type -> mcp.v1.GetServiceStatusRequest
22, // 25: mcp.v1.McpAgentService.LiveCheck:input_type -> mcp.v1.LiveCheckRequest
24, // 26: mcp.v1.McpAgentService.AdoptContainers:input_type -> mcp.v1.AdoptContainersRequest
27, // 27: mcp.v1.McpAgentService.PushFile:input_type -> mcp.v1.PushFileRequest
29, // 28: mcp.v1.McpAgentService.PullFile:input_type -> mcp.v1.PullFileRequest
31, // 29: mcp.v1.McpAgentService.NodeStatus:input_type -> mcp.v1.NodeStatusRequest
3, // 30: mcp.v1.McpAgentService.Deploy:output_type -> mcp.v1.DeployResponse
6, // 31: mcp.v1.McpAgentService.StopService:output_type -> mcp.v1.StopServiceResponse
8, // 32: mcp.v1.McpAgentService.StartService:output_type -> mcp.v1.StartServiceResponse
10, // 33: mcp.v1.McpAgentService.RestartService:output_type -> mcp.v1.RestartServiceResponse
12, // 34: mcp.v1.McpAgentService.SyncDesiredState:output_type -> mcp.v1.SyncDesiredStateResponse
17, // 35: mcp.v1.McpAgentService.ListServices:output_type -> mcp.v1.ListServicesResponse
21, // 36: mcp.v1.McpAgentService.GetServiceStatus:output_type -> mcp.v1.GetServiceStatusResponse
23, // 37: mcp.v1.McpAgentService.LiveCheck:output_type -> mcp.v1.LiveCheckResponse
26, // 38: mcp.v1.McpAgentService.AdoptContainers:output_type -> mcp.v1.AdoptContainersResponse
28, // 39: mcp.v1.McpAgentService.PushFile:output_type -> mcp.v1.PushFileResponse
30, // 40: mcp.v1.McpAgentService.PullFile:output_type -> mcp.v1.PullFileResponse
32, // 41: mcp.v1.McpAgentService.NodeStatus:output_type -> mcp.v1.NodeStatusResponse
30, // [30:42] is the sub-list for method output_type
18, // [18:30] is the sub-list for method input_type
18, // [18:18] is the sub-list for extension type_name
18, // [18:18] is the sub-list for extension extendee
0, // [0:18] is the sub-list for field type_name
36, // 17: mcp.v1.NodeStatusResponse.uptime_since:type_name -> google.protobuf.Timestamp
35, // 18: mcp.v1.PurgeResponse.results:type_name -> mcp.v1.PurgeResult
2, // 19: mcp.v1.McpAgentService.Deploy:input_type -> mcp.v1.DeployRequest
5, // 20: mcp.v1.McpAgentService.StopService:input_type -> mcp.v1.StopServiceRequest
7, // 21: mcp.v1.McpAgentService.StartService:input_type -> mcp.v1.StartServiceRequest
9, // 22: mcp.v1.McpAgentService.RestartService:input_type -> mcp.v1.RestartServiceRequest
11, // 23: mcp.v1.McpAgentService.SyncDesiredState:input_type -> mcp.v1.SyncDesiredStateRequest
14, // 24: mcp.v1.McpAgentService.ListServices:input_type -> mcp.v1.ListServicesRequest
18, // 25: mcp.v1.McpAgentService.GetServiceStatus:input_type -> mcp.v1.GetServiceStatusRequest
22, // 26: mcp.v1.McpAgentService.LiveCheck:input_type -> mcp.v1.LiveCheckRequest
24, // 27: mcp.v1.McpAgentService.AdoptContainers:input_type -> mcp.v1.AdoptContainersRequest
33, // 28: mcp.v1.McpAgentService.PurgeComponent:input_type -> mcp.v1.PurgeRequest
27, // 29: mcp.v1.McpAgentService.PushFile:input_type -> mcp.v1.PushFileRequest
29, // 30: mcp.v1.McpAgentService.PullFile:input_type -> mcp.v1.PullFileRequest
31, // 31: mcp.v1.McpAgentService.NodeStatus:input_type -> mcp.v1.NodeStatusRequest
3, // 32: mcp.v1.McpAgentService.Deploy:output_type -> mcp.v1.DeployResponse
6, // 33: mcp.v1.McpAgentService.StopService:output_type -> mcp.v1.StopServiceResponse
8, // 34: mcp.v1.McpAgentService.StartService:output_type -> mcp.v1.StartServiceResponse
10, // 35: mcp.v1.McpAgentService.RestartService:output_type -> mcp.v1.RestartServiceResponse
12, // 36: mcp.v1.McpAgentService.SyncDesiredState:output_type -> mcp.v1.SyncDesiredStateResponse
17, // 37: mcp.v1.McpAgentService.ListServices:output_type -> mcp.v1.ListServicesResponse
21, // 38: mcp.v1.McpAgentService.GetServiceStatus:output_type -> mcp.v1.GetServiceStatusResponse
23, // 39: mcp.v1.McpAgentService.LiveCheck:output_type -> mcp.v1.LiveCheckResponse
26, // 40: mcp.v1.McpAgentService.AdoptContainers:output_type -> mcp.v1.AdoptContainersResponse
34, // 41: mcp.v1.McpAgentService.PurgeComponent:output_type -> mcp.v1.PurgeResponse
28, // 42: mcp.v1.McpAgentService.PushFile:output_type -> mcp.v1.PushFileResponse
30, // 43: mcp.v1.McpAgentService.PullFile:output_type -> mcp.v1.PullFileResponse
32, // 44: mcp.v1.McpAgentService.NodeStatus:output_type -> mcp.v1.NodeStatusResponse
32, // [32:45] is the sub-list for method output_type
19, // [19:32] is the sub-list for method input_type
19, // [19:19] is the sub-list for extension type_name
19, // [19:19] is the sub-list for extension extendee
0, // [0:19] is the sub-list for field type_name
}
func init() { file_proto_mcp_v1_mcp_proto_init() }
@@ -2114,7 +2320,7 @@ func file_proto_mcp_v1_mcp_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_mcp_v1_mcp_proto_rawDesc), len(file_proto_mcp_v1_mcp_proto_rawDesc)),
NumEnums: 0,
NumMessages: 33,
NumMessages: 36,
NumExtensions: 0,
NumServices: 1,
},

View File

@@ -28,6 +28,7 @@ const (
McpAgentService_GetServiceStatus_FullMethodName = "/mcp.v1.McpAgentService/GetServiceStatus"
McpAgentService_LiveCheck_FullMethodName = "/mcp.v1.McpAgentService/LiveCheck"
McpAgentService_AdoptContainers_FullMethodName = "/mcp.v1.McpAgentService/AdoptContainers"
McpAgentService_PurgeComponent_FullMethodName = "/mcp.v1.McpAgentService/PurgeComponent"
McpAgentService_PushFile_FullMethodName = "/mcp.v1.McpAgentService/PushFile"
McpAgentService_PullFile_FullMethodName = "/mcp.v1.McpAgentService/PullFile"
McpAgentService_NodeStatus_FullMethodName = "/mcp.v1.McpAgentService/NodeStatus"
@@ -50,6 +51,8 @@ type McpAgentServiceClient interface {
LiveCheck(ctx context.Context, in *LiveCheckRequest, opts ...grpc.CallOption) (*LiveCheckResponse, error)
// Adopt
AdoptContainers(ctx context.Context, in *AdoptContainersRequest, opts ...grpc.CallOption) (*AdoptContainersResponse, error)
// Purge
PurgeComponent(ctx context.Context, in *PurgeRequest, opts ...grpc.CallOption) (*PurgeResponse, error)
// File transfer
PushFile(ctx context.Context, in *PushFileRequest, opts ...grpc.CallOption) (*PushFileResponse, error)
PullFile(ctx context.Context, in *PullFileRequest, opts ...grpc.CallOption) (*PullFileResponse, error)
@@ -155,6 +158,16 @@ func (c *mcpAgentServiceClient) AdoptContainers(ctx context.Context, in *AdoptCo
return out, nil
}
func (c *mcpAgentServiceClient) PurgeComponent(ctx context.Context, in *PurgeRequest, opts ...grpc.CallOption) (*PurgeResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(PurgeResponse)
err := c.cc.Invoke(ctx, McpAgentService_PurgeComponent_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *mcpAgentServiceClient) PushFile(ctx context.Context, in *PushFileRequest, opts ...grpc.CallOption) (*PushFileResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(PushFileResponse)
@@ -202,6 +215,8 @@ type McpAgentServiceServer interface {
LiveCheck(context.Context, *LiveCheckRequest) (*LiveCheckResponse, error)
// Adopt
AdoptContainers(context.Context, *AdoptContainersRequest) (*AdoptContainersResponse, error)
// Purge
PurgeComponent(context.Context, *PurgeRequest) (*PurgeResponse, error)
// File transfer
PushFile(context.Context, *PushFileRequest) (*PushFileResponse, error)
PullFile(context.Context, *PullFileRequest) (*PullFileResponse, error)
@@ -244,6 +259,9 @@ func (UnimplementedMcpAgentServiceServer) LiveCheck(context.Context, *LiveCheckR
func (UnimplementedMcpAgentServiceServer) AdoptContainers(context.Context, *AdoptContainersRequest) (*AdoptContainersResponse, error) {
return nil, status.Error(codes.Unimplemented, "method AdoptContainers not implemented")
}
func (UnimplementedMcpAgentServiceServer) PurgeComponent(context.Context, *PurgeRequest) (*PurgeResponse, error) {
return nil, status.Error(codes.Unimplemented, "method PurgeComponent not implemented")
}
func (UnimplementedMcpAgentServiceServer) PushFile(context.Context, *PushFileRequest) (*PushFileResponse, error) {
return nil, status.Error(codes.Unimplemented, "method PushFile not implemented")
}
@@ -436,6 +454,24 @@ func _McpAgentService_AdoptContainers_Handler(srv interface{}, ctx context.Conte
return interceptor(ctx, in, info, handler)
}
func _McpAgentService_PurgeComponent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PurgeRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(McpAgentServiceServer).PurgeComponent(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: McpAgentService_PurgeComponent_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(McpAgentServiceServer).PurgeComponent(ctx, req.(*PurgeRequest))
}
return interceptor(ctx, in, info, handler)
}
func _McpAgentService_PushFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PushFileRequest)
if err := dec(in); err != nil {
@@ -533,6 +569,10 @@ var McpAgentService_ServiceDesc = grpc.ServiceDesc{
MethodName: "AdoptContainers",
Handler: _McpAgentService_AdoptContainers_Handler,
},
{
MethodName: "PurgeComponent",
Handler: _McpAgentService_PurgeComponent_Handler,
},
{
MethodName: "PushFile",
Handler: _McpAgentService_PushFile_Handler,