Summary
Introduce a new crate, objectiveai-laboratory — a local, single-process orchestrator that manages laboratories: OCI containers (run via bundled podman) that each run objectiveai-mcp-filesystem and expose a constrained, bind-mounted view of the host filesystem to connecting agents over MCP.
This crate is local laboratories only. Server-side laboratories will be handled by objectiveai-api and are out of scope here.
The runtime is named for its role, not its implementation (cf. objectiveai-db embedding Postgres without being called objectiveai-postgres). It bundles podman today, but the public API must not leak podman, so the backend can change later without a rename or API break.
Decided design
Process / IPC model
- One
objectiveai-laboratory process per host system, enforced by a file lock (singleton; same posture as the api spawn lock).
- Clients communicate with the orchestrator over a Unix domain socket.
- A single shared API across all three OSes (Linux / macOS / Windows), with
#[cfg(target_os = …)] backends behind it.
Container runtime — bundled podman
- The crate bundles podman internally — ship the binaries and exec them, exactly like
objectiveai-db/pg-bin. No static linking.
- Network usage at first init is acceptable (podman fetches the guest image on mac/Windows).
- Per platform:
- Linux — native podman (crun / conmon / netavark / pasta / fuse-overlayfs); containers run in the host kernel. Fully self-contained.
- Windows — WSL2 is a hard requirement; error clearly if it is absent/unsupported. Linux containers run inside WSL2; podman manages the WSL guest (image fetched at init).
- macOS — ship podman +
vfkit + gvproxy; the hypervisor is macOS's Virtualization.framework (applehv) — no VM or hypervisor is shipped. Podman manages the VM; the Fedora CoreOS image is fetched at init.
- Accept the WSL2/VM 9P bind-mount performance tax on mac/Windows.
Laboratory containers
- A laboratory is an OCI / Dockerfile-defined container running
objectiveai-mcp-filesystem.
- Supports binding host filesystem directories — both read-only and read/write mounts.
- All filesystem operations are performed by the agents that connect to the laboratory over MCP. The orchestrator wires up the container + mounts + MCP endpoint; the agent drives the FS operations (read / write / edit / glob / grep / bash) through
objectiveai-mcp-filesystem.
Laboratories are more than a regular MCP server
Laboratories get special features and first-class integrations that ordinary MCP servers / plugins / tools do not have, for example:
- Cross-laboratory transfer — an agent connected to multiple laboratories can transfer artifacts/files between them.
- (Further lab-only capabilities to be enumerated as the feature develops.)
Out of scope
- Server-side laboratories — handled by
objectiveai-api.
- Statically linking podman (we bundle/ship binaries, not link).
Open questions / follow-ups
objectiveai-mcp-filesystem injection into lab images: bind-mount a musl-static mcp-filesystem into the container at runtime (keeps user Dockerfiles clean — recommended) vs. require lab images to include it themselves.
- Lab MCP transport / reachability: how the orchestrator advertises each lab's MCP endpoint to agents (published port + host localhost via podman networking vs. a socket bridge).
- Rootless vs. rootful containers, and bind-mount UID remapping (
--userns=keep-id) so host file ownership stays sane.
- Lifecycle: lab registry, idempotent start, crash recovery for orphaned containers, and reaping via
kill-all.
- Offline / pinned guest images (bundle the image instead of fetching) — deferred; network-at-init is accepted for now.
- macOS code-signing / notarization + entitlements for the bundled podman / vfkit.
🤖 Generated with Claude Code
Summary
Introduce a new crate,
objectiveai-laboratory— a local, single-process orchestrator that manages laboratories: OCI containers (run via bundled podman) that each runobjectiveai-mcp-filesystemand expose a constrained, bind-mounted view of the host filesystem to connecting agents over MCP.This crate is local laboratories only. Server-side laboratories will be handled by
objectiveai-apiand are out of scope here.The runtime is named for its role, not its implementation (cf.
objectiveai-dbembedding Postgres without being calledobjectiveai-postgres). It bundles podman today, but the public API must not leak podman, so the backend can change later without a rename or API break.Decided design
Process / IPC model
objectiveai-laboratoryprocess per host system, enforced by a file lock (singleton; same posture as theapi spawnlock).#[cfg(target_os = …)]backends behind it.Container runtime — bundled podman
objectiveai-db/pg-bin. No static linking.vfkit+gvproxy; the hypervisor is macOS's Virtualization.framework (applehv) — no VM or hypervisor is shipped. Podman manages the VM; the Fedora CoreOS image is fetched at init.Laboratory containers
objectiveai-mcp-filesystem.objectiveai-mcp-filesystem.Laboratories are more than a regular MCP server
Laboratories get special features and first-class integrations that ordinary MCP servers / plugins / tools do not have, for example:
Out of scope
objectiveai-api.Open questions / follow-ups
objectiveai-mcp-filesysteminjection into lab images: bind-mount a musl-staticmcp-filesysteminto the container at runtime (keeps user Dockerfiles clean — recommended) vs. require lab images to include it themselves.--userns=keep-id) so host file ownership stays sane.kill-all.🤖 Generated with Claude Code