SynapseOrch 2.0 is a release candidate; the stable release is 1.9.3. How to try 2.0

Environment Variables

Infrastructure configuration — the database, storage, ports and secrets. Everything a request can change lives in Settings instead.

Environment variables configure infrastructure: where the database is, where tenant content is written, which ports to bind, and the secrets the backend needs. They are read at startup and need a restart to change.

Everything else — provider keys, model choice, agent behaviour, sandbox mode — lives in the store and is edited in Settings. The split is deliberate: infrastructure is set by whoever deploys the instance, and settings are changed by whoever uses it.

Copy .env.example to .env in the repo root and edit what you need. Every value is optional; SynapseOrch runs on defaults with nothing configured.

cp .env.example .env

The .env file at the project root is loaded at startup, and real environment variables win — a value already set in the environment is not overridden by the file. That is what makes a container's environment authoritative over a .env that happened to be copied into the image.

Provider API keys are not environment variables

OPENAI_API_KEY, ANTHROPIC_API_KEY, AWS_SECRET_ACCESS_KEY and the old SYNAPSE_SETTING_* overlay are no longer read. Provider credentials are held in the store, read per call for the tenant in context, and never written to the process environment.

This is a security boundary, not housekeeping. Anything in the environment is readable through /proc/<pid>/environ and is inherited by every subprocess — and this engine spawns stdio MCP servers and a code sandbox, which would otherwise have been handed every key the process held. Enter provider keys under Settings → Models.


Storage

Three variables decide where state lives. A plain install needs none of them.

SYNAPSE_HOME — the folder an installed SynapseOrch keeps everything in: its data, .env, logs and backups. Default ~/.synapse (%USERPROFILE%\.synapse on Windows). The defaults below sit under its var/. See the CLI.

SYNAPSE_DB_URL — the database holding settings, agents, workflows, tools, schedules, runs and usage. Defaults to SQLite at ~/.synapse/var/synapse.db in an installed SynapseOrch ($SYNAPSE_HOME/var), backend/var/synapse.db in a source checkout and /data/synapse.db in the single-container image, so a fresh install needs nothing running. Point it at Postgres for any deployment serving more than one process:

SYNAPSE_DB_URL=postgresql://user:pass@host:5432/synapse

A postgresql:// or postgres:// URL is converted to the postgresql+asyncpg:// driver form at startup, so either spelling works.

SYNAPSE_BLOB_DIR — where tenant content is written: the vault, run logs, cached responses. Defaults to ~/.synapse/var/blobs in an installed SynapseOrch ($SYNAPSE_HOME/var), backend/var/blobs in a source checkout, /data/blobs in the single-container image and /blobs in Docker Compose. Processes that serve the same data — a main instance and scale mode workers — must share this directory, unless they are all configured with the same bucket (below), which replaces it.

SYNAPSE_STATE_DIR — rebuildable per-replica state, currently the ChromaDB index. Defaults to ~/.synapse/var/state in an installed SynapseOrch ($SYNAPSE_HOME/var), backend/var/state in a source checkout. Losing it costs a re-index, not data, so each replica in a multi-replica deployment should have its own rather than sharing one.

Object storage

With a bucket configured, an S3 or S3-compatible store (MinIO, R2) is the blob store: the vault, run logs, notifications and cached responses are written there instead of SYNAPSE_BLOB_DIR, in the API server, in every worker and in the tool processes they start. Keys are <S3_PREFIX>/<tenant>/…. Nothing already on disk is copied across. The same values can be saved in Settings → Scale instead; the variables win. See Scale Configuration → S3 storage.

VariableNotes
S3_BUCKETRequired — set it, and the bucket is the blob store
S3_REGION
S3_ENDPOINT_URLSet for MinIO, R2 and other S3-compatible services
S3_ACCESS_KEY_ID
S3_SECRET_ACCESS_KEY
S3_PREFIXOptional key prefix, if the bucket is shared

Upgrading from SYNAPSE_DATA_DIR

