Configuration
Solipsist works with no configuration. Every setting has a default; change only what you need.
Settings come from three places. A later one wins over an earlier one:
- the defaults (listed below);
- the config file,
solipsist.yaml; - the environment. The installed
solipsistreads no.env: the folder it runs in may be someone else’s. Run from source (bun src/index.ts), Bun loads the folder’s.envinto the environment first.
A setting that is wrong stops the server at start and says which one:
solipsist.yaml: agent.concurrency must be a whole number ≥ 1 (got "three")AGENT_CONCURRENCY must be a whole number ≥ 1 (got "three")The config file
Section titled “The config file”The first of these that exists is used. Files are not merged.
--config <path>on the command line, or theSOLIPSIST_CONFIGvariable;solipsist.yamlin the folder you start the server from;~/.config/solipsist/config.yaml.
Relative paths inside the file are resolved against the file’s own folder, so it means the same wherever you start the
server. ~ is expanded. The server prints the file it loaded when it starts. A change to the file applies at the next
start.
solipsist.example.yaml lists every key with its default. A minimal file:
md_search_paths: - "*.md" - docs/**/*.mdserver: port: 4000agent: concurrency: 2 cost_limit_usd: 5Secrets
Section titled “Secrets”pi.openrouter_key may go in the file, but solipsist.yaml is easy to commit by accident. Keep
keys in your environment (SOLIPSIST_OPENROUTER_KEY, in your shell’s profile). The server never prints a key:
errors and --print-config say only whether one is set.
Seeing what is in effect
Section titled “Seeing what is in effect”bun src/index.ts --print-config prints every setting’s value and where it came from (default, file or
env:NAME), then exits without starting a server.
In the browser, the gear on a page (and on the pages list) opens the settings dialog. Its Loaded settings tab shows the
same list for the running server: each value, where it came from, a filter box, and the config file that was loaded. A
secret shows only as set. The list comes from GET /api/config, which, like the prompts, answers only requests from
the machine the server runs on, even when server.host opens it to the network.
Prompts
Section titled “Prompts”Everything the agents are told is a prompt you can change: the protocol (the system prompt), the prompt each run is sent, one prompt per task type, and the chat prompts. Open the gear, then Prompts; pick one, edit it, Save. Reset to default brings the built-in text back.
- Your edits are kept outside the repository, one markdown file per prompt, in
prompts.dir(default~/.config/solipsist/prompts;SOLIPSIST_PROMPTS_DIR):protocol.md,run.md,type.gen.md, and so on. A prompt with no file uses the built-in text. You can edit or delete the files by hand; they are read each time they are used. - A change applies to the next run and the next agent started. An agent already running or waiting keeps the instructions it began with.
- Some prompts are templates with
{slots}the server fills in (the dialog lists them). A slot marked required must stay in the text; a save without it is refused and says why. Another{word}is kept as written. - Saving text identical to the built-in one removes the file, so a prompt is “edited” only when it differs.
Reference
Section titled “Reference”The rest of this page is generated from the settings table (src/server/config/). To add or change a setting, edit its
row there and run
bun scripts/config-docs.ts; a test fails while this page or the example file is out of date.
Which files Solipsist offers to work on. This key sits at the top of the file, outside any section.
md_search_paths
Section titled “md_search_paths”Glob patterns for the .md files the file dialog offers.
| Type | Default | Environment |
|---|---|---|
| a list of text (at least one) | *.md |
SOLIPSIST_SEARCH_PATHS |
Relative to the folder Solipsist runs in. *.md is that folder only; docs/**/*.md goes deep; a folder name means the .md files directly in it. A brace holding a slash ({a,b/c}/*.md) matches nothing, so list those as separate patterns. Dot-folders and node_modules are never offered. Anything git ignores isn’t either, unless the pattern starts with the folder’s name: docs/*.md finds them in an ignored docs/, and **/*.md doesn’t. An absolute path or .. is an error. Change it and restart, and the file dialog opens again with the new files it finds.
server
Section titled “server”How the web server is reached.
server.port
Section titled “server.port”The port of the server.
| Type | Default | Environment |
|---|---|---|
| a whole number from 0 to 65535 | 3000 |
PORT |
Give each checkout or worktree its own port in .env when you run several servers. 0 lets the system pick one.
server.host
Section titled “server.host”The address the server listens on.
| Type | Default | Environment |
|---|---|---|
| text | localhost |
SOLIPSIST_HOST |
localhost keeps the server to this machine. 0.0.0.0 opens it to the network. There is no login, so do that only on a network you trust.
server.allowed_hosts
Section titled “server.allowed_hosts”Names other than localhost the server answers to.
| Type | Default | Environment |
|---|---|---|
| a list of text | SOLIPSIST_ALLOWED_HOSTS |
The server refuses a request addressed to any name but localhost, 127.0.0.1 or [::1] on its own port, so a website can’t reach it by pointing a name of its own at this machine. Opened to the network (server.host) or behind a proxy, list the names it is reached by: notes.lan, or notes.lan:8080 for that port only. In the environment, a comma-separated list.
The background agents: when a run starts, how many run at once, how long they may take and cost, and how long a finished agent is kept for a chat.
agent.gap_ms
Section titled “agent.gap_ms”The pause before a failed run is retried (ms).
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 0 | 1000 |
AGENT_GAP_MS |
Raise it if a failing run (a bad key, a provider outage) retries too eagerly.
agent.settle_ms
Section titled “agent.settle_ms”How long the page must stay unchanged before a run starts (ms).
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 0 | 2000 |
AGENT_SETTLE_MS |
A run is sent only once you have stopped typing, so the agent reads the page you meant. Raise it if runs start while you are still writing.
agent.single_agent
Section titled “agent.single_agent”One lasting agent per page handles every request, instead of a fresh agent per request.
| Type | Default | Environment |
|---|---|---|
| true or false | false |
AGENT_SINGLE_AGENT |
On: the page has a single agent, which takes its requests one at a time and keeps everything it has read and written in its conversation, so each answer after the first is shorter to prompt and quicker to come back (agent.concurrency is then 1). It snoozes like any kept agent (agent.wait_ms) and takes its conversation up again on the next request. Off: each request gets a fresh agent that reads the page from nothing. Needs an engine that keeps conversations (Pi).
agent.concurrency
Section titled “agent.concurrency”How many runs may work on one page at once.
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 1 | 3 |
AGENT_CONCURRENCY |
Each pending request gets a run of its own. Lower it to spend less at once; raise it for a page with many requests. agent.max_runs caps all pages together.
agent.max_runs
Section titled “agent.max_runs”How many runs may work at once across all pages.
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 1 | 6 |
AGENT_MAX_RUNS |
A page held back by this limit is skipped as busy and tried again later.
agent.run_timeout_ms
Section titled “agent.run_timeout_ms”How long one run may take before it is stopped (ms).
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 1 | 600000 |
AGENT_RUN_TIMEOUT_MS |
A run that passes it is stopped and counts as failed.
agent.cost_limit_usd
Section titled “agent.cost_limit_usd”The most the agents may cost (US dollars) before no new run starts.
| Type | Default | Environment |
|---|---|---|
| a number > 0 | unset | AGENT_COST_LIMIT_USD |
Counted from the server’s start only (agent.cost_limit_day_usd and agent.cost_limit_month_usd span restarts), over runs and chat replies; a run in flight is not cut short. Unset: no limit.
agent.cost_limit_day_usd
Section titled “agent.cost_limit_day_usd”The most the agents may cost (US dollars) in one day before no new run starts.
| Type | Default | Environment |
|---|---|---|
| a number ≥ 0 | 5 |
AGENT_COST_LIMIT_DAY_USD |
The day is the local calendar day. Counted over runs and chat replies, and across restarts: the server adds up today’s cost from its log when it first needs it (so it only knows what the log holds; log.file off means counting from start). A run in flight is not cut short. 0: no daily limit.
agent.cost_limit_month_usd
Section titled “agent.cost_limit_month_usd”The most the agents may cost (US dollars) in one calendar month before no new run starts.
| Type | Default | Environment |
|---|---|---|
| a number ≥ 0 | 50 |
AGENT_COST_LIMIT_MONTH_USD |
Counted like agent.cost_limit_day_usd, over the local calendar month. 0: no monthly limit.
agent.max_unmetered_runs_day
Section titled “agent.max_unmetered_runs_day”Runs in one day on engines that report no cost, before no new run starts on them.
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 0 | 40 |
AGENT_MAX_UNMETERED_RUNS_DAY |
The dollar limits can only bound an engine that says what a run cost. One that doesn’t (AgentEngine.reportsCost) would run under them untouched, so it is bounded by count instead. Counted over the local calendar day and across restarts, from the server’s log, like agent.cost_limit_day_usd; runs on engines that do report a cost are not counted. 0: no limit, and nothing bounds an engine that reports no cost.
agent.wait_ms
Section titled “agent.wait_ms”How long a Pi agent waits after its suggestion before it snoozes (ms).
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 0 | 300000 |
AGENT_WAIT_MS |
While it waits, a chat or an Ask again continues at once. After it, the conversation is kept on disk and woken on demand, which is slower but holds no process.
agent.max_waiting
Section titled “agent.max_waiting”How many agents may wait on one page at once.
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 0 | 6 |
AGENT_MAX_WAITING |
Per page, unlike agent.max_runs. Past it, the oldest waiting agent snoozes.
agent.max_failures
Section titled “agent.max_failures”Failed runs in a row on one request before it is declined.
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 1 | 3 |
AGENT_MAX_FAILURES |
A declined request is left to you, with the reason, instead of being retried for ever.
agent.preferred_models
Section titled “agent.preferred_models”The models you prefer, listed first in the picker; the first that can run is the default.
| Type | Default | Environment |
|---|---|---|
| a list of text | pi:openrouter/~deepseek/deepseek-flash-latest |
SOLIPSIST_PREFERRED_MODELS |
Choices as engine:model — pi:openrouter/~deepseek/deepseek-flash-latest — or a bare model id, whichever engine has it. They are pinned to the top of the model picker under Preferred, in this order, and a page with no model of its own starts on the first whose engine can run now. The default is DeepSeek Flash on Pi; set it empty to let the engines’ own order decide. One no engine has is passed over. In the environment, a comma-separated list.
review
Section titled “review”Page Review: the agent that reads a page and leaves questions in the margin. It has no way to write the page, so a review never changes a word of it. These settings say how many questions a review may raise and how many the page may hold.
review.on
Section titled “review.on”Whether a page may be read for questions at all.
| Type | Default | Environment |
|---|---|---|
| true or false | true |
SOLIPSIST_REVIEW |
Page Review is the agent that reads your page and leaves questions in the margin, and never writes the page. Off, Page review is refused and the button is hidden.
review.curator
Section titled “review.curator”Who scores the questions a review raised.
| Type | Default | Environment |
|---|---|---|
one of self |
self |
SOLIPSIST_REVIEW_CURATOR |
self is the reviewer’s own score for its own questions, which costs nothing and ranks about as well as you would expect. A second, separate model that scores them against a written rubric is the next thing to build here; until it exists, self is the only choice.
review.min_score
Section titled “review.min_score”A question scoring below this (0 to 10) is dropped.
| Type | Default | Environment |
|---|---|---|
| a number ≥ 0 | 0 |
SOLIPSIST_REVIEW_MIN_SCORE |
Raise it to see fewer, better questions. With review.curator: self the score is the reviewer’s own, so a threshold mostly filters out what it already thought was weak.
review.min_kept
Section titled “review.min_kept”The fewest comments a page may hold on screen at once.
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 1 | 4 |
SOLIPSIST_REVIEW_MIN_KEPT |
However short the page. The cap is max(this, round(review.kept_per_block × non-empty blocks)).
review.kept_per_block
Section titled “review.kept_per_block”How many more comments a page may hold per non-empty block.
| Type | Default | Environment |
|---|---|---|
| a number ≥ 0 | 0.2 |
SOLIPSIST_REVIEW_PER_BLOCK |
A paragraph, heading, list item or table cell with text in it counts as a block. 0.2 means one more comment for every five.
review.max_per_review
Section titled “review.max_per_review”The most questions one review may raise.
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 1 | 3 |
SOLIPSIST_REVIEW_MAX |
The reviewer is asked for at most this many, and a call with more comes back for it to cut down. Low on purpose: three questions a writer reads beat ten they scroll past.
review.max_gloss_words
Section titled “review.max_gloss_words”A margin note longer than this many words is dropped.
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 2 | 10 |
SOLIPSIST_REVIEW_GLOSS_WORDS |
The note is meant to be two to five words, the way a reader pencils one beside a passage. One that runs to a sentence did not follow the brief, which is a fair sign of the question’s quality too.
suggestions
Section titled “suggestions”The limits on what an agent may suggest.
suggestions.max_chars
Section titled “suggestions.max_chars”The longest suggestion accepted from an agent (characters).
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 1 | 20000 |
SOLIPSIST_MAX_SUGGESTION |
A longer reply counts as a failed run. Raise it if you ask for long rewrites.
suggestions.max_edits
Section titled “suggestions.max_edits”The most changes to other blocks one suggestion may carry.
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 0 | 20 |
SOLIPSIST_MAX_EDITS |
A suggestion may also change blocks of the page outside its own range (remove this table). 0 forbids that.
The chat with an agent.
chat.max_message_chars
Section titled “chat.max_message_chars”The longest message you may send in a chat (characters).
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 1 | 20000 |
SOLIPSIST_MAX_MESSAGE |
A longer message is refused.
The Pi agent engine, on OpenRouter. It is the default engine.
pi.models
Section titled “pi.models”The models the picker lists at a glance, the first being the default.
| Type | Default | Environment |
|---|---|---|
| a list of text (at least one) | openrouter/~deepseek/deepseek-flash-latest, openrouter/anthropic/claude-haiku-5.5, openrouter/anthropic/claude-sonnet-5.5, openrouter/~z-ai/glm-latest, openrouter/~moonshotai/kimi-latest, openrouter/google/gemini-3.5-flash |
SOLIPSIST_PI_MODELS |
Ids as <provider>/<model>, e.g. openrouter/anthropic/claude-haiku-5.5. This is only the shortlist: the picker’s search offers every model your Pi has credentials for, read from Pi’s own catalog. One your Pi can’t run is left out, and when Pi names a default of its own (defaultModel in ~/.pi/agent/settings.json) it is listed first. In the environment, a comma-separated list.
pi.tools
Section titled “pi.tools”The tools a Pi agent may use (Pi’s names).
| Type | Default | Environment |
|---|---|---|
| a list of text (at least one) | read, grep, find, ls, bash, write, edit |
SOLIPSIST_PI_TOOLS |
The default leaves out MCP, codemode and tool search, so an agent starts none of your MCP servers. Bash runs where Solipsist runs and is not confined; a write guard limits write and edit to the page’s image folder. In the environment, a comma-separated list.
pi.openrouter_key
Section titled “pi.openrouter_key”Your OpenRouter API key. A secret.
| Type | Default | Environment |
|---|---|---|
| text | unset | SOLIPSIST_OPENROUTER_KEY |
Better kept in your environment than in this file, which you may commit. OPENROUTER_API_KEY works too, and so does any login Pi has saved of its own (pi, then /login) — for OpenRouter or any other provider, which a key set here overrides. With none of them Pi is listed but greyed out.
prompts
Section titled “prompts”Where your edits to the agents’ prompts are kept. Edit them in the app (the gear on a page) or by hand; the built-in text is the default.
prompts.dir
Section titled “prompts.dir”The folder where your edited prompts are kept, one markdown file per prompt.
| Type | Default | Environment |
|---|---|---|
| a folder path | ~/.config/solipsist/prompts |
SOLIPSIST_PROMPTS_DIR |
A prompt with a file here uses it; one without uses the built-in text, so deleting a file brings the default back. Point it at a shared or committed folder to keep prompts with a team. Edits apply to the next run and the next agent started.
comments
Section titled “comments”How long the hidden block at the end of a page keeps what it no longer needs.
comments.orphan_keep_ms
Section titled “comments.orphan_keep_ms”How long an orphaned comment or a decided suggestion is kept before it is removed (ms).
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 0 | 30000 |
ORPHAN_KEEP_MS |
An orphan is a comment whose text is gone. The delay lets an undo bring it back.
support
Section titled “support”The strip that asks you to buy a licence once you have used Solipsist for a while. Nothing is locked and nothing is sent anywhere: the count stays on this machine.
support.after_days
Section titled “support.after_days”After how many days of writing the page asks you to buy a licence.
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 0 | 14 |
SOLIPSIST_SUPPORT_AFTER_DAYS |
A day counts when you save a page on it. “Later” asks again 7 such days on; “I’ve bought one” stops it. 0 never asks.
support.dir
Section titled “support.dir”The folder of support.json, which keeps that count and your answer.
| Type | Default | Environment |
|---|---|---|
| a folder path | ~/.config/solipsist |
SOLIPSIST_SUPPORT_DIR |
Delete the file to start the count again.
What the server records about itself, and how it shows the agents in a terminal.
log.file
Section titled “log.file”The server’s log of its core actions, one JSON line each: a file path, or off.
| Type | Default | Environment |
|---|---|---|
| a file path, or “off” | unset | SOLIPSIST_LOG |
Saves, refused saves, outside edits, runs, waits, chats, stops and errors. Default: .solipsist/server.log in the folder Solipsist runs in. Always off under bun test.
log.max_bytes
Section titled “log.max_bytes”The size at which the log is moved aside (bytes).
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 1024 | 10485760 |
SOLIPSIST_LOG_MAX_BYTES |
Past it, the file moves to server.log.1 (the one before is dropped) and a new one starts, so the log never grows for ever.
log.tui
Section titled “log.tui”Whether the server shows the agents in a terminal view when it runs in a terminal.
| Type | Default | Environment |
|---|---|---|
| true or false | true |
SOLIPSIST_TUI |
false gives the plain line output instead, which is easier to read in a CI log or a pipe.
For working on Solipsist itself.
dev.mock_comments
Section titled “dev.mock_comments”Add a mock comment to every watched page every dev.mock_interval_ms.
| Type | Default | Environment |
|---|---|---|
| true or false | false |
MOCK_COMMENTS |
For trying the comment margin without an agent.
dev.mock_interval_ms
Section titled “dev.mock_interval_ms”The interval of the mock comments (ms).
| Type | Default | Environment |
|---|---|---|
| a whole number ≥ 1 | 5000 |
MOCK_INTERVAL_MS |
Only used with dev.mock_comments.
Variables that are not settings
Section titled “Variables that are not settings”These are read as plain environment variables, outside the settings table.
| Variable | Why |
|---|---|
SOLIPSIST_CONFIG |
The path of the config file, the same as --config <path> on the command line. |
NODE_ENV |
Bun’s and every tool’s. development (bun run dev) turns on hot reload and the dev routes, test (bun test) the dev routes and the test stand-in; anything else, or unset, is neither. Set by a .env in the folder Solipsist runs in, it counts as unset. |
AGENT_CMD |
The test fake: a JSON argv that stands in for an engine. Read only when NODE_ENV is test, and never when a .env in the folder sets it. Never a user setting. |
PI_CODING_AGENT_DIR |
Pi’s own: where it keeps its configuration. |
OPENROUTER_API_KEY |
Pi reads it itself. A fallback behind pi.openrouter_key. |
FUZZ_RUNS |
Test runner only (test/fuzz.test.ts). |
E2E_CHANNEL |
Test runner only (the browser the UI tests use). |
E2E_VIDEO |
Test runner only (where the UI tests record videos). |
For Solipsist 0.1