npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

kb0-mcp

v0.7.0

Published

The knowledge base layer for AI agents — markdown-first, MCP-native, with permissions and provenance built in.

Readme

kb0

The knowledge base layer for AI agents. Markdown-first, MCP-native, git-backed, with ACL built in.

npm License Tests


Why kb0

Most AI agents write to flat files, SQLite, or ad-hoc vector stores with no history, no permissions, and no way to audit what changed — let alone what was read. kb0 is the missing persistence layer: every note is a markdown file, every write is a git commit, every read and search is logged, and every agent operation goes through a typed MCP interface with optional ACL.

| | kb0 | basic-memory | mcp-obsidian | Mem0 / Letta | Pinecone | |---|---|---|---|---|---| | Markdown files | ✓ | ✓ | ✓ | ✗ | ✗ | | Git-backed history | ✓ | ✗ | ✗ | ✗ | ✗ | | Read & search audit log | ✓ | ✗ | ✗ | ✗ | ✗ | | MCP-native | ✓ | partial | ✓ | ✗ | ✗ | | ACL per agent | ✓ | ✗ | ✗ | ✗ | ✗ | | Hybrid search (FTS5 + vec) | ✓ | ✗ | ✗ | ✓ | ✓ | | No external service | ✓ | ✓ | requires Obsidian | ✗ | ✗ |


Quickstart

npm install -g kb0-mcp
kb0 init my-vault          # a git-backed markdown vault

# Optional: restrict per-agent permissions (permissive by default).
# Create .vault-policy.yaml — see the ACL section below.

That's the whole setup. You don't run a server yourself — with MCP (stdio), whatever connects launches kb0 serve for you: an agent host (config below), or a client like kb0-mcp/client (TypeScript) / kb0-mcp (Python). Pick one:

Claude Desktop — add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "kb0": {
      "command": "kb0",
      "args": ["serve", "--agent", "claude", "--vault", "/absolute/path/to/my-vault"],
      "env": { "OPENAI_API_KEY": "sk-..." }
    }
  }
}

TypeScript — the npm kb0-mcp package ships a typed client at kb0-mcp/client, no extra install:

import { VaultClient } from 'kb0-mcp/client';

const kb = await VaultClient.connect({ vault: './my-vault', agent: 'my-agent' });
await kb.write('notes/auth.md', { title: 'Auth', content: '…', tags: ['auth'] });
const hits = await kb.search('token security', { limit: 5 });
await kb.close();

Hosted vault (kb0 cloud) — point the same client at kb0://<name> with your API key for a vault hosted on our servers — no local files, no subprocess. Same methods, same key as the audit log:

const kb = await VaultClient.connect({
  vault: 'kb0://team-kb',
  agent: 'my-agent',
  apiKey: process.env.KB0_API_KEY, // create one in the kb0 dashboard
});
await kb.write('notes/auth.md', { title: 'Auth', content: '…' });

All tools work on hosted vaults — read/write/update/delete, list/recent, keyword search, and the links/backlinks graph. (Semantic search over hosted vaults is coming; today hosted search is keyword.)

Pythonpip install kb0-mcp for a native async client (kb0-python). Anthropic SDK / OpenAI / LangGraph — see docs/quickstart-sdk.md.


How it works

┌──────────────────────────────────────────────┐
│              Your AI Agent                   │
│  Claude / GPT-4o / LangGraph / custom        │
└──────────────────┬───────────────────────────┘
                   │  MCP protocol (stdio)
┌──────────────────▼───────────────────────────┐
│               kb0 server                     │
│                                              │
│  10 MCP tools                                │
│  ├── KbStore   markdown + git commits        │
│  ├── KbIndex   SQLite + FTS5 + sqlite-vec    │
│  └── KbPolicy  glob-based ACL per agent      │
└──────────────────┬───────────────────────────┘
                   │
┌──────────────────▼───────────────────────────┐
│                 Vault                        │
│                                              │
│  notes/           _inbox/                   │
│  .vault-policy.yaml   .gitignore            │
│  .git/            .vault-index/index.db     │
└──────────────────────────────────────────────┘

Every vault.write or vault.update call:

  1. Validates against ACL policy
  2. Writes the markdown file with frontmatter (author, id, timestamps)
  3. Creates a git commit (full audit trail)
  4. Updates the search index synchronously

MCP Tools

| Tool | What it does | |---|---| | vault.write | Create a new note. Server sets author, id, timestamps — agent cannot forge provenance. | | vault.read | Read a note. Returns content, frontmatter, and SHA-256 hash for optimistic locking. | | vault.update | Update a note. Requires expectedHash to prevent overwriting concurrent edits. | | vault.delete | Delete a note. Recorded in git history. | | vault.search | Hybrid search (FTS5 keyword + semantic via embeddings). Returns ranked results with excerpts. | | vault.list | List notes by prefix, tag, or status. ACL-filtered. | | vault.recent | Most recently updated notes. | | vault.backlinks | Notes that link to a given note via [[wikilinks]]. | | vault.links | Outgoing links from a note. | | vault.status | Vault health: note count, stale embeddings, policy mode, log file. |

All tools return structured errors (NOT_FOUND, CONFLICT, VALIDATION, ACL_DENIED) — never silent failures.


Frontmatter schema