Before 2.0 a single DATA_DIR held everything — JSON documents, tenant content and real directories in one tree. It is no longer a runtime path. On first boot SynapseOrch looks for an existing data directory and imports it into the store; see Store and upgrade.

SYNAPSE_DATA_DIR is still read for exactly that: if your deployment sets it, the importer uses it to find the tree to import. It configures nothing afterwards.


Ports and URLs

SYNAPSE_BACKEND_PORT — the FastAPI backend. Default 8765.

SYNAPSE_FRONTEND_PORT — the Next.js frontend. Default 3000.

BACKEND_URL — the backend as the Next.js server sees it, read when that server starts. Unset, it is http://127.0.0.1: and the port in SYNAPSE_BACKEND_PORT, or 8765 if that is unset too. Changing it needs a restart of the frontend, not a rebuild. Set it for Docker or split deployments, for example http://synapse-backend:8765.

CORS_ORIGINS — comma-separated origins the backend accepts. Default http://localhost:3000,http://localhost:5173. Add your own origin when hosting on a custom domain.

OLLAMA_BASE_URL — the Ollama server for local models. Default http://127.0.0.1:11434. See Local models.


Secrets

SYNAPSE_JWT_SECRET — signs login session tokens. Auto-generated and persisted to .env on the first synapse start. Set it explicitly for stateless container deployments where .env does not survive, or every restart invalidates every session.

