Configuration

Rabbithole can be configured via command-line flags or a TOML configuration file. Command-line flags always take precedence over values set in the config file. The config file is optional; Rabbithole will run with defaults if none is provided.

The source of truth is always the binary. Run rabbithole --help to see the current list of flags and their defaults.

CLI Reference

Flag Type Default Description
--seed path (required) Path to a plain-text file containing the seed prompt for the homepage (/). This prompt describes what the root page of the generated site should contain. Every other page is derived from links that the root page (and subsequent pages) produce. See Writing a Seed Prompt.
--port integer 8080 TCP port to listen on. Set to 80 or 443 for production use (may require elevated privileges or a reverse proxy).
--db path rabbithole.db Path to the SQLite database file used to cache generated pages and store the URL-to-prompt mapping table. Created automatically if it does not exist. See Cache Invalidation.
--model string (required) The LLM model name to pass to the API. Examples: claude-sonnet-4-5, gpt-4o, gpt-4.1. Must be a model accessible via your configured API key.
--api-key string see note API key for the LLM provider. If omitted, Rabbithole reads from the OPENAI_API_KEY or ANTHROPIC_API_KEY environment variable depending on the model selected. Prefer the environment variable to avoid exposing secrets in shell history or process listings.
--depth integer 5 Maximum link depth from the seed page before generation stops. See Depth Limit for a detailed explanation.
--web-tools boolean flag false When set, enables the web search and web fetch tools for the LLM during page generation. This allows pages to contain real, up-to-date information pulled from the live web. Increases latency and token usage. See Web Tools.
--system-prompt path (built-in) Path to a plain-text file that overrides the default system prompt sent to the LLM. The default system prompt instructs the model to act as Rabbithole — generating HTML pages and JSON mappings. Only change this if you know what you are doing; an incorrect system prompt will likely break output parsing.
--config path (none) Path to a TOML configuration file. Values in the file are used as defaults; CLI flags override them.

TOML Configuration File

All CLI flags (except --config itself) may be expressed in a TOML file. Keys use the long flag name without the leading dashes, with hyphens replaced by underscores.

Full example: rabbithole.toml

# Rabbithole configuration file
# All fields are optional; shown values are defaults unless marked.

# Path to the seed prompt file (required if not passed on CLI)
seed = "seed.txt"

# TCP port to listen on
port = 8080

# SQLite database path (created if missing)
db = "rabbithole.db"

# LLM model name (required)
model = "claude-sonnet-4-5"

# API key — prefer environment variables instead of hardcoding here
# api_key = "sk-..."

# Maximum crawl depth from the seed page (0 = seed page only)
depth = 5

# Enable web search and web fetch tools
web_tools = false

# Override the built-in system prompt (path to a .txt file)
# system_prompt = "my_system_prompt.txt"

Environment Variables

Variable Description
OPENAI_API_KEY API key for OpenAI-compatible endpoints (GPT-4o, etc.). Used when --api-key is not set.
ANTHROPIC_API_KEY API key for Anthropic models (Claude). Used when --api-key is not set.
RUST_LOG Controls log verbosity. Set to info, debug, or trace for more output. Example: RUST_LOG=rabbithole=debug.

Depth Limit (--depth)

Every URL in Rabbithole has an associated depth: the seed page (/) is at depth 0. Links generated by the seed page are at depth 1. Links generated by depth-1 pages are at depth 2, and so on.

The --depth flag sets a ceiling. When a page is being generated and its depth equals or exceeds the limit:

This prevents unbounded, infinite graph growth. Without a depth limit, a sufficiently creative LLM could generate links indefinitely, consuming API credits and disk space.

Note: The depth limit is about link registration, not page serving. A URL at depth 6 that was registered before you lowered --depth to 5 will still be served from the cache.

Choosing a depth value

Value Typical use
0 Seed page only. No linked pages are ever registered.
1 Seed + one level of direct links from the homepage.
3 Good for small demo sites. Keeps the page count manageable.
5 Default. Suitable for most documentation sites and wikis.
10+ Deep exploratory sites. Watch API costs carefully.

Cache Invalidation

Generated pages are cached permanently in the SQLite database. Once a URL has been generated and stored, Rabbithole will always serve the cached version without calling the LLM again. There is currently no automatic TTL or expiry mechanism.

To invalidate cached content, you have two options:

Option 1 — Delete the entire database

This clears all cached pages and all URL-to-prompt mappings. The next request to any URL will regenerate from scratch, beginning with the seed.

rm rabbithole.db

Option 2 — Delete a specific row

Use the SQLite CLI (or any SQLite client) to remove a single cached page. Rabbithole will regenerate it on next request, using the stored prompt.

sqlite3 rabbithole.db

-- See what's cached:
SELECT url, length(html), created_at FROM pages ORDER BY created_at DESC;

-- Delete a single page so it will be regenerated:
DELETE FROM pages WHERE url = '/some-page.html';

-- Remove a URL from the mapping entirely
-- (prevents it from being served or re-registered):
DELETE FROM mappings WHERE url = '/some-page.html';

.quit
Warning: If you delete a row from pages but leave the corresponding row in mappings, Rabbithole will regenerate the page using the stored prompt on next visit. If you also delete from mappings, the URL becomes permanently unreachable until a parent page is regenerated and re-registers the link.

Example CLI Invocations

Minimal (required flags only)

rabbithole --seed seed.txt --model gpt-4o

Custom port and database path

rabbithole \
  --seed seed.txt \
  --model claude-sonnet-4-5 \
  --port 3000 \
  --db /var/lib/rabbithole/site.db

With web tools enabled and increased depth

rabbithole \
  --seed seed.txt \
  --model gpt-4o \
  --depth 8 \
  --web-tools

Using a config file with an API key override

ANTHROPIC_API_KEY=sk-ant-... rabbithole --config rabbithole.toml

Using a TOML config file, overriding port on CLI

rabbithole --config rabbithole.toml --port 9000

Verbose logging for debugging

RUST_LOG=rabbithole=debug rabbithole --seed seed.txt --model gpt-4o

Precedence Order

When the same option is set in multiple places, Rabbithole resolves it in this order (highest wins):

  1. Command-line flag
  2. TOML config file value
  3. Environment variable (for API keys)
  4. Built-in default

See Also

