Loom is configured through a YAML file (loom.yml) with environment-variable overrides layered on
top. The resolution order is:
-
Load
loom.ymlfrom the first location that exists (see below), or fall back to built-in defaults. -
Apply environment variables — any
LOOM_*variable overrides the corresponding YAML value. -
Validate the result (e.g. a keystore password must be present; one is generated if unset).
So for container deployments you can skip the file entirely and configure everything with environment variables.
Config File Locations
Loom looks for loom.yml in the following order (first match wins):
-
/etc/metaloom/loom.yml— system-wide config -
~/.config/metaloom/loom.yml— user home config -
config/loom.yml— relative to the working directory
If none exist (and none is on the classpath), Loom writes a default config/loom.yml on first start.
Full Configuration Example
Every top-level key maps to an options group. Only the keys you want to change need to be present.
database:
host: "127.0.0.1"
port: 5432
username: "postgres"
password: "finger"
databaseName: "loom"
minPoolSize: 5
acquireIncrement: 5
maxPoolSize: 20
server:
restPort: 8092 # REST API + WebSocket + UI
grpcPort: 8091 # gRPC
monitoringPort: 8989 # health / metrics
mcpPort: 4041 # Model Context Protocol server
bindAddress: "0.0.0.0"
auth:
keystorePath: "keystore.jceks"
keystorePassword: "change-me" # generated if omitted
tokenExpirationTime: 3600
oauth2:
enabled: false
# clientId / clientSecret / authUrl / tokenUrl / userInfoUrl / callbackUrl / logoutUrl / scope
storage:
uploadDirectory: "data/storage" # where uploaded asset binaries are stored
ai: # Chat & AI agent — see the "AI Agent" section below
enabled: true
providerType: "OLLAMA"
url: "http://127.0.0.1:11434"
modelId: "gpt-oss:20b"
sandbox: # Agentic coding sandbox — off by default
enabled: false
backend: "podman"
memory: # Agent memory bank — off by default
enabled: false
Environment Variables
All settings can be overridden with environment variables.
Environment variables take precedence over values in loom.yml.
Database
| Variable | Default | Description |
|---|---|---|
|
|
PostgreSQL host |
|
|
PostgreSQL port |
|
|
Database username |
|
|
Database password |
|
|
Database name |
|
|
Minimum connection pool size |
|
|
Maximum connection pool size |
Server
| Variable | Default | Description |
|---|---|---|
|
|
HTTP REST port (REST + WebSocket + UI) |
|
|
gRPC port |
|
|
Model Context Protocol server port |
|
|
Bind address for all listeners |
|
|
Monitoring/health port |
Storage
| Variable | Default | Description |
|---|---|---|
|
|
Directory where uploaded asset binaries are stored |
Near-duplicate video lookup
Powers "which other videos look like this one?", and with it the near-duplicate review workflow of the deduplication nodes. It is switched off by default because it is only useful once videos have been fingerprinted.
The lookup keeps its own index on disk. That index is built entirely from fingerprints already stored with your assets, so it can be discarded and rebuilt at any time without data loss.
| Variable | Default | Description |
|---|---|---|
|
|
Enable near-duplicate lookup. While off, requests to the similar-videos routes are refused with a clear reason rather than answering "nothing found" |
|
|
Directory holding the lookup index. Give each server its own directory — two servers cannot share one |
|
|
Which fingerprint version takes part in the lookup |
|
|
How close a match must be to count as a near-duplicate. Higher is stricter |
|
|
How many similar videos a query returns by default |
|
Note
|
If the index directory cannot be written, the server still starts normally — only the near-duplicate routes report themselves as unavailable. |
Authentication
| Variable | Default | Description |
|---|---|---|
|
(random) |
Initial admin password (first boot only) |
|
|
JWT token lifetime in seconds |
|
|
Require auth on the MCP endpoints |
|
|
Reject unauthenticated MCP calls (no lenient mode) |
|
|
CORS origins allowed on the MCP SSE endpoint |
The keystore password is read from the auth.keystorePassword config key (a random one is generated
if unset). See Authentication.
OAuth2
Optional OAuth2 login (BFF pattern). Set LOOM_OAUTH2_ENABLED=true and provide your provider’s
endpoints:
| Variable | Description |
|---|---|
|
Enable OAuth2 authentication (default |
|
Client credentials |
|
Provider endpoints |
|
Callback and logout URLs |
|
Scopes to request (default |
AI Agent
Settings for the built-in Chat & AI Agent. The agent is enabled by default
(LOOM_AI_ENABLED=true) but needs a reachable LLM provider to answer.
| Variable | Default | Description |
|---|---|---|
|
|
Master switch for the chat agent |
|
|
LLM provider ( |
|
|
Provider base URL |
|
|
Model id |
|
|
Context window (tokens) |
|
|
Max tool-calling turns per message |
|
|
Per-tool timeout |
|
|
Opt-in true token/reasoning streaming |
|
(model default) |
Enable model "thinking" chunks |
|
(on) |
Auto-title a chat after the first exchange |
Coding Sandbox
Settings for the per-chat coding sandbox (LOOM_AGENT_SANDBOX_*). Off unless
LOOM_AGENT_SANDBOX_ENABLED=true. See Chat & AI Agent — Coding Sandbox for the full
table and deployment (backends, Kubernetes RBAC, the runner image). Key switches:
LOOM_AGENT_SANDBOX_BACKEND (podman \| kubernetes), LOOM_AGENT_SANDBOX_IMAGE,
LOOM_AGENT_SANDBOX_NAMESPACE, LOOM_AGENT_SANDBOX_IDLE_TTL_S, LOOM_AGENT_SANDBOX_MAX_SESSION_S,
LOOM_AGENT_SANDBOX_MAX_CONCURRENT.
Agent Memory
Settings for the agent memory bank (LOOM_AGENT_MEMORY_*):
| Variable | Default | Description |
|---|---|---|
|
|
Enable the memory bank |
|
(quota) |
Max notes per scope |
|
(quota) |
Max size of a single note |
|
(quota) |
Max total size per scope |
|
(quota) |
Max memory writes per agent run |
|
|
Allow shared (cross-user) scopes |
|
|
Mount memory read-only into the coding sandbox |
|
|
Sandbox mount path for memory |
CLI
The Loom server main entry point is LoomServerRunner. Configuration is driven via the YAML
file and environment variables shown above.
The metaloom command-line client is a separate program that talks to a running Loom server
over the REST API and has its own configuration file.