tapper
tapper is a CLI for building knowledge systems with KEGs (Knowledge Exchange
Graphs), including personal knowledge management and agent memory workflows across
domains.
Primary entrypoint:
tap for the full CLI surface
Optional secondary entrypoint:
keg as a pruned, project-focused profile built from the same command system
Problem This Solves
As notes grow across projects, domains, and tools, context gets fragmented:
- important details are buried in disconnected files
- links between ideas, plans, patches, releases, and people are hard to track
- humans and agents cannot reliably reuse the same memory and structure
tapper solves this by storing notes as linked KEG nodes with structured metadata,
predictable config resolution, and CLI workflows for creating, navigating, and
maintaining shared memory.
Installation
Homebrew (macOS and Linux)
brew install jlrickert/formulae/tapper
Optional: install the pruned project-local binary too:
brew install jlrickert/formulae/keg
Shell completions for zsh, bash, and fish are installed automatically.
From source
Prerequisite: Go 1.26.0 or newer.
go install github.com/jlrickert/tapper/cmd/tap@latest
go install github.com/jlrickert/tapper/cmd/keg@latest
If needed, add your Go bin directory to PATH:
export PATH="$(go env GOPATH)/bin:$PATH"
Set up shell completions manually:
# zsh (persist)
tap completion zsh > "${fpath[1]}/_tap"
Precompiled binaries
Download from GitHub Releases.
Verify installation:
tap --help
Quick Start
Create your first keg and start taking notes in under a minute.
1. Initialize a keg
tap init --keg personal --user
Creates a keg under your first kegSearchPaths entry — or under the
platform user-data directory if no kegSearchPaths is configured — and
registers the alias in your user config.
Tip: run tap repo config edit first if you want to set fallbackKeg
(so later commands don't need --keg) or customize kegSearchPaths.
Without configuration, tapper picks sensible platform defaults.
2. Create a node
tap create --keg personal
Opens your editor with a frontmatter template. Write your note, save, and
close. Set fallbackKeg in user config to skip the --keg flag on later
commands.
3. View and edit a node
tap cat 1 --keg personal
On a terminal this opens the node in your editor for viewing and editing.
4. List all nodes
tap list --keg personal
5. Search
tap grep "first" --keg personal
That's it — you have a working knowledge base. See More Examples
for snapshots, archives, and automation workflows.
Using With AI Agents
Tapper ships integration bundles for Claude Code and Codex. Pick the one-command
install that matches your agent. For advanced setups — manual MCP registration,
JSON config for other hosts, per-tool keg targeting — see
MCP Server Setup.
Claude Code
claude plugin marketplace add jlrickert/tapper@main
claude plugin install tapper@jlrickert-tapper
claude plugin marketplace add resolves a bare owner/repo against the
repository's GitHub default branch, which for tapper is dev (development
surface). Pin with @main — main always equals the most recent tagged
release. See Branching Model. The @jlrickert-tapper
argument on the install line is a marketplace name, not a git ref — it
is unaffected by this pin.
Installs tapper as a Claude Code plugin: the MCP server registration, the
bundled /tapper skill, and the orientation prompts in one step. Verify with
claude /mcp — tapper should appear in the server list.
Prefer a local install without the marketplace? tap integrate claude writes
the same plugin tree to ~/.claude/plugins/tapper/; preview target paths
first with --dry-run.
Codex
tap integrate codex
Writes ~/.codex/AGENTS.md, saved prompts under ~/.codex/prompts/, and
~/.codex/config-snippet.toml. Merge the config snippet into your
~/.codex/config.toml to register the MCP server.
Both install paths expose the full KEG tool surface over MCP — read, write,
search, index, snapshot, lock — plus a tiered orient tool that lets an agent
bootstrap against any keg in a bounded token budget. See
Using Tapper From AI Agents for the full
reference.
More Examples
Target a specific keg from any command:
tap --keg personal list
tap --path ~/Documents/kegs/pub snapshot history 12
Initialize a project-local keg:
tap init --keg tapper --project
Create and inspect node history:
tap snapshot create 12 --keg personal -m "before refactor"
tap snapshot history 12 --keg personal
Export and import a keg archive:
tap archive export --keg personal -o notes.keg.tar.gz
tap archive import notes.keg.tar.gz --keg personal
Archive import overwrites matching node IDs in the target keg instead of
allocating new node IDs. Snapshot history is included by default; use
--no-history to export only the current node state.
The keg binary provides the same commands with project-local defaults:
keg snapshot create 12 -m "before refactor"
keg archive export -o notes.keg.tar.gz
Automation and scripting
Commands accept piped stdin for non-interactive use:
echo "Automated note" | tap create --keg personal
tap cat 1 --keg personal --content-only
When stdin is piped, no editor is launched. Use --content-only,
--stats-only, or --meta-only with tap cat to get machine-readable
output.
Configuration Quick Map
- User config:
~/.config/tapper/config.yaml
- Project config:
.tapper/config.yaml
- Keg config:
<keg-root>/keg
Documentation
Project docs live under docs/:
Config Precedence At A Glance
When no explicit keg target is provided, tapper resolves in this order:
defaultKeg
kegMap path match (pathRegex first, then longest pathPrefix)
fallbackKeg
Alias lookup then prefers explicit kegs entries, then discovered aliases from
kegSearchPaths, then project-local alias fallback at ./kegs/<alias>.
Troubleshooting
For common errors such as no keg configured, keg alias not found, and discovery path
issues, see docs/configuration/troubleshooting.md.
Branching Model
This repo uses a dev (development) + main (release-only) split:
dev — default branch. All development commits and PRs target dev. CI runs on
pushes and PRs against dev.
main — release-only. Advances only when the Release workflow runs; main HEAD
always equals a tagged release.
To contribute, branch off dev and open PRs against dev. Releases are cut by
dispatching the Release workflow, which opens a
short-lived release/$VERSION PR into main, merges it via rebase, tags the
commit, and runs goreleaser. Direct pushes to main are blocked by a repository
ruleset.
Repository Layout
cmd/tap - tap entrypoint
cmd/keg - keg entrypoint
pkg/tapper - config, resolution, and init services
pkg/keg - KEG primitives and repository implementation
kegs/tapper - repository KEG content
docs/ - end-user documentation