Every note has a validated frontmatter block:

---
id: 550e8400-e29b-41d4-a716-446655440000   # auto-generated UUID
title: "My Note"
author: agent:my-agent                      # always set by server
status: draft                               # draft | reviewed | canonical
tags: [typescript, architecture]
created: 2024-01-01T12:00:00.000Z
updated: 2024-01-01T12:00:00.000Z
---

Note content here. Supports [[wikilinks]] and #tags.

Unknown fields pass through unchanged (extensibility).

Adding notes by hand

You don't have to go through an agent. Drop a plain markdown file into the vault — even with no frontmatter — and kb0 stamps it on the next kb0 reindex (or live, while kb0 serve is running):

echo "# My Idea

Written straight in my editor." > my-vault/notes/idea.md

kb0 reindex

kb0 fills in author: human, a stable id, a title from the first # heading (or the filename), and timestamps from the file. Files you wrote keep their human provenance; agent writes are tagged agent:<name>. The stamp is written to disk but not auto-committed — your manual files stay in your own git workflow.


ACL policy

Create .vault-policy.yaml in your vault root:

version: 1
agents:
  research-agent:
    read: ["**/*"]
    write: ["_inbox/**"]
    update: ["_inbox/**"]
    delete: []
  curator:
    read: ["**/*"]
    write: ["notes/**"]
    update: ["notes/**"]
    delete: ["notes/**"]
# Agents not listed and no 'default' = DENY ALL

Start with --strict to fail if no policy file exists:

kb0 serve --agent my-agent --strict

Configuration

kb0 runs entirely on your machine — it's not a hosted service. The vault is a local folder, and the npm package is the server. There's no account to create and nothing to connect to.

Git — zero config

kb0 uses an embedded git implementation (isomorphic-git), so you don't need git installed and it doesn't touch your personal ~/.gitconfig. Every write is committed under the agent's own identity for provenance:

kb0 init    → author: kb0 <kb0@localhost>
kb0 serve   → author: agent:<name> <[email protected]>

You never configure git. It just works. To see the agent's history, undo a change, or push your vault to GitHub, you use plain git — see Git & history.

Embeddings — one optional env var

Semantic search needs an embedding provider. Without one, kb0 falls back to keyword-only search (everything else works normally).

| Env var | Default | Purpose | |---|---|---| | OPENAI_API_KEY | — | Enables semantic search. Absent = keyword-only. | | KB0_EMBEDDING_MODEL | text-embedding-3-small | Any OpenAI embedding model. | | KB0_EMBEDDING_DIMENSIONS | per-model (1536 / 3072) | Override vector size. | | KB0_OPENAI_BASE_URL | OpenAI | Point at a compatible endpoint (Azure, LiteLLM, Ollama). |

# Default — OpenAI text-embedding-3-small
export OPENAI_API_KEY=sk-...

# Larger model
export KB0_EMBEDDING_MODEL=text-embedding-3-large

# Local Ollama (OpenAI-compatible)
export OPENAI_API_KEY=ollama
export KB0_OPENAI_BASE_URL=http://localhost:11434/v1
export KB0_EMBEDDING_MODEL=nomic-embed-text
export KB0_EMBEDDING_DIMENSIONS=768

Changing the model is safe: kb0 tracks the model and dimensions per embedding, detects the mismatch on next boot, and re-embeds stale notes in the background.

Search

kb0 uses hybrid search by default — combines BM25 keyword ranking (FTS5) with semantic similarity via Reciprocal Rank Fusion.

# Reindex existing notes (incremental)
kb0 reindex

# Full rebuild
kb0 reindex --rebuild

Audit log

Git records what changed — but agents also read and search, and that trail usually disappears. kb0 logs every tool call to .vault-index/kb0.log as content-free JSON lines: the path read, the query searched, and the paths a search returned. Note bodies are never written to the log.

$ tail -f my-vault/.vault-index/kb0.log
{"event":"tool.success","tool":"vault.search","agent":"research-bot","query":"token security","mode":"hybrid","result_paths":["notes/auth.md"],"result_count":1}
{"event":"tool.success","tool":"vault.read","agent":"research-bot","path":"notes/auth.md"}
{"event":"tool.error","tool":"vault.read","agent":"research-bot","error_code":"NOT_FOUND","path":"notes/secrets.md"}

Every event carries the tool, the agent identity, and a duration. Failed and denied calls are logged too, so you can see what an agent attempted, not just what it changed.


CLI reference

kb0 init <name>              Initialize a new vault
kb0 serve                    Start MCP server (stdio)
  --agent <name>             Agent identity (required)
  --vault <path>             Vault directory (default: cwd)
  --strict                   Fail if .vault-policy.yaml is absent
kb0 reindex                  Incremental reindex
  --rebuild                  Full rebuild
kb0 status                   Vault health and index stats
  --vault <path>             Vault directory (default: cwd)

Integrate with your agent

Using an AI coding agent (Claude Code, Cursor)? kb0 ships a Claude Code skill that teaches your agent to install kb0 and use a vault correctly — copy .claude/skills/kb0/ into your project. There's also a machine-readable llms.txt any agent can fetch for the same.

See the guides:


Contributing

See CONTRIBUTING.md.


License

Apache 2.0 — see LICENSE.