---MAPPINGS--- [{"url": "/", "prompt": "Homepage for Rabbithole — an open-source Rust web server (github.com/ajbt200128/rabbithole, live at isarabbithole.com) that dynamically generates entire websites on the fly using LLMs. DESIGN: Plain minimal HTML like gcc.gnu.org. White background (#ffffff), Arial/Helvetica, no gradients, no JS. Blue links (#0000cc), visited purple (#551a8b). Pipe-separated nav: Home | Getting Started | Architecture | Configuration | Web Tools | Deployment | Examples | About. Paths: /, /getting-started.html, /architecture.html, /configuration.html, /web-tools.html, /deployment.html, /examples.html, /about.html. Pre/code: #f4f4f4 bg, 1px solid #ccc. H2 with bottom border. Footer with GitHub link. CONTENT: Project homepage. Explain what Rabbithole is: a Rust web server that, upon receiving an HTTP request for any URL, looks up a stored prompt for that URL, calls an LLM (with optional web tools), receives back a complete HTML page plus a JSON mappings block of child URL→prompt pairs, caches the page in SQLite, and serves it. Highlight key features: LLM-generated pages, SQLite caching, configurable depth limit, optional web search tools, open source. Link to GitHub and live demo."},{"url": "/getting-started.html", "prompt": "Getting Started page for Rabbithole — an open-source Rust web server (github.com/ajbt200128/rabbithole, live at isarabbithole.com) that dynamically generates entire websites on the fly using LLMs. DESIGN: Plain minimal HTML like gcc.gnu.org. White background (#ffffff), Arial/Helvetica, no gradients, no JS. Blue links (#0000cc), visited purple (#551a8b). Pipe-separated nav: Home | Getting Started | Architecture | Configuration | Web Tools | Deployment | Examples | About. Paths: /, /getting-started.html, /architecture.html, /configuration.html, /web-tools.html, /deployment.html, /examples.html, /about.html. Pre/code: #f4f4f4 bg, 1px solid #ccc. H2 with bottom border. Footer with GitHub link. CONTENT: Step-by-step guide to installing and running Rabbithole. Covers: prerequisites (Rust toolchain, an LLM API key), cloning the repo (github.com/ajbt200128/rabbithole), building with cargo build --release, writing a seed prompt file, running the server with --seed, --model, --port flags, visiting localhost to see the generated site. Include anchor #seed explaining how to write an effective seed prompt. Explain that the seed prompt becomes the homepage and should describe the desired site thoroughly."},{"url": "/architecture.html", "prompt": "Architecture page for Rabbithole — an open-source Rust web server (github.com/ajbt200128/rabbithole, live at isarabbithole.com) that dynamically generates entire websites on the fly using LLMs. DESIGN: Plain minimal HTML like gcc.gnu.org. White background (#ffffff), Arial/Helvetica, no gradients, no JS. Blue links (#0000cc), visited purple (#551a8b). Pipe-separated nav: Home | Getting Started | Architecture | Configuration | Web Tools | Deployment | Examples | About. Paths: /, /getting-started.html, /architecture.html, /configuration.html, /web-tools.html, /deployment.html, /examples.html, /about.html. Pre/code: #f4f4f4 bg, 1px solid #ccc. H2 with bottom border. Footer with GitHub link. CONTENT: Deep dive into how Rabbithole works internally. Cover: the request lifecycle (HTTP request → DB lookup → LLM call → parse HTML + MAPPINGS → store in SQLite → serve response), the SQLite schema (pages table: url, html, depth, created_at; mappings table: url, prompt, depth), the ---MAPPINGS--- output format (JSON array of {url, prompt} objects appended after ), how the depth counter works, how caching is permanent (no TTL), how the LLM is prompted with the child page prompt in isolation with no shared memory. ASCII diagram welcome."},{"url": "/web-tools.html", "prompt": "Web Tools page for Rabbithole — an open-source Rust web server (github.com/ajbt200128/rabbithole, live at isarabbithole.com) that dynamically generates entire websites on the fly using LLMs. DESIGN: Plain minimal HTML like gcc.gnu.org. White background (#ffffff), Arial/Helvetica, no gradients, no JS. Blue links (#0000cc), visited purple (#551a8b). Pipe-separated nav: Home | Getting Started | Architecture | Configuration | Web Tools | Deployment | Examples | About. Paths: /, /getting-started.html, /architecture.html, /configuration.html, /web-tools.html, /deployment.html, /examples.html, /about.html. Pre/code: #f4f4f4 bg, 1px solid #ccc. H2 with bottom border. Footer with GitHub link. CONTENT: Explain the optional --web-tools flag. When enabled, the LLM is given two tool-use functions during page generation: web_search (searches the internet and returns results) and web_fetch (fetches the text content of a URL). This allows generated pages to contain real, current information — e.g. actual documentation, current news, real product specs. Discuss tradeoffs: richer content vs. increased latency and token cost. Show example of a page that benefits from web tools (a news site, a documentation mirror, etc.). Note that isarabbithole.com runs with web tools enabled."},{"url": "/deployment.html", "prompt": "Deployment page for Rabbithole — an open-source Rust web server (github.com/ajbt200128/rabbithole, live at isarabbithole.com) that dynamically generates entire websites on the fly using LLMs. DESIGN: Plain minimal HTML like gcc.gnu.org. White background (#ffffff), Arial/Helvetica, no gradients, no JS. Blue links (#0000cc), visited purple (#551a8b). Pipe-separated nav: Home | Getting Started | Architecture | Configuration | Web Tools | Deployment | Examples | About. Paths: /, /getting-started.html, /architecture.html, /configuration.html, /web-tools.html, /deployment.html, /examples.html, /about.html. Pre/code: #f4f4f4 bg, 1px solid #ccc. H2 with bottom border. Footer with GitHub link. CONTENT: Guide to running Rabbithole in production. Cover: running behind nginx as a reverse proxy (config snippet), setting up as a systemd service (unit file example), using environment variables for API keys securely, considerations for the SQLite database (file permissions, backups), notes on latency (first visit generates, subsequent visits are cached and instant), rate limiting considerations, optional Docker usage. Note that isarabbithole.com is the live reference deployment."},{"url": "/examples.html", "prompt": "Examples page for Rabbithole — an open-source Rust web server (github.com/ajbt200128/rabbithole, live at isarabbithole.com) that dynamically generates entire websites on the fly using LLMs. DESIGN: Plain minimal HTML like gcc.gnu.org. White background (#ffffff), Arial/Helvetica, no gradients, no JS. Blue links (#0000cc), visited purple (#551a8b). Pipe-separated nav: Home | Getting Started | Architecture | Configuration | Web Tools | Deployment | Examples | About. Paths: /, /getting-started.html, /architecture.html, /configuration.html, /web-tools.html, /deployment.html, /examples.html, /about.html. Pre/code: #f4f4f4 bg, 1px solid #ccc. H2 with bottom border. Footer with GitHub link. CONTENT: Showcase of example seed prompts and the kinds of sites they produce. Include 4-6 diverse examples: a personal wiki, a fictional world encyclopedia, a retro-style software documentation site, a news aggregator (using web tools), a recipe site, a sci-fi universe lore site. For each, show the seed prompt text and describe what the resulting site looks like. Emphasize how the prompt controls everything: design, content, tone, navigation structure."},{"url": "/about.html", "prompt": "About page for Rabbithole — an open-source Rust web server (github.com/ajbt200128/rabbithole, live at isarabbithole.com) that dynamically generates entire websites on the fly using LLMs. DESIGN: Plain minimal HTML like gcc.gnu.org. White background (#ffffff), Arial/Helvetica, no gradients, no JS. Blue links (#0000cc), visited purple (#551a8b). Pipe-separated nav: Home | Getting Started | Architecture | Configuration | Web Tools | Deployment | Examples | About. Paths: /, /getting-started.html, /architecture.html, /configuration.html, /web-tools.html, /deployment.html, /examples.html, /about.html. Pre/code: #f4f4f4 bg, 1px solid #ccc. H2 with bottom border. Footer with GitHub link. CONTENT: About Rabbithole. Describe the project: built in Rust, open source on GitHub at github.com/ajbt200128/rabbithole, created by ajbt200128. The live demo runs at isarabbithole.com. Explain the motivation: what if any URL could be a real webpage, generated on demand? Discuss the recursive/fractal nature of the site (this very page was generated by Rabbithole). Include links to GitHub issues, contributing, and license info. Mention that the project name comes from the idea of falling down a rabbit hole of generated content."}]