md-semantic-search 0.4.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +125 -1
  2. package/bin/cli.mjs +482 -34
  3. package/dist/binary-format.d.ts +25 -0
  4. package/dist/binary-format.js +178 -0
  5. package/dist/collapse.d.ts +6 -0
  6. package/dist/collapse.js +20 -0
  7. package/dist/core.d.ts +85 -0
  8. package/dist/core.js +471 -0
  9. package/dist/federation.d.ts +15 -0
  10. package/dist/federation.js +94 -0
  11. package/dist/filter.d.ts +29 -0
  12. package/dist/filter.js +317 -0
  13. package/dist/frontmatter.d.ts +20 -0
  14. package/dist/frontmatter.js +150 -0
  15. package/dist/index-format.d.ts +23 -0
  16. package/dist/index-format.js +125 -0
  17. package/dist/index.d.ts +37 -0
  18. package/dist/index.js +37 -0
  19. package/dist/indexer.d.ts +83 -0
  20. package/dist/indexer.js +466 -0
  21. package/dist/ivf.d.ts +33 -0
  22. package/dist/ivf.js +144 -0
  23. package/dist/lexical.d.ts +44 -0
  24. package/dist/lexical.js +226 -0
  25. package/dist/markdown-parser.d.ts +28 -0
  26. package/dist/markdown-parser.js +311 -0
  27. package/dist/mcp.d.ts +159 -0
  28. package/dist/mcp.js +264 -0
  29. package/dist/metrics.d.ts +43 -0
  30. package/dist/metrics.js +97 -0
  31. package/dist/models.d.ts +38 -0
  32. package/dist/models.js +181 -0
  33. package/dist/quantization.d.ts +24 -0
  34. package/dist/quantization.js +85 -0
  35. package/dist/rag.d.ts +49 -0
  36. package/dist/rag.js +128 -0
  37. package/dist/rerank.d.ts +10 -0
  38. package/dist/rerank.js +41 -0
  39. package/dist/search.d.ts +149 -0
  40. package/dist/search.js +644 -0
  41. package/dist/serve.d.ts +49 -0
  42. package/dist/serve.js +341 -0
  43. package/dist/summarize.d.ts +16 -0
  44. package/dist/summarize.js +82 -0
  45. package/dist/tui.d.ts +18 -0
  46. package/dist/tui.js +219 -0
  47. package/dist/watcher.d.ts +11 -0
  48. package/dist/watcher.js +130 -0
  49. package/dist/wikilinks.d.ts +69 -0
  50. package/dist/wikilinks.js +271 -0
  51. package/package.json +21 -5
  52. package/src/binary-format.ts +216 -0
  53. package/src/{collapse.mjs → collapse.ts} +7 -12
  54. package/src/core.ts +551 -0
  55. package/src/federation.ts +118 -0
  56. package/src/filter.ts +368 -0
  57. package/src/{frontmatter.mjs → frontmatter.ts} +27 -50
  58. package/src/{index-format.mjs → index-format.ts} +58 -41
  59. package/src/{index.mjs → index.ts} +54 -8
  60. package/src/indexer.ts +617 -0
  61. package/src/ivf.ts +190 -0
  62. package/src/{lexical.mjs → lexical.ts} +66 -100
  63. package/src/{markdown-parser.mjs → markdown-parser.ts} +135 -109
  64. package/src/mcp.ts +289 -0
  65. package/src/metrics.ts +135 -0
  66. package/src/models.ts +219 -0
  67. package/src/quantization.ts +93 -0
  68. package/src/rag.ts +189 -0
  69. package/src/rerank.ts +54 -0
  70. package/src/search.ts +805 -0
  71. package/src/serve.ts +393 -0
  72. package/src/summarize.ts +98 -0
  73. package/src/tui.ts +251 -0
  74. package/src/watcher.ts +149 -0
  75. package/src/wikilinks.ts +376 -0
  76. package/src/core.mjs +0 -535
  77. package/src/indexer.mjs +0 -540
  78. package/src/metrics.mjs +0 -186
  79. package/src/models.mjs +0 -299
  80. package/src/rerank.mjs +0 -75
  81. package/src/search.mjs +0 -636
  82. package/src/serve.mjs +0 -387
  83. package/src/wikilinks.mjs +0 -241
package/README.md CHANGED
@@ -255,6 +255,52 @@ error, and `serve --watch` politely defers its cycle until the other writer
255
255
  finishes. A crashed writer can't wedge the index — the lock self-heals by
256
256
  pid-liveness + staleness (a dead-pid or abandoned lock is reclaimed).
257
257
 
