Skip to content
intendant-devPublic

About

Open-source operating environment for autonomous AI agents, with cross-platform machine control, oversight, and multi-host federation.

Topics

Resources

Security policy

Stars

13 stars

Watchers

0 watching

Forks

Latest commit

 

History

6,707 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Intendant

Intendant

Give an AI agent a full machine — under your oversight.

intendant.dev · Docs · How trust works

Intendant is an open-source operating environment for autonomous AI agents, written in Rust. The agent gets a real machine — shell, file editing, a graphical desktop it can see and control, voice, and phone calls — under layered human oversight: an autonomy dial, per-category rules, and per-action approval gates, with every command, diff, and decision logged and replayable. A durable Agenda carries deferred intent across sessions, while a provenance-labeled Memory plane carries explicitly retrieved machine-wide claims. Intendant runs its own agent loop, supervises Codex, Claude Code, Kimi Code, and Pi as managed backends, and is portable across OpenAI, Anthropic, and Gemini — on macOS, Linux, and Windows, all first-class.

Your everyday directory can be a browser tab. Hosted Connect gives any browser zero-install route linking, discovery, and fleet presence, but the default binary gives hosted-origin code an immutable role:none: it cannot open a daemon-control session, even after a local grant or configuration edit. Its rendezvous-controlled fleet WebPKI names are likewise discovery-only. Administration and ordinary control start from a trusted local console or an independently reached daemon-served direct/mTLS dashboard. The packaged macOS app contains a local mTLS bridge, but no Developer ID-signed/notarized release has been published for this alpha; an -unsigned-dev artifact is for development, not a distribution trust anchor.

And it doesn't stop at one box. Daemons federate into fleets, and people and organizations grant other people — and other agents — scoped access to their machines, infrastructure, and resources. Every session's authority is minted by the target machine's own IAM, never by a hosted service. The result is a network of agentic networks.

A daemon in minutes

Stand up a keyless daemon on a fresh box with one command (registration on the hosted rendezvous is invite-only during the alpha; self-hosting is never gated). The installer is a release-pinned GitHub asset — stamped with the release it installs, sha256-committed to a public transparency log, and self-verifying: it announces its release identity at start and fails closed if the tree it fetches doesn't match. Prefer reading before running? Download the same asset, check it against the release's .sha256, then run it. (Until the first v* release is published, the asset URL 404s — clone and build from a checkout below.)

