@j0hanz/memdb 1.3.0 → 1.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.
package/README.md CHANGED
@@ -1,205 +1,663 @@
1
- # MemDB MCP Server
2
-
3
- <img src="assets/logo.svg" alt="MemDB MCP Server Logo" width="225" />
4
-
5
- [![npm version](https://img.shields.io/npm/v/@j0hanz/memdb.svg)](https://www.npmjs.com/package/@j0hanz/memdb) [![License](https://img.shields.io/npm/l/@j0hanz/memdb.svg)](https://github.com/j0hanz/memdb-mcp-server/blob/master/package.json)
6
-
7
- [![Install with NPX in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=memdb&inputs=%5B%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Fmemdb%40latest%22%5D%7D) [![Install with NPX in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=memdb&inputs=%5B%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Fmemdb%40latest%22%5D%7D&quality=insiders)
8
-
9
- [![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/install-mcp?name=memdb&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovbWVtZGJAbGF0ZXN0Il19)
10
-
11
- A specialized Memory MCP Server that provides a local Knowledge Graph and full-text search capabilities for AI assistants, backed by SQLite.
12
-
13
- ## Overview
14
-
15
- MemDB allows AI assistants to persist long-term memories, facts, and relationships in a local SQLite database. Beyond simple storage, it supports **content-deduplicated versioning**, **tag-based organization**, and **graph relationships** (linking memories together). It includes a powerful `recall` tool that traverses these relationships to retrieve connected context, effectively acting as a graph-augmented RAG system for your workspace.
16
-
17
- ## Key Features
18
-
19
- - **Local Storage**: All data persists in a local SQLite database (`.memdb/memory.db`) within your workspace.
20
- - **Knowledge Graph**: Link memories with typed relationships (e.g., `causes`, `depends_on`, `related_to`).
21
- - **Graph Traversal**: `recall` tool traverses the graph (up to 3 hops) to find connected context.
22
- - **Full-Text Search**: Powered by SQLite FTS5 for fast, relevance-ranked searches.
23
- - **Deduplication**: Content is automatically hashed (SHA-256) to prevent duplicate storage.
24
- - **Categorization**: Rich metadata support including tags, importance levels, and memory types.
25
- - **Batch Operations**: dedicated tools for bulk `store` and `delete` actions.
26
-
27
- ## Tech Stack
28
-
29
- - **Runtime**: Node.js >= 22.0.0 (Required for native `node:sqlite`)
30
- - **Database**: SQLite (using `node:sqlite` sync API)
31
- - **Protocol**: Model Context Protocol (MCP) SDK `v1.26.0+`
32
- - **Validation**: Zod schema validation
33
- - **Architecture**: Layered (Core DB <-> Tools <-> Transport)
34
-
35
- ## Requirements
36
-
37
- - **Node.js**: Version **22.0.0** or higher is **strictly required**. This server uses the native `node:sqlite` module available only in recent Node.js versions.
38
-
39
- ## Quickstart
40
-
41
- Run directly with `npx`:
42
-
43
- ```bash
44
- npx -y @j0hanz/memdb@latest
45
- ```
46
-
47
- This will start the server on stdio. The database will be created at `.memdb/memory.db` in the current working directory.
48
-
49
- ## Installation
50
-
51
- ### NPX (Recommended)
52
-
53
- ```bash
54
- npx -y @j0hanz/memdb@latest
55
- ```
56
-
57
- ### From Source
58
-
59
- ```bash
60
- git clone https://github.com/j0hanz/memdb-mcp-server.git
61
- cd memdb-mcp-server
62
- npm install
63
- npm run build
64
- npm start
65
- ```
66
-
67
- ## Configuration
68
-
69
- The server is configured via environment variables.
70
-
71
- | Environment Variable | Description | Default |
72
- | :---------------------- | :---------------------------------------------------------------------- | :----------------- |
73
- | `MEMDB_PATH` | Path to the SQLite database file. Use `:memory:` for ephemeral storage. | `.memdb/memory.db` |
74
- | `MEMDB_LOG_LEVEL` | Logging level (`info`, `warn`, `error`). | `info` |
75
- | `MEMDB_TOOL_TIMEOUT_MS` | Execution timeout for tools in milliseconds. | `15000` |
76
-
77
- **Note**: To keep the database out of version control, add `.memdb/` to your `.gitignore`.
78
-
79
- ## MCP Surface
80
-
81
- ### Tools
82
-
83
- This server exposes 12 tools for managing memories and relationships.
84
-
85
- #### Memory Management
86
-
87
- | Tool | Description | Key Parameters |
88
- | :-------------------- | :------------------------------------------------------- | :---------------------------------------------------- |
89
- | **`store_memory`** | Store a single memory. Deduplicates by content hash. | `content`, `tags`, `importance` (0-10), `memory_type` |
90
- | **`store_memories`** | Batch store multiple memories. Supports partial success. | `items` (array of objects) |
91
- | **`get_memory`** | Retrieve a memory by its SHA-256 hash. | `hash` |
92
- | **`update_memory`** | Update an existing memory (creates new hash). | `hash`, `content`, `tags` (optional replace) |
93
- | **`delete_memory`** | Delete a single memory by hash. | `hash` |
94
- | **`delete_memories`** | Batch delete multiple memories. | `hashes` (array) |
95
-
96
- #### Search & Retrieval
97
-
98
- | Tool | Description | Key Parameters |
99
- | :-------------------- | :---------------------------------------------------------------------------------------- | :-------------------------------- |
100
- | **`search_memories`** | FTS5 full-text search across content and tags. | `query` |
101
- | **`recall`** | **Graph Search**. Finds a memory and traverses relationships to return connected context. | `query`, `depth` (0-3, default 1) |
102
- | **`memory_stats`** | Get total counts, tag counts, and timeline stats. | _(none)_ |
103
-
104
- #### Relationships (Knowledge Graph)
105
-
106
- | Tool | Description | Key Parameters |
107
- | :------------------------ | :---------------------------------------------- | :--------------------------------------------------- |
108
- | **`create_relationship`** | Create a directional link between two memories. | `from_hash`, `to_hash`, `relation_type` |
109
- | **`get_relationships`** | Get linked memories for a given hash. | `hash`, `direction` ('outgoing', 'incoming', 'both') |
110
- | **`delete_relationship`** | Remove a specific link between memories. | `from_hash`, `to_hash`, `relation_type` |
111
-
112
- ### Resources
113
-
114
- | URI | Description | Mime Type |
115
- | :------------------------ | :------------------------------------------------ | :-------------- |
116
- | `internal://instructions` | Usage instructions and guidelines for the server. | `text/markdown` |
117
-
118
- ## Client Configuration Examples
119
-
120
- <details>
121
- <summary><b>VS Code</b></summary>
122
-
123
- Add to `settings.json` or `.vscode/mcp.json`:
124
-
125
- ```json
126
- {
127
- "mcpServers": {
128
- "memdb": {
129
- "command": "npx",
130
- "args": ["-y", "@j0hanz/memdb@latest"]
131
- }
132
- }
133
- }
134
- ```
135
-
136
- </details>
137
-
138
- <details>
139
- <summary><b>Claude Desktop</b></summary>
140
-
141
- Add to `claude_desktop_config.json`:
142
-
143
- ```json
144
- {
145
- "mcpServers": {
146
- "memdb": {
147
- "command": "npx",
148
- "args": ["-y", "@j0hanz/memdb@latest"]
149
- }
150
- }
151
- }
152
- ```
153
-
154
- </details>
155
-
156
- <details>
157
- <summary><b>Cursor</b></summary>
158
-
159
- 1. Open **Cursor Settings** > **Features** > **MCP**.
160
- 2. Click **+ Add New MCP Server**.
161
- 3. **Name**: `memdb`
162
- 4. **Type**: `command`
163
- 5. **Command**: `npx -y @j0hanz/memdb@latest`
164
-
165
- Or use the **Install in Cursor** button at the top of this README.
166
-
167
- </details>
168
-
169
- ## Repository Structure
170
-
171
- ```text
172
- c:\memdb
173
- ├── src
174
- │ ├── core # Database logic, schema, and search
175
- │ │ ├── db.ts # SQLite connection & schema
176
- │ │ ├── memory-read.ts # Get/Delete/Stats operations
177
- │ │ ├── memory-write.ts # Store/Update operations
178
- │ │ ├── relationships.ts# Graph edge operations
179
- │ │ └── search.ts # FTS5 & Graph traversal
180
- │ ├── index.ts # Server entrypoint & transport setup
181
- │ ├── schemas.ts # Zod schemas for tools
182
- ├── tools.ts # Tool definitions & registration
183
- │ └── types.ts # TypeScript interfaces
184
- ├── scripts # Build and test automation
185
- ├── tests/ # Node.js native tests
186
- └── package.json
187
- ```
188
-
189
- ## Development Workflow
190
-
191
- 1. **Install**: `npm install`
192
- 2. **Dev Mode**: `npm run dev` (watches and recompiles)
193
- 3. **Run**: `npm start` (runs `dist/index.js`)
194
- 4. **Test**: `npm test` (runs native Node.js test runner)
195
- 5. **Lint**: `npm run lint`
196
-
197
- ## Troubleshooting
198
-
199
- - **`node:sqlite` not found**: You are likely running a Node.js version older than 22.0.0. Please upgrade Node.js.
200
- - **Database Locked**: This server uses WAL mode (`PRAGMA journal_mode = WAL`). If you access the `.memdb/memory.db` file with another tool while the server is running, you may encounter locking issues.
201
- - **FTS5 Errors**: The bundled `node:sqlite` usually includes FTS5. If you see FTS errors, ensure your Node.js binary was built with standard SQLite extensions.
202
-
203
- ## License
204
-
205
- This project is licensed under the **MIT** License.
1
+ # memdb
2
+
3
+ [![npm version](https://img.shields.io/npm/v/%40j0hanz%2Fmemdb)](https://www.npmjs.com/package/@j0hanz/memdb) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D24-339933?logo=node.js)](https://nodejs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-3178C6?logo=typescript)](https://www.typescriptlang.org/) [![MCP SDK](https://img.shields.io/badge/MCP_SDK-1.26-blueviolet)](https://modelcontextprotocol.io/)
4
+
5
+ [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install_Server-0078d7?logo=visual-studio-code&logoColor=white)](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%7B%22name%22%3A%22memdb%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Fmemdb%40latest%22%5D%7D) [![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install_Server-24bfa5?logo=visual-studio-code&logoColor=white)](https://insiders.vscode.dev/redirect?url=vscode-insiders%3Amcp%2Finstall%3F%7B%22name%22%3A%22memdb%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Fmemdb%40latest%22%5D%7D)
6
+
7
+ > A SQLite-backed MCP memory server with local workspace storage, full-text search (FTS5), and knowledge graph capabilities for AI assistants.
8
+
9
+ ---
10
+
11
+ ## Overview
12
+
13
+ **memdb** is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that provides persistent memory storage for AI assistants. It uses Node.js's native `node:sqlite` module to store memories locally with SHA-256 content deduplication, FTS5 full-text search, and a knowledge graph of typed relationships between memories. Communication happens over **stdio** transport.
14
+
15
+ ## Key Features
16
+
17
+ - **Persistent local storage** — SQLite database stored in the workspace (`.memdb/memory.db` by default) with WAL mode for performance
18
+ - **Full-text search** — FTS5-powered content and tag search with BM25 relevance scoring and recency boosting
19
+ - **Knowledge graph** Directed, typed relationships between memories with recursive graph traversal (`recall`)
20
+ - **SHA-256 deduplication** Content-addressed storage prevents duplicate memories automatically
21
+ - **Batch operations** Store or delete up to 50 memories in a single call with partial success support
22
+ - **Memory classification** Categorize memories by type (general, fact, plan, decision, reflection, lesson, error, gradient) and importance (0–10)
23
+ - **Protocol safety** Custom stdio transport that rejects JSON-RPC batch requests, protocol version guard, and tool execution timeouts
24
+
25
+ ## Tech Stack
26
+
27
+ | Component | Technology |
28
+ | --------------- | ----------------------------------------- |
29
+ | Runtime | Node.js 24 |
30
+ | Language | TypeScript 5.9 (strict mode) |
31
+ | MCP SDK | `@modelcontextprotocol/sdk` v1.26.0 |
32
+ | Database | SQLite via native `node:sqlite` with FTS5 |
33
+ | Validation | Zod v4 |
34
+ | Transport | stdio |
35
+ | Package Manager | npm |
36
+
37
+ ## Architecture
38
+
39
+ ```text
40
+ ┌─────────────────────────────────────────────┐
41
+ │ Client │
42
+ └──────────────────┬──────────────────────────┘
43
+ │ stdio (JSON-RPC)
44
+ ┌──────────────────▼──────────────────────────┐
45
+ │ 1. BatchRejectingStdioServerTransport │ ← Rejects JSON-RPC batch arrays
46
+ │ 2. ProtocolVersionGuardTransport │ ← Validates protocol version
47
+ 3. McpServer (MCP SDK) │ ← Tool/resource registration
48
+ │ 4. Tool handlers with timeout + error wrap │ ← Zod validation, abort signals
49
+ 5. Core layer (db, search, relationships) │ ← SQLite + FTS5 + knowledge graph
50
+ └─────────────────────────────────────────────┘
51
+ ```
52
+
53
+ ## Repository Structure
54
+
55
+ ```text
56
+ memdb/
57
+ ├── src/
58
+ │ ├── core/ # Database and business logic
59
+ │ │ ├── db.ts # SQLite connection, schema, WAL, statement cache
60
+ │ │ ├── memory-read.ts # Get, delete, stats operations
61
+ │ │ ├── memory-write.ts # Store, update with SHA-256 deduplication
62
+ │ │ ├── relationships.ts # Knowledge graph edge operations
63
+ │ │ ├── search.ts # FTS5 search and graph traversal (recall)
64
+ │ │ └── abort.ts # Abort signal utilities
65
+ │ ├── index.ts # Server entrypoint, stdio transport, shutdown
66
+ │ ├── tools.ts # MCP tool registration with timeout handling
67
+ │ ├── schemas.ts # Zod schemas for all 12 tools
68
+ │ ├── types.ts # TypeScript interfaces
69
+ │ ├── config.ts # Environment variable configuration
70
+ │ ├── logger.ts # Logging (console.error, never stdout)
71
+ │ ├── stdio-transport.ts # Custom stdio transport with batch rejection
72
+ │ ├── protocol-version-guard.ts # Protocol version validation
73
+ │ ├── instructions.md # User-facing instructions (MCP resource)
74
+ │ ├── async-context.ts # AsyncLocalStorage for tool context
75
+ │ └── error-utils.ts # Error message extraction
76
+ ├── tests/ # node:test runner tests
77
+ ├── scripts/ # Build & task automation
78
+ ├── assets/ # Logo/icon assets
79
+ ├── .github/workflows/ # CI/CD (npm publish on release)
80
+ ├── package.json
81
+ ├── tsconfig.json
82
+ └── eslint.config.mjs
83
+ ```
84
+
85
+ ## Requirements
86
+
87
+ - **Node.js 24** — required for the native `node:sqlite` module
88
+
89
+ ## Quickstart
90
+
91
+ The fastest way to start using memdb is via `npx`:
92
+
93
+ ```bash
94
+ npx -y @j0hanz/memdb@latest
95
+ ```
96
+
97
+ Add to your MCP client configuration:
98
+
99
+ ```json
100
+ {
101
+ "mcpServers": {
102
+ "memdb": {
103
+ "command": "npx",
104
+ "args": ["-y", "@j0hanz/memdb@latest"]
105
+ }
106
+ }
107
+ }
108
+ ```
109
+
110
+ ## Installation
111
+
112
+ ### NPX (recommended)
113
+
114
+ No installation needed runs the latest version directly:
115
+
116
+ ```bash
117
+ npx -y @j0hanz/memdb@latest
118
+ ```
119
+
120
+ ### Global Install
121
+
122
+ ```bash
123
+ npm install -g @j0hanz/memdb
124
+ memdb
125
+ ```
126
+
127
+ ### From Source
128
+
129
+ ```bash
130
+ git clone https://github.com/j0hanz/memdb-mcp-server.git
131
+ cd memdb-mcp-server
132
+ npm install
133
+ npm run build
134
+ npm start
135
+ ```
136
+
137
+ ## Configuration
138
+
139
+ ### Environment Variables
140
+
141
+ | Variable | Type | Default | Description |
142
+ | ----------------------- | --------------------------- | ------------------ | ------------------------------------------------------------------------------ |
143
+ | `MEMDB_PATH` | `string` | `.memdb/memory.db` | Path to the SQLite database file. Set to `:memory:` for an in-memory database. |
144
+ | `MEMDB_LOG_LEVEL` | `error` \| `warn` \| `info` | `info` | Logging verbosity level |
145
+ | `MEMDB_TOOL_TIMEOUT_MS` | `integer` | `15000` | Tool execution timeout in milliseconds (non-negative integer) |
146
+
147
+ Environment variables can be set via a `.env` file when using `npm run dev:run`, or passed directly to the process.
148
+
149
+ ### Database Location
150
+
151
+ By default, memdb creates the database at `.memdb/memory.db` relative to the working directory. The directory is created automatically if it doesn't exist.
152
+
153
+ ## Usage
154
+
155
+ memdb communicates exclusively over **stdio** transport. Start the server and connect via any MCP-compatible client:
156
+
157
+ ```bash
158
+ # Direct
159
+ node dist/index.js
160
+
161
+ # Via npx
162
+ npx -y @j0hanz/memdb@latest
163
+
164
+ # With custom database path
165
+ MEMDB_PATH=/path/to/my.db npx -y @j0hanz/memdb@latest
166
+ ```
167
+
168
+ ## MCP Surface
169
+
170
+ ### Tools
171
+
172
+ memdb exposes **12 tools** organized into memory management, search, knowledge graph, and diagnostics.
173
+
174
+ ---
175
+
176
+ #### `store_memory`
177
+
178
+ Store a new memory with tags. Idempotent storing the same content returns the existing hash.
179
+
180
+ | Parameter | Type | Required | Default | Description |
181
+ | ------------- | ---------- | -------- | ----------- | ------------------------------------------------------------------------------------------------ |
182
+ | `content` | `string` | Yes | — | The content of the memory (1–100,000 chars) |
183
+ | `tags` | `string[]` | Yes | — | Tags to categorize the memory (1–100 tags, no whitespace, max 50 chars each) |
184
+ | `importance` | `integer` | No | `0` | Priority level 0–10 (0=lowest, 10=critical). Higher importance memories surface first in search. |
185
+ | `memory_type` | `string` | No | `"general"` | Category: `general`, `fact`, `plan`, `decision`, `reflection`, `lesson`, `error`, `gradient` |
186
+
187
+ **Returns:**
188
+
189
+ ```json
190
+ {
191
+ "ok": true,
192
+ "result": {
193
+ "id": 1,
194
+ "hash": "a1b2c3d4e5f6...",
195
+ "isNew": true
196
+ }
197
+ }
198
+ ```
199
+
200
+ ---
201
+
202
+ #### `store_memories`
203
+
204
+ Store multiple memories in a single batch operation (1–50 items). Supports partial success.
205
+
206
+ | Parameter | Type | Required | Default | Description |
207
+ | --------- | ---------- | -------- | ------- | ------------------------------------------------------------------------------------------------------ |
208
+ | `items` | `object[]` | Yes | — | Array of 1–50 memory objects, each with `content`, `tags`, and optional `importance` and `memory_type` |
209
+
210
+ **Returns:**
211
+
212
+ ```json
213
+ {
214
+ "ok": true,
215
+ "result": {
216
+ "results": [
217
+ { "ok": true, "index": 0, "hash": "a1b2...", "isNew": true },
218
+ { "ok": false, "index": 1, "error": "Tag must not contain whitespace" }
219
+ ],
220
+ "succeeded": 1,
221
+ "failed": 1
222
+ }
223
+ }
224
+ ```
225
+
226
+ ---
227
+
228
+ #### `get_memory`
229
+
230
+ Retrieve a single memory by its SHA-256 hash.
231
+
232
+ | Parameter | Type | Required | Default | Description |
233
+ | --------- | -------- | -------- | ------- | ----------------------------------------- |
234
+ | `hash` | `string` | Yes | — | SHA-256 hash of the memory (64 hex chars) |
235
+
236
+ **Returns:**
237
+
238
+ ```json
239
+ {
240
+ "ok": true,
241
+ "result": {
242
+ "id": 1,
243
+ "content": "TypeScript uses structural typing",
244
+ "summary": null,
245
+ "tags": ["typescript", "types"],
246
+ "importance": 5,
247
+ "memory_type": "fact",
248
+ "created_at": "2025-01-15 10:30:00",
249
+ "accessed_at": "2025-01-15 10:30:00",
250
+ "hash": "a1b2c3d4..."
251
+ }
252
+ }
253
+ ```
254
+
255
+ ---
256
+
257
+ #### `update_memory`
258
+
259
+ Update memory content. Returns the new hash since content changes affect the hash. Idempotent.
260
+
261
+ | Parameter | Type | Required | Default | Description |
262
+ | --------- | ---------- | -------- | ------- | ---------------------------------------------- |
263
+ | `hash` | `string` | Yes | — | Hash of the memory to update |
264
+ | `content` | `string` | Yes | — | New content for the memory (1–100,000 chars) |
265
+ | `tags` | `string[]` | No | — | Replace tags (max 100 tags, each max 50 chars) |
266
+
267
+ **Returns:**
268
+
269
+ ```json
270
+ {
271
+ "ok": true,
272
+ "result": {
273
+ "updated": true,
274
+ "oldHash": "a1b2c3d4...",
275
+ "newHash": "e5f6g7h8..."
276
+ }
277
+ }
278
+ ```
279
+
280
+ ---
281
+
282
+ #### `delete_memory`
283
+
284
+ Delete a single memory by hash. Destructive operation.
285
+
286
+ | Parameter | Type | Required | Default | Description |
287
+ | --------- | -------- | -------- | ------- | ----------------------------------------- |
288
+ | `hash` | `string` | Yes | — | SHA-256 hash of the memory (64 hex chars) |
289
+
290
+ **Returns:**
291
+
292
+ ```json
293
+ { "ok": true, "result": { "deleted": true } }
294
+ ```
295
+
296
+ ---
297
+
298
+ #### `delete_memories`
299
+
300
+ Delete multiple memories by hash in a single batch operation (1–50 hashes). Supports partial success. Destructive.
301
+
302
+ | Parameter | Type | Required | Default | Description |
303
+ | --------- | ---------- | -------- | ------- | -------------------------------------- |
304
+ | `hashes` | `string[]` | Yes | — | Array of 1–50 SHA-256 hashes to delete |
305
+
306
+ **Returns:**
307
+
308
+ ```json
309
+ {
310
+ "ok": true,
311
+ "result": {
312
+ "results": [
313
+ { "hash": "a1b2...", "deleted": true },
314
+ { "hash": "c3d4...", "deleted": false, "error": "Memory not found" }
315
+ ],
316
+ "succeeded": 1,
317
+ "failed": 1
318
+ }
319
+ }
320
+ ```
321
+
322
+ ---
323
+
324
+ #### `search_memories`
325
+
326
+ Search memories by content and tags using FTS5 full-text search with BM25 relevance scoring and recency boosting. Read-only.
327
+
328
+ | Parameter | Type | Required | Default | Description |
329
+ | --------- | -------- | -------- | ------- | ------------------------------------------------------- |
330
+ | `query` | `string` | Yes | — | Search query (1–1,000 chars, searches content and tags) |
331
+
332
+ **Returns:**
333
+
334
+ ```json
335
+ {
336
+ "ok": true,
337
+ "result": [
338
+ {
339
+ "id": 1,
340
+ "content": "TypeScript uses structural typing",
341
+ "tags": ["typescript", "types"],
342
+ "importance": 5,
343
+ "memory_type": "fact",
344
+ "relevance": 0.85,
345
+ "hash": "a1b2c3d4...",
346
+ "created_at": "2025-01-15 10:30:00",
347
+ "accessed_at": "2025-01-15 10:30:00"
348
+ }
349
+ ]
350
+ }
351
+ ```
352
+
353
+ ---
354
+
355
+ #### `recall`
356
+
357
+ Search for memories and traverse relationships to return a connected graph cluster. Use for deeper context retrieval that follows knowledge graph connections. Read-only.
358
+
359
+ | Parameter | Type | Required | Default | Description |
360
+ | --------- | --------- | -------- | ------- | -------------------------------------------------------------------------------- |
361
+ | `query` | `string` | Yes | — | Search query to find initial memories (1–1,000 chars) |
362
+ | `depth` | `integer` | No | `1` | How many relationship hops to follow (0–3). 0 = search only, no graph traversal. |
363
+
364
+ **Returns:**
365
+
366
+ ```json
367
+ {
368
+ "ok": true,
369
+ "result": {
370
+ "memories": [{ "id": 1, "content": "...", "relevance": 0.9, "...": "..." }],
371
+ "relationships": [
372
+ {
373
+ "id": 1,
374
+ "from_hash": "a1b2...",
375
+ "to_hash": "c3d4...",
376
+ "relation_type": "related_to",
377
+ "created_at": "2025-01-15 10:30:00"
378
+ }
379
+ ],
380
+ "depth": 1
381
+ }
382
+ }
383
+ ```
384
+
385
+ ---
386
+
387
+ #### `create_relationship`
388
+
389
+ Link two memories with a typed, directed relationship. Idempotent — creating the same relationship returns the existing ID.
390
+
391
+ | Parameter | Type | Required | Default | Description |
392
+ | --------------- | -------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------ |
393
+ | `from_hash` | `string` | Yes | — | SHA-256 hash of the source memory |
394
+ | `to_hash` | `string` | Yes | — | SHA-256 hash of the target memory |
395
+ | `relation_type` | `string` | Yes | — | Type of relationship (e.g., `related_to`, `causes`, `depends_on`, `part_of`, `follows`; 1–50 chars, no whitespace) |
396
+
397
+ **Returns:**
398
+
399
+ ```json
400
+ { "ok": true, "result": { "id": 1, "isNew": true } }
401
+ ```
402
+
403
+ ---
404
+
405
+ #### `get_relationships`
406
+
407
+ Get all relationships for a memory. Read-only.
408
+
409
+ | Parameter | Type | Required | Default | Description |
410
+ | ----------- | -------- | -------- | -------- | --------------------------------------------------- |
411
+ | `hash` | `string` | Yes | — | SHA-256 hash of the memory |
412
+ | `direction` | `string` | No | `"both"` | Direction filter: `outgoing`, `incoming`, or `both` |
413
+
414
+ **Returns:**
415
+
416
+ ```json
417
+ {
418
+ "ok": true,
419
+ "result": [
420
+ {
421
+ "id": 1,
422
+ "from_hash": "a1b2...",
423
+ "to_hash": "c3d4...",
424
+ "relation_type": "depends_on",
425
+ "created_at": "2025-01-15 10:30:00"
426
+ }
427
+ ]
428
+ }
429
+ ```
430
+
431
+ ---
432
+
433
+ #### `delete_relationship`
434
+
435
+ Remove a relationship between two memories. Destructive.
436
+
437
+ | Parameter | Type | Required | Default | Description |
438
+ | --------------- | -------- | -------- | ------- | --------------------------------- |
439
+ | `from_hash` | `string` | Yes | — | SHA-256 hash of the source memory |
440
+ | `to_hash` | `string` | Yes | — | SHA-256 hash of the target memory |
441
+ | `relation_type` | `string` | Yes | — | Type of relationship to delete |
442
+
443
+ **Returns:**
444
+
445
+ ```json
446
+ { "ok": true, "result": { "deleted": true } }
447
+ ```
448
+
449
+ ---
450
+
451
+ #### `memory_stats`
452
+
453
+ Database statistics and health. No parameters required. Read-only.
454
+
455
+ **Returns:**
456
+
457
+ ```json
458
+ {
459
+ "ok": true,
460
+ "result": {
461
+ "memoryCount": 42,
462
+ "tagCount": 15,
463
+ "oldestMemory": "2025-01-01 00:00:00",
464
+ "newestMemory": "2025-02-09 12:00:00"
465
+ }
466
+ }
467
+ ```
468
+
469
+ ---
470
+
471
+ ### Resources
472
+
473
+ | URI | MIME Type | Description |
474
+ | ------------------------- | --------------- | -------------------------------------------------- |
475
+ | `internal://instructions` | `text/markdown` | Server usage instructions and tool reference guide |
476
+
477
+ ### Prompts
478
+
479
+ None.
480
+
481
+ ## Client Configuration Examples
482
+
483
+ <details>
484
+ <summary><b>VS Code / VS Code Insiders</b></summary>
485
+
486
+ Add to your VS Code `settings.json` or use the one-click install buttons above:
487
+
488
+ ```json
489
+ {
490
+ "mcp": {
491
+ "servers": {
492
+ "memdb": {
493
+ "command": "npx",
494
+ "args": ["-y", "@j0hanz/memdb@latest"]
495
+ }
496
+ }
497
+ }
498
+ }
499
+ ```
500
+
501
+ With environment variables:
502
+
503
+ ```json
504
+ {
505
+ "mcp": {
506
+ "servers": {
507
+ "memdb": {
508
+ "command": "npx",
509
+ "args": ["-y", "@j0hanz/memdb@latest"],
510
+ "env": {
511
+ "MEMDB_PATH": "${workspaceFolder}/.memdb/memory.db",
512
+ "MEMDB_LOG_LEVEL": "warn"
513
+ }
514
+ }
515
+ }
516
+ }
517
+ }
518
+ ```
519
+
520
+ </details>
521
+
522
+ <details>
523
+ <summary><b>Claude Desktop</b></summary>
524
+
525
+ Add to your Claude Desktop configuration file (`claude_desktop_config.json`):
526
+
527
+ ```json
528
+ {
529
+ "mcpServers": {
530
+ "memdb": {
531
+ "command": "npx",
532
+ "args": ["-y", "@j0hanz/memdb@latest"]
533
+ }
534
+ }
535
+ }
536
+ ```
537
+
538
+ </details>
539
+
540
+ <details>
541
+ <summary><b>Cursor</b></summary>
542
+
543
+ [![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/install-mcp?name=memdb&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovbWVtZGJAbGF0ZXN0Il19)
544
+
545
+ Or manually add to Cursor MCP settings:
546
+
547
+ ```json
548
+ {
549
+ "mcpServers": {
550
+ "memdb": {
551
+ "command": "npx",
552
+ "args": ["-y", "@j0hanz/memdb@latest"]
553
+ }
554
+ }
555
+ }
556
+ ```
557
+
558
+ </details>
559
+
560
+ <details>
561
+ <summary><b>Windsurf</b></summary>
562
+
563
+ Add to your Windsurf MCP configuration:
564
+
565
+ ```json
566
+ {
567
+ "mcpServers": {
568
+ "memdb": {
569
+ "command": "npx",
570
+ "args": ["-y", "@j0hanz/memdb@latest"]
571
+ }
572
+ }
573
+ }
574
+ ```
575
+
576
+ </details>
577
+
578
+ ## Security
579
+
580
+ - **stdio hygiene** — All logging is sent to `stderr` via `console.error()`. No non-MCP output is written to `stdout`, preventing JSON-RPC corruption.
581
+ - **Batch request rejection** — JSON-RPC batch arrays are explicitly rejected by the custom `BatchRejectingStdioServerTransport` with proper error responses per MCP spec (≥ 2025-06-18).
582
+ - **Protocol version guard** — Unsupported protocol versions are rejected at the transport layer before reaching tool handlers. The connection is closed after sending the error.
583
+ - **Input validation** — All tool inputs are validated via Zod strict schemas at the MCP boundary. Null bytes in environment variables are detected and rejected.
584
+ - **Database safety** — SQLite defensive mode is enabled, foreign key constraints are enforced, and the `allowExtension` option is set to `false`.
585
+
586
+ ## Development Workflow
587
+
588
+ ### Prerequisites
589
+
590
+ - Node.js ≥ 24
591
+
592
+ ### Install dependencies
593
+
594
+ ```bash
595
+ npm install
596
+ ```
597
+
598
+ ### Scripts
599
+
600
+ | Script | Command | Purpose |
601
+ | --------------- | ---------------------------------------- | -------------------------------------------- |
602
+ | `dev` | `tsc --watch` | TypeScript watch mode (compile on change) |
603
+ | `dev:run` | `node --watch dist/index.js` | Run server with auto-restart and `.env` file |
604
+ | `build` | `node scripts/tasks.mjs build` | Compile TypeScript to `dist/` |
605
+ | `start` | `node dist/index.js` | Run the compiled server |
606
+ | `test` | `node scripts/tasks.mjs test` | Run tests with `node:test` runner |
607
+ | `test:coverage` | `node scripts/tasks.mjs test --coverage` | Run tests with coverage |
608
+ | `type-check` | `node scripts/tasks.mjs type-check` | TypeScript type checking (`tsc --noEmit`) |
609
+ | `lint` | `eslint .` | Run ESLint |
610
+ | `lint:fix` | `eslint . --fix` | Auto-fix linting issues |
611
+ | `format` | `prettier --write .` | Format code with Prettier |
612
+ | `clean` | `node scripts/tasks.mjs clean` | Remove build artifacts |
613
+ | `inspector` | `npx @modelcontextprotocol/inspector` | Launch MCP Inspector for debugging |
614
+
615
+ ## Build and Release
616
+
617
+ The project publishes to npm via a GitHub Actions workflow triggered on GitHub Releases:
618
+
619
+ 1. Checkout → Setup Node.js 20 → Install dependencies
620
+ 2. Lint → Type-check → Test → Coverage
621
+ 3. Build → Extract version from release tag → Publish to npm with trusted publishing (OIDC)
622
+
623
+ See [`.github/workflows/publish.yml`](.github/workflows/publish.yml) for the full pipeline.
624
+
625
+ ## Troubleshooting
626
+
627
+ ### `node:sqlite` not found
628
+
629
+ You are running Node.js < 24. The native `node:sqlite` module requires Node.js ≥ 24.
630
+
631
+ ```bash
632
+ node --version # Must be >= 24.0.0
633
+ ```
634
+
635
+ ### Database locked errors
636
+
637
+ The server uses SQLite WAL mode. If you see locked errors, ensure no external tools are accessing `.memdb/memory.db` while the server is running.
638
+
639
+ ### FTS5 errors
640
+
641
+ If you get errors mentioning `fts5` or `no such module`, ensure your Node.js binary includes the standard SQLite FTS5 extension (it should by default in Node.js ≥ 24).
642
+
643
+ ### Debugging with MCP Inspector
644
+
645
+ ```bash
646
+ npx @modelcontextprotocol/inspector node dist/index.js
647
+ ```
648
+
649
+ ### stdout corruption (stdio mode)
650
+
651
+ If your MCP client receives malformed responses, ensure no middleware or debugging tools are writing to `stdout`. memdb routes all logging to `stderr`.
652
+
653
+ ## Contributing
654
+
655
+ Contributions are welcome! Please ensure your changes pass all checks before submitting:
656
+
657
+ ```bash
658
+ npm run lint && npm run type-check && npm run build && npm test
659
+ ```
660
+
661
+ ## License
662
+
663
+ [MIT](https://opensource.org/licenses/MIT)