258
+ ### Export the index (`mdss export`)
259
+
260
+ Export chunks and decoded embedding vectors to JSONL, CSV, or Parquet for downstream pipelines (LangChain, LlamaIndex, Qdrant, Pandas):
261
+
262
+ ```bash
263
+ # Export all chunks with decoded float vectors as JSONL:
264
+ mdss export --db ./notes --format jsonl > chunks.jsonl
265
+
266
+ # Export metadata only without vectors (fast & compact):
267
+ mdss export --db ./notes --format jsonl --no-vectors > chunks_meta.jsonl
268
+
269
+ # Export as CSV (metadata only):
270
+ mdss export --db ./notes --format csv > chunks.csv
271
+
272
+ # Export directly to file:
273
+ mdss export --db ./notes --format jsonl --output ./data/corpus.jsonl
274
+ ```
275
+
276
+ #### JSONL output schema:
277
+ ```json
278
+ {
279
+ "file": "runbooks/failover.md",
280
+ "title": "Database Failover",
281
+ "heading": "Step 2: Promote Replica",
282
+ "headingPath": ["Database Failover", "Step 2: Promote Replica"],
283
+ "text": "Run the promote script...",
284
+ "vec": [0.012, -0.045, 0.089],
285
+ "chunkHash": "a1b2c3...",
286
+ "startLine": 14,
287
+ "endLine": 28
288
+ }
289
+ ```
290
+
291
+ #### Downstream integration example (Python / LangChain / LlamaIndex):
292
+ ```python
293
+ import json
294
+
295
+ # Load into custom vector store / pipeline
296
+ with open("chunks.jsonl") as f:
297
+ for line in f:
298
+ chunk = json.loads(line)
299
+ text = chunk["text"]
300
+ vector = chunk["vec"]
301
+ meta = {"file": chunk["file"], "heading": chunk["heading"]}
302
+ ```
303
+
258
304
  ### Diagnose problems (`mdss check` / `mdss doctor`)
259
305
 
260
306
  `mdss check` (alias: `mdss doctor`) is an **offline, read-only** diagnostic for