# macOS / Linux
curl -fsSL https://github.com/intendant-dev/Intendant/releases/latest/download/install.sh | sh
# Windows
& ([scriptblock]::Create((irm https://github.com/intendant-dev/Intendant/releases/latest/download/install.ps1)))

Add --connect https://intendant.dev (-Connect … — or your self-hosted rendezvous) to link the daemon for discovery, and --service / -Service on an unattended box to register the daemon with the platform's native supervisor (systemd, launchd, Task Scheduler — no init system is a dependency) so it outlives the SSH session and restarts on failure. Then:

  1. Link — the daemon prints a single-use twelve-word claim code. Enter it in Connect to add the route to your account for discovery. Linking changes no IAM state and grants no access.
  2. Anchor — establish root from the machine's console/SSH session with intendant access setup or from an independently reached direct mTLS connection. Hosted and fleet-name origin code cannot mint or exercise root in the default build. No signed/notarized native release exists for this alpha; unsigned development app bundles are not anchors.
  3. Work from the trusted surface — grant scoped browser-mTLS access there, submit tasks, watch the live desktop, and approve what you chose to gate. Browser identity-key records are not a login credential in this alpha, and the hosted Connect tab remains the route directory, not a control surface.

Zero-install discovery, explicit authority

Connect needs no client software to link a daemon, remember its route, and show fleet presence from any browser. That convenience is deliberately separate from authority: a claim code creates no principal or grant, every hosted-provenance session in the default build is capped at the immutable zero-permission role:none, and a fleet-SNI endpoint serves only public shell/discovery bytes. There is no opt-in or ceiling-raising endpoint. Open the daemon from a trusted independently reached direct/mTLS surface to watch displays, send input, annotate, record, or administer access.

Credential custody, with an explicit bridge limit

Intendant implements vault storage, time-boxed leases, and client egress, while still supporting ordinary .env credentials:

  • The vault — Connect implements blind account-vault blob storage, and a separate daemon-store vault is available to trusted direct dashboards. The default Connect directory deliberately does not serve the dashboard vault client or vault-kernel.js, so account-vault storage is currently an API/backend rather than an operable hosted vault. The stores do not bridge.
  • Leases and client egress — the control-channel mechanisms are implemented for authorized sessions, but there is no shipped independently trusted client bridge from the Connect account-vault backend. Until such a client and bridge exist, those stored envelopes cannot fuel a daemon or relay its model calls; use a daemon-origin vault from loopback/direct mTLS or existing local credential configuration.
  • Honest disk boundary — API-key leases are memory-only, but .env remains supported, and full-credential OAuth leases temporarily materialize private auth homes under <state-root>/leased-auth (~/.intendant/leased-auth by default) until expiry, revocation, shutdown, or startup cleanup.

A deliberately keyless daemon outside an active full-credential OAuth lease can therefore avoid durable provider secrets on disk. That is a configuration property, not an unconditional product guarantee. How custody works and what is not bridged yet →

A network of agentic networks

Every daemon is its own authority island. Access — human or agent — is enforced by that machine's local IAM: authenticated local/mTLS principals, peer daemons, grants, and roles over a fine-grained permission catalog. Browser identity-key records exist for fleet signatures, attribution, and future identity work, but are not an active alpha login credential. Connect cannot authenticate a hosted control session, and claiming grants nothing. It is nevertheless trusted for availability, account and route metadata, optional encrypted push delivery, and the browser code it serves; malicious hosted code can lie about or exfiltrate anything the Connect page itself can see. The install scripts sit outside that boundary: they ship as release-pinned GitHub assets with their hashes in the transparency log, and Connect at most redirects to them. Fleet records are client-signed, the component is self-hostable, and an append-only transparency log makes later name-directory rewriting tamper-evident.

Organizations are a root keypair, not a row in someone's database. The org signs grant documents; daemons that trust the org key verify them locally, cap them, expire them, and honor signed revocation lists. Peer-daemon subjects are usable through peer mTLS today. Human browser-key documents currently materialize record state only: peer offers can verify a key for attribution, but no alpha ingress admits it as the controlling IAM principal, so it does not create a usable browser session. Those human and daemon lanes remain separate, separately auditable decisions. The full trust model →

Why "Intendant"

In a theater, performers play and conductors orchestrate. Above them stands the Intendant — the general director who runs the house: who gets the stage, which productions run, on whose authority, with the books open. The Intendant doesn't play a note; it makes the performance possible and accountable. The older sense of the word reaches further: royal intendants administered provinces on behalf of the crown — authority delegated, scoped, and revocable.

That is the shape of this system. Agents perform. Orchestrators conduct — the native orchestrator decomposing work across sub-agents, or Codex, Claude Code, Kimi Code, and Pi as guest conductors bringing their own ensembles. The Intendant runs the house — the machine, the schedule, the stage door, the ledger — and answers to you. And houses federate: your companies can tour other houses on signed contracts, honored at the stage door but always subordinate to the house's own rules. A network of agentic networks.

Architecture

  ┌──────────────────────── intendant (controller) ─────────────────────────┐
  │                                                                          │
  │  Frontends ──intents──►  control plane (single writer) ──► EventBus      │
  │  (Web · MCP ·            session supervisor · task dispatch              │
  │   socket)                     │                │                         │
  │      ▲                        │                │                         │
  │      │ render          ┌──────┴──────┐   ┌─────┴───────────────┐         │
  │   presence ◄───────────┤ native loop │   │ external-agent       │        │
  │   (mediator AI)        │ + sub-agents│   │(Codex/Claude/Kimi/Pi)│        │
  │                        └──────┬──────┘   └─────┬───────────────┘         │
  └───────────────────────────────┼────────────────┼────────────────────────┘
              │                    │                │
              ▼                    ▼                ▼
        Voice / Model APIs   intendant-runtime   external CLI subprocess
        (live + streaming)   (command exec,      (scoped MCP or ctl
                              never holds keys)    bootstrap)

        ◄─── WebRTC display + peer federation ───►  browsers / peer daemons

  intendant-connect: hosted/self-hosted account, route, presence, push, and
  fleet-metadata service (outside the controller/runtime execution boundary)

Three binaries; a two-sided execution boundary — intendant-runtime executes commands and never holds API keys. Its write sandbox uses Landlock on Linux, Seatbelt on macOS, and restricted tokens on Windows; it defaults on for macOS/Linux and is opt-in on Windows. The intendant controller talks to model APIs and dispatches requested actions only through that runtime. intendant-connect is the separate hosted/self-hostable account, route, presence, push, and fleet-metadata service; it is not part of the privileged controller/runtime pair and exposes no hosted control authority in the default build.

Presence layer — a separate AI that mediates between user and agent. Handles conversation, dispatches tasks, narrates events, manages approval gates. Runs as server-side text or browser-side voice (Gemini Live / OpenAI Realtime via WASM).

WebRTC display pipeline — agents see and interact with graphical displays through a custom WebRTC transport (built on rtc-rs): macOS/Linux use a VP8 baseline plus on-demand H264 (VideoToolbox on macOS; NVENC/VA-API with x264 fallback on Linux), while Windows uses one always-on software Media Foundation H264 layer. Tile-based dirty-region streaming, bidirectional clipboard, multi-monitor, and peer-to-peer display sharing run across the same pipeline.

External-agent orchestration — supervise Codex, Claude Code, Kimi Code, or Pi inside the same EventBus, approval, display, computer-use, shared-view, session, diff, history/search, usage, and cost surfaces as native agents. Intendant preserves backend differences honestly: each backend keeps its native powers and its real limits, surfaced through the same supervision plane rather than flattened to a lowest common denominator.

Persistent daemon — a control plane supervises many concurrent sessions and is the single writer of shared state; an idle web server runs headless. Federate with peer daemons for multi-host display and capability-based task routing.

Agenda and Memory — the Agenda is a daemon-wide append-only ledger for tasks, notes, non-blocking questions, reminders, and owner-approved scheduled sessions. Memory is a bounded propose/search/read surface over the vendored, independently reduced owner-plane D0-A format. Memory views always state whether the current daemon is durable or ephemeral, and claims enter model context only through an explicit search.

Phone calls — outbound SIP calls via pjsua with a voice model conducting the conversation, returning structured data.

Four execution shapes: Direct (one native loop), Orchestrate (the same loop with the orchestration prompt and native delegation tools), Sub-Agent (a supervised child task, optionally in an isolated git worktree), and External-Agent (a supervised Codex, Claude Code, Kimi Code, or Pi harness).

Dependencies

  • Rust, pinned for the whole workspace by rust-toolchain.toml (including rustfmt, clippy, and the WASM target); rustup picks the pin up automatically
  • wasm-pack, pinned by .wasm-pack-version — cargo install wasm-pack --locked --version "$(cat .wasm-pack-version)"
  • ffmpeg — display recording and H264 encoding
  • macOS: ./scripts/setup-macos.sh installs everything (cliclick, ffmpeg, Vortex Audio, wasm-pack, app bundle)
  • Linux: ./scripts/setup-linux.sh installs everything (build-essential/binutils, libvpx, libxcb, xdotool, PipeWire, ffmpeg, PulseAudio, Xvfb)
  • Windows: ./scripts/setup-windows.ps1 (x86_64-pc-windows-msvc) — see the Windows support docs
  • Pi (optional external backend): Node.js 22.19+ and npm install -g @earendil-works/pi-coding-agent

Quick Start

On a fresh box, use the installer one-liner above. From a checkout:

cargo build --release
./target/release/intendant

That starts the persistent daemon and prints the dashboard URL (port 8765 by default). The dashboard is the canonical way to drive Intendant — submit and steer tasks, watch the live desktop, approve gated actions, manage access, fuel the daemon. Fuel with credential leases from your vault, or keep keys local in .env (~/.config/intendant/.env for global use).

The same binary is the ops toolbox. Each subcommand stands alone — no project, no API key:

Subcommand What it does
intendant service install | uninstall | status Register the daemon with the platform's native supervisor (systemd / launchd / Task Scheduler) so it survives reboots
intendant access setup | list | recert | remove Browser mTLS certificates on every platform; Windows setup prints local CurrentUser import commands
intendant access serve-certs Strict fingerprint-paired remote device enrollment on macOS/Linux (Windows uses setup's manual local import)
intendant peer invite | join | approve | identities | revoke | … Pair daemons: peer-issued mTLS identities and access requests
intendant org init <handle> Mint an organization root key on this daemon
intendant ctl status | logs | task start | tools call | … Drive a running daemon from scripts and agents (MCP under the hood)
intendant setup browsers Install, verify, or repair the agent's managed Chrome for Testing browser

One-shot and headless invocations, when you want them:

./target/release/intendant "Fix the flaky CI job"        # submit a task straight from the CLI
./target/release/intendant --continue "now the docs"     # resume the most recent session
./target/release/intendant --agent pi "task"             # supervise a harness (codex | claude-code | kimi | pi)
./target/release/intendant --mcp                         # MCP server on stdio (for Claude Code, etc.)
./target/release/intendant --direct --no-web --json "t"  # headless single agent, JSONL to stdout

The full flag reference (providers, models, sandboxing, resume) lives in Getting Started.

Web Dashboard

The web dashboard is the canonical frontend — on by default (port 8765; --no-web disables it), served to any authenticated browser, phone included. It spans live session activity with approvals and steering, session history and search across every backend, the Agenda and Memory planes, live WebRTC displays with remote control and recording, the Station mission-control canvas, embedded terminals and an IAM-scoped file workbench (local and peer), usage and cost, access administration, credential vault surfaces, and settings. The web dashboard chapter tracks the current tab set.

Optional live voice via Gemini Live or OpenAI Realtime — the browser connects directly to the model's realtime API through WASM with presence tools for approving actions, submitting tasks, and querying status by voice.

Testing

cargo test -p intendant --bins
cargo test -p intendant-core -p intendant-display -p intendant-platform \
  -p owner-plane-core -p owner-plane-reducer
cargo test -p intendant --test e2e
cargo clippy --workspace -- -D warnings

These are keyless and match the required CI coverage: all three package binaries, workspace library gates (including the stamped owner-plane corpus), the scripted-provider E2E suite, and workspace-wide Clippy.

Documentation

Read the full documentation — covers the architecture, Agenda and Memory, the trust architecture and credential custody, peer federation, the self-hosted rendezvous and optional hosted-control leases, multi-agent and external-agent orchestration, the display pipeline, computer use and live audio, the web dashboard and Station, autonomy & approvals, MCP, configuration, session logging, and Windows support.

Or build locally with mdBook:

mdbook serve docs

About

Open-source operating environment for autonomous AI agents, with cross-platform machine control, oversight, and multi-host federation.

Topics

Resources

Security policy

Stars

13 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages