Appearance
Environment variables
The server reads its settings from the environment when it starts. It also reads a .env file (KEY=value lines, no variable expansion) from its working directory and from two directories up (the repo root, when it runs from apps/server as pnpm dev and pnpm start do); real environment variables win over the file. An empty value (KEY=) counts as not set. Docker Compose passes the repo root's .env to the container (see Docker); .env.example at the repo root lists the common ones.
A bad value stops the server at startup with Invalid environment: <VARIABLE>: <problem>.
Bot settings (what the agent says, its voice, its limits) are not environment variables: they live in the admin panel. See Configuration.
Basics
Where the server listens, where it keeps its data, and the address the world reaches it at.
| Variable | Type | Default | |
|---|---|---|---|
NODE_ENV | development, production, test | development | Set production for any real deployment (the Docker image does). Outside production the server also accepts the widget socket from localhost pages, allows http:// webhook URLs and serves source maps; development also logs every request in a readable format. |
HOST | string | 0.0.0.0 | The interface to listen on. |
PORT | number (0 to 65535) | 8800 | The port to listen on. |
PUBLIC_URL | URL | (not set) | The address visitors' browsers reach this server at, e.g. https://chat.example.com. Used in the embed code, the bot config URLs, invitation links and preview links, and the chat window's WebSocket only accepts connections from this origin. Without it the server uses the address each request came in on, which is wrong behind most proxies. The session cookie is Secure only when it starts with https://. |
DATA_DIR | string | ./data | Where the server keeps everything: the SQLite database (wireface.db), uploaded files (files/) and the generated master.key. Back this up. |
ROOT_REDIRECT | string | /admin/ | Where a visit to / goes: the admin panel, or a product page when the server is a public service. |
LOG_LEVEL | fatal, error, warn, info, debug, trace, silent | info | How much the server logs. debug helps when looking into a problem. |
Security
Secrets, and the switches that widen what the server may do.
| Variable | Type | Default | |
|---|---|---|---|
WIREFACE_MASTER_KEY | string | (not set) | Encrypts provider API keys, webhook and identity secrets, tool secrets and MCP headers and environment in the database (AES-256-GCM). 32 bytes as base64 or 64 hex characters, e.g. from openssl rand -base64 32. Without it the server generates one into DATA_DIR/master.key on first run. Lose it and every stored key must be entered again. |
WIREFACE_MASTER_KEY_OLD | string | (not set) | The previous master key, while you change it. At startup the server re-encrypts every stored secret still sealed with it under the new key, and the log says when this variable can be removed. See Backups. |
SETUP_TOKEN | string (at least 8 characters) | (not set) | The token the first-run setup at /admin/setup asks for (at least 8 characters). Without it the server makes a random one and prints it in the log until setup is done. |
ALLOW_STDIO_MCP | boolean (true, 1, yes, on) | false | Allow MCP servers that run as commands on this machine (the stdio transport). They get a minimal environment (PATH, HOME and the like) plus the variables the admin sets, never the server's own. Still, only turn it on when everyone with admin access is trusted with a shell. |
ALLOW_PRIVATE_NETWORK | boolean (true, 1, yes, on) | false | Let HTTP tools, MCP servers, webhooks and the knowledge crawler reach private, loopback and link-local addresses. Off, they can only reach the public internet. (One HTTP tool can also be allowed on its own, except in a hosted workspace.) |
Behind a proxy
| Variable | Type | Default | |
|---|---|---|---|
TRUST_PROXY | boolean (true, 1, yes, on) | false | Trust X-Forwarded-For and X-Forwarded-Proto from a reverse proxy, so rate limits see each visitor's own IP and the server knows the request was https. Set it when the server is behind nginx, Caddy or a load balancer. |
Hosted sign-up
For running Wireface Chat as a service: people sign in with their wireface.dev account and each gets a workspace of their own, with these limits. The server owner's workspace (made in the setup) has none of them. See Hosted accounts.
| Variable | Type | Default | |
|---|---|---|---|
WIREFACE_ACCOUNTS_URL | URL | (not set) | The wireface.dev accounts site (https://wireface.dev). Set it, with the secret, to offer "Sign in with your wireface.dev account" on the sign-in page: anyone with an account gets a workspace of their own on first sign-in. Only once this server's own setup is done. |
WIREFACE_ACCOUNTS_SECRET | string (at least 32 characters) | (not set) | The secret the accounts service signs sign-in tokens with (the same value as its CHAT_SSO_SECRET), at least 32 characters, e.g. from openssl rand -base64 48. |
HOSTED_SIGNUPS_PER_DAY | number | 50 | New hosted workspaces a day, in all. |
HOSTED_MAX_BOTS | number | 3 | Bots in a hosted workspace. |
HOSTED_MAX_MEMBERS | number | 3 | People in a hosted workspace, counting invitations. |
HOSTED_MAX_KB_SOURCES | number | 10 | Knowledge sources in a hosted workspace. |
HOSTED_MAX_KB_PAGES | number | 50 | Pages one website or sitemap source may read. |
HOSTED_MAX_KB_FILE_MB | number | 5 | The largest knowledge file, in MB. |
HOSTED_MAX_TOOLS | number | 10 | HTTP tools and MCP servers in a hosted workspace, together. |
HOSTED_MAX_WEBHOOKS | number | 3 | Webhooks in a hosted workspace. |
HOSTED_MAX_FACES | number | 10 | Custom faces (from photos) in a hosted workspace. |
HOSTED_MAX_RETENTION_DAYS | number | 90 | The longest a hosted workspace may keep conversations; they start at this. |
DEMO_SANDBOX | boolean (true, 1, yes, on) | false | Offer "Try the demo" on the sign-in page: one click makes a visitor a sandbox workspace with a sample bot, conversations and leads, without signing in. They can change the bot and talk to it, but not connect keys, add tools or publish; signing in with a wireface.dev account keeps what they made. Needs DEMO_SANDBOX_GEMINI_KEY and this server's own setup done. See Hosted accounts. |
DEMO_SANDBOX_GEMINI_KEY | string | (not set) | The Gemini API key the sandboxes' sample bots run on. It's stored encrypted in each sandbox like any key, and never shown; it's removed when a sandbox is kept by signing in. |
DEMO_SANDBOXES_PER_DAY | number | 200 | New sandboxes a day, in all (and three an hour from one address). |
DEMO_SANDBOX_HOURS | number (1 to 168) | 24 | How long a sandbox lasts before it and everything in it is deleted. |
DEMO_DAILY_USD | number | 3 | What all sandboxes together may spend on the demo key in a day (estimated, USD). Past it, their bots stop answering until midnight UTC. |
DEMO_BOT_DAILY_USD | number | 0.25 | A sandbox bot's daily spending cap (its own caps can only be lower). |
DEMO_BOT_DAILY_MESSAGES | number | 40 | A sandbox bot's daily message cap. |
DEMO_BOT_VOICE_MINUTES | number | 3 | A sandbox bot's daily voice minutes (one voice conversation at a time). |
AI providers
Keys to connect on first run, and other addresses for the providers (proxies, gateways, test mocks).
| Variable | Type | Default | |
|---|---|---|---|
PROVIDER_BASE_URL_ANTHROPIC | string | (not set) | Send Anthropic API calls somewhere else, e.g. a corporate gateway. Default https://api.anthropic.com. (Server-side refusal fallback is only used with the default.) |
PROVIDER_BASE_URL_OPENAI | string | (not set) | Default https://api.openai.com/v1. |
PROVIDER_BASE_URL_GEMINI | string | (not set) | Default https://generativelanguage.googleapis.com. |
PROVIDER_BASE_URL_ELEVENLABS | string | (not set) | Default https://api.elevenlabs.io. |
PROVIDER_WS_URL_OPENAI | string | (not set) | WebSocket base for the Realtime API and transcription. Default wss://api.openai.com/v1. |
PROVIDER_WS_URL_GEMINI | string | (not set) | WebSocket base for the Live API. Default wss://generativelanguage.googleapis.com. |
PROVIDER_WS_URL_ELEVENLABS | string | (not set) | WebSocket base for Agents and Scribe. Default wss://api.elevenlabs.io. |
ANTHROPIC_API_KEY | string | (not set) | If set when the first-run setup completes, an Anthropic connection is made from it. After that, manage keys in the admin panel. |
OPENAI_API_KEY | string | (not set) | The same, for OpenAI. |
GEMINI_API_KEY | string | (not set) | The same, for Google Gemini. |
ELEVENLABS_API_KEY | string | (not set) | The same, for ElevenLabs. |
Static files
Only needed when the built files are not in the usual places of the repo (the Docker image keeps them there).
| Variable | Type | Default | |
|---|---|---|---|
ADMIN_DIST | string | (not set) | Where the built admin panel is. Defaults to apps/admin/dist in the repo. |
WIDGET_DIST | string | (not set) | Where the built widget is. Defaults to packages/widget/dist. |
WIDGET_RELEASES | string | (not set) | Every released widget@x.y.z.js, so pages pinned to an older version keep loading after an upgrade. Defaults to packages/widget/releases. |
DOCS_DIST | string | (not set) | Where these docs are built. Defaults to docs/.vitepress/dist. |
CORE_DIR | string | (not set) | Where the Wireface face engine is. Defaults to vendor/wireface-core. |