mcps-docker-compose/ENVIRONMENT.md

11 KiB
Raw Blame History

Environment variables

Everything an operator can set for the MCP stack, in three parts:

  1. The stack’s .env - what you write in .env next to mcp-stack.compose.yml. Split into required and optional.
  2. What the compose file sets itself - do not put these in .env.
  3. 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