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

@watilde/ontol

v0.1.0

Published

Minimal, local-first ontology & knowledge graph builder for Markdown and AI agents.

Readme

ontol

Minimal, local-first ontology & knowledge graph builder for Markdown and AI agents.

ontol scans a directory of Markdown files, turns each document into a graph node, resolves relative links ([x](./y.md)) into directed edges, and saves the result to .ontol/graph.json. You can then explore the graph from the CLI, or expose it to an AI agent over the Model Context Protocol (MCP).

  • Local-first — everything runs on your machine against plain Markdown. No server, no database.
  • OKF v0.1 compatible — reads Open Knowledge Format bundles (reserved type / description / resource / tags / timestamp fields, index.md / log.md reserved files, bundle-root links), and ontol lint checks conformance.
  • Agent-ready — ships an MCP server so tools like Claude can search and traverse your notes.

Install

Requires Node.js >= 18.

npm install -g ontol
# or run without installing
npx ontol build

Quick start

# 1. Build the graph from the current directory
ontol build

# 2. List / search nodes
ontol list
ontol search "knowledge graph"

# 3. Inspect a single node and its neighbors
ontol inspect alpha

Example

The example/ directory is a small, ready-to-run knowledge base of interlinked notes. Try it from the repository root:

ontol build   example
ontol list    example --tag core
ontol inspect knowledge-graph example

See example/README.md for what to expect.

How documents become a graph

Each .md file is one node. Fields come from YAML frontmatter, with sensible fallbacks:

---
id: alpha            # optional — defaults to the path relative to root (e.g. notes/alpha.md)
title: Alpha Concept # optional — defaults to the file name
type: concept        # OKF: required for conformance (checked by `ontol lint`)
description: ...      # optional — OKF reserved, one-sentence summary
resource: https://…  # optional — OKF reserved, URI of the underlying asset
tags: [core, demo]   # optional — string or array
timestamp: 2026-07-23T00:00:00Z  # optional — OKF reserved, ISO 8601
---

Alpha links to [Beta](./beta.md).

id is an ontol-specific field (OKF identifies concepts by path/resource); unknown frontmatter keys are always preserved on the node.

  • Nodes — one per Markdown file. id is frontmatter.id if present, otherwise the root-relative path.
  • Edges — one per internal Markdown link, relative (./x.md, ../x.md) or bundle-root absolute (/x.md). Directed source → target.
  • Ignored — external URLs (https://…, mailto:), pure anchors (#section), non-.md targets (images), links that escape the project root (../…), and duplicate edges.

The build scans recursively, skipping node_modules/, .git/, .ontol/, and the OKF reserved files index.md / log.md (these are never turned into nodes).

CLI

ontol build   [dir]                       Build the graph and save to <dir>/.ontol/graph.json
ontol list    [dir] [--type T] [--tag T]  List saved nodes
ontol search  <query> [dir] [--type T] [--tag T] [--limit N]
                                          Full-text search over title/id/tags/content
ontol inspect <ref> [dir]                 Show one node plus its outgoing/incoming neighbors
ontol lint    [dir] [--strict]            Check OKF v0.1 conformance (type required, broken links)
ontol mcp     [dir]                        Start the MCP server over stdio

dir defaults to the current directory. list / search / inspect require a graph built with ontol build first.

A node ref (for inspect) is resolved in order: exact id → relative path → file name → file name without .md. So alpha, notes/alpha.md, alpha.md all work.

Search ranking

search (and the MCP search_nodes tool) matches the query as a substring and ranks by where it hit, highest first: title (8) > id (4) > tag (2) > content (1). An empty query returns all nodes (still honoring --type / --tag), sorted by title.

OKF conformance (lint)

ontol lint checks a bundle against the Open Knowledge Format v0.1:

  • error missing-type — a non-reserved .md file has no non-empty type.
  • error invalid-frontmatter — the YAML frontmatter fails to parse.
  • warning broken-link — an internal .md link points to a file that doesn't exist.

Exit code is non-zero when there are errors (or any warnings with --strict), so it fits in CI.

MCP server

Expose your graph to an AI agent:

ontol mcp /path/to/notes

The server communicates over stdio (stdout is reserved for JSON-RPC; logs go to stderr). If no .ontol/graph.json exists yet, the graph is built in memory on startup.

Tools

| Tool | Description | |------|-------------| | search_nodes | Full-text search. Args: query, optional type, tag, limit (default 20). | | get_node | Fetch one node's frontmatter + body. Args: ref. | | get_neighbors | List a node's outgoing and incoming linked nodes. Args: ref. | | rebuild_graph | Re-scan Markdown and rebuild the in-memory graph after edits. |

Claude Desktop / Claude Code config

{
  "mcpServers": {
    "ontol": {
      "command": "ontol",
      "args": ["mcp", "/path/to/notes"]
    }
  }
}

Programmatic API

ontol is also a library (ESM):

import {
  buildGraph,
  saveGraph,
  loadGraph,
  searchNodes,
  resolveNode,
  outgoing,
  incoming,
} from "ontol";

const graph = await buildGraph("./notes");
await saveGraph("./notes", graph);

const hits = searchNodes(graph, "concept", { type: "concept", limit: 10 });
const node = resolveNode(graph, "alpha");
const links = outgoing(graph, node.id);

Graph shape

interface Graph {
  version: 1;
  generatedAt: string;               // ISO timestamp
  nodes: Record<string, GraphNode>;  // keyed by id
  edges: GraphEdge[];
}

interface GraphNode {
  id: string;
  filePath: string;                  // root-relative, "/"-separated
  title: string;
  type?: string;                     // OKF reserved
  description?: string;              // OKF reserved
  resource?: string;                 // OKF reserved (URI)
  timestamp?: string;                // OKF reserved (ISO 8601)
  tags: string[];
  frontmatter: Record<string, unknown>;
  content: string;                   // body without frontmatter
}

interface GraphEdge {
  source: string;                    // node id
  target: string;                    // node id
  kind: "link";
}

Development

npm install
npm run build     # tsc -> dist/
npm run dev       # tsc --watch
npm test          # build + node:test

License

MIT © Daijiro Wachi