Skip to main content
This page walks you through the minimal working IMP backend — three files that boot the platform and serve the API. Complete Setup before continuing.

The three-file structure

An IMP backend separates concerns across three source files: The server and worker run as separate processes in production. They share the same exulu.ts module so configuration is defined once.

src/exulu.ts

app.create() is async and returns a promise that resolves to the initialized ExuluApp. Exporting ready (the promise itself, not awaited) lets both server.ts and worker.ts import and await it independently.

src/server.ts

app.express.init() registers the GraphQL and REST routes, sets up authentication middleware, and — when EXULU_USE_LITELLM=true — starts the LiteLLM proxy supervisor. It returns the Express application, which you listen on directly.

src/worker.ts

The worker process connects to Redis (via REDIS_HOST / REDIS_PORT) and starts processing background jobs: knowledge ingestion, embedding generation, eval runs, and routines. It does not start an HTTP server.
Workers require an Enterprise Edition license (EXULU_ENTERPRISE_LICENSE). The app.bullmq.workers.create() call throws if the license is absent or invalid.

What create() does

When you call app.create(), IMP:
  1. Merges built-in contexts — the platform’s internal contexts (including transcriptions) are merged after your custom contexts, so built-ins always win on key collision.
  2. Registers 19 default providers — Claude Sonnet 4, Claude Sonnet 4.5, Claude Opus 4, GPT-5, GPT-5 Mini, GPT-5 Pro, GPT-5 Codex, GPT-5 Nano, GPT-4.1, GPT-4.1 Mini, GPT-4o, GPT-4o Mini, Gemini 2.5 Flash, Gemini 2.5 Pro, Gemini 3 Pro, Llama Scout 4 (Vertex), GPT-OSS 120B (Cerebras), Llama 3 8B (Cerebras), and Llama 3.3 70B (Cerebras). Pass providers to add your own alongside the defaults.
  3. Loads built-in tools — todo, question, Perplexity, email, and (if LiteLLM and S3 are both configured) the image-generation widget.
  4. Validates IDs — every context, tool, and provider ID must start with a letter or underscore, use only letters, digits, and underscores, and be at most 80 characters. Treat 5 characters as the practical minimum — the runtime error message enforces intent at 5, though the current validator accepts shorter IDs; don’t rely on that. create() throws immediately on validation violations.
  5. Registers the eval_runs queue — if Redis is reachable (REDIS_HOST + REDIS_PORT), the evaluation queue is registered automatically.
  6. Probes system binaries — checks for pandoc, soffice, and pdftoppm. By default (requireSystemDependencies unset or true), create() throws on missing system binaries; set requireSystemDependencies: false to downgrade to warnings instead (recommended in development).

ExuluConfig reference

Both workers and MCP are required top-level fields (no ?). All others are optional.

First run

Start the server in development:
On the first ever boot, initdb runs automatically and prints to stdout:
initdb runs on every startup and logs a freshly generated API key each time, but only the key from the very first boot is ever persisted. Keys logged on subsequent startups are not stored and will not authenticate. Copy the first-boot key to your secrets manager immediately.The admin email is admin@exulu.com and the initial password is admin. Change the password immediately after first login.
In a separate terminal, start the worker:

Environment variables

At minimum, create a .env file with:
See Environment variables for the full reference.

Next steps