SYNAPSE_INTERNAL_TOKEN — gates /api/* and root /chat so that only the frontend can reach them. The frontend sends it as an X-Synapse-Internal header on every proxied request; direct callers without it get a 403. It proves a request came through the frontend, not who sent it: while login is on or an access link is set, the backend also wants a signed-in session, and answers 401 Login required without one. The externally authenticated APIs (/api/v1, /api/v2) are exempt and use API keys instead.

When it is not set the backend falls back to loopback-only: requests whose direct peer is 127.0.0.1 or ::1 are allowed and every remote caller is refused. synapse start and the Docker images generate a token automatically, so this fallback applies only to a backend started some other way.

SYNAPSE_ACCESS_TOKEN — the token in this install's access link, which opens Synapse while login is off. synapse start generates it into .env and the Docker images onto the data volume; set it yourself to pin one. With it unset and login off, anyone who can reach the app's port can use Synapse.

Set a token on anything network-reachable

A backend with no token, login disabled and stdio MCP registration allowed is the exact posture of GHSA-3j67-x3j8-r32x, where registering an MCP server executes local commands. The backend warns loudly at startup when it starts in that state. Set SYNAPSE_INTERNAL_TOKEN, enable login, or set allow_stdio_mcp=false — see Settings.

Note that the loopback check compares the peer address, and a browser on the Windows host reaching a WSL backend arrives as ::ffff:127.0.0.1 rather than 127.0.0.1. Set the token on both processes for that setup or every call 403s.


Egress

EGRESS_ALLOW_HOSTS — comma-separated host names that custom HTTP tools, the web scraper and the PDF and Excel parsers and a knowledge base's web crawls may call even though they resolve to loopback or private address space. Empty by default, which refuses them all. Use it for a service on your own network — a self-hosted n8n, an intranet API — and name the host as the tool's URL spells it:

EGRESS_ALLOW_HOSTS=localhost,n8n,api.internal.company.com

A refused call says which host it was and names this variable. Changing it takes a restart.


Timeouts

All in seconds unless the name says otherwise. Each falls back to the value it had before it was made configurable, so leaving them unset changes nothing. Raise them for slow networks or slow local models; lower them to fail fast.

VariableDefaultApplies to
SYNAPSE_LLM_TIMEOUT180One attempt at a cloud LLM call
SYNAPSE_HTTP_TOOL_TIMEOUT30A custom HTTP or webhook tool call
SYNAPSE_MCP_SESSION_READ_TIMEOUT60Any MCP request
SYNAPSE_MCP_TOOL_CALL_TIMEOUT60A single MCP tool invocation
SYNAPSE_MCP_LIST_TOOLS_TIMEOUT15Discovering a server's tools
SYNAPSE_ORCH_STEP_TIMEOUT300A step that sets no timeout of its own
SYNAPSE_ORCH_GLOBAL_TIMEOUT_MINUTES30 minutesA workflow that sets no timeout of its own
SYNAPSE_ORCH_HUMAN_TIMEOUT3600The default of a human gate's Timeout (seconds): how long a reply in its messaging channel answers it. The gate itself waits until it is answered

Workflows

SYNAPSE_PARALLEL_MAX_BRANCHES — how many branches of a Parallel step run at the same time. Default 4.

SYNAPSE_PARALLEL_BRANCHES — 0 runs every branch of a Parallel step one after another. Default on.


Telemetry

Off unless you turn it on; nothing is ever sent to us. See Telemetry for what each exports.

VariableEffect
OTLP_ENDPOINTTurns OpenTelemetry export on, to this collector
SYNAPSE_TELEMETRYotlp turns it on, to OTEL_EXPORTER_OTLP_ENDPOINT; off keeps it off whatever else is set
OTEL_SDK_DISABLEDtrue keeps it off whatever else is set
METRICS_TOKENServes Prometheus metrics at GET /api/v2/metrics, with this as the Bearer token
SYNAPSE_LOG_FORMATjson writes JSON log lines carrying the trace, run, session and request ids

The CLI's client commands

The CLI's commands that drive a Synapse — synapse run, synapse runs, synapse chat, synapse mcp and the rest — read these. The command line's --url and --api-key win over them.

VariableDefaultEffect
SYNAPSE_API_URLThis machine's backendThe Synapse to drive — an origin such as https://api.synapseorch.com; the CLI adds /api/v1
SYNAPSE_API_KEY—The API key to use. A remote Synapse needs one; this machine's does not
SYNAPSE_CLI_CONFIG~/.synapse/cli.jsonWhere the CLI keeps its own key and its login
SYNAPSE_CHAT_HISTORY~/.synapse/chat_historysynapse chat's input history

Knowledge

How knowledge bases read files. Each file is read in a separate process, which sees these variables and a short list of others — never a database URL or a provider key.

VariableDefault
SYNAPSE_KNOWLEDGE_PARSE_TIMEOUT_S1800Seconds one file may take to read; the pages read by then are kept
SYNAPSE_KNOWLEDGE_PARSE_MEMORY_MB1024Memory for reading one file
SYNAPSE_KNOWLEDGE_DOCLING_MEMORY_MB2048Memory for reading one PDF with the knowledge extra's layout reader
SYNAPSE_KNOWLEDGE_DOCLING_BATCH_PAGES4Pages that reader takes at a time
SYNAPSE_KNOWLEDGE_OCR_TIMEOUT_S900Seconds for reading one file's scanned pages, where OCR is configured
SYNAPSE_KNOWLEDGE_CONTEXT_CONCURRENCY4Contextual Retrieval calls at once
DOCLING_ARTIFACTS_PATHmodels/docling under the state directoryWhere the layout reader's downloaded models are
SYNAPSE_SOFFICEsoffice or libreoffice on PATHLibreOffice, for legacy .doc, .xls and .ppt files

Other

SYNAPSE_LOG_LEVEL — backend log verbosity. Default INFO.

SYNAPSE_PROFILING — enables performance profiling. Default off; synapse start --profile sets it for you. See the CLI.

REDIS_URL — the Redis instance for scale mode. Overrides the redis_url setting. Setting it is what turns scale mode on — there is no separate switch in the environment.

SCALE_POSTGRES_URL — optional. The URL the scale layer connects with, overriding the scale_postgres_url setting. Unset, it uses SYNAPSE_DB_URL, which is what most deployments want: it is the same database, and the scale-side name only predates the store. If you do set it, point it at that same Postgres.

SYNAPSE_TENANT_ID — the tenant a process serves. A single-tenant install never sets this; it exists for deployments that run the engine per tenant.

DATABASE_URL — present in .env.example but read by nothing. The database the SQL agent and the code indexer query is configured in Settings as sql_connection_string, deliberately never from the environment. Setting DATABASE_URL has no effect.

On this page