Configuration
Full environment variable reference for the MCP server and the app.
Sandbox mode needs none of this configured — every variable below has a working sandbox default. This page is for pointing at live, or for operating a hosted deployment.
MCP server (mcp/)
| Variable | Default | Notes |
|---|---|---|
SATCHEL_BASE_URL | http://localhost:3000/api/sandbox | API base URL. Point this at the live Client Office API to flip modes. |
SATCHEL_USERNAME | demo@satchel.mcp | Sent as X-Username on /token. |
SATCHEL_PASSWORD | satchel-demo-key | Sandbox API key, or a plain live Client Office password. Live mode SHA-512 encodes it before sending; an already-encoded 128-hex value is also accepted. |
SATCHEL_MODE | sandbox | sandbox | live. |
SATCHEL_ALLOW_WRITES | unset (false) | Read-only by default. Must be "true" for satchel_move_money to run — in every mode. |
SATCHEL_SECURITY_HEADER | X-Auth-Token | Request header carrying the API token returned by the gateway. Configurable for other Client Office deployments. |
SATCHEL_LOCALE | host default | Drives Intl formatting (currency, dates) in tool output. |
SATCHEL_TIMEZONE | host default | Drives date/time formatting in tool output. |
Copy mcp/.env.example to mcp/.env to use these as defaults, or set them directly in your
MCP client's config (see Getting started).
App (app/) — sandbox and general
| Variable | Default | Notes |
|---|---|---|
SATCHEL_MODE | sandbox | sandbox | live, mirrors the MCP server's setting for the remote route. |
SATCHEL_BASE_URL | http://localhost:3000/api/sandbox | Same meaning as above, for the remote route's upstream client. |
SATCHEL_PUBLIC_ORIGIN | http://localhost:3000 | This deployment's own public origin — used in OAuth metadata documents. |
SATCHEL_SECURITY_HEADER | X-Auth-Token | See above. |
SATCHEL_AUDIT_LOG | false | Emit structured JSON audit events. |
SATCHEL_ALLOW_WRITES | unset (false) | Has no effect on the remote route — satchel_move_money is never registered there regardless. |
NEXT_PUBLIC_SITE_URL | http://localhost:3000 | Base URL used for metadata, sitemap, and Open Graph tags. |
App (app/) — closed live pilot
These matter only for a live deployment of the hosted remote server; see Authentication & security for what each control means in practice.
| Variable | Purpose |
|---|---|
SATCHEL_LIVE_ENABLED | Master switch for live mode. Read once at process start — flipping it needs a restart. Keep false until the deployment is fully reviewed. |
SATCHEL_LIVE_ENVIRONMENT | Required exact uat or production selection. There is no default; an obvious UAT hostname cannot be labelled production. |
SATCHEL_LIVE_ENVIRONMENT_DECISION_REFERENCE | Required evidence reference covering the chosen environment and exact base URL. |
SATCHEL_UAT_EXTERNAL_CLIENT_PERMISSION_REFERENCE | Required for UAT; records the decision permitting external pilot clients to touch that environment. |
SATCHEL_LIVE_ALLOWLIST | Comma-separated list of subjects permitted to authorize live access — who. |
SATCHEL_LIVE_CLIENT_POLICIES | JSON array binding each exact destination to a verified legal entity, one of the three client modes, versioned external notices, and the evidence references required for that mode. Hosted external clients require recipient/AISP/transfer dispositions; Satchel-managed providers require contract owner, DORA register, DPA, transfer and subprocessor evidence. A local client needs an explicit origin: "loopback" policy too. Missing evidence fails closed. |
SATCHEL_TEST_DATA_MODE | Defaults to synthetic outside live mode. Without structured provider evidence, synthetic UAT permits only local /api/sandbox mocks and refuses hosted client policies, Telegram and external monitoring configuration. |
SATCHEL_ICT_PROVIDER_EVIDENCE | Required in live. JSON array naming each Satchel-contracted, managed or depended-on ICT provider actually used, exact category (hosting, client_office, telegram, monitoring or satchel_managed_ai), approved service/use, contract owner, contract reference and DORA register reference. Coverage is provider-by-provider: live always requires hosting, Client Office and Telegram, while configured monitoring and Satchel-managed AI add their own categories. Bare confirmed, missing fields/categories and obvious placeholders are not evidence. Customer-selected AI is classified under its client policy and is not automatically a Satchel vendor. |
SATCHEL_OAUTH_STORE_PATH | Persistent path for the encrypted OAuth store, on durable storage. |
SATCHEL_OAUTH_STORE_KEY | Independent random 32-byte key (base64 / base64url) that encrypts the OAuth store (AES-256-GCM). |
SATCHEL_AUDIT_HMAC_KEY | Independent random 32-byte key that pseudonymizes the audit stream's subject reference. Falls back to SATCHEL_OAUTH_STORE_KEY if unset. |
SATCHEL_AUDIT_LOG_PATH | Append-only JSONL audit sink path. Required in live mode — unset falls back to stdout, which has no defined retention. |
SATCHEL_KILL_FLAG_PATH | Location of the kill-switch flag file, checked on every request. Default is a path under the app's own working directory. |
SATCHEL_KILL_SECRET | 32+ character secret gating the kill-switch HTTP endpoint; required in live. |
TELEGRAM_BOT_TOKEN | Dedicated operational alert bot token; required in live and subject to the ICT-provider evidence gate. |
SATCHEL_TELEGRAM_WEBHOOK_SECRET | 32+ character secret validating inbound Telegram webhook calls; required in live. |
SATCHEL_KILL_TELEGRAM_CHAT_IDS | Explicit dedicated owners chat(s) permitted to issue /kill; required in live. No shared-chat fallback exists. |
SATCHEL_KILL_TELEGRAM_USER_IDS | Exact owner user IDs; at least four are required in live. This technical count does not replace named-role acceptance evidence. |
SATCHEL_ALERT_CHAT_ID | Dedicated alert destination; required in live and must be one of the kill chats. No default exists. |
SATCHEL_ERASE_SECRET | 32+ character secret gating the subject-erasure endpoint (GDPR art. 17); required in live. |
SATCHEL_RATE_LIMIT_SUBJECT_PER_MINUTE | Requests one subject may make to the remote MCP route per minute. Default 60. Exceeding returns 429 with Retry-After. |
SATCHEL_RATE_LIMIT_CLIENT_PER_MINUTE | Requests one OAuth client may make per minute across all its subjects. Default 180. |
Generate the two 32-byte keys with:
openssl rand -base64 32GET /health is the deployment's public readiness endpoint — it returns 200 only when
the OAuth runtime configuration is valid and the encrypted store can be read and written.
Point uptime monitoring at that route rather than the MCP endpoint itself, whose correct
unauthenticated response is 401.