Skip to content

Machine-Readable State ​

An agent cannot act on infrastructure it cannot see. Nanokit exposes its view of the world as structured data — not log scrapes — through three channels.

What is observable today ​

State is reported per project and per environment for four resource families:

FamilyWhat state includes
ServicesDesired vs. running status, image/config drift, health, exposure
DatabasesEngine, mode, branch topology, volume backing
SecretsWhich keys are declared/resolved — never their values
DomainsDeclared hosts, TLS/certificate state

Channel 1 — the bridge WebSocket ​

A bridge process runs alongside your project and listens on ws://127.0.0.1:3006 by default (override with -p or $NANOKIT_BRIDGE_PORT). It is started and managed for you by nkapp up, or explicitly with nkapp hub --start.

It carries telemetry and accepts request/response messages, so an agent can read live state and trigger guarded actions (e.g. volume maintenance) over a single persistent connection. The protocol is message-based JSON validated against Zod contracts — see UI Bridge (WebSockets) for the wire details.

Typical loop for an agent:

  1. Connect to the bridge.
  2. Request current inventory (services/databases/secrets/domains).
  3. Compare against intent; if a change is needed, edit nanokit.yml (see The Declarative Contract).
  4. Re-read state to verify convergence.

Channel 2 — the CLI ​

The same information is available offline via nkapp:

CommandWhat it gives an agent
nkapp plan -e <env>The exact reconcile plan before anything executes — the cheapest way to validate a config edit. Also written as JSON to .nanokit/plans/latest.json (or --output <path>), which is the most directly machine-readable artifact Nanokit produces today.
nkapp doctorEnvironment health and common failure classes, including container and image accumulation. Always exits 0, so parse the output rather than the exit code.
nkapp infra resourcesA live cloud inventory queried straight from the provider APIs (--orphans for resources not declared in the config) — distinct from infra status, which reads the possibly-stale local state file.
nkapp secrets listDeclared secret keys; values are never printed.
nkapp export k8sThe whole config as standard Kubernetes manifests — a fully structured rendering of intent, no cluster required.

Most output is human-formatted

Apart from the plan JSON and export k8s/export helm, the CLI prints human-readable tables and coloured text, not a stable machine format. There is no global --json flag today. Treat CLI stdout as a convenience surface and prefer the plan JSON or the bridge messages for anything a program must depend on.

Both channels report state, never narrative: consumers get typed fields they can branch on, which is what makes closed-loop agent behavior tractable — the loop terminates because convergence is checkable.

Channel 3 — the MCP server ​

nkapp mcp serves the same state as typed tool results, with no parsing: get_environment (one environment's full structured state, including a drift hash, secret keys only), get_state (live inventory with blast-radius flags), get_plan, get_deploy_scope, list_services, list_databases, list_secrets, list_domains, list_backups, get_logs (capped and redacted) and doctor. Every response is a JSON envelope with ok, data, error, warnings and meta. This is the channel to prefer when the consumer is an agent host.

The same server also takes changes, under a plan-then-apply rule and the declarative agent: policy block. See The MCP Server.

Direction

Still on the roadmap, not shipped:

  • Filtering the tool list by your team role. The resolver exists, but the server does not yet resolve the role from your account token, so today only the agent: block filters.
  • Destructive agent tools (destroy, restore, deleting a database branch). These remain human-only commands.
  • A Hub "Agent activity" panel with approve-from-Hub, and a hosted (remote) MCP endpoint.