11 KiB
Environment variables
Everything an operator can set for the MCP stack, in three parts:
- The stack’s
.env- what you write in.envnext tomcp-stack.compose.yml. Split into required and optional. - What the compose file
sets itself - do not put these in
.env. - Per-server
variables - only for starting one image by hand with
docker run, outside Compose.
mcp-stack.env.example is the template:
cp mcp-stack.env.example .env. .env is ignored
by git and holds secrets, so it stays on the machine that runs the
stack.
Compose substitutes an unset variable with an empty string and only warns. A “required” variable below is one whose absence makes the service refuse to start or the stack unusable - not one Compose itself rejects.
1. The stack’s .env
Required
| Variable | What it is | Notes |
|---|---|---|
CODING_AGENT_MCP_API_KEYS |
Bearer tokens that may call the coding-agent MCP. Comma-separated,
optionally subject=token. |
Each token at least 32 characters. The server refuses to start with
none. This is the key in the node’s catalog entry. |
DEV_SERVER_MCP_API_KEYS |
Same, for the dev-server MCP. | Use a different token from the other servers. |
BROWSER_MCP_API_KEYS |
Same, for the browser MCP. | |
MINIO_MCP_API_KEYS |
Same, for the MinIO MCP. | |
DEV_SERVER_WORKER_TOKEN |
Shared secret between dev-server-mcp and
dev-server-worker. |
At least 32 characters; both refuse to start otherwise. Never leaves the stack, so it is not a catalog value. |
MCP_WORKSPACE_HOST_PATH |
Absolute path of the host directory mounted as
/workspace. |
Bind-mount source, so empty fails. A dedicated project directory -
never a home directory or /. |
Generate a token with openssl rand -hex 32.
Required in practice
| Variable | Default | Why |
|---|---|---|
MCP_UID, MCP_GID |
10001 / 10001 |
Keep them. The images run as 10001:10001, and the dev-server’s two
volumes take their owner from the image, so another value leaves the
worker unable to write to them. Give
MCP_WORKSPACE_HOST_PATH to 10001:10001
instead. This file is read literally, no shell runs over it. |
Optional
Images
| Variable | Default | Meaning |
|---|---|---|
MCP_IMAGE_TAG |
the hash named in mcp-stack.compose.yml |
Which build of the four luciolelii/* images to run: a
commit hash of the mcps repository, or latest.
Bumping it is a deploy. |
MinIO MCP
| Variable | Default | Meaning |
|---|---|---|
MINIO_MCP_INTERNAL_BUCKET_PREFIX |
exec- |
Every internal-mode bucket is
<prefix><execution id>. Cannot be empty; at
most 27 lowercase letters, digits or -. It is the boundary
that keeps the API key inside buckets this server made. |
MINIO_MCP_ALLOWED_ENDPOINTS |
empty (any) | Comma-separated S3 origins,
e.g. https://s3.example.org. Set it on an exposed
server. It applies to both modes, so the internal MinIO’s
endpoint must be on it. |
MINIO_MCP_DEFAULT_REGION |
us-east-1 |
Region when a session names none. |
MINIO_MCP_MAX_OBJECT_BYTES |
1048576 (1 MiB) |
Limit for one read and one write. Ceiling 32 MiB. |
MINIO_MCP_MAX_CONNECTIONS_PER_SESSION |
8 |
External mode only. Ceiling 64. |
The internal MinIO’s endpoint and keys are not
variables here: they are headers of the minio-mcp-internal
entry in the workflow manager’s catalog (x-minio-endpoint,
x-minio-access-key, x-minio-secret-key,
optionally x-minio-region).
Dev server
| Variable | Default | Meaning |
|---|---|---|
DEV_SERVER_SERVICES_CONFIG |
./dev-server-mcp/services.example.json |
The services a caller may start. Copy
services.example.json and edit the copy. Mounted
read-only. |
DEV_SERVER_ALLOWED_COMMANDS |
node,npm,python3,./mvnw |
What a service may run. npx is left out on purpose: it
runs an arbitrary package by name. |
DEV_SERVER_PORT_RANGE |
5200-5219 |
Ports given to per-execution instances. Keep aligned with
BROWSER_MCP_ALLOWED_ORIGINS. |
DEV_SERVER_MAX_INSTANCES |
4 |
Concurrent instances. Size by memory: two frontend builds saturate the worker’s 2 GB. |
DEV_SERVER_MAX_WORKSPACE_BYTES |
536870912 (512 MiB) |
Largest workspace copied for an instance. |
DEV_SERVER_IDLE_TIMEOUT_SECONDS |
7200 |
Idle time after which an instance is stopped (its copy is kept). |
DEV_SERVER_MAX_LIFETIME_SECONDS |
86400 |
Absolute lifetime; then everything, copy included, is discarded. |
DEV_SERVER_PREVIEW_BASE_URL |
empty | Public address a person opens a preview at. Empty means no preview proxy and no preview links. |
DEV_SERVER_PREVIEW_PORT |
4500 |
Port of the preview proxy inside the worker. |
DEV_SERVER_EGRESS_PROXY |
http://egress-proxy:3128 |
The only route out the worker has, for installs. |
DEV_SERVER_NO_PROXY |
localhost,127.0.0.1,dev-server-worker |
Hosts that bypass that proxy. |
Browser
| Variable | Default | Meaning |
|---|---|---|
BROWSER_MCP_ALLOWED_ORIGINS |
http://dev-server-worker:5173,http://dev-server-worker:5200-5219 |
Origins the browser may open, exact match. Keep the range aligned
with DEV_SERVER_PORT_RANGE, or a preview looks like a
broken app. |
BROWSER_MCP_MAX_SESSIONS |
8 |
Concurrent browser sessions. |
Published ports (all on loopback,
127.0.0.1)
| Variable | Default | |
|---|---|---|
MCP_GATEWAY_PORT |
3100 |
One port serving every server by path (/coding-agent/,
/dev-server/, /browser/,
/minio/). What the catalog expects. |
CODING_AGENT_MCP_PORT |
3101 |
Per-server ports, kept for clients configured before the gateway. |
DEV_SERVER_MCP_PORT |
3102 |
|
BROWSER_MCP_PORT |
3103 |
|
MINIO_MCP_PORT |
3104 |
Dedicated VM (with the overlay
mcp-stack.vm.compose.yml)
| Variable | Default | Meaning |
|---|---|---|
MCP_GATEWAY_CADDYFILE |
./mcp-stack.Caddyfile |
Set to ./mcp-stack.vm.Caddyfile on the VM: it serves
HTTPS. |
MCP_SITE_ADDRESS |
:3100 |
The public host name Caddy gets a certificate for,
e.g. mcp-stack.example.org. Required with the VM
Caddyfile. |
MCP_TLS_CONTACT |
empty | Contact e-mail for the certificate authority. Set it on the VM. |
MCP_BIND_ADDRESS |
0.0.0.0 |
Address ports 80 and 443 bind to. |
2. What the compose file sets itself
Fixed in mcp-stack.compose.yml. They are not read from
.env, and overriding them there has no effect.
| Variable | Set on | Value |
|---|---|---|
CODING_AGENT_MCP_EXECUTION_BACKEND |
coding-agent-mcp | disabled, so no command-running tool is offered. |
DEV_SERVER_WORKER_URL |
dev-server-mcp | http://dev-server-worker:4000 |
DEV_SERVER_CONFIG |
dev-server-worker | /config/services.json |
DEV_SERVER_WORKSPACE_ROOT |
dev-server-worker | /workspace |
DEV_SERVER_INSTANCES_ROOT,
DEV_SERVER_INSTANCE_HOME,
DEV_SERVER_NPM_CACHE |
dev-server-worker | volumes /instances,
/instances/.shared-home, /npm-cache |
Container paths, user ids of the browser (1000:1000),
memory and CPU limits are fixed in the file too.
3. Per-server variables (running an image by hand)
Only for docker run of one image, outside Compose. The
stack does not forward these, so they cannot be set through
.env. Defaults shown are the ones in the code.
coding-agent-mcp
| Variable | Default | |
|---|---|---|
CODING_AGENT_MCP_API_KEYS |
none, required over HTTP | Also read from MCP_API_KEYS when unset. |
CODING_AGENT_MCP_ROOTS |
the working directory | Workspace root(s), when no --root flag is given. |
CODING_AGENT_MCP_EXECUTION_BACKEND |
local on stdio, disabled on HTTP |
Whether command execution is offered. |
CODING_AGENT_MCP_CORS_ORIGINS |
empty | Comma-separated browser origins allowed. |
CODING_AGENT_MCP_AUDIT_LOG |
none | Path of an audit log file. |
MCP_DEBUG_REQUESTS |
off | 1/true/yes/on
logs requests. Leave it off in production. |
dev-server-mcp
| Variable | Default | |
|---|---|---|
DEV_SERVER_MCP_API_KEYS |
none, required | |
DEV_SERVER_WORKER_TOKEN |
none, required | At least 32 characters. |
DEV_SERVER_WORKER_URL |
http://dev-server-worker:4000 |
|
DEV_SERVER_MCP_HOST / _PORT |
0.0.0.0 / 3000 |
|
DEV_SERVER_MCP_MAX_SESSIONS |
64 |
|
DEV_SERVER_MCP_SESSION_TTL_SECONDS |
1800 |
|
DEV_SERVER_MCP_CORS_ORIGINS |
empty |
dev-server-worker
| Variable | Default | |
|---|---|---|
DEV_SERVER_WORKER_TOKEN |
none, required | At least 32 characters. |
DEV_SERVER_CONFIG |
/config/services.json |
The services file. |
DEV_SERVER_WORKSPACE_ROOT |
/workspace |
|
DEV_SERVER_ALLOWED_COMMANDS |
none, required | The worker refuses to start with it empty, and every service’s
command must be on it. |
DEV_SERVER_INSTANCES_ROOT |
none | Where per-execution copies live. |
DEV_SERVER_INSTANCE_HOME |
/tmp/dev-server |
|
DEV_SERVER_NPM_CACHE |
none | |
DEV_SERVER_NPM_REGISTRY |
none | Registry override. |
DEV_SERVER_PORT_RANGE |
5200-5219 |
Ports for instances: a rising range above 1023. |
DEV_SERVER_MAX_INSTANCES |
4 |
|
DEV_SERVER_MAX_WORKSPACE_BYTES /
_ENTRIES |
512 MiB / 20000 |
|
DEV_SERVER_IDLE_TIMEOUT_SECONDS /
_MAX_LIFETIME_SECONDS |
7200 / 86400 |
|
DEV_SERVER_EGRESS_PROXY / _NO_PROXY |
none | Proxy for installs. |
DEV_SERVER_PREVIEW_BASE_URL |
none | |
DEV_SERVER_PREVIEW_HOST / _PORT |
0.0.0.0 / 4500 |
|
DEV_SERVER_CHILD_PATH |
/opt/java/openjdk/bin:/usr/local/bin:/usr/bin:/bin |
PATH of started services. |
JAVA_HOME |
none | Passed to started services. |
DEV_SERVER_WORKER_HOST / _PORT |
0.0.0.0 / 4000 |
|
DEV_SERVER_WORKER_REQUEST_TIMEOUT_MS |
620000 |
browser-mcp
| Variable | Default | |
|---|---|---|
BROWSER_MCP_API_KEYS |
none, required | |
BROWSER_MCP_ALLOWED_ORIGINS |
none, required | The server refuses to start with it empty. Exact origins, plus
ranges such as http://host:5200-5219. |
BROWSER_MCP_MAX_SESSIONS |
16 |
|
BROWSER_MCP_DEFAULT_TIMEOUT_MS |
15000 |
|
BROWSER_MCP_HOST / _PORT |
0.0.0.0 / 3000 |
|
BROWSER_MCP_SESSION_TTL_SECONDS |
1800 |
|
BROWSER_MCP_CORS_ORIGINS |
empty |
minio-mcp
| Variable | Default | |
|---|---|---|
MINIO_MCP_API_KEYS |
none, required | |
MINIO_MCP_INTERNAL_BUCKET_PREFIX |
exec- |
See above. |
MINIO_MCP_ALLOWED_ENDPOINTS |
empty (any) | |
MINIO_MCP_DEFAULT_REGION |
us-east-1 |
|
MINIO_MCP_MAX_OBJECT_BYTES |
1048576 |
Ceiling 32 MiB. |
MINIO_MCP_MAX_CONNECTIONS_PER_SESSION |
8 |
Ceiling 64. |
MINIO_MCP_MAX_SESSIONS |
32 |
|
MINIO_MCP_SESSION_TTL_SECONDS |
1800 |
|
MINIO_MCP_REQUEST_MAX_BYTES |
derived from MAX_OBJECT_BYTES |
HTTP body limit; base64 adds a third. |
MINIO_MCP_HOST / _PORT |
0.0.0.0 / 3000 |
|
MINIO_MCP_CORS_ORIGINS |
empty |