crouter
SDK

Docker environment

Run a crouter daemon in a container with the separate Docker environment package.

Phase 1.

@crouter/env-docker runs a crouter daemon in a container and tells you how to reach it. It is a separate package because container lifecycle is real work the SDK does not otherwise do — and it has no dependencies, including on the SDK itself.

npm i @crouter/env-docker

Starting a container and connecting to it

import { start } from '@crouter/env-docker';
import Crouter from '@crouter/sdk';

const env = await start({ volume: 'my-agent-home' });
const client = new Crouter(env.connection());

await client.nodes.create({ prompt: 'Do the thing.', root: true });

await env.stop();

connection() returns { baseURL, headers } — exactly the shape the Crouter constructor takes, so the result passes straight through with no adapter.

Methods

MethodWhat it does
start(opts?)Starts a container running crtrd and returns an environment handle.
attach(name)Returns a handle for the already-running container named name.
stop()On a start() handle, stops and removes the container. On an attach() handle, stops it without removing it.
connection()Connection ({ baseURL: string; headers?: Record<string, string> }) — returned synchronously and passed to new Crouter().
start() optionTypeDefaultEffect
imagestringghcr.io/crouton-labs/crtrd:latestImage to run.
envRecord<string, string>unsetExtra container environment variables; they are not logged.
namestringgenerated nameContainer name for later attach(name).
volumestringunsetNamed volume mounted at /home/agent/.crouter.
portnumberDocker-assigned portHost port bound on 127.0.0.1.

connection() replaced daemon()

daemon() is gone, along with the package's Environment type. The new name says what the method returns, and its field is spelled baseURL to match the constructor option rather than baseUrl.

// before
const env = await start({ volume: 'my-agent-home' });
const { baseUrl, headers } = await env.daemon();
const client = new CrtrClient({ baseUrl, headers });

// after
const env = await start({ volume: 'my-agent-home' });
const client = new Crouter(env.connection());

connection() is typed structurally — { baseURL: string; headers?: Record<string, string> } — which is how the package stays dependency-free while producing something the SDK accepts directly.

The volume is the agent's home

The volume you pass is the container's canvas home: nodes, transcripts, documents, and profiles all live there. Reuse the same volume across start calls and the agent keeps everything it learned; use a fresh one and it starts from nothing. start() mounts an existing named volume unchanged; it does not inspect or reject it based on the crouter version that last wrote it.

On this page