Configuration
Configuration lives in .env at the repo root (start from .env.example).
docker-compose.yml forwards these into the backend container.
Required
Section titled “Required”| Variable | Meaning |
|---|---|
ANTHROPIC_API_KEY | Your Claude API key. Without it the app runs but every call to Claude fails. |
SUMISURA_CLAUDE_BACKEND | api (default) calls the Claude API. claude-code runs Selection, Rewrite and Cover Letter drafting through headless Claude Code (claude -p) on your own Claude subscription. See below. |
CLAUDE_CODE_OAUTH_TOKEN | Long-lived token from claude setup-token, used by the claude-code backend. |
Using your Claude subscription
Section titled “Using your Claude subscription”With SUMISURA_CLAUDE_BACKEND=claude-code, Selection, Rewrite and Cover Letter
drafting run as claude -p subprocesses authenticated with your own
subscription (Pro/Max) instead of per-token API billing. Run claude setup-token on your machine and put the token in CLAUDE_CODE_OAUTH_TOKEN.
The claude binary must be on the backend’s PATH (the published image does
not include it yet). ANTHROPIC_API_KEY is removed from the subprocess
environment, otherwise Claude Code would bill the key. The cost shown for a
Generation is an API-equivalent estimate, not real spend, and the calls count
against your subscription’s usage limits.
RAL estimation, contact research, capture hints and Application Method
inference still use the API and need ANTHROPIC_API_KEY.
This is for your own use only: Sumisura is single-user and self-hosted, and must not serve anyone else’s requests through your subscription. See ADR-0047.
Which model runs where
Section titled “Which model runs where”Each kind of call runs on a model chosen for that kind of work. Calls whose output you review, and the web-research calls, run on Sonnet; calls that only read structured fields out of a previous call’s notes run on Haiku.
| Call site | Default | What it does | Override |
|---|---|---|---|
selection_rewrite | Sonnet 5 | Selection + Rewrite for a Generation | SUMISURA_MODEL_SELECTION_REWRITE |
selection_preview | Sonnet 5 | Selection-only preview | SUMISURA_MODEL_SELECTION_PREVIEW |
cover_letter | Sonnet 5 | Cover letter drafting | SUMISURA_MODEL_COVER_LETTER |
ral_research | Sonnet 5 | Salary-range research | SUMISURA_MODEL_RAL_RESEARCH |
ral_extraction | Haiku 4.5 | Pulling the range out of those notes | SUMISURA_MODEL_RAL_EXTRACTION |
application_method_inference | Haiku 4.5 | How one applies | SUMISURA_MODEL_APPLICATION_METHOD_INFERENCE |
contact_research | Sonnet 5 | Contact research | SUMISURA_MODEL_CONTACT_RESEARCH |
contact_extraction | Haiku 4.5 | Pulling the contact out of those notes | SUMISURA_MODEL_CONTACT_EXTRACTION |
capture_hints | Haiku 4.5 | Company and Job Title from a Job Description pasted on the phone | SUMISURA_MODEL_CAPTURE_HINTS |
import_master_data | Sonnet 5 | Draft Entries from a pasted CV on the Import page | SUMISURA_MODEL_IMPORT_MASTER_DATA |
Override one call site, or all of them:
SUMISURA_MODEL_SELECTION_REWRITE=claude-opus-5 # try Opus on Rewrite aloneSUMISURA_MODEL_DEFAULT=claude-haiku-4-5 # everything at onceSUMISURA_MODEL_DEFAULT sets every call site at once. A per-call-site variable beats SUMISURA_MODEL_DEFAULT, which beats the
built-in default. Values are passed to the API unchanged — an unknown model id
does not stop the backend starting, the affected call just fails with the API’s
own error.
Restart the backend after changing .env.
What it costs
Section titled “What it costs”The app tracks usage and estimated cost per Generation and in total — see the usage view. Estimates come from a price table in the repo; a model missing from it estimates at $0 and logs a warning. Your actual bill is whatever Anthropic charges your key.
Other variables
Section titled “Other variables”| Variable | Meaning |
|---|---|
BIND_ADDR | 127.0.0.1 by default. See LAN-reachable mode. |
SUMISURA_API_URL | Where the tailor-cv skill reaches the backend, http://127.0.0.1:8080 by default. Set it in .env when the app runs on another machine, such as a home server; the skill reads it, the backend does not. |
LAN_AUTH_TOKEN | Shared token required in LAN mode. Unset means the check is off. |
LAN_AUTH_USER | With LAN_AUTH_PASSWORD, lets a browser sign in with a username and password instead of the token. Needs LAN_AUTH_TOKEN; set both or neither. See LAN-reachable mode. |
LAN_AUTH_PASSWORD | The password that goes with LAN_AUTH_USER. Changing it signs every browser out; the token keeps working for the extension and the skill. |
PORT | The port the backend listens on inside its container, 8080 by default. Change the published port in the compose file instead. |
LISTEN_HOST | The address the backend binds, 0.0.0.0 by default. Leave it in a container, where BIND_ADDR decides who can reach the published port. Running the binary directly on a host behind a reverse proxy, set 127.0.0.1 so only the proxy can reach it. |
DATA_DIR | Where Master Data and records live. The default suits a normal checkout. |
PROJECT_ROOT | The directory holding template/, output/ and data/ for rendering. The default suits a normal checkout. |
STATIC_DIR | The built frontend the backend serves (ADR-0039). Set inside the release image; leave unset from a checkout, where Vite serves the frontend. |
SUMISURA_VERSION | Which published image docker-compose.release.yml runs. Unset means latest; pin a tag for deliberate upgrades. |