feat(examples): SQLR-40 Node.js MCP-powered notes assistant#141
Merged
Conversation
Adds `examples/nodejs-notes/` — a Node.js CLI that ingests a folder of markdown notes into SQLRite, then exposes the database to Claude Desktop (or any MCP client) via `sqlrite-mcp --read-only`. End user effect: `sqlrite-notes init ~/Documents/notes` + one block of JSON into Claude Desktop's config, then ask Claude about your notes. Hits two of the engine's most distinctive features end-to-end: hybrid HNSW + BM25 retrieval (the canonical fused `ORDER BY` shape from `docs/fts.md`) and the first-party MCP server. Default embedder is a deterministic offline hash bag-of-words so the demo works fully offline; `--embedder openai` switches to `text-embedding-3-small` for real semantic recall. Surfaced engine bug SQLR-8 during the `refresh` flow — HNSW panics on DELETE + INSERT within the same connection — and worked around it by splitting ingest into delete-phase → close/reopen → insert-phase. The reopen hop only runs when there are actual deletions, so first-time `init` skips it. README "Known limitations" documents it. Tests: 40 unit + integration tests via `node:test`, all passing against the prebuilt `@joaoh82/sqlrite@^0.10.0` napi-rs binding. Integration tests skip cleanly when the binding isn't installed. Cross-references updated: top-level README points at both SQLR-39 (python-agent) and SQLR-40 (nodejs-notes) under "End-to-end example apps"; `examples/README.md` gains a Node.js notes assistant section; `web/src/app/examples/page.tsx` adds a card for the new example with the right feature tags and structured-data entry. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
examples/nodejs-notes/— a Node.js CLI that ingests a folder of markdown notes into SQLRite, then exposes the database to Claude Desktop / any MCP client viasqlrite-mcp --read-only. End-user effect:sqlrite-notes init ~/Documents/notes+ one block of JSON intoclaude_desktop_config.json, then ask Claude about your notes (bm25_search/vector_search/query/askall light up automatically).ORDER BYshape fromdocs/fts.md) and the first-party MCP server. Default embedder is a deterministic offline hash bag-of-words — the demo works fully offline, no API key.--embedder openaiswitches totext-embedding-3-small(withdimensions: 384to match the schema).What's in it
Pins `@joaoh82/sqlrite@^0.10.0` — installs with prebuilt napi-rs binaries for macOS-arm64, Linux x64/arm64, and Windows x64. No Rust toolchain required on the user's side; `sqlrite-mcp` is the one Rust binary they install separately (or `SQLRITE_MCP_BIN=/path` overrides the lookup).
Engine bug surfaced
`refresh` (DELETE + re-INSERT through an HNSW chunk index) panicked inside `DistanceMetric::compute` with `index out of bounds: the len is 0 but the index is 0`. Worked around in `src/ingest.mjs` by splitting ingest into delete-phase → close/reopen → insert-phase — the reopen forces a clean HNSW rebuild on next open. First-time `init` skips the reopen entirely (only paid when there are actual deletions). Filed as SQLR-8 with a 10-line reproducer; once it lands, `src/ingest.mjs` can drop the `db.reopen()` call.
Cross-references updated
Test plan
🤖 Generated with Claude Code