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: find the code behind a concept, trace how a symbol connects across files,
and assemble the context around a change, all from the CLI with no
infrastructure to stand up. Run inkentry init once and the first search and
context already tell you how the code fits together. 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 --versionHomebrew (macOS and Linux)
Installs both binaries from the tap:
brew install inkentries/inkentry/inkentry
inkentry --versionWindows (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 --versionScoop, Debian and Ubuntu .deb packages, manual tarballs, and build-from-source
instructions are on the
releases page.
First commands
Open a terminal inside any git repository and run init once. That one command
is the whole setup: it registers the project, parses and chunks the source tree,
starts the bundled inkentry-server in the background when run interactively (if
one is not already running), and hands the embedding pass to that server — so the
prompt comes back after parsing rather than after the full embed:
cd /path/to/your/project
inkentry init
# 1. Find the code behind a concept — any phrase, not just an identifier
inkentry search "error handling"
# 2. Take an exact symbol name from those results and trace how it connects
inkentry search "<SymbolName>" --graphThe 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 contextThe 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.
Start with search: it takes a concept or a keyword, so it works on a repo you
have never opened before. Full-text results are available the moment init has
parsed the tree; semantic ranking improves them as embeddings land in the
background. --only-text is explicit about wanting the no-server path.
--graph is the natural next step, and it resolves an exact symbol name
rather than a concept phrase — feed it an identifier you just saw in your
results, a function, type or method name.
Every command operates on a local project. 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.
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 daemonIn 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 logWindows: 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.
Full-text results are available as soon as init has parsed the tree, so
inkentry search "..." returns something useful while embeddings are still
building. --only-text asks for that path explicitly and needs no server.
Semantic search
# Find code by meaning
inkentry search "error handling in the HTTP layer"
# Memory only, when you want the decision rather than the code
inkentry search "authentication" --only-memory
# With call-graph enrichment
inkentry search "authentication" --graph
# Fit results within a token budget
inkentry search "database layer" --budget 4000Check index health at any time:
inkentry status # index statistics, including an "Embedding in progress" line while the embed pass runsSearch 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" --only-text
# Trace a symbol's call graph
inkentry search "Database" --graph
# Search memory for the reasoning behind the code
inkentry search "why did we choose this" --only-memory
# JSON output for agents
AGENT=true inkentry memory list --kind decisionMemory 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 installOther 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 uninstallAt 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 contextSee 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 point at inkentry cloud.
| Tier | What runs it | What it adds | Where memory lives |
|---|---|---|---|
| Built-in (zero infra) | just the inkentry binary | git-notes memory, full-text search, code graph | local memory.db |
| Local semantic server | a loopback inkentry-server, auto-started on demand | semantic ranking for search | still local memory.db: the server is inference only, never a memory store |
| Team memory server | a shared inkentry-server you deploy, set via an explicit server_url | one shared memory index for the team | the shared server you run: memory leaves your machine, your code stays local |
| inkentry cloud (hosted) | a managed service: nothing to deploy or maintain | the same shared-team memory as a self-hosted server, without running one | the 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 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, shared instance the whole team reads and writes. Each developer's code stays local; only memory travels.
There are two ways to run it, and a project uses one or the other: the hosted
inkentry cloud, or a self-hosted inkentry-server behind your own
firewall.
inkentry cloud
The hosted option: nothing to deploy, patch, or keep running. Sign in, flip one switch, and the team shares memory.
Sign in once per machine (this opens your browser to approve the sign-in):
inkentry loginThen add .inkentry/config.toml at your repo root and commit it (it holds no
secrets):
# .inkentry/config.toml - commit this
cloud = true
project_id = "github.com/my-org/my-awesome-project"cloud = true is the whole switch. There is no URL to set: cloud is a fixed
service and inkentry already knows where it lives. If you belong to more than one
organisation, pin this repo to one with org = "your-org", or switch the active
one with inkentry org switch.
Bring the memory already on your machine up to the cloud, then keep recording decisions as usual:
inkentry sync # reconcile your local memory with the cloudWith cloud, the hosted service is the team's memory home.
Self-hosted team server
Prefer to run the server yourself? Deploy an inkentry-server (see the server
setup guide) and point everyone at it with server_url
instead of cloud:
# .inkentry/config.toml - commit this
server_url = "https://inkentry.internal.example.com"
project_id = "github.com/my-org/my-awesome-project"
server_urlmust behttps://unless it points at loopback (127.0.0.1,::1, orlocalhost). A non-loopbackhttp://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.
cloud and server_url are mutually exclusive: set one or the other, never both.
inkentry stops at startup with an error explaining the conflict if it finds both.
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"Bring your existing local memory up to the server, then keep recording decisions as usual:
inkentry sync # reconcile your local memory with the server (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.
What's next
- Memory guide - kinds, supersede chains, harvesting from git history
- CLI reference - every command, flag, and environment variable
- Config reference - all config fields in one place
- Server setup - self-host inkentry-server for your team
- GitHub - source, issues, releases