d56f2243595781e8041368e9cea0c2360c4ea7f0
Implements the hypervisor design's Phase 1: a second runtime.Runtime backend (QEMU) that runs each service component as a Nanos unikernel VM instead of a podman container, selected per-component via a new runtime = "unikernel" service-def field. - internal/runtime/qemu.go: QEMURuntime. Pull extracts the ELF from the OCI image; Run does `ops build` + boots qemu-system-x86_64 with KVM, user-mode net port-forwards, QMP control socket and serial console log; Stop/Remove/Inspect/List/Logs map onto VM lifecycle + state dir. - proto/registry/servicedef: add runtime, memory_mb, vcpus fields (registry migration 5). - agent: holds both runtimes; runtimeFor() selects per component; listAllContainers() merges containers + VMs so drift/status see both. Unikernel runtime auto-enables on nodes with /dev/kvm + ops. Validated end-to-end on straylight: a test service deploys via `mcp deploy --direct`, boots as a Nanos unikernel, serves HTTP through the agent port-forward, and reports running via `mcp status`/`mcp logs`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
MCP — Metacircular Control Plane
MCP is the orchestrator for the Metacircular platform. It manages container lifecycle, tracks what services run where, and transfers files between the operator's workstation and managed nodes.
Architecture
CLI (mcp) — thin client on the operator's workstation. Reads local
service definition files, pushes intent to agents, queries status.
Agent (mcp-agent) — per-node daemon. Manages containers via rootless
podman, stores a SQLite registry of desired/observed state, monitors for
drift, and alerts the operator.
Quick Start
Build
make all # vet, lint, test, build
make mcp # CLI only
make mcp-agent # agent only
Install the CLI
cp mcp ~/.local/bin/
mkdir -p ~/.config/mcp/services
Create ~/.config/mcp/mcp.toml:
[services]
dir = "/home/<user>/.config/mcp/services"
[mcias]
server_url = "https://mcias.metacircular.net:8443"
service_name = "mcp"
[auth]
token_path = "/home/<user>/.config/mcp/token"
[[nodes]]
name = "rift"
address = "100.95.252.120:9444"
Authenticate
mcp login
Check status
mcp status # full picture: services, drift, events
mcp ps # live container check with uptime
mcp list # quick registry query
Deploy a service
Write a service definition in ~/.config/mcp/services/<name>.toml:
name = "myservice"
node = "rift"
active = true
[[components]]
name = "api"
image = "mcr.svc.mcp.metacircular.net:8443/myservice:v1.0.0"
network = "mcpnet"
user = "0:0"
restart = "unless-stopped"
ports = ["127.0.0.1:8443:8443"]
volumes = ["/srv/myservice:/srv/myservice"]
cmd = ["server", "--config", "/srv/myservice/myservice.toml"]
Then deploy:
mcp deploy myservice
Commands
| Command | Description |
|---|---|
mcp login |
Authenticate to MCIAS |
mcp deploy <service>[/<component>] |
Deploy from service definition |
mcp stop <service> |
Stop all components |
mcp start <service> |
Start all components |
mcp restart <service> |
Restart all components |
mcp list |
List services (registry) |
mcp ps |
Live container check |
mcp status [service] |
Full status with drift and events |
mcp sync |
Push all service definitions |
mcp adopt <service> |
Adopt running containers |
mcp service show <service> |
Print spec from agent |
mcp service edit <service> |
Edit definition in $EDITOR |
mcp service export <service> |
Export agent spec to file |
mcp push <file> <service> [path] |
Push file to node |
mcp pull <service> <path> [file] |
Pull file from node |
mcp node list |
List nodes |
mcp node add <name> <addr> |
Add a node |
mcp node remove <name> |
Remove a node |
Documentation
- ARCHITECTURE.md — design specification
- RUNBOOK.md — operational procedures
- PROJECT_PLAN_V1.md — implementation plan
- PROGRESS_V1.md — progress and remaining work
Description
Languages
Go
98.8%
Shell
0.7%
Nix
0.3%
Makefile
0.2%