@@ -373,21 +419,66 @@ const r = await fetch('http://localhost:8747/search', {
373
419
  const { results } = await r.json();
374
420
  ```
375
421
 
376
- The API is unauthenticated — by default it binds to **loopback only**
422
+ The API is unauthenticated by default (or secured via `--api-key`) — by default it binds to **loopback only**
377
423
  (`127.0.0.1`), so other machines on your LAN cannot reach it. Pass `--host
378
424
  0.0.0.0` (or `MDSS_HOST`) only if you intend to expose it on a network, and put
379
425
  a reverse proxy (or at least a firewall rule) in front of it. Request bodies
380
426
  are capped at 64 KB (oversized → `413`), and malformed JSON gets a clear `400`
381
427
  instead of being silently swallowed.
382
428
 
429
+ ### 4. MCP Server (Claude Desktop, Cursor, Copilot, Antigravity)
430
+
431
+ `md-semantic-search` provides a zero-dependency **Model Context Protocol (MCP)** server over standard I/O (JSON-RPC 2.0). This allows AI agents and IDEs to query your local notes privately by meaning without uploading text to external clouds.
432
+
433
+ ```bash
434
+ mdss mcp --db /path/to/your/markdown
435
+ ```
436
+
437
+ #### Available MCP Tools:
438
+ - **`search_markdown`**: Hybrid semantic vector + BM25 search with optional `path` glob and `tag` filters.
439
+ - **`get_chunk`**: Retrieve a specific section by file and heading.
440
+ - **`list_files`**: List indexed Markdown files with chunk counts.
441
+ - **`index_status`**: Inspect index health, chunk counts, and model metadata.
442
+
443
+ #### Claude Desktop Configuration:
444
+ Add to your `claude_desktop_config.json`:
445
+
446
+ ```json
447
+ {
448
+ "mcpServers": {
449
+ "md-semantic-search": {
450
+ "command": "npx",
451
+ "args": ["-y", "md-semantic-search", "mcp", "--db", "C:\\path\\to\\your\\notes"]
452
+ }
453
+ }
454
+ }
455
+ ```
456
+
457
+ #### Cursor Configuration (`.cursor/mcp.json`):
458
+ ```json
459
+ {
460
+ "mcpServers": {
461
+ "md-semantic-search": {
462
+ "command": "npx",
463
+ "args": ["-y", "md-semantic-search", "mcp", "--db", "./notes"]
464
+ }
465
+ }
466
+ }
467
+ ```
468
+
383
469
  ### Options
384
470
 
385
471
  | Flag | Meaning |
386
472
  |------|---------|
473
+ | `--config <file>` | Path to config file (default: `.mdssrc.json`, `mdss.config.json`, `.mdssrc`). |
387
474
  | `--db <dir>` | Folder of `.md` files (or set `MDSS_DB`). Can be anywhere on disk. |
388
475
  | `--index-dir <dir>` | Where to store the index (default: `<db>/.mdss`). |
389
476
  | `--cache-dir <dir>` | Model cache dir. Default: `$XDG_CACHE_HOME/mdss` if set, else `~/.cache/mdss` on **all** platforms (so on Windows that's `C:\Users\<you>\.cache\mdss` — *not* `%LOCALAPPDATA%`; override with `MDSS_CACHE_DIR`). |
390
477
  | `--model <name\|id>` | Embedding model (default `e5-base`). See `mdss models`. |
478
+ | `--workers <n>` | Number of parallel batch workers for embedding (default: 1). |
479
+ | `--format <fmt>` | Export format: `jsonl` (default), `csv`, `parquet` (`export`). |
480
+ | `--no-vectors` | Omit embeddings from export (`export`). |
481
+ | `--output <file>` | Output file path (`export`, default: stdout). |
391
482
  | `--ignore <glob>` | Skip files/paths; repeatable. e.g. `--ignore "log.md" --ignore "**/archive/**"`. |
392
483
  | `--path <glob>` | Search only files matching glob; repeatable. e.g. `--path "docs/**"`. |
393
484
  | `--since <date>` | Search only files modified at/after date (`YYYY-MM-DD` or ISO 8601). |
@@ -395,6 +486,10 @@ instead of being silently swallowed.
395
486
  | `--json` | Machine-readable output: `index` → build result JSON, `stats` → index stats JSON, `search` → hit list JSON (each hit includes `matches` — the query terms found in the chunk). |
396
487
  | `--semantic` | `search` only: pure vector ranking, skip lexical/RRF fusion (zero lexical tokenization). |
397
488
  | `--rerank` | Re-rank the candidate pool with a cross-encoder (`Xenova/bge-reranker-base`, ~280 MB model, downloaded on first use). Slower, sharper results — see *Reranking* below. |
489
+ | `--graph-boost <n>` | Weight for Obsidian wikilink graph ranking and PageRank prior (search; default 0). Incorporates document centrality and 2-hop contextual propagation. |
490
+ | `--filter <expr>` | Rich boolean filter across frontmatter tags and properties (e.g. `tag:engineering AND status != archived`). |
491
+ | `--ann` | Approximate nearest neighbor search via IVF clustering (search; auto-enables for large corpora). |
492
+ | `--nprobe <n>` | Number of nearest centroid clusters to probe during ANN search (default 8). |
398
493
  | `--port <n>` | HTTP port for `serve` (default 8747, or `MDSS_PORT`). |
399
494
  | `--host <ip>` | Bind address for `serve` (default `127.0.0.1` — loopback only; use `0.0.0.0` to expose on the LAN, or `MDSS_HOST`). |
400
495
  | `--watch` | `serve`: re-index incrementally when files change. |
@@ -422,6 +517,30 @@ mdss index
422
517
  mdss search "incident runbook for db failover"
423
518
  ```
424
519
 
520
+ ### Configuration file (`.mdssrc` / `mdss.config.json`)
521
+
522
+ Instead of repeating CLI options on every command, create a `.mdssrc.json` or `mdss.config.json` file.
523
+ `mdss` discovers config files by searching:
524
+ 1. An explicit path passed via `--config <path>` or the `MDSS_CONFIG` environment variable.
525
+ 2. Current working directory up through ancestor directories (`.mdssrc.json`, `mdss.config.json`, `.mdssrc`).
526
+ 3. User global config at `~/.mdssrc.json` or `~/.mdssrc`.
527
+
528
+ CLI flags always override configuration values.
529
+
530
+ Example `.mdssrc.json`:
531
+
532
+ ```json
533
+ {
534
+ "db": "./notes",
535
+ "model": "e5-base",
536
+ "indexDir": "./notes/.mdss",
537
+ "ignore": ["archive/**", "drafts/**"],
538
+ "k": 6
539
+ }
540
+ ```
541
+
542
+ Run `mdss check` to validate your configuration file schema and detect unknown keys.
543
+
425
544
  ## Models
426
545
 
427
546
  ```bash
@@ -527,6 +646,11 @@ section instead of silently producing wrong vectors.
527
646
  No external services, no database — the whole index is one JSON file and search
528
647
  is an in-memory dot-product sweep.
529
648
 
649
+ ## Integrations
650
+
651
+ - **Obsidian**: An official plugin is available in [`integrations/obsidian`](./integrations/obsidian) providing a live semantic search panel directly in your vault connected to `mdss serve`.
652
+ - **Model Context Protocol (MCP)**: Native stdio JSON-RPC 2.0 server (`mdss mcp`) integrating with Claude Desktop, Cursor, Copilot, Antigravity, and AI agents for local knowledge retrieval.
653
+
530
654
  ## License
531
655
 
532
656
  MIT © chelslava