Reference

Configuration

What the desktop app configures for you, the data directory layout, and where to change the defaults.

Nothing is required to configure by hand. The desktop app generates a bearer token, points the backend at its own data directory, and starts the bundled embedder, all before you see the window. Everything on this page is for tuning behavior, not for getting started — see First run and setup for that.

What the desktop app sets up for you

On first launch, the desktop shell:

  • generates SERVER_API_KEY (the bearer token) and MCP_SECRETS_KEY (the encryption key for stored provider secrets) and keeps them in local.bin in the app's userData folder, next to the data directory rather than inside it
  • picks a data directory (see below) and passes it as DATA_DIR
  • spawns the backend with PORT=0 and reads back the port it actually bound
  • points EMBEDDINGS_BASE_URL at its own bundled embedder, so code search and RAG work with no provider connected
  • passes its own apiToken to the page so the UI can call the backend

You never edit a config file to get a working install. Everything below is for changing a default.

The data directory

Where it lives, and what's in it, is covered in full in Data directory and security. In short: one Postgres cluster, the downloaded Postgres binaries, every repository's clones and per-task checkouts under workspaces/, and uploaded files when RAG is on. The generated secrets live in local.bin in the app's userData folder, next to this directory and not inside it.

Where overrides go

There are three places, in the order most people reach for them:

  1. Admin settings pages, in the running app — the right place for anything you'd change without a restart:
    • Settings → LLM — OpenAI-compatible endpoints (your own IP, Ollama, LM Studio, vLLM, OpenRouter, Groq, …), native providers (Gemini, Anthropic), and local agent CLIs (Claude Code and friends) — connect, disconnect, set a default, set a request timeout.
    • Settings → Integrations — GitHub, Vercel, App Store Connect, Google Play: the accounts TaskTrooper acts on your behalf through. Saved once, used by every project.
    • Settings → Usage — token usage by day and by model; nothing to configure here, but it's where you'd notice a runaway agent.
    • Board Workflow (per project) — the columns and the transition rules between them.
    • Per-repository settings (verify/build/test commands, pipeline job mapping, lifecycle gates, deploy targets, test strategy, incident policy) — see Git and pull requests, Deploy targets and recipes and Production incidents.
  2. Environment variables, read once at backend boot (server/README.md). The desktop app sets the required ones itself; you'd only set these running the server yourself (see Run from source).
  3. resources/config.yml, for the knobs with no settings-page equivalent yet — orchestration limits, board gate timing, evolution budgets, embedding throttling. Not something a packaged install expects you to edit; relevant mainly if you're running from source. ${VAR} in the file is substituted from the environment.

Environment variables

The backend refuses to start without the first two; everything else has a default.

