Everything is configured with environment variables. The server checks all of them at startup and refuses to start with a list of every problem it found, so a typo never leaves it half configured.
General rules:
An empty value counts as unset.
Every variable can also be read from a file by appending _FILE to its name, for example ICLOUD_APP_PASSWORD_FILE=/run/secrets/icloud. A value set directly wins over the file, and a trailing newline in the file is ignored. Use this for secrets with Docker or Kubernetes secrets.
Booleans accept true, false, 1, 0, yes, no, on and off.
Lists are comma separated; spaces around names are ignored.
Key that signs OAuth tokens, at least 32 bytes. Changing it signs every client out
OAUTH_ADMIN_PASSWORD
yes
a passphrase
Password for the server’s login page, at least 12 characters (the server warns below 15). Changing it signs every connector out
MCP_AUTH_TOKEN
no
output of openssl rand -hex 32
Static bearer token accepted on every endpoint, for clients that can send a header. Treat it like the admin password. Must not contain exactly two dots
Log filter in tracing syntax. Targets: mcp_icloud_mail, mcp_icloud_calendar, mcp_icloud_contacts, mcp_server_core. The audit target always stays on at info
LOG_FORMAT
no
json
pretty
json or pretty
DEBUG
no
false
true
Debug logging with content redacted: tool arguments, result sizes, protocol command labels and status codes. Never IMAP protocol lines, bodies or credentials
DEBUG_UNSAFE_LOG_CONTENT
no
false
true
Also logs full tool results and CalDAV and CardDAV bodies, which puts your mail, event and contact content in the logs. A warning is printed at startup. Credentials are never logged
METRICS_ADDR
no
0.0.0.0:9090
Starts a separate plain-HTTP Prometheus listener. Keep it on an internal network
OTEL_EXPORTER_OTLP_ENDPOINT
no
https://otel.example.com
Exports traces over OTLP/HTTP. The standard OTEL_EXPORTER_OTLP_HEADERS is honoured. Nothing is exported unless it is set
AUDIT_LOG_PATH
no
/audit/audit.jsonl
File every write tool call is appended to as one JSON line (created with mode 0600). Audit lines are always logged too. See Security