Reference

Configuration

The defaults are chosen so npm run dev works with nothing set. They are also chosen so that nothing survives a restart. That is the right trade on a laptop and the wrong one everywhere else, and the boot banner tells you which one you are in.

The four that decide whether this is real

VarUnset means
MYCEL_DATABASE_URLEverything in memory: tasks, events, tenants, vault, audit. No queue — queue=inline, tasks run in the API process
MYCEL_SECRET_KEYAn ephemeral vault key. Every stored credential is unreadable after a restart
MYCEL_SANDBOXlocal unless DAYTONA_API_KEY is set. Local is a temp directory on your host, not isolation
MYCEL_API_KEYA new key printed on every boot, so your product breaks on every restart

Nothing here fails loudly if you skip it. The boot line is the check: [sandbox=… store=… model=… queue=…].

Identity and access

VarDefaultPurpose
MYCEL_API_KEYgenerated, msk_…Default project key for your product
MYCEL_OWNER_EMAILfounder@mycel.localBootstrap owner account
MYCEL_OWNER_PASSWORDgenerated, own_…Portal login
MYCEL_GATE_TOKENrandom per processShared secret for the sandbox plugin gate. Fix it if sandboxes outlive the process
MYCEL_RATE_MAX120Task creations per minute per credential

Storage

VarDefaultPurpose
MYCEL_DATABASE_URLPostgres for tasks, events, tenants, vault, audit, and the graphile-worker queue. Migrations run on boot
MYCEL_SECRET_KEYephemeralAES-256-GCM master key. Hex or base64, must decode to exactly 32 bytes
MYCEL_ARTIFACTSinlineinline | fs | s3
MYCEL_ARTIFACTS_DIR.mycel/artifactsFor fs
MYCEL_ARTIFACTS_BUCKETFor s3. Needs @aws-sdk/client-s3 installed
MYCEL_LOG_DIR.mycel/logsPer-task JSONL event logs and llm.jsonl. Always on
head -c 32 /dev/urandom | base64    # a valid MYCEL_SECRET_KEY

Execution

VarDefaultPurpose
MYCEL_RUNTIMEopencodeExactly mock selects the mock runtime. Anything else is OpenCode
MYCEL_SANDBOXdaytona if DAYTONA_API_KEY, else locallocal | docker | daytona. Not validated — a typo silently gives you local
MYCEL_SANDBOX_IMAGEmycel/sandbox:latestImage for docker and daytona
OPENCODE_PORT4444OpenCode server inside the sandbox
MYCEL_WEDGES_DIR<cwd>/wedgesWhere wedge folders are read from
MYCEL_BLUEPRINTS_DIR<cwd>/blueprintsWhere blueprint JSON is read from
MYCEL_WORKFLOW_TIMEOUT_MS5000Per-workflow timeout
MYCEL_WORKERon0 gives an API-only replica
MYCEL_WORKER_CONCURRENCY10Concurrent runs per worker. Each run holds a sandbox, so memory is the limit
PORT4000Kernel listen port

Models, cost and the proxy

VarDefaultPurpose
MYCEL_MODELanthropic/claude-opus-4-8Fallback model. A wedge's model wins, and input.model on a task wins over that
MYCEL_PROXY_MODEoff1 routes model calls through the harness so the provider key never enters the sandbox
MYCEL_LLM_UPSTREAMderived from the providerOverride the OpenAI-compatible upstream base URL
MYCEL_PUBLIC_URLhttp://127.0.0.1:4000How the sandbox reaches the harness. Docker needs host.docker.internal; Daytona needs a reachable URL
MYCEL_MAX_COST_USD50Server ceiling per task; client constraints are clamped to it
MYCEL_MAX_RUNTIME_S1800Server runtime ceiling
MYCEL_MAX_TOKENS8192Cap on max_tokens the sandbox may request through the proxy
MYCEL_READ_MAX_PER_TASK200Ungated reads per task

Provider keys themselves — ANTHROPIC_API_KEYand friends — are read from the environment by name derived from the model's provider prefix.

Integrations and tracing

VarDefaultPurpose
COMPOSIO_API_KEYWithout it every Composio route returns 501
COMPOSIO_BASE_URLhttps://backend.composio.devComposio REST base
DAYTONA_API_KEYRemote sandboxes. Its presence alone changes the default MYCEL_SANDBOX
LANGFUSE_SECRET_KEY / LANGFUSE_PUBLIC_KEYBoth required, or the Langfuse sink stays off
LANGFUSE_HOSThttps://cloud.langfuse.comSelf-hosted Langfuse

Tracing needs no configuration. The kernel writes a durable event row for everything a run does, and GET /v1/tasks/:id/trace folds that log into a span tree — steps, tool calls with redacted arguments, generations, approvals, timings and cost. It is always there, it is scoped exactly like the task, and no third party sees it.

The LANGFUSE_* keys above are separate and entirely optional: your account, for when you want an LLM-debugging UI over your own runs. Install it yourself (npm install langfuse) — if the keys are set but the package is not installed the kernel warns rather than pretending. Nothing provisions a Langfuse project per business: that needs Langfuse's Organization Management API, which is self-hosted Enterprise only and does not exist on Langfuse Cloud, so the code that tried was removed.

Your product

  • MYCEL_KERNEL_URL — where the kernel is, e.g. http://localhost:4000
  • MYCEL_API_KEY — server-side only. Never a build argument: Next inlines build-time env into the client bundle

Failure modes

  • MYCEL_SECRET_KEY must be 32 bytes (got N) — the kernel refuses to start rather than sealing secrets with the wrong key.
  • Secrets unreadable after a deploy. The key changed. The log names the key fingerprint that sealed them.
  • Sandbox cannot reach the harness. MYCEL_PUBLIC_URL still points at 127.0.0.1 from inside a container.
  • Runs are serialised and slow. queue=inline in the banner — no MYCEL_DATABASE_URL, so there is no queue.
  • Mock runtime not taking effect. Only the exact string mock matches.

What to read next

Deploying — which of these become non-negotiable once the kernel is not on your laptop.