Getting started with inkentry

Install inkentry, understand an unfamiliar codebase in the first five minutes, then add memory, agents, and team sharing as you need them. No API keys or servers required to start.

inkentry is a single binary that helps you understand an unfamiliar codebase fast: trace how a symbol connects across files, find the code behind a concept, and assemble the context around a change, all from the CLI with nothing to set up. As you keep working, it also records the decisions behind the code, so a later session (yours or a teammate's) does not re-derive them.

Where grep and code search tell you where a thing is, inkentry is built to tell you why it was decided. On a fresh repo there is no memory yet, so the first retrieval delivers fast code understanding; the why-layer fills in as you record decisions and, later, as an agent captures them for you.

Read this page in order the first time. Reach for the CLI reference and config reference for lookup afterwards.


Install

Install script (macOS and Linux) - recommended

Detects your OS and architecture, resolves the latest release, and installs both inkentry and inkentry-server to your $PATH:

curl -fsSL https://get.inkentry.com/install.sh | sh
inkentry --version

Windows (PowerShell)

The script downloads the latest release and installs inkentry.exe and inkentry-server.exe under %LOCALAPPDATA%\Programs\inkentry, adding it to your user PATH:

iex ((New-Object Net.WebClient).DownloadString('https://get.inkentry.com/install.ps1'))
inkentry --version

Scoop, Debian and 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. search and graph need no index and no server, so you can start here before configuring anything:

# 1. Find the code behind a concept - works with any phrase, no index needed
inkentry search "error handling"

# 2. Take an exact symbol name from those results and trace how it connects.
#    graph matches a real identifier, not a phrase - swap in one of your own.
inkentry graph <SymbolName>

Start with search: it takes any concept or keyword, so it works on a repo you have never opened before. inkentry search with no --mode runs in auto mode - it uses semantic search when a server is available and otherwise degrades to a live structural (ast-grep) scan, so it returns results with nothing indexed and never errors on a fresh repo.

inkentry graph is the natural next step, but it resolves an exact symbol name rather than a concept phrase, so feed it an identifier you just saw in your search results - a function, type, or method name - not a keyword. It runs the same live scan and likewise needs no index or server.

Full-text search (--mode text), memory, and inkentry context operate on a local project. Create one with inkentry init (next section); in a directory with no .inkentry/ project they fail closed with a no inkentry project here error rather than falling back to a machine-global store.


Semantic search - built in, no setup required

cd /path/to/your/project
inkentry init

That is the whole setup. inkentry init registers the project, parses and chunks every source file, starts the bundled inkentry-server in the background when run interactively (if one is not already running), and embeds your code so semantic search works out of the box.

The server bundles a native embedding model (codefuse-ai/F2LLM-v2-330M, an 896-dimension Q8_0 GGUF run through the candle runtime; it uses Metal or the GPU on macOS and the CPU elsewhere). The weights (~339 MB) download once on first use and are cached under your platform's local data directory, in an inkentry/models subfolder. There is no LM Studio, Ollama, or other external inference server to run by default.

init also writes .inkentry/.gitignore so the machine-specific SQLite files (index.db*, memory.db*) stay out of version control, while leaving .inkentry/config.toml tracked so it can be committed and shared. An existing .inkentry/.gitignore is never overwritten, so re-running init is safe.

Output looks like:

inkentry initialised for my-project

  Index:   142 files, 1840 chunks
  DB:      /path/to/my-project/.inkentry/index.db
  Project: my-project  (written to .inkentry/config.toml)
  Hook:    not installed  (run `inkentry hooks install` to add)
  Server:  http://127.0.0.1:7777  ✓  (auto-started)
  Memory:  configured notes fetch refspec on 'origin' (teammates' memory arrives on fetch)
           your memory stays local until you install the pre-push hook: inkentry hooks install --pre-push
           configured notes.rewriteRef (memory survives `git commit --amend` and `git rebase`)

Next steps:
  inkentry search "your query"
  inkentry context

The embed pass is handed to a background worker, so init returns before it finishes and prints no vector count; check progress later with inkentry status. The Memory: block appears only inside a git repository with an origin remote; outside one, init prints the reason it skipped and the command to configure it by hand.

Manage the background server

inkentry server start     # start the local daemon (idempotent; auto-binds 127.0.0.1)
inkentry server status    # PID, port, instance id, uptime
inkentry server logs      # last 50 lines of the server log
inkentry server stop      # stop the daemon

In non-interactive contexts (CI, agent harnesses) inkentry init does not auto-spawn the server. Run inkentry server start first if you want semantic search there, or set INKENTRY_NO_SERVER=1 to stay fully offline.

Troubleshooting: semantic search is not working

If inkentry search returns only text matches, the background server probably is not reachable and every command has fallen back to offline (text-only) search. Check the current tier:

inkentry server status    # is it running, and on what port?
inkentry status           # index statistics for the project
inkentry server logs      # last 50 lines of the server log

Windows: the first time inkentry-server starts, Windows Defender Firewall may prompt to allow it. Accept the prompt. If it was dismissed, the server is blocked on its loopback port, and every command silently falls back to offline search. Allow inkentry-server through the firewall, then re-run inkentry index ..

First run is slow: the embedding model (~339 MB) downloads once on first use. Give the server a moment to become healthy before you search, and watch progress with inkentry server logs.

Even when semantic search is unavailable, plain inkentry search "..." (no --mode) still returns results: it falls back to a live ast-grep scan that needs no server and no index. (--mode text is the one mode that needs a prebuilt full-text index, so run inkentry index . first if you want it.)

# Find code by meaning
inkentry search "error handling in the HTTP layer"

# Hybrid search (semantic + full-text)
inkentry search "authentication" --mode hybrid

# With call-graph enrichment
inkentry search "authentication" --graph

# Fit results within a token budget
inkentry search "database layer" --budget 4000

Check index health at any time:

inkentry status          # index statistics, including an "Embedding in progress" line while the embed pass runs

Search and memory together

With your project indexed, code search and memory work together: search answers how and where, memory answers why.

# Record a decision as you make it
inkentry memory add --kind decision \
  --title "Chose token bucket for rate limiting" \
  --body "Simpler than sliding window; sufficient for low RPS"

# Read your decisions back
inkentry memory list --kind decision

# Find code by text (uses the full-text index inkentry init built)
inkentry search "handleRequest" --mode text

# Trace a symbol's call graph
inkentry graph Database --kind calls

# Search memory for the reasoning behind the code
inkentry memory search "why did we choose this"

# JSON output for agents
AGENT=true inkentry memory list --kind decision

Memory is stored in the project's local .inkentry/memory.db and, by default, mirrored to git notes so it travels with the repository. Passed together to a reasoning model, code and memory give a complete picture.


Configure your agent

This is where the payoff lands. If you code with an AI agent, you connect it to inkentry once and the why-layer starts filling itself: as the agent works, the reasoning behind each change is captured for you, with no time set aside to sit down and write it up. Every later inkentry context or inkentry search then hands those decisions back.

The mechanism is the agent itself. Wired to inkentry through a skill (the Claude Code skill, or a drop-in AGENT.md), it records each decision as it makes it, so the why-layer accrues as a by-product of the work. A git hook complements this: a post-commit step runs inkentry harvest to catch any reasoning left in commit messages, so nothing slips through.

Install the git hook once:

inkentry hooks install

Other developers without inkentry installed are unaffected: the hook is a no-op when inkentry is not on PATH. Remove it at any time:

inkentry hooks uninstall

At the start of a session, pull all prior context in one command:

# Start-of-session context - decisions, requirements, questions, handoffs
inkentry context

# JSON for machine processing
AGENT=true inkentry context

See the memory guide for how decisions, requirements, and handoffs are stored and retrieved.


Capability tiers: where inference and memory live

inkentry works at several capability tiers, and the team-memory tier can be a server you host yourself or the managed inkentry cloud (both are shown as rows below). You do not pick a tier by hand; inkentry uses the best one available and degrades cleanly when a server is not reachable. The load-bearing distinction is that a local server does inference only and never stores memory. Your memory always lives in the project's local memory.db until you explicitly configure a team server or subscribe to inkentry cloud.

TierWhat runs itWhat it addsWhere memory lives
Built-in (zero infra)just the inkentry binarygit-notes memory, full-text and ast-grep search, code graphlocal memory.db
Local semantic servera loopback inkentry-server, auto-started on demandsemantic and hybrid search, LLM summariesstill local memory.db: the server is inference only, never a memory store
Team memory servera shared inkentry-server you deploy, set via an explicit server_urlone shared memory index for the teamthe shared server you run: memory leaves your machine, your code stays local
inkentry cloud (hosted)a managed service: nothing to deploy or maintainthe same shared-team memory as a self-hosted server, without running onethe hosted service: memory leaves your machine, your code stays local

The local semantic server is auto-discovered on loopback (127.0.0.1) and started for you the first time a command needs it. It embeds queries and runs LLM calls, but a project's memory stays in memory.db regardless of whether it is running. Memory moves off the local machine only when you point at a team server: a self-hosted one via an explicit server_url, or the hosted inkentry cloud (see Share memory across a team below). Either way, each developer's code still stays local.

To stay fully offline (CI, air-gapped, or you just do not want a background process), set INKENTRY_NO_SERVER=1: inkentry then runs built-in only, and inference-only commands exit with a clear message instead of starting anything.


Share memory across a team

Working with a team? Point everyone at a shared inkentry-server so they share decisions, requirements, and context instead of siloing them locally. This is a different server from the local one inkentry auto-starts for inference: it is a long-lived, deployed instance with an API key. Each developer's code stays local; only memory travels to the server.

If you don't already have a team server running, see the server setup guide for how to deploy one, or use the hosted inkentry cloud instead of running your own. Once you have a server URL and an API key:

Add .inkentry/config.toml at your repo root and commit it (it holds no secrets):

# .inkentry/config.toml - commit this
server_url = "https://inkentry.internal.example.com"
project_id = "my-awesome-app"

server_url must be https:// unless it points at loopback (127.0.0.1, ::1, or localhost). A non-loopback http:// URL is rejected at startup, with no opt-out, because the CLI attaches your bearer token to these requests. See the server setup guide for putting TLS in front of a deployed server.

Each developer provides their own API key. Set it with inkentry auth set-key --server <url>, which stores the key in your OS keychain (macOS Keychain, Linux Secret Service, Windows Credential Manager) rather than in plaintext, keyed by the server's origin. For CI or headless use, the INKENTRY_SERVER_KEY environment variable works everywhere and takes precedence:

export INKENTRY_SERVER_KEY="your-shared-api-key"

Seed the server with your existing local memory, then keep recording decisions as usual:

inkentry plumbing push   # one-way: seed the server with your existing local entries
inkentry sync            # force a synchronous two-way reconcile (usually not needed; see below)

In the default local_first mode you rarely run inkentry sync by hand. Your writes commit to the local memory.db immediately and never block on the network; from an interactive terminal a background reconciler then drains what you recorded up to the server and pulls teammates' entries down, so the shared memory converges on its own. inkentry sync is the explicit escape hatch for when you want that reconcile to happen synchronously now rather than in the background, such as a CI job that needs entries pushed before it exits. Code never travels; only memory does.

If you would rather not run a server yourself, the hosted inkentry cloud service is the managed alternative for teams. Setup and deployment details for the self-hosted server are in the server setup guide.


What's next

On this page