@j0hanz/memdb 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 (74) hide show
  1. package/README.md +223 -0
  2. package/dist/core/database.d.ts +9 -0
  3. package/dist/core/database.d.ts.map +1 -0
  4. package/dist/core/database.js +87 -0
  5. package/dist/core/database.js.map +1 -0
  6. package/dist/core/memory-service.d.ts +31 -0
  7. package/dist/core/memory-service.d.ts.map +1 -0
  8. package/dist/core/memory-service.js +179 -0
  9. package/dist/core/memory-service.js.map +1 -0
  10. package/dist/index.d.ts +3 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +67 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/lib/errors.d.ts +19 -0
  15. package/dist/lib/errors.d.ts.map +1 -0
  16. package/dist/lib/errors.js +20 -0
  17. package/dist/lib/errors.js.map +1 -0
  18. package/dist/lib/tool_response.d.ts +5 -0
  19. package/dist/lib/tool_response.d.ts.map +1 -0
  20. package/dist/lib/tool_response.js +7 -0
  21. package/dist/lib/tool_response.js.map +1 -0
  22. package/dist/schemas/inputs.d.ts +31 -0
  23. package/dist/schemas/inputs.d.ts.map +1 -0
  24. package/dist/schemas/inputs.js +91 -0
  25. package/dist/schemas/inputs.js.map +1 -0
  26. package/dist/schemas/outputs.d.ts +10 -0
  27. package/dist/schemas/outputs.d.ts.map +1 -0
  28. package/dist/schemas/outputs.js +7 -0
  29. package/dist/schemas/outputs.js.map +1 -0
  30. package/dist/tools/delete-memory.d.ts +3 -0
  31. package/dist/tools/delete-memory.d.ts.map +1 -0
  32. package/dist/tools/delete-memory.js +32 -0
  33. package/dist/tools/delete-memory.js.map +1 -0
  34. package/dist/tools/get-memory.d.ts +3 -0
  35. package/dist/tools/get-memory.d.ts.map +1 -0
  36. package/dist/tools/get-memory.js +32 -0
  37. package/dist/tools/get-memory.js.map +1 -0
  38. package/dist/tools/get-related.d.ts +3 -0
  39. package/dist/tools/get-related.d.ts.map +1 -0
  40. package/dist/tools/get-related.js +29 -0
  41. package/dist/tools/get-related.js.map +1 -0
  42. package/dist/tools/index.d.ts +3 -0
  43. package/dist/tools/index.d.ts.map +1 -0
  44. package/dist/tools/index.js +17 -0
  45. package/dist/tools/index.js.map +1 -0
  46. package/dist/tools/link-memories.d.ts +3 -0
  47. package/dist/tools/link-memories.d.ts.map +1 -0
  48. package/dist/tools/link-memories.js +29 -0
  49. package/dist/tools/link-memories.js.map +1 -0
  50. package/dist/tools/memory-stats.d.ts +3 -0
  51. package/dist/tools/memory-stats.d.ts.map +1 -0
  52. package/dist/tools/memory-stats.js +28 -0
  53. package/dist/tools/memory-stats.js.map +1 -0
  54. package/dist/tools/search-memories.d.ts +3 -0
  55. package/dist/tools/search-memories.d.ts.map +1 -0
  56. package/dist/tools/search-memories.js +29 -0
  57. package/dist/tools/search-memories.js.map +1 -0
  58. package/dist/tools/store-memory.d.ts +3 -0
  59. package/dist/tools/store-memory.d.ts.map +1 -0
  60. package/dist/tools/store-memory.js +29 -0
  61. package/dist/tools/store-memory.js.map +1 -0
  62. package/dist/types/index.d.ts +22 -0
  63. package/dist/types/index.d.ts.map +1 -0
  64. package/dist/types/index.js +2 -0
  65. package/dist/types/index.js.map +1 -0
  66. package/dist/utils/config.d.ts +4 -0
  67. package/dist/utils/config.d.ts.map +1 -0
  68. package/dist/utils/config.js +6 -0
  69. package/dist/utils/config.js.map +1 -0
  70. package/dist/utils/logger.d.ts +6 -0
  71. package/dist/utils/logger.d.ts.map +1 -0
  72. package/dist/utils/logger.js +12 -0
  73. package/dist/utils/logger.js.map +1 -0
  74. package/package.json +67 -0
