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

daftari

v1.29.0

Published

An open-source, multi-user knowledge vault exposed to AI agents via an MCP server.

Downloads

2,544

Readme

Daftari

CI npm version License: MIT

Daftari (دفتری) is the Urdu word for a ledger-keeper: the person in a trading house who maintained the daftar, the bound register where every transaction was recorded, cross-referenced, and preserved. The daftar was not a filing cabinet. It was a living document. Entries referenced earlier entries. Corrections were noted, not erased. The ledger got more valuable the longer it was kept, because the accumulated record revealed patterns no single entry could.

Daftari is the long-term memory cortex for your LLM agents — a persistent, structured vault they read, write, and curate over time, portable across any model. A cortex, not a clipboard.

Rent the brain, own the memory

LLMs are stateless; they forget. So memory is being bolted on everywhere — but inside the model: ChatGPT memory, Claude projects, Copilot, Gemini. Memory is becoming a feature of the provider, and whoever holds your memory holds you.

Daftari takes the other path. The model is the rented part — swappable, obsolete in six months. Your memory is the durable asset, so it should belong to you and travel with you: plain markdown on your disk, under git, readable in any editor, queryable by any agent. Compilation over retrieval — the agent compiles an answer once and writes it back, so every later read starts from the compiled result instead of re-stitching chunks from zero.

Not a second brain

Second brains are memory for a human to think with — you catch the stale fact, you notice the contradiction. Daftari is memory for an agent to reason with: the persistence layer for a consumer that acts on what it is handed and cannot sanity-check it first. Same substrate (markdown, links); reversed purpose — and a higher bar, because the reliability has to live in the memory, not the reader.

It remembers — it doesn't resolve for you

Because the agent can't infer them, the vault carries three things and collapses none:

  • what's current — supersession follows a real edge to the latest source
  • what's grounded — provenance on every entry; the vault never mints a value
  • what's contested — contradictions surface as tensions, held open, not flattened into a false answer

The daftar noted corrections rather than erasing them. Daftari keeps that as a law:

A tension may never masquerade as a supersession.

It resolves only by discovery — a real edge — never by invention. The agent compiles; the vault preserves; you keep the judgment. See the manifesto for the full argument.

What it is

A directory of markdown files with YAML frontmatter, exposed to agents as 14 MCP tools over stdio. The vault is plain text: you can read it in any editor, git log it, grep it. Daftari adds the machinery agents need to treat it as a shared workspace.

npx daftari --init ./my-vault
npx daftari --vault ./my-vault --user me --role admin

Point any MCP client (Claude Desktop, Claude Code, an agent SDK) at it.

The four layers

Storage and access control are table stakes. The moat is layers 3 and 4.

|Layer |What it does |Why it matters | |---------------------|------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------| |Storage |Markdown + frontmatter on disk, git history, rebuildable SQLite index for hybrid BM25 + vector search.|Plain text is the source of truth. Delete every .db file and rebuild.| |Access control |Config-driven RBAC. Roles and per-collection read/write/promote permissions in .daftari/config.yaml.|Multiple agents, scoped access, no user-management system. | |Write arbitration|File-level locks (60s TTL), auto-commit to git, structured provenance log. |Concurrent agents write safely. Every mutation is attributable. | |Curation |Draft-to-canonical lifecycle, TTL-based staleness, tension logging, advisory linter. |Knowledge that stops being true gets surfaced, not silently trusted. |

The tools

Read: vault_read, vault_index, vault_status

Search: vault_search (hybrid BM25 + vector), vault_search_related, vault_themes (thematic clustering), vault_reindex

Write: vault_write, vault_append, vault_promote, vault_deprecate

Curate: vault_tension_log, vault_lint, vault_provenance

The curation engine is advisory: vault_lint reports problems and vault_tension_log records contradictions. Neither auto-fixes anything. Every change is a deliberate, attributable act.

Evaluate (opt-in, requires an Anthropic API key): daftari eval — scores how well an LLM can use the curation surface to answer multi-hop questions about the vault. See the design spec for the rationale and the cortex framing.

Two kinds of knowledge

Every document declares a domain. The distinction drives how the curation layer treats it.

Accumulation documents compile and compound. A competitive-intel note, a pricing breakdown, a researched comparison. Each write builds on the last. Going stale is a problem to fix.

Generative documents speculate. A moonshot sketch, a brainstorm, a “what if.” Going stale is expected, not a defect.

The same curation rules applied uniformly would either nag about every brainstorm or quietly trust every stale fact. The domain split lets the system hold each to the right standard.

Access control

No user-management system. Roles live in config, the server starts with one:

