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

memolayer

v0.2.2

Published

Client installer for memolayer — a shared, curated memory layer for coding agents over MCP. Registers the MCP server and wires the auto-recall hook.

Readme

memolayer

A universal, tool-agnostic shared memory layer for coding agents, delivered over MCP.

memolayer stores curated, durable engineering knowledge about a codebase — decisions (with rationale), conventions, gotchas, and patterns — and serves it to any coding agent through the Model Context Protocol. Unlike a flat CLAUDE.md / AGENTS.md, it offers selective retrieval (hybrid vector + keyword), a memory lifecycle, provenance, conflict detection, and live cross-agent sharing.

This repository currently implements Phase 0 (skeleton): a working backend where remember stores a memory with an embedding and recall returns relevant memories ranked above irrelevant ones. See ../../IMPLEMENTATION_PLAN.md for the full roadmap (Phases 1–3).

Status: Phases 0–2 deployed on the VPS and verified (2026-07-14).

  • Phase 0/1 (agent-facing MCP): node packages/mcp-server/test/acceptance.mjs (12/12).
  • Phase 2 (human curation): the api service (127.0.0.1:3200) serves the Palimpsest React/Vite dashboard at /dashboard, with session-cookie auth and the full curation surface (review queue, browser, side-by-side conflict resolution). AUTO_ACCEPT=false — agent captures now land as pending and become retrievable only after a curator approves them. Admin login is seeded from ADMIN_EMAIL/ADMIN_PASSWORD in .env. The dashboard is bound to 127.0.0.1 — reach it via SSH -L 3200:127.0.0.1:3200, Tailscale, or a TLS reverse proxy (set COOKIE_SECURE=true when serving over HTTPS).

Architecture (Phase 0)

Three containers on a single VPS, orchestrated with Docker Compose:

| Service | Image | Exposure | Role | |--------------|---------------------------------------------------|-------------------------|------| | db | pgvector/pgvector:pg16 | 127.0.0.1:5432 | Postgres 16 + pgvector: relational + vector store | | embeddings | ghcr.io/huggingface/text-embeddings-inference | 127.0.0.1:8080 | Local BAAI/bge-m3 (1024-dim, multilingual) over HTTP | | mcp | built from packages/mcp-server | 127.0.0.1:3100※ | MCP Streamable-HTTP server: recall + remember |

Only the mcp service is ever exposed publicly — behind nginx/Caddy + TLS + a bearer token. The DB and embedding service stay bound to 127.0.0.1 / the internal Docker network.

This VPS remaps the MCP host port to 3100 because 3000 is already in use by another service. The container still listens on 3000 internally; only the host binding changed.

Prerequisites on this VPS

Two host-level prerequisites are not yet in place and require sudo (run them yourself):

# 1) Docker Engine + Compose plugin (not currently installed)
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker "$USER"   # then log out/in so `docker` works without sudo

# 2) 2 GB swap file — OOM insurance during HNSW index builds / embedding bursts
sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile \
  && sudo mkswap /swapfile && sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab   # persist across reboots

Deploy

cd ~/projects/memolayer

# 1) Secrets
cp .env.example .env
sed -i "s/^DB_PASSWORD=.*/DB_PASSWORD=$(openssl rand -hex 32)/"        .env
sed -i "s/^MCP_BEARER_TOKEN=.*/MCP_BEARER_TOKEN=$(openssl rand -hex 32)/" .env

# 2) Build & start (the embedding model downloads ~2.2 GB on first start)
docker compose up -d --build
docker compose logs -f embeddings   # wait for "Ready" before testing

# 3) Sanity-check the stack
docker compose ps
docker compose exec db psql -U memolayer -d memolayer -c '\dt'   # memories table exists

# 4) Seed ~10 varied memories, then smoke-test recall/remember
docker compose exec mcp node dist/seed.js

Connect a coding agent

Register the server as a remote HTTP MCP server (example: Claude Code):

claude mcp add --transport http memolayer http://127.0.0.1:3100/mcp \
  --header "Authorization: Bearer $(grep MCP_BEARER_TOKEN .env | cut -d= -f2)"

For remote clients, put nginx/Caddy + TLS in front of 127.0.0.1:3100 on a public hostname and point the client at https://<host>/mcp. Confirm the firewall exposes only 80/443 + SSH — never 5432, 8080, or 3100.

Tools

  • recall { query, scope?, limit=8, types? } → compact ranked hits [{ id, type, scope, content (truncated), score }]. Hybrid retrieval (vector + keyword) over status='active' memories in the requested scope plus global.
  • remember { content, type, scope='global', rationale?, client?, session_id? }{ id, status, conflict? }. Embeds the content, runs a conflict pre-check (cosine > 0.85 against active same-type memories), and inserts. In Phase 0 (AUTO_ACCEPT=true) new memories are active immediately; from Phase 2 they land as pending for curation.

Repository layout

memolayer/
├── docker-compose.yml
├── .env.example
├── db/migrations/0001_init.sql      # runs on first DB init only
└── packages/mcp-server/
    └── src/
        ├── index.ts        # HTTP transport, auth, tool + prompt registration
        ├── db.ts           # pg pool + query helpers
        ├── embeddings.ts   # HTTP client for the embedding service
        ├── retrieval.ts    # hybrid (vector + keyword) ranking
        ├── seed.ts         # inserts ~10 varied memories for sanity checks
        ├── types.ts        # TS types matching the schema
        └── tools/{recall,remember}.ts

Operational notes

  • Migrations in db/migrations/ run only on an empty data dir (via /docker-entrypoint-initdb.d). For later schema changes, add a migration runner (node-pg-migrate / drizzle-kit) — do not rely on the init folder beyond 0001.
  • Embeddings are disposable: the raw content is always the source of truth; a vector can be recomputed. Queries are embedded with the same model as stored memories, by construction.
  • The MCP server retries its DB and embeddings connections on startup, so docker compose up is safe even though the embedding model takes minutes to download on first boot.
  • Embeddings memory (8 GB box): bge-m3's model warmup allocates O(seq²) attention buffers, so a high --max-batch-tokens (e.g. 16384) makes warmup spike multiple GB and OOM-kill the container in a restart loop. It's pinned to 2048 with a mem_limit: 4g safety cap; steady-state RSS is ~2.3 GB. Memories are short facts, so 2048 is ample — raise both together only if you truly need to embed very long documents, and watch docker stats.