# every variable core reads is listed here explicitly, even when empty. # `make setup` copies this template to core.local.env (gitignored) when # missing; the dev compose reads only the .local.env file — put secrets # and local tweaks there. # infrastructure wiring (compose service hostnames) OXYNOTE_CORE_DB_DSN=postgresql://devuser:devpass@postgres/devdb?sslmode=disable # an empty DSN disables search: documents are not indexed, the search # endpoint refuses, and the assistant loses its search tool. OXYNOTE_CORE_MEILISEARCH_URL=http://meilisearch:7700 OXYNOTE_CORE_MEILISEARCH_MASTER_KEY=devmasterkey # an empty URL disables valkey: the assistant keeps conversation history, # checkpoints and pending confirmations in the core process instead. # redis[s]://[username:password@]host:port[/db] OXYNOTE_CORE_VALKEY_DSN=redis://valkey:6379 # an empty URL disables the object store: objects are kept in a directory # on the local filesystem instead, and the rest of the STORAGE_ values are # unread. They are then not shared between instances and are lost with the # container unless the storage path is a volume. The dev stack runs this # way; set a URL and the values below to point it at an object store. OXYNOTE_CORE_OBJECT_STORAGE_URL= # an empty region signs requests for us-east-1, which suits object stores # that have no concept of regions; set it when the bucket lives in a real # region that would reject a mismatched signature. OXYNOTE_CORE_OBJECT_STORAGE_REGION= OXYNOTE_CORE_OBJECT_STORAGE_ACCESS_KEY= OXYNOTE_CORE_OBJECT_STORAGE_SECRET_KEY= OXYNOTE_CORE_OBJECT_STORAGE_BUCKET= # where objects are kept when no object store URL is configured. Core has # no default for it: with neither a URL nor a path it refuses to boot # rather than put objects somewhere nobody chose. The process must be able # to create the directory, or write to it if it is already there — in the # core image /home/nonroot is the only directory owned by the uid it runs # as, and the dev stack mounts a volume there. OXYNOTE_CORE_OBJECT_STORAGE_LOCAL_PATH=/home/nonroot/storage OXYNOTE_CORE_SERVER_AUTH_BETTER_AUTH_URL=http://auth-realtime:8081/api/auth/get-session OXYNOTE_CORE_SERVER_MCP_SESSION_URL=http://auth-realtime:8081/api/internal/mcp/session OXYNOTE_CORE_AUTH_REALTIME_URL=http://auth-realtime:8081 # an empty URL disables changedetection.io: url-watcher hooks cannot be # created and existing ones are skipped. OXYNOTE_CORE_CHANGEDETECTION_API_URL=http://changedetection:5000 # auto-populated in core.local.env by make run/start/dev (see # docker/sync-changedetection-key.sh) — no need to fill in manually. OXYNOTE_CORE_CHANGEDETECTION_API_KEY= # server # the listen address as host:port; empty binds all interfaces on 8080. OXYNOTE_CORE_SERVER_ADDRESS= # public URLs (the caddy front door) OXYNOTE_CORE_SERVER_PUBLIC_URL=http://localhost:8080/core OXYNOTE_CORE_BASE_APP_URL=http://localhost:8080 # the canonical MCP resource URL (must match auth-realtime's MCP_RESOURCE). OXYNOTE_CORE_SERVER_MCP_RESOURCE_URL=http://localhost:8080/core/api/mcp OXYNOTE_CORE_ORIGINS=http://localhost:8080,localhost:8080,http://localhost:3000,localhost:3000 # Integrations. All of them are optional and degrade gracefully when empty. # To enable the GitHub App, set GITHUB_APP_ID and drop the app's private key # into docker/github/oxynote.private-key.pem; an empty GITHUB_APP_ID disables # the integration entirely. To enable Slack, set all SLACK_* values; an empty # SLACK_CLIENT_ID disables it. # # Both apps deliver to the public callback surface, which they must be # configured to call (BASE_APP_URL + the path below): # github webhook url: /core/api/apps/github/events # slack request url: /core/api/apps/slack/events # slack command urls: /core/api/apps/slack/commands and /slash # slack direct install: /core/api/apps/slack/install # SLACK_REDIRECT_URL below is different: it points at the frontend page that # finishes the in-app connect flow, not at core. OXYNOTE_CORE_GITHUB_APP_ID= OXYNOTE_CORE_GITHUB_APP_SLUG= OXYNOTE_CORE_GITHUB_SIGNATURE_SECRET= OXYNOTE_CORE_GITHUB_CLIENT_SECRET= OXYNOTE_CORE_GITHUB_INSTALLATION_SIGNING_SECRET= OXYNOTE_CORE_GITHUB_PRIVATE_KEY_PATH=/etc/oxynote/core/github/oxynote.private-key.pem OXYNOTE_CORE_SLACK_CLIENT_ID= OXYNOTE_CORE_SLACK_CLIENT_SECRET= OXYNOTE_CORE_SLACK_SIGNATURE_SECRET= OXYNOTE_CORE_SLACK_REDIRECT_URL=http://localhost:8080/slack OXYNOTE_CORE_SLACK_INSTALLATION_SIGNING_SECRET= # AI assistant. An empty PROVIDER disables the assistant: core boots, # the chat endpoint refuses, and the MCP surface keeps working. To # enable it, set PROVIDER to the vendor (anthropic, openai, google, ollama, # or openrouter) and the credentials the vendor needs (an API key for # every provider except ollama); a set provider with missing pieces is a # boot error. MODEL is the vendor's own model identifier and is # optional: empty defaults to the provider's strongest supported model. # # The assistant is entirely tool-driven, so the model must be reliable at # calling tools against a large schema. MODEL is judged against the # supported list in the README: a mid-tier model runs with a logged # warning, and a too-weak or unlisted one disables the assistant instead # of failing boot. GET /api/capabilities reports the verdict. OXYNOTE_CORE_ASSISTANT_PROVIDER= OXYNOTE_CORE_ASSISTANT_MODEL= OXYNOTE_CORE_ASSISTANT_API_KEY= # optional. Overrides the provider endpoint. Required for ollama, and the # way to reach any OpenAI-compatible server with PROVIDER=openai. OXYNOTE_CORE_ASSISTANT_BASE_URL= # optional. Caps one reply and bounds one request to the provider. OXYNOTE_CORE_ASSISTANT_MAX_TOKENS=64000 OXYNOTE_CORE_ASSISTANT_REQUEST_TIMEOUT=10m # optional. Summarising a long conversation is mechanical work; point it # at a cheaper model to avoid paying chat rates for it. Defaults to MODEL. OXYNOTE_CORE_ASSISTANT_SUMMARY_MODEL= # optional, PROVIDER=openai only: set to target Azure OpenAI. OXYNOTE_CORE_ASSISTANT_AZURE_API_VERSION= # optional, PROVIDER=anthropic only: set REGION to reach Claude via AWS # Bedrock. Leave the keys empty to use the ambient AWS credential chain. OXYNOTE_CORE_ASSISTANT_BEDROCK_REGION= OXYNOTE_CORE_ASSISTANT_BEDROCK_ACCESS_KEY= OXYNOTE_CORE_ASSISTANT_BEDROCK_SECRET_ACCESS_KEY= OXYNOTE_CORE_ASSISTANT_BEDROCK_SESSION_TOKEN= # optional, PROVIDER=anthropic only: set PROJECT_ID to reach Claude via # Google Vertex. Leave the service account empty to use application # default credentials. OXYNOTE_CORE_ASSISTANT_VERTEX_PROJECT_ID= OXYNOTE_CORE_ASSISTANT_VERTEX_REGION= OXYNOTE_CORE_ASSISTANT_VERTEX_SERVICE_ACCOUNT_JSON= # document history retention. Entries pin the files they reference, so # these bounds also decide how long a removed image survives. 0 disables # the respective bound. OXYNOTE_CORE_DB_MAX_DOCUMENT_HISTORY_ENTRIES=100 OXYNOTE_CORE_DB_DOCUMENT_HISTORY_RETENTION=2160h # secrets OXYNOTE_CORE_DB_DATA_SOURCE_CREDENTIALS_SIGNING_SECRET=devsigningsecret # observability # an empty DSN disables sentry. OXYNOTE_CORE_SENTRY_DSN= # slog level (DEBUG, INFO, WARN, ERROR); empty means INFO. OXYNOTE_CORE_LOG_LEVEL= # email OXYNOTE_CORE_EMAIL_SMTP_HOST=mailpit OXYNOTE_CORE_EMAIL_SMTP_PORT=1025 OXYNOTE_CORE_EMAIL_SMTP_USERNAME= OXYNOTE_CORE_EMAIL_SMTP_PASSWORD= OXYNOTE_CORE_EMAIL_SMTP_TLS=none OXYNOTE_CORE_EMAIL_FROM_ADDRESS=Oxynote