Configuration
Look up environment variables, secrets, bindings and app defaults when deploying or troubleshooting configuration.
Most of Calends is configured in the app and stored in the database. These are the only deployment-level settings.
Environment variables and bindings
Section titled “Environment variables and bindings”| Name | Kind | Applies to | Details |
|---|---|---|---|
SETUP_TOKEN |
secret / env | all | Required to set the first password on a fresh deployment. On Cloudflare, set it with wrangler secret put SETUP_TOKEN; on Docker it’s generated if unset. Not needed once the password is set. |
SITE_URL |
var / env | all | Your site address, e.g. https://calends.example.com, used in reminder messages and calendar feed links. If unset: requests use the address being visited; scheduled jobs use the address recorded the last time you opened the app. |
EMAIL |
binding | Cloudflare | The Cloudflare Email Sending send_email binding, needed for email reminders. |
MAIL_FROM |
var | Cloudflare | Sender address; must be allowed by the EMAIL binding. Email works once both are set. |
MAIL_FROM_NAME |
var | Cloudflare | Sender name, optional. |
TRUST_PROXY |
env | self-hosted | Set to 1 behind a reverse proxy so X-Forwarded-For is trusted as the visitor IP and sign-in rate limiting is accurate. Don’t set it without a proxy. |
DATA_DIR |
env | Docker | Data directory, /data by default. |
PORT |
env | Docker | Listening port, 8787 by default. |
LOG_LEVEL |
env | Docker | Worker log level, warn by default. |
DEMO_MODE |
var | Cloudflare | 1 turns the instance into a demo: visitors can browse the app read-only without signing in, and every change and MCP request is refused. Never enable it on your own ledger. |
OWNER_PASSCODE |
secret | legacy | Early versions kept the passcode directly in a secret. After the first successful sign-in it’s converted to a hash and can be deleted. Not needed for new deployments. |
DEV_BYPASS_AUTH |
.dev.vars |
local dev | 1 skips sign-in. Local use only — never set it in production. |
On Cloudflare, variables go in vars in wrangler.jsonc or in the Worker’s settings in the dashboard, and secrets via wrangler secret put. On Docker, everything is an environment variable.
Settings in the app
Section titled “Settings in the app”These aren’t environment variables; change them in the app:
| Setting | Where | Default |
|---|---|---|
| Base currency | Settings → General | USD |
| Time zone | Settings → General | UTC |
| Language | Settings → General | System default |
| Remind me | Settings → Reminders | 3 days |
| Send at | Settings → Reminders | 09:05 |
| Monthly preview on the 1st | Settings → Reminders | On |
| Public page | Settings → Sharing & access | Off |
| AI access (MCP) | Settings → Sharing & access | On |
| Max signed-in devices | Settings → Security | 10 |
Routes
Section titled “Routes”| Path | What |
|---|---|
/admin |
The app |
/ |
The public page (when enabled) |
/api/* |
API for the app and public page |
/mcp |
MCP endpoint |
/cal/<token>.ics |
Calendar feed |