roles:
  analyst:
    read: [competitive-intel, pricing]
    write: [competitive-intel, _drafts]
  researcher:
    read: ["*"]
    write: [moonshot, _drafts]
  admin:
    read: ["*"]
    write: ["*"]
    promote: true
    ratify: true   # may approve/reject staged actions and contest edges

No --role or an unknown name falls back to deny-all. An agent identity is just a role too — e.g. a curation-loop role that reads and writes but leaves ratify off: the agent proposes, humans ratify.

File format

Markdown with YAML frontmatter. Frontmatter is the metadata layer; there is no separate database.

---
title: "Aurora Pipelines — Positioning Overview"
domain: accumulation
collection: competitive-intel
status: canonical
confidence: medium
created: 2026-05-17
updated: 2026-05-17
updated_by: agent:claude-code
provenance: synthesized
sources:
  - aurora-product-page
ttl_days: 120
tags: [aurora, ingestion, competitive]
questions_answered:
  - "How does Aurora frame the ingestion/transformation boundary?"
questions_raised:
  - "Does an authored-pipeline model slow teams down at small scale?"
---

Documents can make their epistemic edges explicit: questions_answered is what later agents can take as settled, questions_raised is where to build next. vault_lint turns the open questions across the vault into a coverage map.

Full field reference in <docs/file-format.md>.

Adopting an existing vault

Already have a wiki or an Obsidian vault? Daftari adopts it in place — it indexes and curates the same markdown files you already edit, not a separate copy.

# Dry run — see what would change, write nothing
daftari import obsidian ~/my-vault --plan

# Adopt one folder at a time (per-folder ratification; --yes to skip the prompt)
daftari import obsidian ~/my-vault --apply --scope notes

The import is non-destructive to your content. It fills only the missing Daftari frontmatter — collection from the folder, dates from git history (or file mtime), sensible defaults for the rest — and preserves everything you already had, including custom frontmatter fields. Obsidian specifics: inline #tags are merged into tags, a Web Clipper source is mapped into sources, and [[wikilinks]] are left untouched (Daftari resolves them as written). Filling frontmatter is deliberate, not automatic — re-run the import to pick up newly added notes.

Cloud-synced vaults (iCloud, Dropbox, …)

Daftari versions every change with git, and a .git/ directory churning inside a cloud-synced folder can corrupt. For a synced vault, keep git's data outside it:

daftari import obsidian "~/Library/Mobile Documents/.../my-vault" \
  --apply --scope notes --external-git-dir

This writes git_dir: external to .daftari/config.yaml, so Daftari uses git init --separate-git-dir: only a tiny static .git file stays in the vault (syncs harmlessly) while the repo data lives under ~/.local/share/daftari/git/. Pass --external-git-dir=/path for an explicit location, or set git_dir directly in config to apply the same to any vault. History is per-device; your notes still sync everywhere.

Lower-level: backfill

daftari import obsidian is a thin, Obsidian-aware wrapper over daftari backfill — the git-driven frontmatter migration that works on any markdown wiki. Use it directly for non-Obsidian trees:

daftari backfill --plan
daftari backfill --apply --scope specs

How it compares

| |AGENTS.md |RAG |Daftari | |--------------------|-----------------|-----------------------------|-------------------------------------| |Who writes? |Humans |Nobody (retrieval only) |Agents + humans | |Scales? |One file, doesn’t|Scales storage, not coherence|Structured collections with lifecycle| |Knowledge compounds?|No |No |Yes, draft → canonical → deprecated | |Contradictions? |Invisible |Invisible |Tension log surfaces them | |Staleness? |Silent |Silent |TTL-based decay with advisory lint |

What’s not in v1

Deliberately deferred to keep the surface tight:

  • Cloud-hosted multi-tenant server with S3/GCS backend and token auth
  • Remote MCP transport for claude.ai web, mobile, and Cowork (v1 is a local desktop extension for Claude Desktop and Claude Code)
  • Conflict resolution beyond file-level locks (CRDTs, semantic merge)
  • Background curation agent running lint on a cadence
  • LLM reranking of search results
  • Enforced domain separation (v1 documents the convention; v2 enforces it)

Each is a clean increment on a surface that already works.

Coherence audit

daftari audit is a read-only, deterministic check across one or more markdown repos for broken cross-repo references and link-graph transitive staleness. It works against any markdown tree — daftari-managed or not. The audit creates no .daftari/ directory and writes nothing to the audited repos.

Multi-repo (the headline use case)

When two or more repos link to each other, the audit detects broken references that neither repo's own lint could see — because each repo only knows about itself.

daftari audit \
  --repo ~/repos/service-a \
  --repo ~/repos/service-b

