Skip to content

Configuration

Config Wizard

On first launch, Engram presents a Config Wizard that walks you through essential setup:

  • MakeMKV path -- auto-detected if on your system PATH
  • FFmpeg path -- auto-detected if on your system PATH
  • Staging path -- where ripped files are stored temporarily
  • Library paths -- separate directories for Movies and TV shows
  • TMDB Read Access Token -- for media metadata and poster art
  • MakeMKV license key -- your MakeMKV registration key

Settings are stored in the SQLite database and can be edited at any time from the Settings page (gear icon in the dashboard header).

TMDB API Token

The TMDB setting requires a Read Access Token (v4 auth), not the shorter v3 API Key.

To obtain your token:

  1. Create an account at TMDB.
  2. Go to API Settings.
  3. Copy the Read Access Token -- this is a long JWT string starting with eyJ....

Common mistake

The v3 "API Key" is a short alphanumeric string. Engram needs the v4 "Read Access Token" (the long JWT). Using the wrong one will cause TMDB lookups to fail silently.

The configuration field is named tmdb_api_key for backwards compatibility, but it expects the v4 Read Access Token.

Environment Variables

An optional backend/.env file can override server-level defaults. These settings are not managed through the Config Wizard -- they control the server itself.

Variable Description Default
DATABASE_URL SQLite connection string sqlite+aiosqlite:///./engram.db
HOST Server bind address 127.0.0.1
PORT Server port 8000
DEBUG Enable simulation endpoints false

Example .env file:

DEBUG=true
HOST=0.0.0.0
PORT=8000

Note

The .env file is optional. All fields have sensible defaults. The file is included in .gitignore and should never be committed.

LAN Access (Dashboard on Other Devices)

By default Engram binds to 127.0.0.1 (localhost only), so the dashboard is only reachable on the machine running Engram. To monitor from a phone, tablet, or another computer on the same network:

Via Settings (Windows desktop)

  1. Open the Settings page (gear icon) → Preferences step.
  2. Enable "Allow access from other devices on my network (LAN)".
  3. The panel below the toggle shows your LAN address and a QR code once the change is applied.
  4. Click Save, then Restart now when Settings offers it (packaged build) — the bind address is fixed at startup. A source or Docker run shows how to restart instead, and Restart now stays disabled while a disc is being processed.

No authentication

Engram has no login. Anyone on your network can view job status and control the application. Only enable this on a trusted home network.

After restart, access the dashboard from any device on your LAN at http://<host-ip>:8000. The QR code makes it easy to open on a phone or tablet.

Via environment variable (power users / Docker)

Set HOST=0.0.0.0 in your backend/.env file (or pass it as an environment variable in Docker). The env var takes precedence over the UI toggle:

HOST=0.0.0.0
PORT=8000

For Docker containers this is typically the right approach — the container has its own network namespace, so binding to 127.0.0.1 inside the container would make it unreachable even via published ports.

Configuration Sources

Configuration is resolved in this priority order:

  1. Database (app_config table) -- runtime configuration, editable via API and Config Wizard
  2. Environment variables (or .env file) -- server-level settings only
  3. Defaults -- hardcoded in the AppConfig model

Moving Settings to Another Install

Settings > Import & Export saves your configuration to a file and loads it on another install, for example when moving to a new machine, switching between the desktop build and Docker, or rebuilding after a lost database. First-run setup also offers Restoring from another install? Import a settings file on its first step.

Export

Download settings file saves engram-settings-YYYY-MM-DD.json with your paths, preferences, thresholds, naming formats, Discord templates and toggles, and AI, TheDiscDB and OpenSubtitles choices.

Keys and passwords (MakeMKV key, TMDB token, TheTVDB key, AI key, OpenSubtitles key and password, TheDiscDB key, Discord webhook) are left out unless you tick Include keys and passwords. The file is then named ...-with-keys.json. It is not encrypted: anyone who has it can use those credentials, so store it like a password.

