CLI-first personal knowledge base for AI agents — structured, navigable, zero extra cost
Project description
kvault
Persistent, structured memory for AI agents — plain Markdown, a CLI, zero services.
pip install knowledgevault
Your agent creates nodes (people, projects, notes), keeps every parent summary a rollup of what's below, and orients itself with one cheap command:
$ kvault tree
. « Knowledge Base » [3 children, 11 total] ~2026-06-07
notes [1 children, 1 total] ~2026-04-11
reading_list ~2026-04-11
people [2 children, 5 total] ~2026-06-02
contacts [2 children, 2 total] ~2026-06-02
mike_torres ~2026-01-20
sarah_chen ~2026-06-02
friends [1 children, 1 total] ~2026-03-14
alex_rivera ~2026-03-14
projects [2 children, 2 total] ~2026-06-07
launch_plan « Launch Plan — v2 » ~2026-06-07
website_redesign ~2026-05-28
One outline line per node: title, size, and most-recent activity — about 15 tokens each, so a
several-hundred-node KB orients an agent for a few thousand tokens. Anything pruned by
--depth or --max-children is called out in place (…74 nodes below), so a partial view
can never silently hide content.
Built for developers using AI coding tools who want their agent to remember things between sessions — contacts, projects, meeting notes, research — in a structured, navigable format. kvault needs no API keys, no hosted service, no database: any agent that can run shell commands can use it.
How it works
- A node is a directory containing a single
_summary.md— YAML frontmatter plus Markdown. Leaf nodes are entities (a person, a project); parent nodes summarize their descendants. - Parent summaries are the index. Every level is a comprehensive rollup of the subtree below it, written by the agent itself. Navigation is top-down reading, not blind grepping.
- Writes propagate.
kvault writereturns the full ancestor chain so the agent rewrites those summaries in one follow-up call — the "2-call write workflow." - The KB instructs the agent.
kvault initgenerates anAGENTS.mdwith the workflow, the rules (search before create, never fabricate, propagate everything), and a periodic maintenance playbook.
Quickstart (30 seconds)
pip install knowledgevault
kvault init ./my_kb --name "Your Name"
Then tell your agent:
"Use kvault CLI commands to manage my knowledge base at ./my_kb"
The agent reads the generated AGENTS.md and starts working.
| Tool | Setup |
|---|---|
| Project-instruction agents | Keep AGENTS.md in the KB root so the agent reads the workflow automatically |
| Terminal agents | Tell the agent: "Read AGENTS.md for the kvault workflow, then use shell commands to manage ./my_kb" |
| Custom-instruction agents | Paste the generated AGENTS.md workflow into the workspace or system instructions |
Agent skill included. skills/kvault/SKILL.md
carries the full workflow in the portable SKILL.md agent-skills format, so the agent loads
it on demand from any directory — no per-KB setup. Install it wherever your tool discovers
skills:
# Claude Code
cp -r skills/kvault ~/.claude/skills/kvault
# OpenClaw (per workspace)
cp -r skills/kvault ~/.openclaw/workspace/skills/kvault
# Other agents: copy into your tool's skills directory, or paste the
# SKILL.md body into its custom instructions
Already have data? Point your agent at an export from a chat, email, or notes tool — see docs/importing-data.md.
The 2-call write workflow
# Call 1: write the node (stdin = frontmatter + markdown body)
kvault write people/contacts/sarah_chen --create --reasoning "Met at NeurIPS" --json --kb-root ./my_kb <<'EOF'
---
source: manual
aliases: [Sarah Chen, sarah@example.com]
---
# Sarah Chen
Research scientist at Acme AI...
EOF
# → {"success": true, "ancestors": [{path, current_content}, ...], "journal_logged": true}
# Call 2: the agent rewrites the returned ancestors, including root
kvault update-summaries --json --kb-root ./my_kb <<'EOF'
[
{"path": "people/contacts", "content": "# Contacts\n...updated..."},
{"path": "people", "content": "# People\n...updated..."},
{"path": ".", "content": "# Knowledge Base\n...updated..."}
]
EOF
Required frontmatter: source, aliases — kvault stamps created/updated automatically
(and preserves them on no-op rewrites, so the recency signal in the tree stays honest).
The maintenance loop
KBs rot without pruning. The tree annotations make refactor triggers deterministic instead of aspirational — agents read them off the orientation pass:
| Signal | Action |
|---|---|
Branch with >10 children ([N children, ...]) |
Split into subgroups; kvault move entities; re-propagate |
Branch ~updated_max older than ~6 months |
Review for stale or dead content |
SUMMARY: warnings from kvault check |
Rewrite flagged parents as comprehensive rollups |
| Near-duplicate titles or aliases | Verify identifiers, merge, delete the duplicate |
kvault check also catches stale propagation, and works as a pre-prompt hook:
{
"hooks": {
"UserPromptSubmit": [
{"type": "command", "command": "kvault check --kb-root /absolute/path/to/my_kb"}
]
}
}
CLI reference
| Category | Commands |
|---|---|
| Orient & discover | kvault tree [path] [--depth N] [--max-children N] [--gist], kvault search "<query>" |
| Nodes | kvault read, kvault write (stdin), kvault list, kvault delete, kvault move |
| Summaries | kvault read-summary, kvault write-summary (stdin), kvault update-summaries (stdin JSON), kvault ancestors |
| Quality | kvault validate, kvault check |
| Journal & artifacts | kvault journal, kvault artifact daily, kvault log summary |
| Lifecycle | kvault init, kvault status |
Agent-facing commands accept --json for machine-readable output and --kb-root
(auto-detected from cwd by default), before or after the subcommand.
MCP server (optional)
The CLI is the primary interface. For MCP-native clients, a stdio compatibility server ships
with the [mcp] extra (Python 3.10+), bound to one KB root per process:
pip install "knowledgevault[mcp]"
kvault-mcp --kb-root /absolute/path/to/my_kb
{
"mcpServers": {
"kvault": {
"command": "kvault-mcp",
"args": ["--kb-root", "/absolute/path/to/my_kb"]
}
}
}
It exposes the same operations as the CLI (kvault_tree, kvault_search,
kvault_read_node, kvault_write_node, summary/journal/validation tools), plus a strict
parent-summary workflow with stale-write detection. Set KVAULT_ALLOWED_ROOTS to pin
allowed roots on shared runtimes. Protocol details:
ARCHITECTURE.md.
It's just files
kvault produces Markdown with YAML frontmatter in a plain directory. No proprietary format, no database to export from. Your existing tools work out of the box:
| Want to... | Use |
|---|---|
| Semantic search | Embed the .md files with any vector tool |
| Exact text search | rg -n "phrase" ./my_kb |
| Visual browsing | Open the KB directory in Obsidian or Logseq |
| Publish as a site | Point Hugo, Jekyll, or Astro at the directory |
| CI validation | Run kvault validate or kvault check in a GitHub Action |
| Bulk export | find . -name _summary.md + yq over the frontmatter |
Python API
from pathlib import Path
from kvault.core import operations as ops
kg_root = Path("my_kb")
outline = ops.build_outline(kg_root, depth=2) # annotated tree as nested dict
node = ops.read_node(kg_root, "people/contacts/sarah_chen")
result = ops.write_node(kg_root, "people/contacts/new_person", "# Content", create=True)
matches = ops.search_nodes(kg_root, "sarah follow up")
Development
pip install -e ".[dev,mcp]"
pytest -q
ruff check .
black --check kvault/ tests/
mypy kvault/ --ignore-missing-imports
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file knowledgevault-0.11.3.tar.gz.
File metadata
- Download URL: knowledgevault-0.11.3.tar.gz
- Upload date:
- Size: 76.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
43c013a06fe296a26bb2ba7a2cb4ae011cb7d05ed5680a0e8873c03de5c95998
|
|
| MD5 |
618afeecca41185422a05c37038e9b49
|
|
| BLAKE2b-256 |
727b1ca933df34ab0b2bb0ad8ac5fdbe121b25a9bd934c5dff9e3493a39e5d13
|
Provenance
The following attestation bundles were made for knowledgevault-0.11.3.tar.gz:
Publisher:
publish.yml on cimo-labs/kvault
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knowledgevault-0.11.3.tar.gz -
Subject digest:
43c013a06fe296a26bb2ba7a2cb4ae011cb7d05ed5680a0e8873c03de5c95998 - Sigstore transparency entry: 1819983753
- Sigstore integration time:
-
Permalink:
cimo-labs/kvault@55dac78ed169b2b84f1f93216007d92e3f46d69b -
Branch / Tag:
refs/tags/v0.11.3 - Owner: https://github.com/cimo-labs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@55dac78ed169b2b84f1f93216007d92e3f46d69b -
Trigger Event:
push
-
Statement type:
File details
Details for the file knowledgevault-0.11.3-py3-none-any.whl.
File metadata
- Download URL: knowledgevault-0.11.3-py3-none-any.whl
- Upload date:
- Size: 63.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
607fab8d7b351659e00efce4552be644bbe3d5a703f3e96297be7f221c350759
|
|
| MD5 |
af876aeb875b473efdc66285de4562b8
|
|
| BLAKE2b-256 |
b837fdff4ad462f63a1f2b706816a56bfebbf23b221428784923c74fb770b1ec
|
Provenance
The following attestation bundles were made for knowledgevault-0.11.3-py3-none-any.whl:
Publisher:
publish.yml on cimo-labs/kvault
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knowledgevault-0.11.3-py3-none-any.whl -
Subject digest:
607fab8d7b351659e00efce4552be644bbe3d5a703f3e96297be7f221c350759 - Sigstore transparency entry: 1819983787
- Sigstore integration time:
-
Permalink:
cimo-labs/kvault@55dac78ed169b2b84f1f93216007d92e3f46d69b -
Branch / Tag:
refs/tags/v0.11.3 - Owner: https://github.com/cimo-labs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@55dac78ed169b2b84f1f93216007d92e3f46d69b -
Trigger Event:
push
-
Statement type: