cd /news/ai-infrastructure/show-hn-open-source-toolkit-for-ai-m… · home topics ai-infrastructure article
[ARTICLE · art-17215] src=github.com pub= topic=ai-infrastructure verified=true sentiment=↑ positive

Show HN: Open-source toolkit for AI memory that scales

Lithium, an open-source toolkit for AI memory, launched with a PostgreSQL-based storage engine that uses hierarchical versioned storage to scale tree-structured data. The toolkit, which includes zero runtime dependencies and built-in versioning, claims to outperform graph and vector databases for tree queries by using PostgreSQL's ltree extension for index-backed subtree lookups instead of graph traversal.

read4 min publishedMay 29, 2026

Hierarchical versioned storage on PostgreSQL ltree. Scoped retrieval, built-in versioning, zero runtime deps.

const lithium = new Lithium(drizzleAdapter(db));

await lithium.clusters.create({ name: "infra" });
await lithium.clusters.create({ name: "database", parentPath: "infra" });

const context = await lithium.getContext({ path: "infra" });

Memory graphs don't scale for tree-structured data. Graph traversal becomes a bottleneck. Vector search gives you "similar to X" when you need "everything under X."

PostgreSQL's ltree

handles tree queries significantly faster. Index-backed subtree lookups, not traversal. Lithium wraps it in a clean TypeScript API with built-in versioning.

Lithium Graph DBs Vector DBs
Structure
Tree hierarchy Arbitrary graph Flat
Query speed
ltree index-backed Graph traversal ANN search
Retrieval
Deterministic, scoped Pattern matching Fuzzy, similarity
Versioning
Built-in, immutable Manual Overwrite
Infrastructure
Your existing Postgres Separate service Separate service
Package What Size
@lithium-ai/core
Zero-dep storage engine
@lithium-ai/postgres
PostgreSQL ltree adapter
@lithium-ai/drizzle
Drizzle ORM adapter
@lithium-ai/mcp
MCP server for AI tools

Prerequisites: PostgreSQL with ltree

extension.

With Drizzle:

npm install @lithium-ai/core @lithium-ai/drizzle drizzle-orm
js
import { Lithium } from "@lithium-ai/core";
import { drizzleAdapter } from "@lithium-ai/drizzle";

const lithium = new Lithium(drizzleAdapter(db));

With raw postgres:

npm install @lithium-ai/core @lithium-ai/postgres postgres
js
import { Lithium } from "@lithium-ai/core";
import { postgresAdapter } from "@lithium-ai/postgres";
import postgres from "postgres";

const sql = postgres("postgres://...");
const lithium = new Lithium(postgresAdapter(sql));

Then:

// Create hierarchy
const infra = await lithium.clusters.create({ name: "infra" });
await lithium.clusters.create({ name: "database", parentPath: "infra" });

// Create versioned entries
const entry = await lithium.entries.create({ clusterId: infra.value.id });
await lithium.entries.update({ id: entry.value.entry.id });

// Scoped retrieval: everything under "infra"
const context = await lithium.getContext({ path: "infra" });
npm install @lithium-ai/mcp
js
// server.ts
import { Lithium } from "@lithium-ai/core";
import { postgresAdapter } from "@lithium-ai/postgres";
import { serveMcp } from "@lithium-ai/mcp";
import postgres from "postgres";

const sql = postgres(process.env.DATABASE_URL!);

const lithium = new Lithium(postgresAdapter(sql), async (versionIds) => {
  const rows = await sql`
    SELECT entry_version_id, title, content
    FROM your_content_table
    WHERE entry_version_id = ANY(${versionIds})
  `;
  return new Map(rows.map((r) => [r.entry_version_id, r]));
});

serveMcp(lithium);

Add to Claude Code:

{
  "mcpServers": {
    "lithium": {
      "command": "npx",
      "args": ["tsx", "server.ts"]
    }
  }
}

Entries are pure structure. Your content lives in your own tables, referenced by entry version IDs.

Cluster
  id, parentId, path ("infra.database"), name, description, createdAt

Entry
  id, clusterId, createdAt

EntryVersion
  id, entryId, version (auto-incremented), createdAt

Your Content Table
  entryVersionId (FK), title, content, ...whatever you want
Method What
create({ name, parentPath?, description? })
Create cluster, resolve parent
findByPath({ path })
Find by dot-path
list()
All clusters ordered by path
listDescendantIds({ path })
ltree subtree query
Method What
create({ clusterId })
New entry + version 1
update({ id })
Auto-increment version
get({ id, version? })
Entry + version (latest or specific)
list({ clusterIds })
Entries by cluster IDs
listWithLatestVersion({ clusterIds })
Entries + latest versions (batch)
Method What
getContext({ path })
Scoped retrieval with optional content resolver

Every method returns Result<T, E>

. No thrown exceptions.

const result = await lithium.clusters.create({ name: "infra" });
if (!result.success) {
  // result.error is ValidationError | NotFoundError | SystemError
  // Discriminate via error.kind or instanceof
}

Drizzle users: Import the schemas and use drizzle-kit push

:

export { clusters, entries, entryVersions } from "@lithium-ai/drizzle";
npx drizzle-kit push

Raw SQL: Run the reference migrations from @lithium-ai/postgres

:

psql -d your_db -f node_modules/@lithium-ai/postgres/src/migrations/001_clusters.sql
psql -d your_db -f node_modules/@lithium-ai/postgres/src/migrations/002_entries.sql

Requires CREATE EXTENSION IF NOT EXISTS ltree;

before running.

  • Core storage engine ( @lithium-ai/core

) - PostgreSQL ltree adapter ( @lithium-ai/postgres

) - MCP server ( @lithium-ai/mcp

) - Content resolver callback for getContext

  • Drizzle ORM adapter ( @lithium-ai/drizzle

) - GitHub Actions CI

  • Integration tests (testcontainers)

  • Transaction support (atomic createEntry)

  • MCP write tools (create_cluster, create_entry)

  • Example projects

  • Prisma adapter

  • AI agent memory (structured retrieval, scoped context)

  • Decision tracking across teams

  • Config versioning

  • Documentation hierarchies

Read more: Memory Graphs Don't Scale

Issues and PRs welcome.

MIT

── more in #ai-infrastructure 4 stories · sorted by recency
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/show-hn-open-source-…] indexed:0 read:4min 2026-05-29 ·