@aeriondyseti/vector-memory-mcp 0.9.0-dev.5 โ 0.9.0-dev.8
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/dist/package.json +72 -0
- package/dist/scripts/test-runner.d.ts +9 -0
- package/dist/scripts/test-runner.d.ts.map +1 -0
- package/dist/scripts/test-runner.js +61 -0
- package/dist/scripts/test-runner.js.map +1 -0
- package/dist/scripts/warmup.d.ts +8 -0
- package/dist/scripts/warmup.d.ts.map +1 -0
- package/dist/scripts/warmup.js +61 -0
- package/dist/scripts/warmup.js.map +1 -0
- package/dist/src/config/index.d.ts +24 -0
- package/dist/src/config/index.d.ts.map +1 -0
- package/dist/src/config/index.js +48 -0
- package/dist/src/config/index.js.map +1 -0
- package/dist/src/db/connection.d.ts +3 -0
- package/dist/src/db/connection.d.ts.map +1 -0
- package/dist/src/db/connection.js +10 -0
- package/dist/src/db/connection.js.map +1 -0
- package/dist/src/db/memory.repository.d.ts +38 -0
- package/dist/src/db/memory.repository.d.ts.map +1 -0
- package/dist/src/db/memory.repository.js +176 -0
- package/dist/src/db/memory.repository.js.map +1 -0
- package/dist/src/db/schema.d.ts +4 -0
- package/dist/src/db/schema.d.ts.map +1 -0
- package/dist/src/db/schema.js +15 -0
- package/dist/src/db/schema.js.map +1 -0
- package/dist/src/http/mcp-transport.d.ts +19 -0
- package/dist/src/http/mcp-transport.d.ts.map +1 -0
- package/dist/src/http/mcp-transport.js +191 -0
- package/dist/src/http/mcp-transport.js.map +1 -0
- package/dist/src/http/server.d.ts +13 -0
- package/dist/src/http/server.d.ts.map +1 -0
- package/dist/src/http/server.js +210 -0
- package/dist/src/http/server.js.map +1 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +59 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mcp/handlers.d.ts +12 -0
- package/dist/src/mcp/handlers.d.ts.map +1 -0
- package/dist/src/mcp/handlers.js +198 -0
- package/dist/src/mcp/handlers.js.map +1 -0
- package/dist/src/mcp/server.d.ts +5 -0
- package/dist/src/mcp/server.d.ts.map +1 -0
- package/dist/src/mcp/server.js +22 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/mcp/tools.d.ts +10 -0
- package/dist/src/mcp/tools.d.ts.map +1 -0
- package/dist/src/mcp/tools.js +272 -0
- package/dist/src/mcp/tools.js.map +1 -0
- package/dist/src/services/embeddings.service.d.ts +12 -0
- package/dist/src/services/embeddings.service.d.ts.map +1 -0
- package/dist/src/services/embeddings.service.js +37 -0
- package/dist/src/services/embeddings.service.js.map +1 -0
- package/dist/src/services/memory.service.d.ts +33 -0
- package/dist/src/services/memory.service.d.ts.map +1 -0
- package/dist/src/services/memory.service.js +200 -0
- package/dist/src/services/memory.service.js.map +1 -0
- package/dist/src/types/memory.d.ts +28 -0
- package/dist/src/types/memory.d.ts.map +1 -0
- package/dist/src/types/memory.js +18 -0
- package/dist/src/types/memory.js.map +1 -0
- package/package.json +11 -8
- package/src/config/index.ts +5 -2
- package/src/http/server.ts +85 -12
- package/scripts/publish.ts +0 -61
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { randomUUID } from "crypto";
|
|
2
|
+
import { isDeleted } from "../types/memory.js";
|
|
3
|
+
const INTENT_PROFILES = {
|
|
4
|
+
continuity: { weights: { relevance: 0.3, recency: 0.5, utility: 0.2 }, jitter: 0.02 },
|
|
5
|
+
fact_check: { weights: { relevance: 0.6, recency: 0.1, utility: 0.3 }, jitter: 0.02 },
|
|
6
|
+
frequent: { weights: { relevance: 0.2, recency: 0.2, utility: 0.6 }, jitter: 0.02 },
|
|
7
|
+
associative: { weights: { relevance: 0.7, recency: 0.1, utility: 0.2 }, jitter: 0.05 },
|
|
8
|
+
explore: { weights: { relevance: 0.4, recency: 0.3, utility: 0.3 }, jitter: 0.15 },
|
|
9
|
+
};
|
|
10
|
+
const sigmoid = (x) => 1 / (1 + Math.exp(-x));
|
|
11
|
+
export class MemoryService {
|
|
12
|
+
repository;
|
|
13
|
+
embeddings;
|
|
14
|
+
constructor(repository, embeddings) {
|
|
15
|
+
this.repository = repository;
|
|
16
|
+
this.embeddings = embeddings;
|
|
17
|
+
}
|
|
18
|
+
async store(content, metadata = {}, embeddingText) {
|
|
19
|
+
const id = randomUUID();
|
|
20
|
+
const now = new Date();
|
|
21
|
+
const textToEmbed = embeddingText ?? content;
|
|
22
|
+
const embedding = await this.embeddings.embed(textToEmbed);
|
|
23
|
+
const memory = {
|
|
24
|
+
id,
|
|
25
|
+
content,
|
|
26
|
+
embedding,
|
|
27
|
+
metadata,
|
|
28
|
+
createdAt: now,
|
|
29
|
+
updatedAt: now,
|
|
30
|
+
supersededBy: null,
|
|
31
|
+
usefulness: 0,
|
|
32
|
+
accessCount: 0,
|
|
33
|
+
lastAccessed: now, // Initialize to createdAt for fair discovery
|
|
34
|
+
};
|
|
35
|
+
await this.repository.insert(memory);
|
|
36
|
+
return memory;
|
|
37
|
+
}
|
|
38
|
+
async get(id) {
|
|
39
|
+
const memory = await this.repository.findById(id);
|
|
40
|
+
if (!memory) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
// Track access on explicit get
|
|
44
|
+
const updatedMemory = {
|
|
45
|
+
...memory,
|
|
46
|
+
accessCount: memory.accessCount + 1,
|
|
47
|
+
lastAccessed: new Date(),
|
|
48
|
+
};
|
|
49
|
+
await this.repository.upsert(updatedMemory);
|
|
50
|
+
return updatedMemory;
|
|
51
|
+
}
|
|
52
|
+
async delete(id) {
|
|
53
|
+
return await this.repository.markDeleted(id);
|
|
54
|
+
}
|
|
55
|
+
async update(id, updates) {
|
|
56
|
+
const existing = await this.repository.findById(id);
|
|
57
|
+
if (!existing) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
const newContent = updates.content ?? existing.content;
|
|
61
|
+
const newMetadata = updates.metadata ?? existing.metadata;
|
|
62
|
+
// Regenerate embedding if content or embeddingText changed
|
|
63
|
+
let newEmbedding = existing.embedding;
|
|
64
|
+
if (updates.content !== undefined || updates.embeddingText !== undefined) {
|
|
65
|
+
const textToEmbed = updates.embeddingText ?? newContent;
|
|
66
|
+
newEmbedding = await this.embeddings.embed(textToEmbed);
|
|
67
|
+
}
|
|
68
|
+
const updatedMemory = {
|
|
69
|
+
...existing,
|
|
70
|
+
content: newContent,
|
|
71
|
+
embedding: newEmbedding,
|
|
72
|
+
metadata: newMetadata,
|
|
73
|
+
updatedAt: new Date(),
|
|
74
|
+
};
|
|
75
|
+
await this.repository.upsert(updatedMemory);
|
|
76
|
+
return updatedMemory;
|
|
77
|
+
}
|
|
78
|
+
async vote(id, value) {
|
|
79
|
+
const existing = await this.repository.findById(id);
|
|
80
|
+
if (!existing) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
// Vote also tracks access (explicit utilization signal)
|
|
84
|
+
const updatedMemory = {
|
|
85
|
+
...existing,
|
|
86
|
+
usefulness: existing.usefulness + value,
|
|
87
|
+
accessCount: existing.accessCount + 1,
|
|
88
|
+
lastAccessed: new Date(),
|
|
89
|
+
updatedAt: new Date(),
|
|
90
|
+
};
|
|
91
|
+
await this.repository.upsert(updatedMemory);
|
|
92
|
+
return updatedMemory;
|
|
93
|
+
}
|
|
94
|
+
async search(query, intent, limit = 10, includeDeleted = false) {
|
|
95
|
+
const queryEmbedding = await this.embeddings.embed(query);
|
|
96
|
+
const fetchLimit = limit * 5; // Fetch more for re-ranking
|
|
97
|
+
const candidates = await this.repository.findHybrid(queryEmbedding, query, fetchLimit);
|
|
98
|
+
const profile = INTENT_PROFILES[intent];
|
|
99
|
+
const now = new Date();
|
|
100
|
+
const scored = candidates
|
|
101
|
+
.filter((m) => includeDeleted || !isDeleted(m))
|
|
102
|
+
.map((candidate) => {
|
|
103
|
+
// Relevance: RRF score (already normalized ~0-1)
|
|
104
|
+
const relevance = candidate.rrfScore;
|
|
105
|
+
// Recency: exponential decay
|
|
106
|
+
const lastAccessed = candidate.lastAccessed ?? candidate.createdAt;
|
|
107
|
+
const hoursSinceAccess = Math.max(0, (now.getTime() - lastAccessed.getTime()) / (1000 * 60 * 60));
|
|
108
|
+
const recency = Math.pow(0.995, hoursSinceAccess);
|
|
109
|
+
// Utility: sigmoid of usefulness + log(accessCount)
|
|
110
|
+
const utility = sigmoid((candidate.usefulness + Math.log(candidate.accessCount + 1)) / 5);
|
|
111
|
+
// Weighted score
|
|
112
|
+
const { weights, jitter } = profile;
|
|
113
|
+
const score = weights.relevance * relevance +
|
|
114
|
+
weights.recency * recency +
|
|
115
|
+
weights.utility * utility;
|
|
116
|
+
// Apply jitter
|
|
117
|
+
const finalScore = score * (1 + (Math.random() * 2 - 1) * jitter);
|
|
118
|
+
return { memory: candidate, finalScore };
|
|
119
|
+
});
|
|
120
|
+
// Sort by final score descending
|
|
121
|
+
scored.sort((a, b) => b.finalScore - a.finalScore);
|
|
122
|
+
// Return top N (read-only - no access tracking)
|
|
123
|
+
return scored.slice(0, limit).map((s) => s.memory);
|
|
124
|
+
}
|
|
125
|
+
async trackAccess(ids) {
|
|
126
|
+
const now = new Date();
|
|
127
|
+
for (const id of ids) {
|
|
128
|
+
const memory = await this.repository.findById(id);
|
|
129
|
+
if (memory && !isDeleted(memory)) {
|
|
130
|
+
await this.repository.upsert({
|
|
131
|
+
...memory,
|
|
132
|
+
accessCount: memory.accessCount + 1,
|
|
133
|
+
lastAccessed: now,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
static UUID_ZERO = "00000000-0000-0000-0000-000000000000";
|
|
139
|
+
async storeHandoff(args) {
|
|
140
|
+
// Track access for utilized memories
|
|
141
|
+
if (args.memory_ids && args.memory_ids.length > 0) {
|
|
142
|
+
await this.trackAccess(args.memory_ids);
|
|
143
|
+
}
|
|
144
|
+
const now = new Date();
|
|
145
|
+
const date = now.toISOString().slice(0, 10);
|
|
146
|
+
const time = now.toISOString().slice(11, 16);
|
|
147
|
+
const list = (items) => {
|
|
148
|
+
if (!items || items.length === 0) {
|
|
149
|
+
return "- (none)";
|
|
150
|
+
}
|
|
151
|
+
return items.map((i) => `- ${i}`).join("\n");
|
|
152
|
+
};
|
|
153
|
+
const content = `# Handoff - ${args.project}
|
|
154
|
+
**Date:** ${date} ${time} | **Branch:** ${args.branch ?? "unknown"}
|
|
155
|
+
|
|
156
|
+
## Summary
|
|
157
|
+
${args.summary}
|
|
158
|
+
|
|
159
|
+
## Completed
|
|
160
|
+
${list(args.completed)}
|
|
161
|
+
|
|
162
|
+
## In Progress / Blocked
|
|
163
|
+
${list(args.in_progress_blocked)}
|
|
164
|
+
|
|
165
|
+
## Key Decisions
|
|
166
|
+
${list(args.key_decisions)}
|
|
167
|
+
|
|
168
|
+
## Next Steps
|
|
169
|
+
${list(args.next_steps)}
|
|
170
|
+
|
|
171
|
+
## Memory IDs
|
|
172
|
+
${list(args.memory_ids)}`;
|
|
173
|
+
const metadata = {
|
|
174
|
+
...(args.metadata ?? {}),
|
|
175
|
+
type: "handoff",
|
|
176
|
+
project: args.project,
|
|
177
|
+
date,
|
|
178
|
+
branch: args.branch ?? "unknown",
|
|
179
|
+
memory_ids: args.memory_ids ?? [],
|
|
180
|
+
};
|
|
181
|
+
const memory = {
|
|
182
|
+
id: MemoryService.UUID_ZERO,
|
|
183
|
+
content,
|
|
184
|
+
embedding: new Array(this.embeddings.dimension).fill(0),
|
|
185
|
+
metadata,
|
|
186
|
+
createdAt: now,
|
|
187
|
+
updatedAt: now,
|
|
188
|
+
supersededBy: null,
|
|
189
|
+
usefulness: 0,
|
|
190
|
+
accessCount: 0,
|
|
191
|
+
lastAccessed: now, // Initialize to now for consistency
|
|
192
|
+
};
|
|
193
|
+
await this.repository.upsert(memory);
|
|
194
|
+
return memory;
|
|
195
|
+
}
|
|
196
|
+
async getLatestHandoff() {
|
|
197
|
+
return await this.get(MemoryService.UUID_ZERO);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=memory.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.service.js","sourceRoot":"","sources":["../../../src/services/memory.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const DELETED_TOMBSTONE = "DELETED";
|
|
2
|
+
export interface Memory {
|
|
3
|
+
id: string;
|
|
4
|
+
content: string;
|
|
5
|
+
embedding: number[];
|
|
6
|
+
metadata: Record<string, unknown>;
|
|
7
|
+
createdAt: Date;
|
|
8
|
+
updatedAt: Date;
|
|
9
|
+
supersededBy: string | null;
|
|
10
|
+
usefulness: number;
|
|
11
|
+
accessCount: number;
|
|
12
|
+
lastAccessed: Date | null;
|
|
13
|
+
}
|
|
14
|
+
export declare function isDeleted(memory: Memory): boolean;
|
|
15
|
+
export declare function memoryToDict(memory: Memory): Record<string, unknown>;
|
|
16
|
+
export type SearchIntent = 'continuity' | 'fact_check' | 'frequent' | 'associative' | 'explore';
|
|
17
|
+
export interface IntentProfile {
|
|
18
|
+
weights: {
|
|
19
|
+
relevance: number;
|
|
20
|
+
recency: number;
|
|
21
|
+
utility: number;
|
|
22
|
+
};
|
|
23
|
+
jitter: number;
|
|
24
|
+
}
|
|
25
|
+
export interface HybridRow extends Memory {
|
|
26
|
+
rrfScore: number;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/types/memory.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAE3C,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYpE;AAED,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,CAAC;AAEhG,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACjE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAU,SAAQ,MAAM;IACvC,QAAQ,EAAE,MAAM,CAAC;CAClB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const DELETED_TOMBSTONE = "DELETED";
|
|
2
|
+
export function isDeleted(memory) {
|
|
3
|
+
return memory.supersededBy === DELETED_TOMBSTONE;
|
|
4
|
+
}
|
|
5
|
+
export function memoryToDict(memory) {
|
|
6
|
+
return {
|
|
7
|
+
id: memory.id,
|
|
8
|
+
content: memory.content,
|
|
9
|
+
metadata: memory.metadata,
|
|
10
|
+
createdAt: memory.createdAt.toISOString(),
|
|
11
|
+
updatedAt: memory.updatedAt.toISOString(),
|
|
12
|
+
supersededBy: memory.supersededBy,
|
|
13
|
+
usefulness: memory.usefulness,
|
|
14
|
+
accessCount: memory.accessCount,
|
|
15
|
+
lastAccessed: memory.lastAccessed?.toISOString() ?? null,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../src/types/memory.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAe3C,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,OAAO,MAAM,CAAC,YAAY,KAAK,iBAAiB,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE;QACzC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE;QACzC,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,WAAW,EAAE,IAAI,IAAI;KACzD,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aeriondyseti/vector-memory-mcp",
|
|
3
|
-
"version": "0.9.0-dev.
|
|
3
|
+
"version": "0.9.0-dev.8",
|
|
4
4
|
"description": "A zero-configuration RAG memory server for MCP clients",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "src/index.
|
|
6
|
+
"main": "dist/src/index.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"vector-memory-mcp": "src/index.
|
|
8
|
+
"vector-memory-mcp": "dist/src/index.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
|
+
"dist",
|
|
11
12
|
"src",
|
|
12
13
|
"scripts",
|
|
13
14
|
"hooks",
|
|
@@ -24,20 +25,21 @@
|
|
|
24
25
|
},
|
|
25
26
|
"homepage": "https://github.com/AerionDyseti/vector-memory-mcp#readme",
|
|
26
27
|
"scripts": {
|
|
27
|
-
"start": "
|
|
28
|
+
"start": "node dist/src/index.js",
|
|
29
|
+
"start:bun": "bun run src/index.ts",
|
|
28
30
|
"dev": "bun --watch run src/index.ts",
|
|
29
|
-
"build": "
|
|
31
|
+
"build": "tsc",
|
|
32
|
+
"prebuild": "rm -rf dist",
|
|
30
33
|
"typecheck": "bunx tsc --noEmit",
|
|
31
34
|
"test": "bun run scripts/test-runner.ts",
|
|
32
35
|
"test:raw": "bun test --preload ./tests/preload.ts",
|
|
33
36
|
"test:quick": "bun test",
|
|
34
37
|
"test:coverage": "bun test --preload ./tests/preload.ts --coverage",
|
|
38
|
+
"benchmark": "bun test tests/benchmark.test.ts --preload ./tests/preload.ts",
|
|
35
39
|
"test:preload": "bun run tests/preload.ts",
|
|
36
40
|
"warmup": "bun run scripts/warmup.ts",
|
|
37
41
|
"postinstall": "bun run scripts/warmup.ts",
|
|
38
|
-
"
|
|
39
|
-
"publish:npm": "bun run scripts/publish.ts",
|
|
40
|
-
"publish:dev": "npm publish --access public --tag dev"
|
|
42
|
+
"prepublishOnly": "bun run build"
|
|
41
43
|
},
|
|
42
44
|
"keywords": [
|
|
43
45
|
"mcp",
|
|
@@ -48,6 +50,7 @@
|
|
|
48
50
|
],
|
|
49
51
|
"license": "MIT",
|
|
50
52
|
"dependencies": {
|
|
53
|
+
"@hono/node-server": "^1.19.9",
|
|
51
54
|
"@huggingface/transformers": "^3.8.0",
|
|
52
55
|
"@lancedb/lancedb": "^0.22.3",
|
|
53
56
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
package/src/config/index.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import arg from "arg";
|
|
2
|
-
import { join } from "path";
|
|
2
|
+
import { isAbsolute, join } from "path";
|
|
3
|
+
import packageJson from "../../package.json" with { type: "json" };
|
|
4
|
+
|
|
5
|
+
export const VERSION = packageJson.version;
|
|
3
6
|
|
|
4
7
|
export type TransportMode = "stdio" | "http" | "both";
|
|
5
8
|
|
|
@@ -28,7 +31,7 @@ const DEFAULT_HTTP_PORT = 3271;
|
|
|
28
31
|
const DEFAULT_HTTP_HOST = "127.0.0.1";
|
|
29
32
|
|
|
30
33
|
function resolvePath(path: string): string {
|
|
31
|
-
return path
|
|
34
|
+
return isAbsolute(path) ? path : join(process.cwd(), path);
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
export function loadConfig(overrides: ConfigOverrides = {}): Config {
|
package/src/http/server.ts
CHANGED
|
@@ -1,11 +1,61 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
2
|
import { cors } from "hono/cors";
|
|
3
|
+
import { serve as nodeServe } from "@hono/node-server";
|
|
4
|
+
import { createServer } from "net";
|
|
3
5
|
import type { MemoryService } from "../services/memory.service.js";
|
|
4
6
|
import type { Config } from "../config/index.js";
|
|
5
7
|
import { isDeleted } from "../types/memory.js";
|
|
6
8
|
import { createMcpRoutes } from "./mcp-transport.js";
|
|
7
9
|
import type { Memory, SearchIntent } from "../types/memory.js";
|
|
8
10
|
|
|
11
|
+
// Detect runtime
|
|
12
|
+
const isBun = typeof globalThis.Bun !== "undefined";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Check if a port is available by attempting to bind to it
|
|
16
|
+
*/
|
|
17
|
+
async function isPortAvailable(port: number, host: string): Promise<boolean> {
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
const server = createServer();
|
|
20
|
+
server.once("error", () => {
|
|
21
|
+
resolve(false);
|
|
22
|
+
});
|
|
23
|
+
server.once("listening", () => {
|
|
24
|
+
server.close(() => resolve(true));
|
|
25
|
+
});
|
|
26
|
+
server.listen(port, host);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Find an available port, starting with the preferred port.
|
|
32
|
+
* If preferred port is unavailable, picks a random available port.
|
|
33
|
+
*/
|
|
34
|
+
async function findAvailablePort(
|
|
35
|
+
preferredPort: number,
|
|
36
|
+
host: string
|
|
37
|
+
): Promise<number> {
|
|
38
|
+
if (await isPortAvailable(preferredPort, host)) {
|
|
39
|
+
return preferredPort;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
console.error(
|
|
43
|
+
`[vector-memory-mcp] Port ${preferredPort} is in use, finding an available port...`
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
// Let the OS pick a random available port
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
const server = createServer();
|
|
49
|
+
server.once("error", reject);
|
|
50
|
+
server.once("listening", () => {
|
|
51
|
+
const address = server.address();
|
|
52
|
+
const port = typeof address === "object" && address ? address.port : 0;
|
|
53
|
+
server.close(() => resolve(port));
|
|
54
|
+
});
|
|
55
|
+
server.listen(0, host);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
9
59
|
export interface HttpServerOptions {
|
|
10
60
|
memoryService: MemoryService;
|
|
11
61
|
config: Config;
|
|
@@ -172,20 +222,43 @@ export function createHttpApp(memoryService: MemoryService, config: Config): Hon
|
|
|
172
222
|
export async function startHttpServer(
|
|
173
223
|
memoryService: MemoryService,
|
|
174
224
|
config: Config
|
|
175
|
-
): Promise<{ stop: () => void }> {
|
|
225
|
+
): Promise<{ stop: () => void; port: number }> {
|
|
176
226
|
const app = createHttpApp(memoryService, config);
|
|
177
227
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
hostname: config.httpHost,
|
|
181
|
-
fetch: app.fetch,
|
|
182
|
-
});
|
|
228
|
+
// Find an available port (uses configured port if available, otherwise picks a random one)
|
|
229
|
+
const actualPort = await findAvailablePort(config.httpPort, config.httpHost);
|
|
183
230
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
231
|
+
if (isBun) {
|
|
232
|
+
// Use Bun's native server
|
|
233
|
+
const server = Bun.serve({
|
|
234
|
+
port: actualPort,
|
|
235
|
+
hostname: config.httpHost,
|
|
236
|
+
fetch: app.fetch,
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
console.error(
|
|
240
|
+
`[vector-memory-mcp] HTTP server listening on http://${config.httpHost}:${actualPort}`
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
stop: () => server.stop(),
|
|
245
|
+
port: actualPort,
|
|
246
|
+
};
|
|
247
|
+
} else {
|
|
248
|
+
// Use Node.js server via @hono/node-server
|
|
249
|
+
const server = nodeServe({
|
|
250
|
+
fetch: app.fetch,
|
|
251
|
+
port: actualPort,
|
|
252
|
+
hostname: config.httpHost,
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
console.error(
|
|
256
|
+
`[vector-memory-mcp] HTTP server listening on http://${config.httpHost}:${actualPort}`
|
|
257
|
+
);
|
|
187
258
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
259
|
+
return {
|
|
260
|
+
stop: () => server.close(),
|
|
261
|
+
port: actualPort,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
191
264
|
}
|
package/scripts/publish.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
/**
|
|
3
|
-
* Publish script for vector-memory-mcp
|
|
4
|
-
*
|
|
5
|
-
* Prerequisites:
|
|
6
|
-
* 1. Create a granular access token at https://www.npmjs.com/settings/tokens
|
|
7
|
-
* 2. Store it: npm config set //registry.npmjs.org/:_authToken=npm_YOUR_TOKEN
|
|
8
|
-
* Or set NPM_TOKEN environment variable
|
|
9
|
-
*
|
|
10
|
-
* Usage: bun run scripts/publish.ts [--dry-run]
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { $ } from "bun";
|
|
14
|
-
|
|
15
|
-
const dryRun = process.argv.includes("--dry-run");
|
|
16
|
-
|
|
17
|
-
async function main() {
|
|
18
|
-
// Check for authentication
|
|
19
|
-
console.log("๐ Checking NPM authentication...");
|
|
20
|
-
try {
|
|
21
|
-
const whoami = await $`npm whoami`.text();
|
|
22
|
-
console.log(`โ
Authenticated as: ${whoami.trim()}`);
|
|
23
|
-
} catch {
|
|
24
|
-
console.error("โ Not authenticated with NPM.");
|
|
25
|
-
console.error(" Option 1: npm login");
|
|
26
|
-
console.error(" Option 2: npm config set //registry.npmjs.org/:_authToken=npm_YOUR_TOKEN");
|
|
27
|
-
console.error(" Option 3: Set NPM_TOKEN environment variable");
|
|
28
|
-
process.exit(1);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Run tests
|
|
32
|
-
console.log("๐งช Running tests...");
|
|
33
|
-
const testResult = await $`bun run test`.quiet();
|
|
34
|
-
if (testResult.exitCode !== 0) {
|
|
35
|
-
console.error("โ Tests failed. Aborting publish.");
|
|
36
|
-
process.exit(1);
|
|
37
|
-
}
|
|
38
|
-
console.log("โ
Tests passed");
|
|
39
|
-
|
|
40
|
-
// Build
|
|
41
|
-
console.log("๐จ Building...");
|
|
42
|
-
await $`bun run build`;
|
|
43
|
-
console.log("โ
Build complete");
|
|
44
|
-
|
|
45
|
-
// Get version info
|
|
46
|
-
const pkg = await Bun.file("package.json").json();
|
|
47
|
-
console.log(`\n๐ฆ Publishing ${pkg.name}@${pkg.version}...`);
|
|
48
|
-
|
|
49
|
-
if (dryRun) {
|
|
50
|
-
console.log("๐ Dry run - would publish:");
|
|
51
|
-
await $`npm publish --dry-run`;
|
|
52
|
-
} else {
|
|
53
|
-
await $`npm publish --access public`;
|
|
54
|
-
console.log(`\nโ
Published ${pkg.name}@${pkg.version}`);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
main().catch((err) => {
|
|
59
|
-
console.error("โ Publish failed:", err.message);
|
|
60
|
-
process.exit(1);
|
|
61
|
-
});
|