An export with keys works only when the dashboard is opened as localhost or by IP address (for example http://192.168.1.50:8000). Opened under another host name, Engram refuses, because that is how a malicious web page would try to read the file through your browser. Export without keys works from any address.

These are never exported or imported, because they belong to one install:

  • whether first-run setup is finished (the new install still walks you through setup, with the imported values filled in)
  • LAN access (switch it on deliberately on the machine it exposes)
  • consent to share fingerprints with the Engram network

Import

Choose a settings file and Engram shows every setting in it before anything changes:

Group Meaning Ticked by default
Changes Differs from what this install has Yes
Check before applying A server Engram sends keys or data to (TheDiscDB URL, local AI URL, fingerprint server, Discord webhook, of which only the host is shown) or a program it runs (MakeMKV, FFmpeg, fpcalc). A file from someone else could point these somewhere you did not choose No
Not found on this machine A folder or program path that does not exist here. Applying a folder creates it on this machine, so tick it only if that is where you want it No
Network paths (not checked) A \\server\share path. Engram does not open network paths from an imported file, so it cannot say whether the share is there No
Invalid Fails the same checks as saving in Settings (a bad naming placeholder, an internal webhook address, an unwritable library folder); the reason is shown Cannot be ticked
Unchanged Already the same here No
Not recognized Not a setting this version imports (a newer Engram's setting, or one of the per-install settings above); skipped No

Keys and passwords show as will be replaced, never as values. Settings the file does not mention are left as they are, and a blank key in the file never clears a stored one. Apply checks the ticked settings again and writes all of them or, if any is refused, none.

Both export and import are reachable from the machine running Engram, and from other devices only when LAN access is on.

Configuration Fields

Paths

Field Description Default
staging_path Temporary directory for ripped files (set during wizard)
library_movies_path Movie library root directory (set during wizard)
library_tv_path TV show library root directory (set during wizard)
makemkv_path Path to makemkvcon executable (auto-detected)
ffmpeg_path Path to ffmpeg executable (auto-detected)

API Keys

Field Description Notes
makemkv_key MakeMKV registration key Redacted in API responses
tmdb_api_key TMDB Read Access Token (v4) Redacted in API responses

Matching & Processing

Field Description Default
max_concurrent_matches Parallel episode-matching (ASR) tasks 2
matcher_min_confidence Minimum confidence to auto-accept an episode match 0.6
enable_gpu_acceleration Run transcription on an NVIDIA GPU (opt-in; downloads the CUDA runtime) false
conflict_resolution_default File conflict handling "ask"
makemkv_min_title_length MakeMKV's minimum title length, in seconds (--minlength) 120

makemkv_min_title_length is passed to MakeMKV on every scan, rip and backup. Titles shorter than it are hidden by MakeMKV and never reach Engram, so lower it (Settings, Minimum Title Length) if a disc's specials or featurettes run under two minutes. 0 shows every title, including menu loops and logos.

max_concurrent_matches is the main matching-throughput knob. It's clamped to your hardware and takes effect on restart — see Performance & Hardware for how to tune it for CPU vs GPU and bulk imports.

enable_gpu_acceleration is best toggled from Settings → Matching → GPU Acceleration rather than edited directly, since enabling it triggers the one-time CUDA-runtime download. See GPU acceleration.

The conflict_resolution_default field accepts one of four values:

  • "ask" -- prompt via the review queue (default)
  • "skip" -- skip files that already exist in the library
  • "overwrite" -- replace existing files
  • "rename" -- keep both by writing a numbered (vN) variant

AI-Powered Title Resolution

ai_identification_enabled (default: false) — when enabled, Engram sends the disc volume label and any collected metadata to your configured AI provider to help resolve ambiguous or unrecognised disc titles.

Field Description Notes
ai_identification_enabled Enable AI-assisted disc title resolution Requires ai_provider, plus ai_api_key for a hosted provider
ai_provider AI provider to use Hosted: anthropic, openai, openrouter, gemini. Local: ollama, lmstudio
ai_api_key API key for the selected provider Redacted in API responses. Not needed for a local provider
ai_model Model override Blank uses Engram's default for the provider. Set this when your key has no access to that default. Required for a local provider, which has no default
ai_local_base_url Address of a local AI server Local providers only. Blank uses the provider's conventional port

See Local AI to run this against your own machine instead of a paid API.

AI-Powered Episode Matching

ai_episode_matching_enabled (default: false) — when enabled, low-confidence TV episode matches are sent to your configured AI provider with the season's TMDB synopses for a suggested episode. Always surfaces through the review queue; never auto-organizes. Shares ai_provider/ai_api_key with AI-Powered Title Resolution.

See the LLM Episode Matcher guide for accuracy expectations and provider recommendations (Gemini Flash-Lite is best on this task).

Local AI (Ollama and LM Studio)

Both AI features above can run against a model on your own machine instead of a paid hosted API. Two servers are supported, and they work the same way because they expose the same OpenAI-compatible interface.

No API key is required. The key field is hidden when a local provider is selected.

Setup

  1. Start your server:
    • Ollama: run ollama serve, then pull a model with ollama pull llama3.1:8b.
    • LM Studio: open the Developer tab, load a model, and start the server.
  2. In Engram, open Settings → Data sharing → AI assistance, enable AI identification, and choose Ollama (local) or LM Studio (local).
  3. Leave Server Address blank to use the default:

    Provider Default address
    Ollama http://localhost:11434/v1
    LM Studio http://localhost:1234/v1

    Set it only if your server runs on another port, or on another machine on your network. 4. Pick a model from the Model dropdown. The list is read from your server, so it only populates once the server is running. Unlike the hosted providers there is no default model, because the answer depends on what you installed. 5. Click Test Connection to confirm Engram can reach it.

Choosing a model

Any instruction-tuned model in roughly the 7B-14B range works well. Both tasks ask for a small JSON reply, so reasoning-heavy or very large models cost a lot of time for little benefit.

The dropdown lists everything the server offers, including embedding models (names containing embed). Those cannot answer chat requests; pick an instruction-tuned model instead. Neither server's model list distinguishes the two, so Engram cannot filter them for you.

Performance

Set Max Concurrent Matches to 1 in Preferences → Matching. A local server has one GPU or CPU, so parallel requests queue rather than overlap, and several large contexts at once can exhaust VRAM. Engram shows a reminder in Settings when a local provider is selected with concurrency above 1; it does not override your setting.

The first request after loading a model is slow. LM Studio loads weights on demand, which can take 30-60 seconds before any text appears. Engram allows up to five minutes for a local response, so this is expected rather than a failure.

Troubleshooting

Message Cause
Could not reach Ollama at ... The server is not running, or the address is wrong
'<model>' is not installed on this server The model is not pulled (Ollama) or not downloaded (LM Studio). The message lists what is available
Select a model first Local providers have no default; pick one from the dropdown

Why Engram checks the model list before testing

LM Studio answers a request for an unknown model by silently serving whichever model is currently loaded, returning HTTP 200 with no warning. A typo would otherwise pass the connection test and then quietly matter at match time, so Engram verifies the model against the server's own list first.

Extras Policy

Controls how bonus content (behind-the-scenes, deleted scenes, etc.) is handled during organization:

Field Description Default
extras_policy How to handle extras ("keep", "skip", "ask") "keep"

With "skip", TV tracks that are clearly too short to be episodes are skipped before ripping, so they never take up rip time. A track is skipped only when every available signal agrees it is short:

  • TMDB: it runs more than 5 minutes under the season's shortest episode runtime.
  • The disc itself: it is under half the length of the disc's main group of similar-length tracks (under 40% when TMDB runtimes are unavailable).

There is no fixed minute cutoff, so shows with short episodes (11-minute cartoons) are not affected. Skipped tracks stay on the dashboard card with the reason, and UN-SKIP puts one back in the rip queue as long as it has not been ripped yet. Anything that slips through is still caught after ripping, when its length is checked against the episode runtimes and it is discarded as an extra.

With "keep" or "ask", every track is ripped so extras can be filed or reviewed.

Movie discs

The policy applies to movie discs too. Engram never drops a title that could be the movie itself: every feature-length cut (theatrical, extended, director's cut) is always ripped.

Policy Before ripping After ripping
"keep" Every title is ripped. The feature is filed; every other title goes to the movie's Extras/ folder.
"skip" Titles that cannot be the feature are skipped (see below). Any non-feature title that was still ripped is discarded instead of filed.
"ask" Every title is ripped. The disc waits in the Review Queue. Discard any extras you don't want, then Select the feature; the extras you kept go to Extras/.

Under "skip", a title is skipped before ripping when:

  • TheDiscDB knows the disc and tags a different title as the main movie, or
  • it is shorter than the movie-length floor (analyst_movie_min_duration, 80 minutes by default) while at least one title on the disc is longer. A disc with nothing that long (a short film) is ripped whole and sorted out afterwards.

As with TV, skipped titles stay on the dashboard card with the reason and can be UN-SKIPped until the rip reaches them.

Import Watch Folder

Engram can auto-ingest pre-ripped MKV files dropped into a watched folder. See the Import Watch Folder guide for folder layouts and the full workflow.

Field Description Default
import_watch_path Folder to watch for incoming MKV files (unset = disabled) (none)
import_destination_mode "library" files imports into your Movies/TV libraries; "in_place" organizes them inside the watch folder "library"
staging_watch_enabled Also auto-import folders dropped into the staging directory false

Staging Cleanup

Controls when the staging directory is reclaimed after a job finishes. Watch-folder imports are never deleted regardless of this setting (the source folder is yours). See sizing the staging directory.

Field Description Default
staging_cleanup_policy "on_success", "on_completion", "manual", or "after_days" "on_success"
staging_cleanup_days Retention period when policy is "after_days" 7

Drive Behavior

Field Description Default
auto_eject_enabled Eject the disc automatically when ripping finishes true

Disable auto_eject_enabled if you want to keep the disc in the drive after ripping — for example, to manually verify the output or to re-rip a title without re-inserting the disc. Applies to both normal rips and re-rips triggered from the review queue.

Disc Backup

Field Description Default
backup_before_rip Copy the whole disc to a separate folder first, then extract from that copy false
backup_path Where those copies go (empty)

With this on, Engram writes a full decrypted MakeMKV copy of each disc under backup_path after identifying it, then extracts your MKVs from that copy instead of from the drive. Three things change:

  • The disc is read once, sequentially, instead of once per title. That is much gentler on a scratched or fragile disc.
  • The disc comes out of the drive as soon as the copy finishes, not when the whole rip finishes, so you can swap discs sooner.
  • You keep the copy. Engram never deletes a completed backup. It is yours to move to a preservation server or re-import later.

The cost is time and space: a Blu-ray backup is typically 25 to 50 GB and adds a full pass over the disc before extraction starts.

Backups mirror your library layout, so the shelf browses the way your library does:

backups/
  Movies/
    Inception (2010)/
  TV/
    Frasier/
      Season 01/
        S01D01/
  Unidentified/
    THE_SWEETEST_THING/

The folder names come from your own naming settings, so if you customise naming_movie_format or naming_tv_show_format the backups follow.

If anything prevents a backup (no folder configured, not enough free space, a disc MakeMKV cannot address, or a copy that fails partway) Engram rips directly from the drive instead and tells you why on the job card. Turning this on cannot make a disc less likely to finish.

You can also point the Import button at a backup you already have. A folder containing BDMV or VIDEO_TS, or an .iso file, is recognised as a disc image and run through the normal scan, identify, rip, match and organize pipeline. Point it at a whole shelf of backups and it queues one job per disc.

Naming Conventions

Out of the box, organized files follow these patterns:

  • Movies: Movies/Name (Year)/Name (Year).mkv
  • TV Shows: TV/Show/Season XX/Show - SXXEXX.mkv

Both patterns are configurable under Settings → Preferences → Naming & extras. (The season and episode formats appear once you set Naming Convention to Custom.) Formats are Python format strings, and any placeholder that turns out to be empty takes its surrounding group with it, so a movie with no known year is filed as Blade Runner, never Blade Runner ().

Movie naming

Setting Default Placeholders
Movie Folder Format {title} ({year}) {title}, {year}, {tmdb_id}
Movie Filename Format blank {title}, {year}, {tmdb_id}, {edition}

Leaving the filename format blank means "reuse the folder format", so customizing the folder carries through to the file and the two cannot drift apart:

Folder format "{title} - {year}", filename blank
  -> Movies/Blade Runner - 1982/Blade Runner - 1982.mkv

When a movie has an edition (chosen in the review queue), Engram appends the Plex {edition-...} tag to the inherited filename, because Plex reads the edition off the file rather than the folder:

Movies/Blade Runner (1982)/Blade Runner (1982) {edition-Final Cut}.mkv

Setting an explicit filename format takes full control and turns off both the inheritance and the automatic edition tag.

TV naming

Setting Default Placeholders
Show Folder Format {show} {show}, {year}, {tmdb_id}
Season Folder Format Season {season:02d} {season}
Episode Filename Format {show} - S{season:02d}E{episode:02d} {show}, {season}, {episode}, {year}, {tmdb_id}

Letting same-name titles coexist

Two different shows or movies can share a name (Frasier 1993 and Frasier 2023). Adding the id tag your media server expects keeps them in separate folders and stops the server from merging them:

  • Plex: {title} ({year}) {{tmdb-{tmdb_id}}} (or {show} ... for TV)
  • Jellyfin: {title} ({year}) [tmdbid-{tmdb_id}]

The doubled braces in the Plex form are how a literal { is written in a format string.

Configuration Flow

User edits config in Config Wizard / Settings page
  |
  v
PUT /api/config
  |
  v
Update AppConfig in database
  |
  v
JobManager reloads config on next operation
  |
  v
Components use updated settings

Validation

Configuration is validated at multiple levels:

  • Pydantic models -- type checking and required fields
  • API routes -- path existence checks, MakeMKV license validation
  • Validation endpoints -- POST /api/validate/makemkv, POST /api/validate/ffmpeg, GET /api/detect-tools
  • JobManager -- pre-flight checks before starting any job

API keys are redacted (masked as "***") in GET /api/config responses. The PUT /api/config endpoint accepts new values but never returns sensitive fields in the response.