That works for relative-path links (../service-b/docs/api.md). For GitHub-style URL links between repos (https://github.com/org/service-b/...), declare each repo's URL patterns in an audit.yaml so the resolver can map them back to the local repo:

# audit.yaml
repos:
  - name: service-a
    path: ~/repos/service-a
    urls: ["github.com/org/service-a"]
  - name: service-b
    path: ~/repos/service-b
    urls: ["github.com/org/service-b"]
daftari audit --config audit.yaml

Single repo

The same command, one --repo:

daftari audit --repo ./docs

In single-repo mode the cross-repo check trivially has no work, but the staleness check still runs over the in-repo link graph.

What gets detected

  • Missing files. A link from service-a/intro.md to ../service-b/api.md or https://github.com/org/service-b/blob/main/api.md — flagged if api.md doesn't exist in service-b.
  • Missing anchors. Same link with #run — flagged if api.md has no ## Run heading.
  • Direct staleness. Any doc whose git mtime is older than staleness.threshold_days (default 540, ~18 months).
  • Transitive staleness. A fresh doc that links — directly or through a chain — to a stale doc is itself flagged, with the shortest chain reported. Catches the case where you keep touching an index page while the docs it links to are rotting.

Sample output

# Coherence Audit Report

## Totals
- repos scanned: **2**
- docs scanned: **47**
- broken cross-repo refs: **2**
- directly stale docs: **3**
- transitively stale docs: **5**

## Broken cross-repo references
| kind           | source                    | target                  | href |
|----------------|---------------------------|-------------------------|------|
| missing_anchor | service-a/intro.md        | service-b/api.md#run    | `https://github.com/org/service-b/blob/main/api.md#run` |
| missing_file   | service-a/architecture.md | service-b/deleted.md    | `../service-b/deleted.md` |

## Staleness
| kind       | doc                      | mtime      | chain |
|------------|--------------------------|------------|-------|
| transitive | service-a/onboarding.md  | 2026-04-01 | service-a/onboarding.md → service-b/legacy-flow.md |

JSON output (--output-json or output.json in config) carries the same structure with full detail in brokenRefs[] and staleness[] arrays plus a totals summary block for compact downstream rendering.

CI integration

The audit's exit code is designed to gate CI:

# .github/workflows/docs-audit.yml
name: Docs audit
on: [pull_request]
jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }   # full history so git mtime works
      - run: npx daftari@latest audit --config audit.yaml

Exit codes:

| code | meaning | |------|---------| | 0 | clean run, all findings within fail_on thresholds | | 1 | clean run but a threshold was exceeded — CI fails | | 2 | config error (missing required fields, bad paths, malformed YAML) | | 3 | runtime error (IO failure during collection) |

CLI flags

audit.yaml and CLI flags overlap; CLI wins. A warning is printed to stderr when --output or --output-json displaces a value from the config.

  • --repo <path> — add a repo. May be repeated. Anonymous CLI repos get no URL patterns; URL-based cross-refs into them won't be detected. Use --config for URL-aware repos.
  • --config <path> — load an audit.yaml.
  • --output <md> — markdown report destination (default: stdout).
  • --output-json <json> — JSON report destination (default: not written).
  • --help — full help text.

Full audit.yaml schema

repos:
  - name: service-a
    path: ~/repos/service-a
    docs_glob: "docs/**/*.md"       # default: "**/*.md"
    urls:                            # optional; enables URL-pattern matching
      - "github.com/org/service-a"

  - name: service-b
    path: ~/repos/service-b
    urls:
      - "github.com/org/service-b"

output:
  markdown: coherence-report.md      # default: stdout
  json: coherence-report.json        # default: not emitted

staleness:
  threshold_days: 540                # default: 540 (18 months)

fail_on:
  broken_refs: 1                     # default: fail on any broken ref
  transitive_staleness: 100          # default: generous; teams tune

Development

npm install
npm run build
npm test

Design tenets: functions and types, no classes; tool handlers return Result<T, Error> rather than throwing; tests mirror the src/ structure.

Documentation

  • <docs/getting-started.md> — scaffold, write, search, lint, promote, deprecate
  • <docs/architecture.md> — layered design, request path, accumulation vs. generative domains
  • <docs/file-format.md> — complete frontmatter reference

Integrations

  • integrations/langchain/langchain-daftari, a Python package that exposes the 14 daftari tools as LangChain BaseTools for use with LangGraph / create_react_agent. Sync + async, schemas pulled live from tools/list.
  • packages/router — multi-vault MCP router that fans out across N Daftari vaults

Privacy

Daftari is a local MCP server. It runs on your machine, against vault files on your machine. The default configuration makes no network calls — vault content stays on your local filesystem and is read or written only through tools the MCP client invokes. The only optional egress is the OpenAI embedding provider, which the user must explicitly opt into per vault.

Full policy: PRIVACY.md — covers data collection (none), storage (local-only), the OpenAI opt-in, third-party integrations (none), retention, and contact.

License

MIT.