P0.2: Proto definitions and code generation

Full gRPC service definition with 12 RPCs: Deploy, StopService,
StartService, RestartService, SyncDesiredState, ListServices,
GetServiceStatus, LiveCheck, AdoptContainers, PushFile, PullFile,
NodeStatus. buf lint passes. Generated Go code compiles.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-26 11:14:43 -07:00
parent eaad18116a
commit 3f23b14ef4
7 changed files with 2972 additions and 2 deletions

View File

@@ -3,7 +3,7 @@
## Phase 0: Project Scaffolding
- [x] **P0.1** Repository and module setup
- [ ] **P0.2** Proto definitions and code generation
- [x] **P0.2** Proto definitions and code generation
## Phase 1: Core Libraries

9
buf.yaml Normal file
View File

@@ -0,0 +1,9 @@
version: v2
modules:
- path: proto
lint:
use:
- STANDARD
breaking:
use:
- FILE

2128
gen/mcp/v1/mcp.pb.go Normal file

File diff suppressed because it is too large Load Diff

551
gen/mcp/v1/mcp_grpc.pb.go Normal file
View File

@@ -0,0 +1,551 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.6.1
// - protoc v6.32.1
// source: proto/mcp/v1/mcp.proto
package mcpv1
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
McpAgentService_Deploy_FullMethodName = "/mcp.v1.McpAgentService/Deploy"
McpAgentService_StopService_FullMethodName = "/mcp.v1.McpAgentService/StopService"
McpAgentService_StartService_FullMethodName = "/mcp.v1.McpAgentService/StartService"
McpAgentService_RestartService_FullMethodName = "/mcp.v1.McpAgentService/RestartService"
McpAgentService_SyncDesiredState_FullMethodName = "/mcp.v1.McpAgentService/SyncDesiredState"
McpAgentService_ListServices_FullMethodName = "/mcp.v1.McpAgentService/ListServices"
McpAgentService_GetServiceStatus_FullMethodName = "/mcp.v1.McpAgentService/GetServiceStatus"
McpAgentService_LiveCheck_FullMethodName = "/mcp.v1.McpAgentService/LiveCheck"
McpAgentService_AdoptContainers_FullMethodName = "/mcp.v1.McpAgentService/AdoptContainers"
McpAgentService_PushFile_FullMethodName = "/mcp.v1.McpAgentService/PushFile"
McpAgentService_PullFile_FullMethodName = "/mcp.v1.McpAgentService/PullFile"
McpAgentService_NodeStatus_FullMethodName = "/mcp.v1.McpAgentService/NodeStatus"
)
// McpAgentServiceClient is the client API for McpAgentService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type McpAgentServiceClient interface {
// Service lifecycle
Deploy(ctx context.Context, in *DeployRequest, opts ...grpc.CallOption) (*DeployResponse, error)
StopService(ctx context.Context, in *StopServiceRequest, opts ...grpc.CallOption) (*StopServiceResponse, error)
StartService(ctx context.Context, in *StartServiceRequest, opts ...grpc.CallOption) (*StartServiceResponse, error)
RestartService(ctx context.Context, in *RestartServiceRequest, opts ...grpc.CallOption) (*RestartServiceResponse, error)
// Desired state
SyncDesiredState(ctx context.Context, in *SyncDesiredStateRequest, opts ...grpc.CallOption) (*SyncDesiredStateResponse, error)
// Status and registry
ListServices(ctx context.Context, in *ListServicesRequest, opts ...grpc.CallOption) (*ListServicesResponse, error)
GetServiceStatus(ctx context.Context, in *GetServiceStatusRequest, opts ...grpc.CallOption) (*GetServiceStatusResponse, error)
LiveCheck(ctx context.Context, in *LiveCheckRequest, opts ...grpc.CallOption) (*LiveCheckResponse, error)
// Adopt
AdoptContainers(ctx context.Context, in *AdoptContainersRequest, opts ...grpc.CallOption) (*AdoptContainersResponse, 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)
// Node
NodeStatus(ctx context.Context, in *NodeStatusRequest, opts ...grpc.CallOption) (*NodeStatusResponse, error)
}
type mcpAgentServiceClient struct {
cc grpc.ClientConnInterface
}
func NewMcpAgentServiceClient(cc grpc.ClientConnInterface) McpAgentServiceClient {
return &mcpAgentServiceClient{cc}
}
func (c *mcpAgentServiceClient) Deploy(ctx context.Context, in *DeployRequest, opts ...grpc.CallOption) (*DeployResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(DeployResponse)
err := c.cc.Invoke(ctx, McpAgentService_Deploy_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *mcpAgentServiceClient) StopService(ctx context.Context, in *StopServiceRequest, opts ...grpc.CallOption) (*StopServiceResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(StopServiceResponse)
err := c.cc.Invoke(ctx, McpAgentService_StopService_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *mcpAgentServiceClient) StartService(ctx context.Context, in *StartServiceRequest, opts ...grpc.CallOption) (*StartServiceResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(StartServiceResponse)
err := c.cc.Invoke(ctx, McpAgentService_StartService_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *mcpAgentServiceClient) RestartService(ctx context.Context, in *RestartServiceRequest, opts ...grpc.CallOption) (*RestartServiceResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(RestartServiceResponse)
err := c.cc.Invoke(ctx, McpAgentService_RestartService_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *mcpAgentServiceClient) SyncDesiredState(ctx context.Context, in *SyncDesiredStateRequest, opts ...grpc.CallOption) (*SyncDesiredStateResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(SyncDesiredStateResponse)
err := c.cc.Invoke(ctx, McpAgentService_SyncDesiredState_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *mcpAgentServiceClient) ListServices(ctx context.Context, in *ListServicesRequest, opts ...grpc.CallOption) (*ListServicesResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ListServicesResponse)
err := c.cc.Invoke(ctx, McpAgentService_ListServices_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *mcpAgentServiceClient) GetServiceStatus(ctx context.Context, in *GetServiceStatusRequest, opts ...grpc.CallOption) (*GetServiceStatusResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetServiceStatusResponse)
err := c.cc.Invoke(ctx, McpAgentService_GetServiceStatus_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *mcpAgentServiceClient) LiveCheck(ctx context.Context, in *LiveCheckRequest, opts ...grpc.CallOption) (*LiveCheckResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(LiveCheckResponse)
err := c.cc.Invoke(ctx, McpAgentService_LiveCheck_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *mcpAgentServiceClient) AdoptContainers(ctx context.Context, in *AdoptContainersRequest, opts ...grpc.CallOption) (*AdoptContainersResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AdoptContainersResponse)
err := c.cc.Invoke(ctx, McpAgentService_AdoptContainers_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)
err := c.cc.Invoke(ctx, McpAgentService_PushFile_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *mcpAgentServiceClient) PullFile(ctx context.Context, in *PullFileRequest, opts ...grpc.CallOption) (*PullFileResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(PullFileResponse)
err := c.cc.Invoke(ctx, McpAgentService_PullFile_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *mcpAgentServiceClient) NodeStatus(ctx context.Context, in *NodeStatusRequest, opts ...grpc.CallOption) (*NodeStatusResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(NodeStatusResponse)
err := c.cc.Invoke(ctx, McpAgentService_NodeStatus_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// McpAgentServiceServer is the server API for McpAgentService service.
// All implementations must embed UnimplementedMcpAgentServiceServer
// for forward compatibility.
type McpAgentServiceServer interface {
// Service lifecycle
Deploy(context.Context, *DeployRequest) (*DeployResponse, error)
StopService(context.Context, *StopServiceRequest) (*StopServiceResponse, error)
StartService(context.Context, *StartServiceRequest) (*StartServiceResponse, error)
RestartService(context.Context, *RestartServiceRequest) (*RestartServiceResponse, error)
// Desired state
SyncDesiredState(context.Context, *SyncDesiredStateRequest) (*SyncDesiredStateResponse, error)
// Status and registry
ListServices(context.Context, *ListServicesRequest) (*ListServicesResponse, error)
GetServiceStatus(context.Context, *GetServiceStatusRequest) (*GetServiceStatusResponse, error)
LiveCheck(context.Context, *LiveCheckRequest) (*LiveCheckResponse, error)
// Adopt
AdoptContainers(context.Context, *AdoptContainersRequest) (*AdoptContainersResponse, error)
// File transfer
PushFile(context.Context, *PushFileRequest) (*PushFileResponse, error)
PullFile(context.Context, *PullFileRequest) (*PullFileResponse, error)
// Node
NodeStatus(context.Context, *NodeStatusRequest) (*NodeStatusResponse, error)
mustEmbedUnimplementedMcpAgentServiceServer()
}
// UnimplementedMcpAgentServiceServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedMcpAgentServiceServer struct{}
func (UnimplementedMcpAgentServiceServer) Deploy(context.Context, *DeployRequest) (*DeployResponse, error) {
return nil, status.Error(codes.Unimplemented, "method Deploy not implemented")
}
func (UnimplementedMcpAgentServiceServer) StopService(context.Context, *StopServiceRequest) (*StopServiceResponse, error) {
return nil, status.Error(codes.Unimplemented, "method StopService not implemented")
}
func (UnimplementedMcpAgentServiceServer) StartService(context.Context, *StartServiceRequest) (*StartServiceResponse, error) {
return nil, status.Error(codes.Unimplemented, "method StartService not implemented")
}
func (UnimplementedMcpAgentServiceServer) RestartService(context.Context, *RestartServiceRequest) (*RestartServiceResponse, error) {
return nil, status.Error(codes.Unimplemented, "method RestartService not implemented")
}
func (UnimplementedMcpAgentServiceServer) SyncDesiredState(context.Context, *SyncDesiredStateRequest) (*SyncDesiredStateResponse, error) {
return nil, status.Error(codes.Unimplemented, "method SyncDesiredState not implemented")
}
func (UnimplementedMcpAgentServiceServer) ListServices(context.Context, *ListServicesRequest) (*ListServicesResponse, error) {
return nil, status.Error(codes.Unimplemented, "method ListServices not implemented")
}
func (UnimplementedMcpAgentServiceServer) GetServiceStatus(context.Context, *GetServiceStatusRequest) (*GetServiceStatusResponse, error) {
return nil, status.Error(codes.Unimplemented, "method GetServiceStatus not implemented")
}
func (UnimplementedMcpAgentServiceServer) LiveCheck(context.Context, *LiveCheckRequest) (*LiveCheckResponse, error) {
return nil, status.Error(codes.Unimplemented, "method LiveCheck not implemented")
}
func (UnimplementedMcpAgentServiceServer) AdoptContainers(context.Context, *AdoptContainersRequest) (*AdoptContainersResponse, error) {
return nil, status.Error(codes.Unimplemented, "method AdoptContainers not implemented")
}
func (UnimplementedMcpAgentServiceServer) PushFile(context.Context, *PushFileRequest) (*PushFileResponse, error) {
return nil, status.Error(codes.Unimplemented, "method PushFile not implemented")
}
func (UnimplementedMcpAgentServiceServer) PullFile(context.Context, *PullFileRequest) (*PullFileResponse, error) {
return nil, status.Error(codes.Unimplemented, "method PullFile not implemented")
}
func (UnimplementedMcpAgentServiceServer) NodeStatus(context.Context, *NodeStatusRequest) (*NodeStatusResponse, error) {
return nil, status.Error(codes.Unimplemented, "method NodeStatus not implemented")
}
func (UnimplementedMcpAgentServiceServer) mustEmbedUnimplementedMcpAgentServiceServer() {}
func (UnimplementedMcpAgentServiceServer) testEmbeddedByValue() {}
// UnsafeMcpAgentServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to McpAgentServiceServer will
// result in compilation errors.
type UnsafeMcpAgentServiceServer interface {
mustEmbedUnimplementedMcpAgentServiceServer()
}
func RegisterMcpAgentServiceServer(s grpc.ServiceRegistrar, srv McpAgentServiceServer) {
// If the following call panics, it indicates UnimplementedMcpAgentServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&McpAgentService_ServiceDesc, srv)
}
func _McpAgentService_Deploy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeployRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(McpAgentServiceServer).Deploy(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: McpAgentService_Deploy_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(McpAgentServiceServer).Deploy(ctx, req.(*DeployRequest))
}
return interceptor(ctx, in, info, handler)
}
func _McpAgentService_StopService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(StopServiceRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(McpAgentServiceServer).StopService(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: McpAgentService_StopService_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(McpAgentServiceServer).StopService(ctx, req.(*StopServiceRequest))
}
return interceptor(ctx, in, info, handler)
}
func _McpAgentService_StartService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(StartServiceRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(McpAgentServiceServer).StartService(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: McpAgentService_StartService_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(McpAgentServiceServer).StartService(ctx, req.(*StartServiceRequest))
}
return interceptor(ctx, in, info, handler)
}
func _McpAgentService_RestartService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(RestartServiceRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(McpAgentServiceServer).RestartService(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: McpAgentService_RestartService_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(McpAgentServiceServer).RestartService(ctx, req.(*RestartServiceRequest))
}
return interceptor(ctx, in, info, handler)
}
func _McpAgentService_SyncDesiredState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SyncDesiredStateRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(McpAgentServiceServer).SyncDesiredState(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: McpAgentService_SyncDesiredState_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(McpAgentServiceServer).SyncDesiredState(ctx, req.(*SyncDesiredStateRequest))
}
return interceptor(ctx, in, info, handler)
}
func _McpAgentService_ListServices_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListServicesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(McpAgentServiceServer).ListServices(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: McpAgentService_ListServices_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(McpAgentServiceServer).ListServices(ctx, req.(*ListServicesRequest))
}
return interceptor(ctx, in, info, handler)
}
func _McpAgentService_GetServiceStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetServiceStatusRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(McpAgentServiceServer).GetServiceStatus(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: McpAgentService_GetServiceStatus_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(McpAgentServiceServer).GetServiceStatus(ctx, req.(*GetServiceStatusRequest))
}
return interceptor(ctx, in, info, handler)
}
func _McpAgentService_LiveCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(LiveCheckRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(McpAgentServiceServer).LiveCheck(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: McpAgentService_LiveCheck_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(McpAgentServiceServer).LiveCheck(ctx, req.(*LiveCheckRequest))
}
return interceptor(ctx, in, info, handler)
}
func _McpAgentService_AdoptContainers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AdoptContainersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(McpAgentServiceServer).AdoptContainers(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: McpAgentService_AdoptContainers_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(McpAgentServiceServer).AdoptContainers(ctx, req.(*AdoptContainersRequest))
}
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 {
return nil, err
}
if interceptor == nil {
return srv.(McpAgentServiceServer).PushFile(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: McpAgentService_PushFile_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(McpAgentServiceServer).PushFile(ctx, req.(*PushFileRequest))
}
return interceptor(ctx, in, info, handler)
}
func _McpAgentService_PullFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PullFileRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(McpAgentServiceServer).PullFile(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: McpAgentService_PullFile_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(McpAgentServiceServer).PullFile(ctx, req.(*PullFileRequest))
}
return interceptor(ctx, in, info, handler)
}
func _McpAgentService_NodeStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(NodeStatusRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(McpAgentServiceServer).NodeStatus(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: McpAgentService_NodeStatus_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(McpAgentServiceServer).NodeStatus(ctx, req.(*NodeStatusRequest))
}
return interceptor(ctx, in, info, handler)
}
// McpAgentService_ServiceDesc is the grpc.ServiceDesc for McpAgentService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var McpAgentService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "mcp.v1.McpAgentService",
HandlerType: (*McpAgentServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Deploy",
Handler: _McpAgentService_Deploy_Handler,
},
{
MethodName: "StopService",
Handler: _McpAgentService_StopService_Handler,
},
{
MethodName: "StartService",
Handler: _McpAgentService_StartService_Handler,
},
{
MethodName: "RestartService",
Handler: _McpAgentService_RestartService_Handler,
},
{
MethodName: "SyncDesiredState",
Handler: _McpAgentService_SyncDesiredState_Handler,
},
{
MethodName: "ListServices",
Handler: _McpAgentService_ListServices_Handler,
},
{
MethodName: "GetServiceStatus",
Handler: _McpAgentService_GetServiceStatus_Handler,
},
{
MethodName: "LiveCheck",
Handler: _McpAgentService_LiveCheck_Handler,
},
{
MethodName: "AdoptContainers",
Handler: _McpAgentService_AdoptContainers_Handler,
},
{
MethodName: "PushFile",
Handler: _McpAgentService_PushFile_Handler,
},
{
MethodName: "PullFile",
Handler: _McpAgentService_PullFile_Handler,
},
{
MethodName: "NodeStatus",
Handler: _McpAgentService_NodeStatus_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "proto/mcp/v1/mcp.proto",
}

10
go.mod
View File

@@ -2,9 +2,17 @@ module git.wntrmute.dev/kyle/mcp
go 1.25.7
require github.com/spf13/cobra v1.10.2
require (
github.com/spf13/cobra v1.10.2
google.golang.org/grpc v1.79.3
google.golang.org/protobuf v1.36.11
)
require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/pflag v1.0.9 // indirect
golang.org/x/net v0.48.0 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.32.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
)

38
go.sum
View File

@@ -1,4 +1,16 @@
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -6,5 +18,31 @@ github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

236
proto/mcp/v1/mcp.proto Normal file
View File

@@ -0,0 +1,236 @@
syntax = "proto3";
package mcp.v1;
option go_package = "git.wntrmute.dev/kyle/mcp/gen/mcp/v1;mcpv1";
import "google/protobuf/timestamp.proto";
service McpAgentService {
// Service lifecycle
rpc Deploy(DeployRequest) returns (DeployResponse);
rpc StopService(StopServiceRequest) returns (StopServiceResponse);
rpc StartService(StartServiceRequest) returns (StartServiceResponse);
rpc RestartService(RestartServiceRequest) returns (RestartServiceResponse);
// Desired state
rpc SyncDesiredState(SyncDesiredStateRequest) returns (SyncDesiredStateResponse);
// Status and registry
rpc ListServices(ListServicesRequest) returns (ListServicesResponse);
rpc GetServiceStatus(GetServiceStatusRequest) returns (GetServiceStatusResponse);
rpc LiveCheck(LiveCheckRequest) returns (LiveCheckResponse);
// Adopt
rpc AdoptContainers(AdoptContainersRequest) returns (AdoptContainersResponse);
// File transfer
rpc PushFile(PushFileRequest) returns (PushFileResponse);
rpc PullFile(PullFileRequest) returns (PullFileResponse);
// Node
rpc NodeStatus(NodeStatusRequest) returns (NodeStatusResponse);
}
// --- Service lifecycle ---
message ComponentSpec {
string name = 1;
string image = 2;
string network = 3;
string user = 4;
string restart = 5;
repeated string ports = 6;
repeated string volumes = 7;
repeated string cmd = 8;
}
message ServiceSpec {
string name = 1;
bool active = 2;
repeated ComponentSpec components = 3;
}
message DeployRequest {
ServiceSpec service = 1;
// Deploy a single component by name. Empty means deploy all.
string component = 2;
}
message DeployResponse {
repeated ComponentResult results = 1;
}
message ComponentResult {
string name = 1;
bool success = 2;
string error = 3;
}
message StopServiceRequest {
string name = 1;
}
message StopServiceResponse {
repeated ComponentResult results = 1;
}
message StartServiceRequest {
string name = 1;
}
message StartServiceResponse {
repeated ComponentResult results = 1;
}
message RestartServiceRequest {
string name = 1;
}
message RestartServiceResponse {
repeated ComponentResult results = 1;
}
// --- Desired state ---
message SyncDesiredStateRequest {
// All services for this node.
repeated ServiceSpec services = 1;
}
message SyncDesiredStateResponse {
repeated ServiceSyncResult results = 1;
}
message ServiceSyncResult {
string name = 1;
// Whether the desired state was updated.
bool changed = 2;
string summary = 3;
}
// --- Status and registry ---
message ListServicesRequest {}
message ServiceInfo {
string name = 1;
bool active = 2;
repeated ComponentInfo components = 3;
}
message ComponentInfo {
string name = 1;
string image = 2;
// "running", "stopped", "ignore"
string desired_state = 3;
// "running", "stopped", "exited", "removed", "unknown"
string observed_state = 4;
// Extracted from the image tag.
string version = 5;
google.protobuf.Timestamp started = 6;
}
message ListServicesResponse {
repeated ServiceInfo services = 1;
}
message GetServiceStatusRequest {
// Empty means all services.
string name = 1;
}
message DriftInfo {
string service = 1;
string component = 2;
string desired_state = 3;
string observed_state = 4;
}
message EventInfo {
string service = 1;
string component = 2;
string prev_state = 3;
string new_state = 4;
google.protobuf.Timestamp timestamp = 5;
}
message GetServiceStatusResponse {
repeated ServiceInfo services = 1;
repeated DriftInfo drift = 2;
repeated EventInfo recent_events = 3;
}
message LiveCheckRequest {}
message LiveCheckResponse {
// Services with freshly observed state from the container runtime.
repeated ServiceInfo services = 1;
}
// --- Adopt ---
message AdoptContainersRequest {
// Service name. The agent matches containers named <service>-*.
string service = 1;
}
message AdoptResult {
// Runtime container name (e.g., "metacrypt-api").
string container = 1;
// Derived component name (e.g., "api").
string component = 2;
bool success = 3;
string error = 4;
}
message AdoptContainersResponse {
repeated AdoptResult results = 1;
}
// --- File transfer ---
// All paths are relative to /srv/<service>/ on the node.
message PushFileRequest {
string service = 1;
// Relative path within the service directory.
string path = 2;
bytes content = 3;
// File permissions (e.g., 0600).
uint32 mode = 4;
}
message PushFileResponse {
bool success = 1;
string error = 2;
}
message PullFileRequest {
string service = 1;
// Relative path within the service directory.
string path = 2;
}
message PullFileResponse {
bytes content = 1;
uint32 mode = 2;
string error = 3;
}
// --- Node ---
message NodeStatusRequest {}
message NodeStatusResponse {
string node_name = 1;
// "podman" or "docker"
string runtime = 2;
string runtime_version = 3;
uint32 service_count = 4;
uint32 component_count = 5;
uint64 disk_total_bytes = 6;
uint64 disk_free_bytes = 7;
uint64 memory_total_bytes = 8;
uint64 memory_free_bytes = 9;
double cpu_usage_percent = 10;
google.protobuf.Timestamp uptime_since = 11;
}