Getting started with spelunk
Install spelunk, run your first commands, and add memory, search, and team sharing as you need them. No API keys or servers required to start.
spelunk gives AI coding agents persistent memory, a code graph, and search — straight from the CLI. No API keys or servers required to start.
Install
Install script (macOS and Linux) — recommended
Detects your OS/arch and installs both spelunk and spelunk-server to your $PATH:
curl -fsSL https://raw.githubusercontent.com/spelunk-cloud/spelunk/refs/heads/main/install.sh | sh
spelunk --versionHomebrew (macOS and Linux)
brew install spelunk-cloud/spelunk/spelunk
spelunk --versionDebian/Ubuntu .deb packages, manual tarballs, and build-from-source
instructions are on the
releases page.
First commands — no setup needed
Open a terminal inside any git repository. Nothing to configure.
# Trace callers and callees for any symbol
spelunk graph validate_token
# Full-text search (no embedding server required)
spelunk search "error handling" --mode text
# Store a decision
spelunk memory add --kind decision \
--title "Chose token bucket for rate limiting" \
--body "Simpler than sliding window; sufficient for <1k RPS"
# Read it back
spelunk memory list --kind decisionMemory is stored in git notes — no database, no server, no setup. It travels with the repo.
Search and memory together
# Find code by text
spelunk search "handleRequest" --mode text
# Trace a symbol's call graph
spelunk graph Database --kind calls
# Search memory for context
spelunk memory search "why did we choose this"
# JSON output for agents
AGENT=true spelunk memory list --kind decisionAuto-harvest memory from commits
Install a git post-commit hook so spelunk captures context on every commit:
spelunk hooks installOther developers without spelunk installed are not affected — the hook checks for the binary first. Remove it at any time:
spelunk hooks uninstallSemantic search — built in, no setup required
cd /path/to/your/project
spelunk initThat's the whole setup. spelunk init registers the project, parses and chunks
every source file, starts the bundled spelunk-server in the background (if
one isn't already running), and embeds your code so semantic search works out
of the box. The server bundles a native embedding model (Nomic Embed Text
v1.5, via fastembed-rs); the weights download once on first use and are cached
under ~/.local/share/spelunk/models/. There's no LM Studio, Ollama, or other
external inference server to run by default.
Output looks like:
spelunk initialised for my-project
Index: 142 files, 1 840 chunks
DB: ~/.local/share/spelunk/my-project.db
Embeddings: 1 840 vectorsManage the background server
spelunk server start # start the local daemon (idempotent; auto-binds 127.0.0.1)
spelunk server status # PID, port, instance id, uptime
spelunk server logs # last 50 lines of the server log
spelunk server stop # stop the daemonIn non-interactive contexts (CI, agent harnesses) spelunk init does not
auto-spawn the server — run spelunk server start first if you want semantic
search there, or set SPELUNK_NO_SERVER=1 to stay fully offline.
Semantic search
# Find code by meaning
spelunk search "error handling in the HTTP layer"
# Hybrid search (semantic + full-text, default)
spelunk search "authentication" --mode hybrid
# With call-graph enrichment
spelunk search "authentication" --graph
# Fit results within a token budget
spelunk search "database layer" --budget 4000Check index health at any time:
spelunk status # index statistics
spelunk check # exits 1 if the index is staleUsing your own inference server (advanced)
By default the bundled spelunk-server provides embeddings (native, via
fastembed-rs). If you'd rather point spelunk at your own OpenAI-compatible
endpoint (LM Studio, Ollama, vLLM) instead of the native embedder, set it in
~/.config/spelunk/config.toml:
# OpenAI-compatible endpoint (default: http://127.0.0.1:1234)
api_base_url = "http://127.0.0.1:1234"
# Must match your endpoint's model identifier
embedding_model = "text-embedding-embeddinggemma-300m-qat"
# Embedding batch size — lower if you run out of memory
batch_size = 32Re-run spelunk init (or spelunk index . --force to re-embed unchanged
files) afterwards so embeddings are generated through your endpoint.
Share memory across a team (optional)
By default each developer's memory is local. Run spelunk-server to share decisions and context across the team without sharing code. See the server setup guide for Docker instructions, API key setup, and production notes.
Quick config: add a .spelunk/config.toml at your repo root and commit it:
# .spelunk/config.toml — safe to commit, contains no secrets
server_url = "http://spelunk.internal:7777"
project_id = "my-awesome-app"Each developer adds their key to their personal config (never commit this):
# ~/.config/spelunk/config.toml
server_key = "shared-team-key"The older
memory_server_url/memory_server_keykeys are still accepted as deprecated aliases forserver_url/server_key.
Push any existing local entries to the server:
spelunk memory pushWhat's next
- CLI reference — every command, flag, and environment variable
- Memory guide — kinds, supersede chains, harvesting from git history
- Server setup — self-host spelunk-server for your team
- Config reference — all config fields in one place
- GitHub — source, issues, releases