context-vault 2.2.0 → 2.4.0

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 (32) hide show
  1. package/bin/cli.js +393 -63
  2. package/node_modules/@context-vault/core/LICENSE +21 -0
  3. package/node_modules/@context-vault/core/package.json +36 -0
  4. package/{src → node_modules/@context-vault/core/src}/capture/index.js +3 -2
  5. package/{src → node_modules/@context-vault/core/src}/core/categories.js +1 -0
  6. package/{src → node_modules/@context-vault/core/src}/core/config.js +5 -0
  7. package/{src → node_modules/@context-vault/core/src}/core/files.js +1 -0
  8. package/{src → node_modules/@context-vault/core/src}/core/status.js +32 -8
  9. package/node_modules/@context-vault/core/src/index/db.js +245 -0
  10. package/node_modules/@context-vault/core/src/index/embed.js +87 -0
  11. package/{src → node_modules/@context-vault/core/src}/index/index.js +51 -12
  12. package/node_modules/@context-vault/core/src/index.js +29 -0
  13. package/{src → node_modules/@context-vault/core/src}/retrieve/index.js +52 -43
  14. package/{src → node_modules/@context-vault/core/src}/server/tools.js +195 -31
  15. package/package.json +15 -15
  16. package/scripts/postinstall.js +45 -0
  17. package/scripts/prepack.js +31 -0
  18. package/src/server/index.js +127 -68
  19. package/ui/serve.js +7 -6
  20. package/README.md +0 -431
  21. package/smithery.yaml +0 -10
  22. package/src/capture/README.md +0 -23
  23. package/src/core/README.md +0 -20
  24. package/src/index/README.md +0 -28
  25. package/src/index/db.js +0 -139
  26. package/src/index/embed.js +0 -57
  27. package/src/retrieve/README.md +0 -19
  28. package/src/server/README.md +0 -44
  29. /package/{src → node_modules/@context-vault/core/src}/capture/file-ops.js +0 -0
  30. /package/{src → node_modules/@context-vault/core/src}/capture/formatters.js +0 -0
  31. /package/{src → node_modules/@context-vault/core/src}/core/frontmatter.js +0 -0
  32. /package/{src → node_modules/@context-vault/core/src}/server/helpers.js +0 -0
@@ -9,74 +9,133 @@ import { fileURLToPath } from "node:url";
9
9
  const __dirname = dirname(fileURLToPath(import.meta.url));
10
10
  const pkg = JSON.parse(readFileSync(join(__dirname, "..", "..", "package.json"), "utf-8"));
11
11
 