package/README.md ADDED
@@ -0,0 +1,223 @@
1
+ # memdb
2
+
3
+ A memory-based MCP server using SQLite in-memory database.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@j0hanz/memdb.svg)](https://www.npmjs.com/package/@j0hanz/memdb)
6
+
7
+ ## One-Click Install
8
+
9
+ [![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)
10
+
11
+ [![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/install-mcp?name=memdb&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovbWVtZGJAbGF0ZXN0Il19)
12
+
13
+ ## ✨ Features
14
+
15
+ | Feature | Description |
16
+ | :----------------------- | :-------------------------------------------------------- |
17
+ | 🧠 **Memory Storage** | Store text-based memories with tags and importance scores |
18
+ | πŸ” **Full-Text Search** | Search memories using FTS5 with relevance ranking |
19
+ | πŸ•ΈοΈ **Graph Connections** | Link memories together to create knowledge graphs |
20
+ | πŸ“Š **Analytics** | Track memory statistics and database health |
21
+ | πŸ”’ **Local Privacy** | All data stored locally in SQLite (`data/memory.db`) |
22
+
23
+ ## πŸš€ Quick Start
24
+
25
+ ### VS Code / Cursor
26
+
27
+ Add this to your `mcpServers` configuration:
28
+
29
+ ```json
30
+ {
31
+ "memdb": {
32
+ "command": "npx",
33
+ "args": ["-y", "@j0hanz/memdb@latest"]
34
+ }
35
+ }
36
+ ```
37
+
38
+ ## πŸ“¦ Installation
39
+
40
+ ### NPX (Recommended)
41
+
42
+ ```bash
43
+ npx -y @j0hanz/memdb@latest
44
+ ```
45
+
46
+ ### Global Installation
47
+
48
+ ```bash
49
+ npm install -g @j0hanz/memdb
50
+ ```
51
+
52
+ ### From Source
53
+
54
+ ```bash
55
+ git clone https://github.com/j0hanz/memdb-mcp-server.git
56
+ cd memdb-mcp-server
57
+ npm install
58
+ npm run build
59
+ ```
60
+
61
+ ## βš™οΈ Configuration
62
+
63
+ The server uses a local SQLite database located at `data/memory.db` relative to the working directory. No environment variables are required for basic operation.
64
+
65
+ ## πŸ”§ Tools
66
+
67
+ ### `store_memory`
68
+
69
+ Store a new memory with optional tags and metadata.
70
+
71
+ | Parameter | Type | Required | Default | Description |
72
+ | :----------- | :------- | :------- | :------ | :---------------------------------------------- |
73
+ | `content` | string | βœ… | - | The content of the memory |
74
+ | `tags` | string[] | ❌ | - | Tags to categorize the memory |
75
+ | `importance` | number | ❌ | - | Importance score (0-10) |
76
+ | `memoryType` | string | ❌ | - | Type of memory (e.g., conversation, fact, rule) |
77
+
78
+ **Returns:** The created memory object with its hash.
79
+
80
+ ### `search_memories`
81
+
82
+ Full-text search with filters.
83
+
84
+ | Parameter | Type | Required | Default | Description |
85
+ | :------------- | :------- | :------- | :------ | :------------------------ |
86
+ | `query` | string | βœ… | - | Search query |
87
+ | `limit` | number | ❌ | - | Maximum number of results |
88
+ | `tags` | string[] | ❌ | - | Filter by tags |
89
+ | `minRelevance` | number | ❌ | - | Minimum relevance score |
90
+
91
+ **Returns:** Array of matching memories.
92
+
93
+ ### `get_memory`
94
+
95
+ Retrieve a specific memory by its hash.
96
+
97
+ | Parameter | Type | Required | Default | Description |
98
+ | :-------- | :----- | :------- | :------ | :--------------------- |
99
+ | `hash` | string | βœ… | - | MD5 hash of the memory |
100
+
101
+ **Returns:** The memory object.
102
+
103
+ ### `delete_memory`
104
+
105
+ Delete a memory by its hash.
106
+
107
+ | Parameter | Type | Required | Default | Description |
108
+ | :-------- | :----- | :------- | :------ | :--------------------- |
109
+ | `hash` | string | βœ… | - | MD5 hash of the memory |
110
+
111
+ **Returns:** Confirmation of deletion.
112
+
113
+ ### `link_memories`
114
+
115
+ Create a relationship between two memories.
116
+
117
+ | Parameter | Type | Required | Default | Description |
118
+ | :------------- | :----- | :------- | :------ | :------------------------ |
119
+ | `fromHash` | string | βœ… | - | Hash of the source memory |
120
+ | `toHash` | string | βœ… | - | Hash of the target memory |
121
+ | `relationType` | string | βœ… | - | Type of relationship |
122
+
123
+ **Returns:** Confirmation of link creation.
124
+
125
+ ### `get_related`
126
+
127
+ Get memories related to a given memory.
128
+
129
+ | Parameter | Type | Required | Default | Description |
130
+ | :------------- | :----- | :------- | :------ | :-------------------------- |
131
+ | `hash` | string | βœ… | - | Hash of the memory |
132
+ | `relationType` | string | ❌ | - | Filter by relationship type |
133
+ | `depth` | number | ❌ | - | Traversal depth (1-3) |
134
+
135
+ **Returns:** Array of related memories.
136
+
137
+ ### `memory_stats`
138
+
139
+ Get database statistics and health information.
140
+
141
+ _No parameters required._
142
+
143
+ **Returns:** Database statistics (count, size, etc.).
144
+
145
+ ## πŸ”Œ Client Configuration
146
+
147
+ <details>
148
+ <summary><b>VS Code</b></summary>
149
+
150
+ Add to your `settings.json` or `mcpServers` config:
151
+
152
+ ```json
153
+ {
154
+ "mcpServers": {
155
+ "memdb": {
156
+ "command": "npx",
157
+ "args": ["-y", "@j0hanz/memdb@latest"]
158
+ }
159
+ }
160
+ }
161
+ ```
162
+
163
+ </details>
164
+
165
+ <details>
166
+ <summary><b>Claude Desktop</b></summary>
167
+
168
+ Add to your `claude_desktop_config.json`:
169
+
170
+ ```json
171
+ {
172
+ "mcpServers": {
173
+ "memdb": {
174
+ "command": "npx",
175
+ "args": ["-y", "@j0hanz/memdb@latest"]
176
+ }
177
+ }
178
+ }
179
+ ```
180
+
181
+ </details>
182
+
183
+ <details>
184
+ <summary><b>Cursor</b></summary>
185
+
186
+ 1. Go to **Cursor Settings** > **Features** > **MCP**
187
+ 2. Click **+ Add New MCP Server**
188
+ 3. Name: `memdb`
189
+ 4. Type: `command`
190
+ 5. Command: `npx -y @j0hanz/memdb@latest`
191
+
192
+ </details>
193
+
194
+ ## πŸ› οΈ Development
195
+
196
+ ### Prerequisites
197
+
198
+ - Node.js >= 22.0.0
199
+
200
+ ### Scripts
201
+
202
+ | Command | Description |
203
+ | :-------------- | :--------------------------------- |
204
+ | `npm run build` | Compile TypeScript to `dist/` |
205
+ | `npm run dev` | Run in development mode with watch |
206
+ | `npm run test` | Run tests |
207
+ | `npm run lint` | Run ESLint |
208
+
209
+ ### Project Structure
210
+
211
+ ```text
212
+ src/
213
+ β”œβ”€β”€ index.ts # Entry point
214
+ β”œβ”€β”€ core/ # Database and memory service
215
+ β”œβ”€β”€ tools/ # Tool implementations
216
+ β”œβ”€β”€ schemas/ # Zod input/output schemas
217
+ β”œβ”€β”€ lib/ # Utility functions
218
+ └── utils/ # Config and logger
219
+ ```
220
+
221
+ ## 🀝 Contributing
222
+
223
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,9 @@
1
+ import { DatabaseSync } from 'node:sqlite';
2
+ export declare class DatabaseManager {
3
+ private db;
4
+ constructor();
5
+ private init;
6
+ getDb(): DatabaseSync;
7
+ }
8
+ export declare const dbManager: DatabaseManager;
9
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/core/database.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,qBAAa,eAAe;IAC1B,OAAO,CAAC,EAAE,CAAe;;IAYzB,OAAO,CAAC,IAAI;IA8EL,KAAK,IAAI,YAAY;CAG7B;AAED,eAAO,MAAM,SAAS,iBAAwB,CAAC"}
@@ -0,0 +1,87 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { DatabaseSync } from 'node:sqlite';
4
+ import { config } from '../utils/config.js';
5
+ export class DatabaseManager {
6
+ db;
7
+ constructor() {
8
+ const dbDir = path.dirname(config.dbPath);
9
+ if (!fs.existsSync(dbDir)) {
10
+ fs.mkdirSync(dbDir, { recursive: true });
11
+ }
12
+ this.db = new DatabaseSync(config.dbPath, { timeout: 5000 });
13
+ this.init();
14
+ }
15
+ init() {
16
+ this.db.exec('PRAGMA journal_mode = WAL');
17
+ this.db.exec('PRAGMA synchronous = NORMAL');
18
+ this.db.exec(`
19
+ CREATE TABLE IF NOT EXISTS memories (
20
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
21
+ content TEXT NOT NULL,
22
+ summary TEXT,
23
+ importance INTEGER DEFAULT 0,
24
+ memory_type TEXT DEFAULT 'general',
25
+ created_at TEXT DEFAULT CURRENT_TIMESTAMP,
26
+ accessed_at TEXT DEFAULT CURRENT_TIMESTAMP,
27
+ hash TEXT UNIQUE NOT NULL
28
+ ) STRICT;
29
+ `);
30
+ this.db.exec(`
31
+ CREATE TABLE IF NOT EXISTS tags (
32
+ memory_id INTEGER NOT NULL,
33
+ tag TEXT NOT NULL,
34
+ PRIMARY KEY (memory_id, tag),
35
+ FOREIGN KEY (memory_id) REFERENCES memories(id) ON DELETE CASCADE
36
+ ) STRICT;
37
+ `);
38
+ this.db.exec(`
39
+ CREATE TABLE IF NOT EXISTS relationships (
40
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
41
+ from_memory_id INTEGER NOT NULL,
42
+ to_memory_id INTEGER NOT NULL,
43
+ relation_type TEXT NOT NULL,
44
+ created_at TEXT DEFAULT CURRENT_TIMESTAMP,
45
+ FOREIGN KEY (from_memory_id) REFERENCES memories(id) ON DELETE CASCADE,
46
+ FOREIGN KEY (to_memory_id) REFERENCES memories(id) ON DELETE CASCADE,
47
+ UNIQUE(from_memory_id, to_memory_id, relation_type)
48
+ ) STRICT;
49
+ `);
50
+ // FTS5
51
+ const ftsRow = this.db
52
+ .prepare("SELECT count(*) as count FROM sqlite_master WHERE type='table' AND name='memories_fts'")
53
+ .get();
54
+ const ftsExists = ftsRow?.count ?? 0;
55
+ if (ftsExists === 0) {
56
+ this.db.exec(`
57
+ CREATE VIRTUAL TABLE memories_fts USING fts5(
58
+ content,
59
+ summary,
60
+ content_rowid='id'
61
+ );
62
+ `);
63
+ this.db.exec(`
64
+ CREATE TRIGGER memories_ai AFTER INSERT ON memories BEGIN
65
+ INSERT INTO memories_fts(rowid, content, summary)
66
+ VALUES (new.id, new.content, new.summary);
67
+ END;
68
+ `);
69
+ this.db.exec(`
70
+ CREATE TRIGGER memories_au AFTER UPDATE ON memories BEGIN
71
+ DELETE FROM memories_fts WHERE rowid = old.id;
72
+ INSERT INTO memories_fts(rowid, content, summary) VALUES (new.id, new.content, new.summary);
73
+ END;
74
+ `);
75
+ this.db.exec(`
76
+ CREATE TRIGGER memories_ad AFTER DELETE ON memories BEGIN
77
+ DELETE FROM memories_fts WHERE rowid = old.id;
78
+ END;
79
+ `);
80
+ }
81
+ }
82
+ getDb() {
83
+ return this.db;
84
+ }
85
+ }
86
+ export const dbManager = new DatabaseManager();
87
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/core/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,OAAO,eAAe;IAClB,EAAE,CAAe;IAEzB;QACE,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,CAAC,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAEO,IAAI;QACV,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QAC1C,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAE5C,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;KAWZ,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;;;KAOZ,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;KAWZ,CAAC,CAAC;QAEH,OAAO;QACP,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE;aACnB,OAAO,CACN,wFAAwF,CACzF;aACA,GAAG,EAAmC,CAAC;QAC1C,MAAM,SAAS,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC,CAAC;QAErC,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;;SAMV,CAAC,CAAC;YAEL,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;SAKV,CAAC,CAAC;YAEL,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;SAKV,CAAC,CAAC;YAEL,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;SAIV,CAAC,CAAC;QACP,CAAC;IACH,CAAC;IAEM,KAAK;QACV,OAAO,IAAI,CAAC,EAAE,CAAC;IACjB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,eAAe,EAAE,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { Memory, SearchResult } from '../types/index.js';
2
+ interface RelatedMemory extends Memory {
3
+ relation_type: string;
4
+ depth: number;
5
+ }
6
+ interface StatementResult {
7
+ changes: number | bigint;
8
+ lastInsertRowid: number | bigint;
9
+ }
10
+ interface MemoryInsertResult {
11
+ id: number;
12
+ hash: string;
13
+ isNew: boolean;
14
+ }
15
+ interface MemoryStats {
16
+ memoryCount: number;
17
+ relationshipCount: number;
18
+ }
19
+ export declare class MemoryService {
20
+ private db;
21
+ createMemory(content: string, tags?: string[], importance?: number, memoryType?: string): MemoryInsertResult;
22
+ searchMemories(query: string, limit?: number, tags?: string[], minRelevance?: number): SearchResult[];
23
+ getMemory(hash: string): Memory | undefined;
24
+ deleteMemory(hash: string): StatementResult;
25
+ linkMemories(fromHash: string, toHash: string, relationType: string): StatementResult;
26
+ getRelated(hash: string, relationType?: string, depth?: number): RelatedMemory[];
27
+ getStats(): MemoryStats;
28
+ }
29
+ export declare const memoryService: MemoryService;
30
+ export {};
31
+ //# sourceMappingURL=memory-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-service.d.ts","sourceRoot":"","sources":["../../src/core/memory-service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG9D,UAAU,aAAc,SAAQ,MAAM;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,GAAG,MAAM,CAAC;CAClC;AAED,UAAU,kBAAkB;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,UAAU,WAAW;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAAqB;IAE/B,YAAY,CACV,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,UAAU,SAAI,EACd,UAAU,SAAY,GACrB,kBAAkB;IAwCrB,cAAc,CACZ,KAAK,EAAE,MAAM,EACb,KAAK,SAAK,EACV,IAAI,GAAE,MAAM,EAAO,EACnB,YAAY,CAAC,EAAE,MAAM,GACpB,YAAY,EAAE;IA+DjB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAM3C,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;IAM3C,YAAY,CACV,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GACnB,eAAe;IAclB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,aAAa,EAAE;IA+E3E,QAAQ,IAAI,WAAW;CAaxB;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC"}
@@ -0,0 +1,179 @@
1
+ import crypto from 'node:crypto';
2
+ import { dbManager } from './database.js';
3
+ export class MemoryService {
4
+ db = dbManager.getDb();
5
+ createMemory(content, tags = [], importance = 0, memoryType = 'general') {
6
+ const hash = crypto.createHash('md5').update(content).digest('hex');
7
+ // Check if exists
8
+ const existing = this.db
9
+ .prepare('SELECT id FROM memories WHERE hash = ?')
10
+ .get(hash);
11
+ if (existing) {
12
+ return { id: existing.id, hash, isNew: false };
13
+ }
14
+ const insert = this.db.prepare('INSERT INTO memories (content, importance, memory_type, hash) VALUES (?, ?, ?, ?)');
15
+ const uniqueTags = tags.length > 0 ? [...new Set(tags)] : [];
16
+ if (uniqueTags.length > 0) {
17
+ this.db.exec('BEGIN IMMEDIATE');
18
+ try {
19
+ const result = insert.run(content, importance, memoryType, hash);
20
+ const memoryId = result.lastInsertRowid;
21
+ const insertTag = this.db.prepare('INSERT INTO tags (memory_id, tag) VALUES (?, ?)');
22
+ for (const tag of uniqueTags) {
23
+ insertTag.run(memoryId, tag);
24
+ }
25
+ this.db.exec('COMMIT');
26
+ return { id: memoryId, hash, isNew: true };
27
+ }
28
+ catch (err) {
29
+ this.db.exec('ROLLBACK');
30
+ throw err;
31
+ }
32
+ }
33
+ const result = insert.run(content, importance, memoryType, hash);
34
+ const memoryId = result.lastInsertRowid;
35
+ return { id: memoryId, hash, isNew: true };
36
+ }
37
+ searchMemories(query, limit = 10, tags = [], minRelevance) {
38
+ const uniqueTags = tags.length > 0 ? [...new Set(tags)] : [];
39
+ const relevanceExpr = '1.0 / (1.0 + abs(bm25(memories_fts)))';
40
+ const whereParts = ['memories_fts MATCH ?'];
41
+ const params = [query];
42
+ if (uniqueTags.length > 0) {
43
+ whereParts.push(`m.id IN (SELECT memory_id FROM tags WHERE tag IN (${uniqueTags
44
+ .map(() => '?')
45
+ .join(', ')}))`);
46
+ params.push(...uniqueTags);
47
+ }
48
+ let sql = `
49
+ WITH ranked AS (
50
+ SELECT m.*, ${relevanceExpr} as relevance
51
+ FROM memories m
52
+ JOIN memories_fts fts ON m.id = fts.rowid
53
+ WHERE ${whereParts.join(' AND ')}
54
+ )
55
+ SELECT * FROM ranked
56
+ `;
57
+ if (minRelevance !== undefined) {
58
+ sql += ' WHERE relevance >= ?';
59
+ params.push(minRelevance);
60
+ }
61
+ sql += ' ORDER BY relevance DESC LIMIT ?';
62
+ params.push(limit);
63
+ const stmt = this.db.prepare(sql);
64
+ let rows;
65
+ try {
66
+ rows = stmt.all(...params);
67
+ }
68
+ catch (err) {
69
+ const message = err instanceof Error ? err.message : String(err);
70
+ if (message.includes('fts5') || message.includes('syntax error')) {
71
+ throw new Error(`Invalid search query syntax. Check for unbalanced quotes or special characters. Details: ${message}`);
72
+ }
73
+ throw err;
74
+ }
75
+ return rows.map((row) => ({
76
+ id: row.id,
77
+ content: row.content,
78
+ summary: row.summary,
79
+ importance: row.importance,
80
+ memory_type: row.memory_type,
81
+ created_at: row.created_at,
82
+ accessed_at: row.accessed_at,
83
+ hash: row.hash,
84
+ relevance: row.relevance,
85
+ }));
86
+ }
87
+ getMemory(hash) {
88
+ return this.db
89
+ .prepare('SELECT * FROM memories WHERE hash = ?')
90
+ .get(hash);
91
+ }
92
+ deleteMemory(hash) {
93
+ return this.db
94
+ .prepare('DELETE FROM memories WHERE hash = ?')
95
+ .run(hash);
96
+ }
97
+ linkMemories(fromHash, toHash, relationType) {
98
+ const from = this.getMemory(fromHash);
99
+ const to = this.getMemory(toHash);
100
+ if (!from || !to) {
101
+ throw new Error('One or both memories not found');
102
+ }
103
+ const insert = this.db.prepare('INSERT OR IGNORE INTO relationships (from_memory_id, to_memory_id, relation_type) VALUES (?, ?, ?)');
104
+ return insert.run(from.id, to.id, relationType);
105
+ }
106
+ getRelated(hash, relationType, depth = 1) {
107
+ const memory = this.getMemory(hash);
108
+ if (!memory)
109
+ return [];
110
+ const maxDepth = Math.max(1, depth);
111
+ const baseFilter = relationType ? ' AND r.relation_type = ?' : '';
112
+ const baseParams = [memory.id];
113
+ if (relationType) {
114
+ baseParams.push(relationType);
115
+ }
116
+ if (maxDepth === 1) {
117
+ const sql = `
118
+ SELECT m.*, r.relation_type as relation_type, 1 as depth
119
+ FROM memories m
120
+ JOIN relationships r ON m.id = r.to_memory_id
121
+ WHERE r.from_memory_id = ?${baseFilter}
122
+ `;
123
+ const rows = this.db.prepare(sql).all(...baseParams);
124
+ return rows.map((row) => ({
125
+ id: row.id,
126
+ content: row.content,
127
+ summary: row.summary,
128
+ importance: row.importance,
129
+ memory_type: row.memory_type,
130
+ created_at: row.created_at,
131
+ accessed_at: row.accessed_at,
132
+ hash: row.hash,
133
+ relation_type: row.relation_type,
134
+ depth: row.depth,
135
+ }));
136
+ }
137
+ const sql = `
138
+ WITH RECURSIVE rels(depth, from_id, to_id, relation_type) AS (
139
+ SELECT 1, r.from_memory_id, r.to_memory_id, r.relation_type
140
+ FROM relationships r
141
+ WHERE r.from_memory_id = ?${baseFilter}
142
+ UNION ALL
143
+ SELECT rels.depth + 1, r.from_memory_id, r.to_memory_id, r.relation_type
144
+ FROM relationships r
145
+ JOIN rels ON r.from_memory_id = rels.to_id
146
+ WHERE rels.depth < ?${relationType ? ' AND r.relation_type = ?' : ''}
147
+ )
148
+ SELECT m.*, rels.relation_type as relation_type, MIN(rels.depth) as depth
149
+ FROM rels
150
+ JOIN memories m ON m.id = rels.to_id
151
+ GROUP BY m.id, rels.relation_type
152
+ ORDER BY depth, m.id
153
+ `;
154
+ const recursiveParams = [...baseParams, maxDepth];
155
+ if (relationType) {
156
+ recursiveParams.push(relationType);
157
+ }
158
+ const rows = this.db.prepare(sql).all(...recursiveParams);
159
+ return rows.map((row) => ({
160
+ id: row.id,
161
+ content: row.content,
162
+ summary: row.summary,
163
+ importance: row.importance,
164
+ memory_type: row.memory_type,
165
+ created_at: row.created_at,
166
+ accessed_at: row.accessed_at,
167
+ hash: row.hash,
168
+ relation_type: row.relation_type,
169
+ depth: row.depth,
170
+ }));
171
+ }
172
+ getStats() {
173
+ const memoryCount = this.db.prepare('SELECT COUNT(*) as count FROM memories').get().count;
174
+ const relationshipCount = this.db.prepare('SELECT COUNT(*) as count FROM relationships').get().count;
175
+ return { memoryCount, relationshipCount };
176
+ }
177
+ }
178
+ export const memoryService = new MemoryService();
179
+ //# sourceMappingURL=memory-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-service.js","sourceRoot":"","sources":["../../src/core/memory-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+ import process from 'node:process';
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
+ import { createErrorResponse } from './lib/errors.js';
7
+ import { registerAllTools } from './tools/index.js';
8
+ import { logger } from './utils/logger.js';
9
+ const require = createRequire(import.meta.url);
10
+ const packageJson = require('../package.json');
11
+ const SERVER_VERSION = packageJson.version ?? '0.0.0';
12
+ const server = new McpServer({ name: 'memdb', version: SERVER_VERSION }, {
13
+ instructions: 'A Memory MCP Server for AI Assistants using node:sqlite',
14
+ capabilities: { logging: {} },
15
+ });
16
+ // Ensure tool errors always include structuredContent (matches DefaultOutputSchema).
17
+ server.createToolError = (message) => createErrorResponse('E_TOOL_ERROR', message);
18
+ registerAllTools(server);
19
+ let transport;
20
+ let shutdownInProgress = false;
21
+ async function shutdown(signal) {
22
+ if (shutdownInProgress)
23
+ return;
24
+ shutdownInProgress = true;
25
+ logger.info(`Received ${signal}, shutting down gracefully...`);
26
+ const forceExitTimer = setTimeout(() => {
27
+ logger.warn('Shutdown timeout exceeded, forcing exit');
28
+ process.exit(1);
29
+ }, 5000);
30
+ try {
31
+ if (transport) {
32
+ await transport.close();
33
+ }
34
+ clearTimeout(forceExitTimer);
35
+ process.exit(0);
36
+ }
37
+ catch (err) {
38
+ logger.error('Error during shutdown:', err);
39
+ clearTimeout(forceExitTimer);
40
+ process.exit(1);
41
+ }
42
+ }
43
+ async function main() {
44
+ try {
45
+ transport = new StdioServerTransport();
46
+ await server.connect(transport);
47
+ logger.info('Memory MCP Server running on stdio');
48
+ }
49
+ catch (error) {
50
+ logger.error('Failed to start server', error);
51
+ process.exit(1);
52
+ }
53
+ }
54
+ void main();
55
+ // Graceful shutdown handlers
56
+ process.on('SIGTERM', () => void shutdown('SIGTERM'));
57
+ process.on('SIGINT', () => void shutdown('SIGINT'));
58
+ // Uncaught error handlers
59
+ process.on('uncaughtException', (err, origin) => {
60
+ logger.error(`Uncaught exception (${origin}):`, err);
61
+ process.exit(1);
62
+ });
63
+ process.on('unhandledRejection', (reason) => {
64
+ logger.error('Unhandled rejection:', reason);
65
+ process.exit(1);
66
+ });
67
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
2
+ export interface ErrorResponse extends CallToolResult {
3
+ content: {
4
+ type: 'text';
5
+ text: string;
6
+ }[];
7
+ structuredContent: {
8
+ ok: false;
9
+ error: {
10
+ code: string;
11
+ message: string;
12
+ };
13
+ result?: unknown;
14
+ };
15
+ isError: true;
16
+ }
17
+ export declare function getErrorMessage(error: unknown): string;
18
+ export declare function createErrorResponse(code: string, message: string, result?: unknown): ErrorResponse;
19
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,iBAAiB,EAAE;QACjB,EAAE,EAAE,KAAK,CAAC;QACV,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC;QACzC,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,OAAO,EAAE,IAAI,CAAC;CACf;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAItD;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,OAAO,GACf,aAAa,CAWf"}