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

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;
}