12
- import { resolveConfig } from "../core/config.js";
13
- import { embed } from "../index/embed.js";
14
- import { initDatabase, prepareStatements, insertVec, deleteVec } from "../index/db.js";
15
- import { registerTools } from "./tools.js";
16
-
17
- // ─── Config Resolution ──────────────────────────────────────────────────────
18
-
19
- const config = resolveConfig();
20
-
21
- // Create directories
22
- mkdirSync(config.dataDir, { recursive: true });
23
- mkdirSync(config.vaultDir, { recursive: true });
24
-
25
- // Write .context-mcp marker (always update to reflect current version)
26
- const markerPath = join(config.vaultDir, ".context-mcp");
27
- const markerData = existsSync(markerPath) ? JSON.parse(readFileSync(markerPath, "utf-8")) : {};
28
- writeFileSync(markerPath, JSON.stringify({ created: markerData.created || new Date().toISOString(), version: pkg.version }, null, 2) + "\n");
29
-
30
- // Update existence flag after directory creation
31
- config.vaultDirExists = existsSync(config.vaultDir);
32
-
33
- // Startup diagnostics
34
- console.error(`[context-mcp] Vault: ${config.vaultDir}`);
35
- console.error(`[context-mcp] Database: ${config.dbPath}`);
36
- console.error(`[context-mcp] Dev dir: ${config.devDir}`);
37
- if (!config.vaultDirExists) {
38
- console.error(`[context-mcp] WARNING: Vault directory not found!`);
12
+ import { resolveConfig } from "@context-vault/core/core/config";
13
+ import { embed } from "@context-vault/core/index/embed";
14
+ import { initDatabase, NativeModuleError, prepareStatements, insertVec, deleteVec } from "@context-vault/core/index/db";
15
+ import { registerTools } from "@context-vault/core/server/tools";
16
+
17
+ // ─── Phased Startup ─────────────────────────────────────────────────────────
18
+
19
+ async function main() {
20
+ let phase = "CONFIG";
21
+ let db;
22
+
23
+ try {
24
+ // ── Phase: CONFIG ────────────────────────────────────────────────────────
25
+ const config = resolveConfig();
26
+
27
+ // ── Phase: DIRS ──────────────────────────────────────────────────────────
28
+ phase = "DIRS";
29
+ mkdirSync(config.dataDir, { recursive: true });
30
+ mkdirSync(config.vaultDir, { recursive: true });
31
+
32
+ // Write .context-mcp marker (non-fatal)
33
+ try {
34
+ const markerPath = join(config.vaultDir, ".context-mcp");
35
+ const markerData = existsSync(markerPath) ? JSON.parse(readFileSync(markerPath, "utf-8")) : {};
36
+ writeFileSync(markerPath, JSON.stringify({ created: markerData.created || new Date().toISOString(), version: pkg.version }, null, 2) + "\n");
37
+ } catch (markerErr) {
38
+ console.error(`[context-mcp] Warning: could not write marker file: ${markerErr.message}`);
39
+ }
40
+
41
+ config.vaultDirExists = existsSync(config.vaultDir);
42
+
43
+ // Startup diagnostics
44
+ console.error(`[context-mcp] Vault: ${config.vaultDir}`);
45
+ console.error(`[context-mcp] Database: ${config.dbPath}`);
46
+ console.error(`[context-mcp] Dev dir: ${config.devDir}`);
47
+ if (!config.vaultDirExists) {
48
+ console.error(`[context-mcp] WARNING: Vault directory not found!`);
49
+ }
50
+
51
+ // ── Phase: DB ────────────────────────────────────────────────────────────
52
+ phase = "DB";
53
+ db = await initDatabase(config.dbPath);
54
+ const stmts = prepareStatements(db);
55
+
56
+ const ctx = {
57
+ db,
58
+ config,
59
+ stmts,
60
+ embed,
61
+ insertVec: (rowid, embedding) => insertVec(stmts, rowid, embedding),
62
+ deleteVec: (rowid) => deleteVec(stmts, rowid),
63
+ };
64
+
65
+ // ── Phase: SERVER ────────────────────────────────────────────────────────
66
+ phase = "SERVER";
67
+ const server = new McpServer(
68
+ { name: "context-mcp", version: pkg.version },
69
+ { capabilities: { tools: {} } }
70
+ );
71
+
72
+ registerTools(server, ctx);
73
+
74
+ // ── Graceful Shutdown ────────────────────────────────────────────────────
75
+ function shutdown(signal) {
76
+ console.error(`[context-mcp] Received ${signal}, shutting down...`);
77
+ try {
78
+ if (db.inTransaction) {
79
+ console.error("[context-mcp] Rolling back active transaction...");
80
+ db.exec("ROLLBACK");
81
+ }
82
+ db.pragma("wal_checkpoint(TRUNCATE)");
83
+ db.close();
84
+ console.error("[context-mcp] Database closed cleanly.");
85
+ } catch (shutdownErr) {
86
+ console.error(`[context-mcp] Shutdown error: ${shutdownErr.message}`);
87
+ }
88
+ process.exit(0);
89
+ }
90
+ process.on("SIGINT", () => shutdown("SIGINT"));
91
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
92
+
93
+ // ── Phase: CONNECTED ─────────────────────────────────────────────────────
94
+ phase = "CONNECTED";
95
+ const transport = new StdioServerTransport();
96
+ await server.connect(transport);
97
+
98
+ // ── Non-blocking Update Check ────────────────────────────────────────────
99
+ setTimeout(() => {
100
+ import("node:child_process").then(({ execSync }) => {
101
+ try {
102
+ const latest = execSync("npm view context-vault version", {
103
+ encoding: "utf-8",
104
+ timeout: 5000,
105
+ stdio: ["pipe", "pipe", "pipe"],
106
+ }).trim();
107
+ if (latest && latest !== pkg.version) {
108
+ console.error(`[context-mcp] Update available: v${pkg.version} → v${latest}. Run: context-mcp update`);
109
+ }
110
+ } catch {}
111
+ }).catch(() => {});
112
+ }, 3000);
113
+
114
+ } catch (err) {
115
+ if (err instanceof NativeModuleError) {
116
+ // Boxed diagnostic for native module mismatch
117
+ console.error("");
118
+ console.error("╔══════════════════════════════════════════════════════════════╗");
119
+ console.error("║ context-mcp: Native Module Error ║");
120
+ console.error("╚══════════════════════════════════════════════════════════════╝");
121
+ console.error("");
122
+ console.error(err.message);
123
+ console.error("");
124
+ console.error(` Node.js path: ${process.execPath}`);
125
+ console.error(` Node.js version: ${process.version}`);
126
+ console.error("");
127
+ process.exit(78); // EX_CONFIG
128
+ }
129
+
130
+ console.error(`[context-mcp] Fatal error during ${phase} phase: ${err.message}`);
131
+ if (phase === "DB") {
132
+ console.error(`[context-mcp] Try deleting the DB file and restarting: rm "${err.dbPath || "vault.db"}"`);
133
+ }
134
+ process.exit(1);
135
+ }
39
136
  }
40
137
 
41
- // ─── Database Init ───────────────────────────────────────────────────────────
42
-
43
- let db, stmts;
44
- try {
45
- db = initDatabase(config.dbPath);
46
- stmts = prepareStatements(db);
47
- } catch (e) {
48
- console.error(`[context-mcp] Database init failed: ${e.message}`);
49
- console.error(`[context-mcp] DB path: ${config.dbPath}`);
50
- console.error(`[context-mcp] Try deleting the DB file and restarting: rm "${config.dbPath}"`);
138
+ main().catch((err) => {
139
+ console.error(`[context-mcp] Unexpected fatal error: ${err.message}`);
51
140
  process.exit(1);
52
- }
53
-
54
- const ctx = {
55
- db,
56
- config,
57
- stmts,
58
- embed,
59
- insertVec: (rowid, embedding) => insertVec(stmts, rowid, embedding),
60
- deleteVec: (rowid) => deleteVec(stmts, rowid),
61
- };
62
-
63
- // ─── MCP Server ──────────────────────────────────────────────────────────────
64
-
65
- const server = new McpServer(
66
- { name: "context-mcp", version: pkg.version },
67
- { capabilities: { tools: {} } }
68
- );
69
-
70
- registerTools(server, ctx);
71
-
72
- // ─── Graceful Shutdown ───────────────────────────────────────────────────────
73
-
74
- function shutdown() {
75
- try { db.close(); } catch {}
76
- process.exit(0);
77
- }
78
- process.on("SIGINT", shutdown);
79
- process.on("SIGTERM", shutdown);
80
-
81
- const transport = new StdioServerTransport();
82
- await server.connect(transport);
141
+ });
package/ui/serve.js CHANGED
@@ -12,10 +12,10 @@ import { createServer } from "node:http";
12
12
  import { readFileSync, writeFileSync, existsSync, statSync, readdirSync } from "node:fs";
13
13
  import { resolve, dirname, join, basename } from "node:path";
14
14
  import { fileURLToPath } from "node:url";
15
- import { resolveConfig } from "../src/config.js";
16
- import { initDatabase } from "../src/db.js";
17
- import { embed } from "../src/embed.js";
18
- import { hybridSearch } from "../src/search.js";
15
+ import { resolveConfig } from "@context-vault/core/core/config";
16
+ import { initDatabase } from "@context-vault/core/index/db";
17
+ import { embed } from "@context-vault/core/index/embed";
18
+ import { hybridSearch } from "@context-vault/core/retrieve";
19
19
 
20
20
  const __dirname = dirname(fileURLToPath(import.meta.url));
21
21
 
@@ -348,8 +348,9 @@ async function handleSearch(res, url) {
348
348
 
349
349
  if (!query) return jsonResponse(res, { results: [] });
350
350
 
351
- const sorted = await hybridSearch(db, embed, query, kindFilter);
352
- jsonResponse(res, { query, results: sorted });
351
+ const searchCtx = { db, config, embed };
352
+ const results = await hybridSearch(searchCtx, query, { kindFilter });
353
+ jsonResponse(res, { query, results });
353
354
  }
354
355
 
355
356
  // ─── Config Handlers ─────────────────────────────────────────────────────────
package/README.md DELETED
@@ -1,431 +0,0 @@
1
- # context-mcp
2
-
3
- [![npm version](https://img.shields.io/npm/v/context-vault)](https://www.npmjs.com/package/context-vault)
4
- [![npm downloads](https://img.shields.io/npm/dm/context-vault)](https://www.npmjs.com/package/context-vault)
5
- [![license](https://img.shields.io/npm/l/context-vault)](./LICENSE)
6
- [![node](https://img.shields.io/node/v/context-vault)](https://nodejs.org)
7
-
8
- Persistent memory for AI agents — saves and searches knowledge across sessions.
9
-
10
- <p align="center">
11
- <img src="assets/demo.gif" alt="context-vault demo — Claude Code and Cursor using the knowledge vault" width="800">
12
- </p>
13
-
14
- ## Quick Start
15
-
16
- ```bash
17
- npm install -g context-vault
18
- context-mcp setup
19
- ```
20
-
21
- Setup auto-detects your tools (Claude Code, Claude Desktop, Cursor, Windsurf, Cline), downloads the embedding model, seeds your vault with a starter entry, and verifies everything works. Then open your AI tool and try:
22
-
23
- > "Search my vault for getting started"
24
-
25
- ## What It Does
26
-
27
- - **Save** insights, decisions, patterns, and any custom knowledge kind from AI sessions
28
- - **Search** with hybrid full-text + semantic similarity, ranked by relevance and recency
29
- - **Own your data** — plain markdown files in folders you control, git-versioned, human-editable
30
-
31
- ## Tools
32
-
33
- The server exposes five tools. Your AI agent calls them automatically — you don't invoke them directly.
34
-
35
- | Tool | Type | Description |
36
- |------|------|-------------|
37
- | `get_context` | Read | Hybrid FTS5 + vector search across all knowledge |
38
- | `save_context` | Write | Save new knowledge or update existing entries by ID |
39
- | `list_context` | Browse | List vault entries with filtering and pagination |
40
- | `delete_context` | Delete | Remove an entry by ID (file + index) |
41
- | `context_status` | Diag | Show resolved config, health, and per-kind file counts |
42
-
43
- ### `get_context` — Search your vault
44
-
45
- ```js
46
- get_context({
47
- query: "react query caching", // Natural language or keywords
48
- kind: "insight", // Optional: filter by kind
49
- tags: ["react"], // Optional: filter by tags
50
- limit: 5 // Optional: max results (default 10)
51
- })
52
- ```
53
-
54
- Returns entries ranked by combined full-text and semantic similarity, with recency weighting.
55
-
56
- ### `save_context` — Save or update knowledge
57
-
58
- ```js
59
- // Create new entry
60
- save_context({
61
- kind: "insight", // Determines folder: insights/
62
- body: "React Query staleTime defaults to 0",
63
- tags: ["react", "performance"],
64
- title: "staleTime gotcha", // Optional
65
- meta: { type: "gotcha" }, // Optional: any structured data
66
- folder: "react/hooks", // Optional: subfolder organization
67
- source: "debugging-session" // Optional: provenance
68
- })
69
- // → ~/vault/knowledge/insights/react/hooks/staletime-gotcha.md
70
-
71
- // Update existing entry by ID
72
- save_context({
73
- id: "01HXYZ...", // ULID from a previous save
74
- body: "Updated content here", // Only provide fields you want to change
75
- tags: ["react", "updated"] // Omitted fields are preserved
76
- })
77
- ```
78
-
79
- The `kind` field accepts any string — `"insight"`, `"decision"`, `"pattern"`, `"reference"`, or any custom kind. The folder is auto-created from the pluralized kind name.
80
-
81
- When updating (`id` provided), omitted fields are preserved from the original. You cannot change `kind` or `identity_key` — delete and re-create instead.
82
-
83
- ### `list_context` — Browse entries
84
-
85
- ```js
86
- list_context({
87
- kind: "insight", // Optional: filter by kind
88
- category: "knowledge", // Optional: knowledge, entity, or event
89
- tags: ["react"], // Optional: filter by tags
90
- limit: 10, // Optional: max results (default 20, max 100)
91
- offset: 0 // Optional: pagination offset
92
- })
93
- ```
94
-
95
- Returns entry metadata (id, title, kind, category, tags, created_at) without body content. Use `get_context` with a search query to retrieve full entries.
96
-
97
- ### `delete_context` — Remove an entry
98
-
99
- ```js
100
- delete_context({
101
- id: "01HXYZ..." // ULID of the entry to delete
102
- })
103
- ```
104
-
105
- Removes the markdown file from disk and cleans up the database and vector index.
106
-
107
- ### `context_status` — Diagnostics
108
-
109
- Shows vault path, database size, file counts per kind, embedding coverage, and any issues.
110
-
111
- ## Knowledge Organization
112
-
113
- ### Folders and Kinds
114
-
115
- Each top-level subdirectory in the vault maps to a `kind` value. The directory name is depluralized:
116
-
117
- ```
118
- knowledge/insights/ → kind: "insight"
119
- knowledge/decisions/ → kind: "decision"
120
- knowledge/patterns/ → kind: "pattern"
121
- knowledge/references/ → kind: "reference"
122
- ```
123
-
124
- Within each kind directory, nested subfolders provide human-browsable organization. The subfolder path is stored in `meta.folder`:
125
-
126
- ```
127
- ON DISK IN DB (vault table)
128
- knowledge/insights/ kind: "insight", meta.folder: null
129
- flat-file.md
130
- knowledge/insights/react/hooks/ kind: "insight", meta.folder: "react/hooks"
131
- use-query-gotcha.md
132
- ```
133
-
134
- Tags are semantic (what the content is about). Folder structure is organizational (where it lives). These are separate concerns.
135
-
136
- ### File Format
137
-
138
- All knowledge files use YAML frontmatter:
139
-
140
- ```markdown
141
- ---
142
- id: 01HXYZ...
143
- tags: ["react", "performance"]
144
- source: claude-code
145
- created: 2026-02-17T12:00:00Z
146
- ---
147
- React Query's staleTime defaults to 0 — set it explicitly or every mount triggers a refetch.
148
- ```
149
-
150
- Standard keys: `id`, `tags`, `source`, `created`. Any extra frontmatter keys (`type`, `status`, `language`, `folder`, etc.) are stored in a `meta` JSON column automatically.
151
-
152
- ### Custom Kinds
153
-
154
- No code changes required:
155
-
156
- 1. `mkdir ~/vault/knowledge/references/`
157
- 2. Add `.md` files with YAML frontmatter
158
- 3. The next session auto-indexes them
159
-
160
- The kind name comes from the directory: `references/` → kind `reference`.
161
-
162
- ## Configuration
163
-
164
- Works out of the box with zero config. All paths are overridable:
165
-
166
- ```
167
- CLI args > env vars > config file > convention defaults
168
- ```
169
-
170
- ### Defaults
171
-
172
- | Setting | Default |
173
- |---------|---------|
174
- | Vault dir | `~/vault/` |
175
- | Data dir | `~/.context-mcp/` |
176
- | Database | `~/.context-mcp/vault.db` |
177
- | Dev dir | `~/dev/` |
178
-
179
- ### Config File (`~/.context-mcp/config.json`)
180
-
181
- Lives in the data directory alongside the database. Created by `setup`, or create it manually:
182
-
183
- ```json
184
- {
185
- "vaultDir": "/Users/you/vault/",
186
- "dataDir": "/Users/you/.context-mcp",
187
- "dbPath": "/Users/you/.context-mcp/vault.db",
188
- "devDir": "/Users/you/dev"
189
- }
190
- ```
191
-
192
- ### Environment Variables
193
-
194
- | Variable | Overrides |
195
- |----------|-----------|
196
- | `CONTEXT_MCP_VAULT_DIR` | Vault directory (knowledge files) |
197
- | `CONTEXT_MCP_DB_PATH` | Database path |
198
- | `CONTEXT_MCP_DEV_DIR` | Dev directory |
199
- | `CONTEXT_MCP_DATA_DIR` | Data directory (DB + config storage) |
200
-
201
- ### CLI Arguments
202
-
203
- ```bash
204
- context-mcp serve --vault-dir /custom/vault --dev-dir /custom/dev
205
- context-mcp serve --data-dir /custom/data --db-path /custom/data/vault.db
206
- ```
207
-
208
- ## CLI
209
-
210
- ```bash
211
- context-mcp <command> [options]
212
- ```
213
-
214
- | Command | Description |
215
- |---------|-------------|
216
- | `setup` | Interactive MCP installer — detects tools, writes configs |
217
- | `serve` | Start the MCP server (used by AI clients in MCP configs) |
218
- | `ui [--port 3141]` | Launch the web dashboard |
219
- | `reindex` | Rebuild search index from knowledge files |
220
- | `status` | Show vault diagnostics (paths, counts, health) |
221
-
222
- If running from source without a global install, use `node bin/cli.js` instead of `context-mcp`.
223
-
224
- ## Install
225
-
226
- ### npm (Recommended)
227
-
228
- ```bash
229
- npm install -g context-vault
230
- context-mcp setup
231
- ```
232
-
233
- The `setup` command auto-detects installed tools (Claude Code, Claude Desktop, Cursor, Windsurf, Cline), lets you pick which to configure, and writes the correct MCP config for each. Existing configs are preserved — only the `context-mcp` entry is added or updated.
234
-
235
- ### Local Development
236
-
237
- ```bash
238
- git clone https://github.com/fellanH/context-mcp.git
239
- cd context-mcp
240
- npm install
241
-
242
- # Interactive setup — detects your tools and configures them
243
- node bin/cli.js setup
244
- ```
245
-
246
- For non-interactive environments (CI, scripts):
247
-
248
- ```bash
249
- context-mcp setup --yes
250
- ```
251
-
252
- ### Manual Configuration
253
-
254
- If you prefer manual setup, add to your tool's MCP config. Pass `--vault-dir` to point at your vault folder (omit it to use the default `~/vault/`).
255
-
256
- **npm install** (portable — survives upgrades):
257
-
258
- ```json
259
- {
260
- "mcpServers": {
261
- "context-mcp": {
262
- "command": "context-mcp",
263
- "args": ["serve", "--vault-dir", "/path/to/vault"]
264
- }
265
- }
266
- }
267
- ```
268
-
269
- **Local dev clone** (absolute path to source):
270
-
271
- ```json
272
- {
273
- "mcpServers": {
274
- "context-mcp": {
275
- "command": "node",
276
- "args": ["/path/to/context-mcp/src/server/index.js", "--vault-dir", "/path/to/vault"]
277
- }
278
- }
279
- }
280
- ```
281
-
282
- You can also pass config via environment variables in the MCP config block:
283
-
284
- ```json
285
- {
286
- "mcpServers": {
287
- "context-mcp": {
288
- "command": "context-mcp",
289
- "args": ["serve"],
290
- "env": {
291
- "CONTEXT_MCP_VAULT_DIR": "/path/to/vault"
292
- }
293
- }
294
- }
295
- }
296
- ```
297
-
298
- ### How the Server Runs
299
-
300
- The server is an MCP (Model Context Protocol) process — you don't start or stop it manually. Your AI client (Claude Code, Cursor, Cline, etc.) spawns it automatically as a child process when a session begins, based on the `mcpServers` config above. The server communicates over stdio and lives for the duration of the session. When the session ends, the client terminates the process and SQLite cleans up its WAL files.
301
-
302
- This means:
303
- - **No daemon, no port, no background service.** The server only runs while your AI client is active.
304
- - **Multiple sessions** can run separate server instances concurrently — SQLite WAL mode handles concurrent access safely.
305
- - **Embedding model** is downloaded during `setup` (~22MB, all-MiniLM-L6-v2). If setup was skipped, it downloads on first use.
306
- - **Auto-reindex** on first tool call per session ensures the search index is always in sync with your files on disk. No manual reindex needed.
307
-
308
- ## Desktop App (macOS)
309
-
310
- A macOS dock application that starts the UI server and opens the dashboard in your browser.
311
-
312
- ```bash
313
- osacompile -o "/Applications/Context.app" ui/Context.applescript
314
- ```
315
-
316
- The app checks if port 3141 is already in use, starts the server if not, and opens `http://localhost:3141`. Server logs are written to `/tmp/context-mcp.log`.
317
-
318
- ## How It Works
319
-
320
- ```
321
- YOUR FILES (source of truth) SEARCH INDEX (derived)
322
- ~/vault/ ~/.context-mcp/vault.db
323
- ├── knowledge/ ┌───────────────────────────────┐
324
- │ ├── insights/ │ vault table │
325
- │ │ ├── react-query-caching.md │ kind: insight │
326
- │ │ └── react/hooks/ │ meta.folder: "react/hooks" │
327
- │ │ └── use-query-gotcha.md │ kind: decision │
328
- │ ├── decisions/ │ kind: pattern │
329
- │ │ └── use-sqlite-over-pg.md │ kind: <any custom> │
330
- │ └── patterns/ │ + FTS5 full-text │
331
- │ └── api-error-handler.md │ + vec0 embeddings │
332
- ├── entities/ └───────────────────────────────┘
333
- └── events/
334
- Human-editable, git-versioned Fast hybrid search, RAG-ready
335
- You own these files Rebuilt from files anytime
336
- ```
337
-
338
- The SQLite database is stored at `~/.context-mcp/vault.db` by default (configurable via `--db-path`, `CONTEXT_MCP_DB_PATH`, or `config.json`). It contains FTS5 full-text indexes and sqlite-vec embeddings (384-dim float32, all-MiniLM-L6-v2). The database is a derived index — delete it and the server rebuilds it automatically on next session.
339
-
340
- Requires **Node.js 20** or later.
341
-
342
- ### Architecture
343
-
344
- ```
345
- src/
346
- ├── core/ Shared utilities (config, frontmatter, files, status)
347
- ├── capture/ Write path — creates .md files in the vault
348
- ├── index/ Sync layer — SQLite schema, embeddings, reindex
349
- ├── retrieve/ Read path — hybrid FTS5 + vector search
350
- └── server/ MCP server — wires layers into tool handlers
351
-
352
- bin/
353
- └── cli.js CLI entry point (setup, serve, ui, reindex, status)
354
-
355
- ui/
356
- ├── serve.js HTTP server for web dashboard
357
- ├── index.html Single-page dashboard UI
358
- └── Context.applescript macOS dock app launcher
359
- ```
360
-
361
- Each layer has a single responsibility and can be understood independently. The server is the only module that imports across layer boundaries.
362
-
363
- ### Module Dependency Graph
364
-
365
- ```
366
- core/files.js, core/frontmatter.js ← capture/
367
-
368
- core/config.js server/ ← bin/cli.js
369
-
370
- index/embed.js ← retrieve/ ← ui/serve.js
371
-
372
- index/db.js ←────────────────── (all consumers)
373
- ```
374
-
375
- ## Troubleshooting
376
-
377
- ### Native module build failures
378
-
379
- `better-sqlite3` and `sqlite-vec` include native C code compiled for your platform. If install fails:
380
-
381
- ```bash
382
- npm rebuild better-sqlite3 sqlite-vec
383
- ```
384
-
385
- On Apple Silicon Macs, ensure you're running a native ARM Node.js (not Rosetta). Check with `node -p process.arch` — it should say `arm64`.
386
-
387
- ### Vault directory not found
388
-
389
- If `context_status` or `get_context` reports the vault directory doesn't exist:
390
-
391
- ```bash
392
- context-mcp status # Shows resolved paths
393
- mkdir -p ~/vault # Create the default vault directory
394
- ```
395
-
396
- Or re-run `context-mcp setup` to reconfigure.
397
-
398
- ### Embedding model download
399
-
400
- The embedding model (all-MiniLM-L6-v2, ~22MB) is normally downloaded during `context-mcp setup`. If setup was skipped or the cache was cleared, it downloads automatically on first use. If it hangs, check your network or proxy settings.
401
-
402
- ### Stale search index
403
-
404
- If search results seem outdated or missing:
405
-
406
- ```bash
407
- context-mcp reindex
408
- ```
409
-
410
- This rebuilds the entire index from your vault files. Auto-reindex runs on every session start, but manual reindex can help diagnose issues.
411
-
412
- ### Config path debugging
413
-
414
- ```bash
415
- context-mcp status
416
- ```
417
-
418
- Shows all resolved paths (vault dir, data dir, DB path, config file) and where each was resolved from (defaults, config file, env, or CLI args).
419
-
420
- ## Dependencies
421
-
422
- | Package | Purpose |
423
- |---------|---------|
424
- | `@modelcontextprotocol/sdk` | MCP protocol (McpServer, StdioServerTransport) |
425
- | `better-sqlite3` | SQLite driver |
426
- | `sqlite-vec` | Vector search (384-dim float32) |
427
- | `@huggingface/transformers` | Local embeddings (all-MiniLM-L6-v2, ~22MB) |
428
-
429
- ## License
430
-
431
- MIT
package/smithery.yaml DELETED
@@ -1,10 +0,0 @@
1
- startCommand:
2
- type: stdio
3
- configSchema:
4
- type: object
5
- properties:
6
- vaultDir:
7
- type: string
8
- description: "Path to the vault directory containing your knowledge files. Defaults to ~/vault/"
9
- commandFunction: |-
10
- (config) => ({ command: 'npx', args: ['-y', 'context-vault', 'serve', ...(config.vaultDir ? ['--vault-dir', config.vaultDir] : [])] })