@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.
Files changed (65) hide show
  1. package/dist/package.json +72 -0
  2. package/dist/scripts/test-runner.d.ts +9 -0
  3. package/dist/scripts/test-runner.d.ts.map +1 -0
  4. package/dist/scripts/test-runner.js +61 -0
  5. package/dist/scripts/test-runner.js.map +1 -0
  6. package/dist/scripts/warmup.d.ts +8 -0
  7. package/dist/scripts/warmup.d.ts.map +1 -0
  8. package/dist/scripts/warmup.js +61 -0
  9. package/dist/scripts/warmup.js.map +1 -0
  10. package/dist/src/config/index.d.ts +24 -0
  11. package/dist/src/config/index.d.ts.map +1 -0
  12. package/dist/src/config/index.js +48 -0
  13. package/dist/src/config/index.js.map +1 -0
  14. package/dist/src/db/connection.d.ts +3 -0
  15. package/dist/src/db/connection.d.ts.map +1 -0
  16. package/dist/src/db/connection.js +10 -0
  17. package/dist/src/db/connection.js.map +1 -0
  18. package/dist/src/db/memory.repository.d.ts +38 -0
  19. package/dist/src/db/memory.repository.d.ts.map +1 -0
  20. package/dist/src/db/memory.repository.js +176 -0
  21. package/dist/src/db/memory.repository.js.map +1 -0
  22. package/dist/src/db/schema.d.ts +4 -0
  23. package/dist/src/db/schema.d.ts.map +1 -0
  24. package/dist/src/db/schema.js +15 -0
  25. package/dist/src/db/schema.js.map +1 -0
  26. package/dist/src/http/mcp-transport.d.ts +19 -0
  27. package/dist/src/http/mcp-transport.d.ts.map +1 -0
  28. package/dist/src/http/mcp-transport.js +191 -0
  29. package/dist/src/http/mcp-transport.js.map +1 -0
  30. package/dist/src/http/server.d.ts +13 -0
  31. package/dist/src/http/server.d.ts.map +1 -0
  32. package/dist/src/http/server.js +210 -0
  33. package/dist/src/http/server.js.map +1 -0
  34. package/dist/src/index.d.ts +3 -0
  35. package/dist/src/index.d.ts.map +1 -0
  36. package/dist/src/index.js +59 -0
  37. package/dist/src/index.js.map +1 -0
  38. package/dist/src/mcp/handlers.d.ts +12 -0
  39. package/dist/src/mcp/handlers.d.ts.map +1 -0
  40. package/dist/src/mcp/handlers.js +198 -0
  41. package/dist/src/mcp/handlers.js.map +1 -0
  42. package/dist/src/mcp/server.d.ts +5 -0
  43. package/dist/src/mcp/server.d.ts.map +1 -0
  44. package/dist/src/mcp/server.js +22 -0
  45. package/dist/src/mcp/server.js.map +1 -0
  46. package/dist/src/mcp/tools.d.ts +10 -0
  47. package/dist/src/mcp/tools.d.ts.map +1 -0
  48. package/dist/src/mcp/tools.js +272 -0
  49. package/dist/src/mcp/tools.js.map +1 -0
  50. package/dist/src/services/embeddings.service.d.ts +12 -0
  51. package/dist/src/services/embeddings.service.d.ts.map +1 -0
  52. package/dist/src/services/embeddings.service.js +37 -0
  53. package/dist/src/services/embeddings.service.js.map +1 -0
  54. package/dist/src/services/memory.service.d.ts +33 -0
  55. package/dist/src/services/memory.service.d.ts.map +1 -0
  56. package/dist/src/services/memory.service.js +200 -0
  57. package/dist/src/services/memory.service.js.map +1 -0
  58. package/dist/src/types/memory.d.ts +28 -0
  59. package/dist/src/types/memory.d.ts.map +1 -0
  60. package/dist/src/types/memory.js +18 -0
  61. package/dist/src/types/memory.js.map +1 -0
  62. package/package.json +11 -8
  63. package/src/config/index.ts +5 -2
  64. package/src/http/server.ts +85 -12
  65. 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.5",
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.ts",
6
+ "main": "dist/src/index.js",
7
7
  "bin": {
8
- "vector-memory-mcp": "src/index.ts"
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": "bun run src/index.ts",
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": "bun run typecheck",
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
- "publish:check": "bun run scripts/publish.ts --dry-run",
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",
@@ -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.startsWith("/") ? path : join(process.cwd(), path);
34
+ return isAbsolute(path) ? path : join(process.cwd(), path);
32
35
  }
33
36
 
34
37
  export function loadConfig(overrides: ConfigOverrides = {}): Config {
@@ -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
- const server = Bun.serve({
179
- port: config.httpPort,
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
- console.error(
185
- `[vector-memory-mcp] HTTP server listening on http://${config.httpHost}:${config.httpPort}`
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
- return {
189
- stop: () => server.stop(),
190
- };
259
+ return {
260
+ stop: () => server.close(),
261
+ port: actualPort,
262
+ };
263
+ }
191
264
  }
@@ -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
- });