88 lines
4.4 KiB
Markdown
88 lines
4.4 KiB
Markdown
# CLAUDE.md
|
||
|
||
## Project Overview
|
||
|
||
MCP (Metacircular Control Plane) 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
|
||
|
||
MCP has two components:
|
||
- **CLI** (`mcp`) — thin client on the operator's workstation. Reads local service definition files, pushes intent to agents, queries status. No database.
|
||
- **Agent** (`mcp-agent`) — smart per-node daemon. Manages containers via podman, stores the registry (SQLite), monitors for drift, alerts the operator.
|
||
|
||
### Runtimes (containers + unikernels)
|
||
|
||
The agent holds two `runtime.Runtime` backends and selects per component via
|
||
`a.runtimeFor(comp.Runtime)`:
|
||
- **Podman** (`internal/runtime/podman.go`) — containers (default).
|
||
- **QEMU** (`internal/runtime/qemu.go`) — Nanos unikernel VMs, when a component
|
||
sets `runtime = "unikernel"` and the node has KVM + `ops`.
|
||
|
||
`listAllContainers()` merges both backends so status/drift see VMs and
|
||
containers uniformly. See the root repo's `docs/unikernels.md` for the full
|
||
operator + developer guide, and `docs/hypervisor-design.md` for the rationale.
|
||
Service-def fields: `runtime`, `memory`, `vcpus` (proto `ComponentSpec`
|
||
fields 11–13; registry migration 5). **All container behavior is unchanged.**
|
||
|
||
Services have one or more components (containers). Container naming: `<service>-<component>`.
|
||
|
||
## v2 Development (Multi-Node)
|
||
|
||
MCP v2 extends the single-node agent model to a multi-node fleet with a central master process. See the root repo's `docs/phase-e-plan.md` and `docs/architecture-v2.md` for the full design.
|
||
|
||
**Current state:**
|
||
- **svc** is operational as an edge node (manages mc-proxy routing only, no containers)
|
||
- **rift** runs the agent with full container management
|
||
- **orion** is provisioned but offline for maintenance
|
||
|
||
**Key v2 concepts (in development):**
|
||
- **mcp-master** — central orchestrator on rift. Accepts CLI commands, dispatches to agents, maintains node registry, coordinates edge routing.
|
||
- **Agent self-registration** — agents register with the master on startup (name, role, address, arch). No static node config required after bootstrap.
|
||
- **Tier-based placement** — `tier = "core"` runs on the master node, `tier = "worker"` (default) is auto-placed on a worker with capacity, `node = "<name>"` overrides for pinned services.
|
||
- **Edge routing** — `public = true` on routes declares intent; the master assigns the route to an edge node (currently svc).
|
||
|
||
## Build Commands
|
||
|
||
```bash
|
||
make all # vet → lint → test → build both binaries
|
||
make build # go build ./...
|
||
make test # go test ./...
|
||
make vet # go vet ./...
|
||
make lint # golangci-lint run ./...
|
||
make proto # regenerate gRPC code from .proto files
|
||
make proto-lint # buf lint + buf breaking
|
||
make mcp # build CLI binary
|
||
make mcp-agent # build agent binary
|
||
make clean # remove binaries
|
||
```
|
||
|
||
Run a single test: `go test ./internal/registry/ -run TestComponentCRUD`
|
||
|
||
## Project Structure
|
||
|
||
- `cmd/mcp/` — CLI entry point
|
||
- `cmd/mcp-agent/` — Agent entry point
|
||
- `internal/agent/` — Agent core (deploy, lifecycle, sync, adopt, status, files, edge_rpc, dns, proxy, certs)
|
||
- `internal/runtime/` — Container runtime abstraction (podman)
|
||
- `internal/registry/` — SQLite registry (services, components, events)
|
||
- `internal/monitor/` — Monitoring subsystem (watch loop, alerting)
|
||
- `internal/servicedef/` — Service definition file parsing (TOML)
|
||
- `internal/auth/` — MCIAS integration (token validation, interceptor)
|
||
- `internal/config/` — Configuration loading (CLI + agent)
|
||
- `proto/mcp/v1/` — Proto definitions
|
||
- `gen/mcp/v1/` — Generated Go gRPC code
|
||
|
||
## Critical Rules
|
||
|
||
1. Agent is gRPC-only (no REST). This is a deliberate exception to the platform's REST+gRPC parity rule.
|
||
2. Container naming convention: `<service>-<component>` (e.g., `metacrypt-api`, `metacrypt-web`).
|
||
3. File operations are scoped to `/srv/<service>/`. Path traversal is rejected.
|
||
4. Alert commands use exec-style invocation (argv array, no shell). Never use `sh -c`.
|
||
5. The agent binds to the overlay interface only, not all interfaces. It does NOT sit behind MC-Proxy.
|
||
6. Every RPC is audit-logged at info level (method, caller, timestamp).
|
||
7. `active: true/false` in service definitions controls desired state. `mcp stop/start` update the file.
|
||
|
||
## Module Path
|
||
|
||
`git.wntrmute.dev/mc/mcp`
|