VarDefaultMeaning
SERVER_API_KEY— (required)The bearer token every request must carry
MCP_SECRETS_KEY— (required)Encrypts provider API keys, MCP secrets and store credentials at rest — must stay the same across runs, or everything already encrypted becomes unreadable
DATABASE_URLempty → embedded PostgresExternal Postgres DSN. Empty starts an embedded Postgres 17 under $DATA_DIR/postgres
DATA_DIR./dataWorkspaces, RAG files, embedded Postgres data
PORT8085HTTP port; 0 picks a free one (what the desktop app uses)
EMBEDDED_POSTGRES_CACHE_DIR$DATA_DIR/postgres-binWhere the Postgres binaries are downloaded and extracted (first start only)
EMBEDDINGS_BASE_URL—An OpenAI-compatible host serving POST /v1/embeddings; set, a local embedding provider is created at boot (nomic-embed-text-v1.5, 768 dimensions)
CORS_ORIGINSapp://tasktrooper,http://localhost:3200,http://127.0.0.1:3200Origins allowed to call this server
PUBLIC_BASE_URLhttp://127.0.0.1:<port>The origin a Claude Code session calls TaskTrooper's own tools back on
CLAUDE_CODE_BINclaudeThe Claude Code CLI, resolved on PATH
CURSOR_AGENT_BIN / ANTIGRAVITY_BIN / OPENCODE_BINcursor-agent / agy / opencodeThe other agent CLIs, resolved on PATH
CHROME_BIN—Chromium binary for the browser_* tools
CONFIG_PATHresources/config.ymlConfig file path; falls back to the copy embedded in the binary if absent
SHUTDOWN_GRACE9mHow long the server keeps working after SIGTERM before in-flight runs are cancelled
SHUTDOWN_ON_STDIN_CLOSE—1 makes an stdin EOF start the same drain as SIGTERM; the desktop app sets it so the server never outlives the app (notably on Windows)
EMBEDDINGS_SOURCEonnx-int8The engine behind EMBEDDINGS_BASE_URL (onnx-int8, the desktop's embedder, or tei); the catalog's shipped skill vectors stand in only while embeddings go to that URL
AGENT_CATALOG_REPO—Where the role agents sync from, at boot and on a schedule. A local directory is read in place, a git URL is fetched; unset, no role agents are created. The desktop ships its own copy; make dev points at the checkout's catalog/
MOBILE_APPIUM_HUB_URL / APPIUM_BIN—The Appium hub the mobile_* tools drive, and the appium executable. The desktop sets both when Appium is installed, and the backend then runs the hub on demand itself

DATABASE_URL, SERVER_API_KEY and MCP_SECRETS_KEY are scrubbed from the process's own environment once read, so no child process (an agent CLI, a shell tool) can read them back out.

The most useful config.yml keys

The shipped defaults are tuned for a single local machine. A few are worth knowing about even if you never open the file:

KeyDefaultWhat it controls
claude_code.max_concurrent_sessionsunset (no cap)An optional host-wide cap on Claude Code sessions running at once, on top of the concurrency limits in Settings. Unset or 0 adds no cap of its own.
claude_code.max_turns100Turn budget for one Claude Code session before it returns what it has
orchestration.max_parallel_tasks3How many subtasks an orchestrated run executes in parallel
orchestration.max_plan_tasks10Max tasks in one orchestration plan
board.pipeline_gate_timeout45mHow long a task waits in Code Review for a build/test result before the reviewer is dispatched anyway
board.pipeline_gate_interval2mHow often the pipeline gate sweeper re-asks GitHub about an unfinished pipeline
board.verification_enabledfalsePost-run build/vet verification with an automatic fix loop (up to verify_max_fix_attempts, default 2) before a broken task is sent back to In Progress
board.require_criteria_completefalseBlocks a task from ready_for_qa/done/released while it still has open acceptance criteria
evolution.enabledfalseMaster switch for agent self-evolution (periodic, revision-triggered and manual reflection, KPI evaluation) — see Self-evolution and KPIs
evolution.golden_gatefalse (true in the shipped config.yml)Rehearses a proposed skill/rule change on the golden tasks and evolution.probe_cases recent requests before writing it; only a variant that does better is adopted
rag.enabledfalseFile upload and retrieval-augmented context
rag.top_k5Chunks injected into chat context per query
tools.terminal.enabledfalseEnables run_terminal
tools.terminal.sandbox.modeoffallowlist, blocklist, or off for shell command restriction
tools.web.enabledfalseEnables fetch_url
tools.search.enabled—Enables web_search (DuckDuckGo, falling back to Bing; no API key needed)
embedding.requests_per_minute0 (unthrottled)Caps embedding calls per minute; the shipped config tunes this for Mistral's free tier (55)
prod_ops.probe_interval3mHow often the health monitor probes a deploy target; two consecutive failures open an incident, one success closes it

Full reference, every key: server/.ai/config-reference.md in the repository (not published on this site, since it documents server internals rather than a screen you'll see).

Running from source: make dev and .env.local

If you're building TaskTrooper yourself rather than running the packaged app, copy server/.env.local.example to server/.env.local and fill in SERVER_API_KEY and MCP_SECRETS_KEY (openssl rand -base64 32 for the latter); make dev from the repository root loads it and runs the backend (embedded Postgres) plus the UI dev server in your terminal. See Run from source for the full setup, prerequisites and verify commands.

Edit this page on GitHub