@aeriondyseti/vector-memory-mcp 0.9.0-dev.2 → 0.9.0-dev.3

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 (79) hide show
  1. package/README.md +21 -1
  2. package/dist/scripts/publish.d.ts +13 -0
  3. package/dist/scripts/publish.d.ts.map +1 -0
  4. package/dist/scripts/publish.js +56 -0
  5. package/dist/scripts/publish.js.map +1 -0
  6. package/dist/scripts/test-runner.d.ts +9 -0
  7. package/dist/scripts/test-runner.d.ts.map +1 -0
  8. package/dist/scripts/test-runner.js +61 -0
  9. package/dist/scripts/test-runner.js.map +1 -0
  10. package/dist/scripts/warmup.d.ts +8 -0
  11. package/dist/scripts/warmup.d.ts.map +1 -0
  12. package/dist/scripts/warmup.js +61 -0
  13. package/dist/scripts/warmup.js.map +1 -0
  14. package/dist/src/config/index.d.ts +23 -0
  15. package/dist/src/config/index.d.ts.map +1 -0
  16. package/dist/src/config/index.js +46 -0
  17. package/dist/src/config/index.js.map +1 -0
  18. package/dist/src/db/connection.d.ts +3 -0
  19. package/dist/src/db/connection.d.ts.map +1 -0
  20. package/dist/src/db/connection.js +10 -0
  21. package/dist/src/db/connection.js.map +1 -0
  22. package/dist/src/db/memory.repository.d.ts +13 -0
  23. package/dist/src/db/memory.repository.d.ts.map +1 -0
  24. package/dist/src/db/memory.repository.js +97 -0
  25. package/dist/src/db/memory.repository.js.map +1 -0
  26. package/dist/src/db/schema.d.ts +4 -0
  27. package/dist/src/db/schema.d.ts.map +1 -0
  28. package/dist/src/db/schema.js +12 -0
  29. package/dist/src/db/schema.js.map +1 -0
  30. package/dist/src/http/mcp-transport.d.ts +19 -0
  31. package/dist/src/http/mcp-transport.d.ts.map +1 -0
  32. package/dist/src/http/mcp-transport.js +191 -0
  33. package/dist/src/http/mcp-transport.js.map +1 -0
  34. package/dist/src/http/server.d.ts +12 -0
  35. package/dist/src/http/server.d.ts.map +1 -0
  36. package/dist/src/http/server.js +168 -0
  37. package/dist/src/http/server.js.map +1 -0
  38. package/dist/src/index.d.ts +3 -0
  39. package/dist/src/index.d.ts.map +1 -0
  40. package/dist/src/index.js +59 -0
  41. package/dist/src/index.js.map +1 -0
  42. package/dist/src/mcp/handlers.d.ts +11 -0
  43. package/dist/src/mcp/handlers.d.ts.map +1 -0
  44. package/dist/src/mcp/handlers.js +175 -0
  45. package/dist/src/mcp/handlers.js.map +1 -0
  46. package/dist/src/mcp/server.d.ts +5 -0
  47. package/dist/src/mcp/server.d.ts.map +1 -0
  48. package/dist/src/mcp/server.js +22 -0
  49. package/dist/src/mcp/server.js.map +1 -0
  50. package/dist/src/mcp/tools.d.ts +9 -0
  51. package/dist/src/mcp/tools.d.ts.map +1 -0
  52. package/dist/src/mcp/tools.js +243 -0
  53. package/dist/src/mcp/tools.js.map +1 -0
  54. package/dist/src/services/embeddings.service.d.ts +12 -0
  55. package/dist/src/services/embeddings.service.d.ts.map +1 -0
  56. package/dist/src/services/embeddings.service.js +37 -0
  57. package/dist/src/services/embeddings.service.js.map +1 -0
  58. package/dist/src/services/memory.service.d.ts +31 -0
  59. package/dist/src/services/memory.service.d.ts.map +1 -0
  60. package/dist/src/services/memory.service.js +131 -0
  61. package/dist/src/services/memory.service.js.map +1 -0
  62. package/dist/src/types/memory.d.ts +17 -0
  63. package/dist/src/types/memory.d.ts.map +1 -0
  64. package/dist/src/types/memory.js +15 -0
  65. package/dist/src/types/memory.js.map +1 -0
  66. package/package.json +12 -8
  67. package/src/config/index.ts +0 -75
  68. package/src/db/connection.ts +0 -11
  69. package/src/db/memory.repository.ts +0 -115
  70. package/src/db/schema.ts +0 -34
  71. package/src/http/mcp-transport.ts +0 -255
  72. package/src/http/server.ts +0 -190
  73. package/src/index.ts +0 -70
  74. package/src/mcp/handlers.ts +0 -248
  75. package/src/mcp/server.ts +0 -34
  76. package/src/mcp/tools.ts +0 -254
  77. package/src/services/embeddings.service.ts +0 -48
  78. package/src/services/memory.service.ts +0 -185
  79. package/src/types/memory.ts +0 -31
@@ -0,0 +1,191 @@
1
+ /**
2
+ * MCP HTTP Transport Handler
3
+ *
4
+ * Provides StreamableHTTP transport for MCP over HTTP.
5
+ * and other HTTP-based MCP clients to connect to the memory server.
6
+ *
7
+ * This implementation handles the MCP protocol directly using Hono's streaming
8
+ * capabilities, since StreamableHTTPServerTransport expects Node.js req/res objects.
9
+ */
10
+ import { Hono } from "hono";
11
+ import { streamSSE } from "hono/streaming";
12
+ import { randomUUID } from "node:crypto";
13
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
14
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
15
+ import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
16
+ import { tools } from "../mcp/tools.js";
17
+ import { handleToolCall } from "../mcp/handlers.js";
18
+ /**
19
+ * Creates MCP routes for a Hono app.
20
+ *
21
+ * Uses InMemoryTransport internally and bridges to HTTP/SSE manually,
22
+ * since StreamableHTTPServerTransport requires Node.js req/res objects.
23
+ */
24
+ export function createMcpRoutes(memoryService) {
25
+ const app = new Hono();
26
+ // Store active sessions by session ID
27
+ const sessions = new Map();
28
+ /**
29
+ * Creates a new MCP server instance configured with memory tools.
30
+ */
31
+ async function createSession() {
32
+ const server = new Server({ name: "vector-memory-mcp", version: "0.6.0" }, { capabilities: { tools: {} } });
33
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
34
+ return { tools };
35
+ });
36
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
37
+ const { name, arguments: args } = request.params;
38
+ return handleToolCall(name, args, memoryService);
39
+ });
40
+ // Create linked in-memory transports
41
+ const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
42
+ // Connect server to its transport
43
+ await server.connect(serverTransport);
44
+ const session = {
45
+ server,
46
+ serverTransport,
47
+ clientTransport,
48
+ pendingResponses: new Map(),
49
+ sseClients: new Set(),
50
+ };
51
+ // Handle messages from server (responses and notifications)
52
+ clientTransport.onmessage = (message) => {
53
+ // Check if this is a response to a pending request
54
+ if ("id" in message && message.id !== undefined) {
55
+ const resolver = session.pendingResponses.get(message.id);
56
+ if (resolver) {
57
+ resolver(message);
58
+ session.pendingResponses.delete(message.id);
59
+ return;
60
+ }
61
+ }
62
+ // Otherwise, broadcast to SSE clients (notifications)
63
+ for (const sendToClient of session.sseClients) {
64
+ sendToClient(message);
65
+ }
66
+ };
67
+ return session;
68
+ }
69
+ /**
70
+ * Handle POST requests - session initialization and message handling
71
+ */
72
+ app.post("/mcp", async (c) => {
73
+ const sessionId = c.req.header("mcp-session-id");
74
+ const body = await c.req.json();
75
+ let session;
76
+ let newSessionId;
77
+ if (sessionId && sessions.has(sessionId)) {
78
+ // Reuse existing session
79
+ session = sessions.get(sessionId);
80
+ }
81
+ else if (isInitializeRequest(body)) {
82
+ // New session initialization
83
+ newSessionId = randomUUID();
84
+ session = await createSession();
85
+ sessions.set(newSessionId, session);
86
+ console.error(`[vector-memory-mcp] MCP session initialized: ${newSessionId}`);
87
+ }
88
+ else {
89
+ // Invalid request - no session ID and not an initialize request
90
+ return c.json({
91
+ jsonrpc: "2.0",
92
+ error: {
93
+ code: -32000,
94
+ message: "Invalid session. Send initialize request without session ID to start.",
95
+ },
96
+ id: body.id ?? null,
97
+ }, 400);
98
+ }
99
+ // Send message to server and wait for response
100
+ const response = await sendAndWaitForResponse(session, body);
101
+ // Include session ID header for new sessions
102
+ if (newSessionId) {
103
+ c.header("mcp-session-id", newSessionId);
104
+ }
105
+ return c.json(response);
106
+ });
107
+ /**
108
+ * Handle GET requests - SSE stream for server-to-client notifications
109
+ */
110
+ app.get("/mcp", async (c) => {
111
+ const sessionId = c.req.header("mcp-session-id");
112
+ if (!sessionId || !sessions.has(sessionId)) {
113
+ return c.json({
114
+ jsonrpc: "2.0",
115
+ error: { code: -32000, message: "Invalid or missing session ID" },
116
+ id: null,
117
+ }, 400);
118
+ }
119
+ const session = sessions.get(sessionId);
120
+ return streamSSE(c, async (stream) => {
121
+ // Register this SSE client
122
+ const sendMessage = (message) => {
123
+ stream.writeSSE({
124
+ data: JSON.stringify(message),
125
+ event: "message",
126
+ });
127
+ };
128
+ session.sseClients.add(sendMessage);
129
+ // Keep connection open
130
+ try {
131
+ // Send a ping every 30 seconds to keep connection alive
132
+ while (true) {
133
+ await stream.sleep(30000);
134
+ await stream.writeSSE({ event: "ping", data: "" });
135
+ }
136
+ }
137
+ finally {
138
+ session.sseClients.delete(sendMessage);
139
+ }
140
+ });
141
+ });
142
+ /**
143
+ * Handle DELETE requests - session termination
144
+ */
145
+ app.delete("/mcp", async (c) => {
146
+ const sessionId = c.req.header("mcp-session-id");
147
+ if (!sessionId || !sessions.has(sessionId)) {
148
+ return c.json({
149
+ jsonrpc: "2.0",
150
+ error: { code: -32000, message: "Invalid or missing session ID" },
151
+ id: null,
152
+ }, 400);
153
+ }
154
+ const session = sessions.get(sessionId);
155
+ // Close transports
156
+ await session.clientTransport.close();
157
+ await session.serverTransport.close();
158
+ await session.server.close();
159
+ sessions.delete(sessionId);
160
+ console.error(`[vector-memory-mcp] MCP session closed: ${sessionId}`);
161
+ return c.json({ success: true });
162
+ });
163
+ return app;
164
+ }
165
+ /**
166
+ * Send a message to the server and wait for its response.
167
+ */
168
+ async function sendAndWaitForResponse(session, message) {
169
+ return new Promise((resolve) => {
170
+ // Register response handler for requests (messages with id)
171
+ if ("id" in message && message.id !== undefined) {
172
+ session.pendingResponses.set(message.id, resolve);
173
+ }
174
+ // Send message to server
175
+ session.clientTransport.send(message);
176
+ // For notifications (no id), resolve immediately with empty response
177
+ if (!("id" in message) || message.id === undefined) {
178
+ resolve({ jsonrpc: "2.0" });
179
+ }
180
+ });
181
+ }
182
+ /**
183
+ * Check if a message is an initialize request.
184
+ */
185
+ function isInitializeRequest(body) {
186
+ return (typeof body === "object" &&
187
+ body !== null &&
188
+ "method" in body &&
189
+ body.method === "initialize");
190
+ }
191
+ //# sourceMappingURL=mcp-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-transport.js","sourceRoot":"","sources":["../../../src/http/mcp-transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { Hono } from "hono";
2
+ import type { MemoryService } from "../services/memory.service.js";
3
+ import type { Config } from "../config/index.js";
4
+ export interface HttpServerOptions {
5
+ memoryService: MemoryService;
6
+ config: Config;
7
+ }
8
+ export declare function createHttpApp(memoryService: MemoryService, config: Config): Hono;
9
+ export declare function startHttpServer(memoryService: MemoryService, config: Config): Promise<{
10
+ stop: () => void;
11
+ }>;
12
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/http/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAQjD,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;CAChB;AAKD,wBAAgB,aAAa,CAAC,aAAa,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAwJhF;AAED,wBAAsB,eAAe,CACnC,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC,CAkC/B"}
@@ -0,0 +1,168 @@
1
+ import { Hono } from "hono";
2
+ import { cors } from "hono/cors";
3
+ import { serve as nodeServe } from "@hono/node-server";
4
+ import { isDeleted } from "../types/memory.js";
5
+ import { createMcpRoutes } from "./mcp-transport.js";
6
+ // Detect runtime
7
+ const isBun = typeof globalThis.Bun !== "undefined";
8
+ // Track server start time for uptime calculation
9
+ const startedAt = Date.now();
10
+ export function createHttpApp(memoryService, config) {
11
+ const app = new Hono();
12
+ // Enable CORS for local development
13
+ app.use("/*", cors());
14
+ // Mount MCP routes for StreamableHTTP transport
15
+ const mcpApp = createMcpRoutes(memoryService);
16
+ app.route("/", mcpApp);
17
+ // Health check endpoint with config info
18
+ app.get("/health", (c) => {
19
+ return c.json({
20
+ status: "ok",
21
+ timestamp: new Date().toISOString(),
22
+ pid: process.pid,
23
+ uptime: Math.floor((Date.now() - startedAt) / 1000),
24
+ config: {
25
+ dbPath: config.dbPath,
26
+ embeddingModel: config.embeddingModel,
27
+ embeddingDimension: config.embeddingDimension,
28
+ },
29
+ });
30
+ });
31
+ // Search endpoint
32
+ app.post("/search", async (c) => {
33
+ try {
34
+ const body = await c.req.json();
35
+ const query = body.query;
36
+ const limit = body.limit ?? 10;
37
+ if (!query || typeof query !== "string") {
38
+ return c.json({ error: "Missing or invalid 'query' field" }, 400);
39
+ }
40
+ const memories = await memoryService.search(query, limit);
41
+ return c.json({
42
+ memories: memories.map((m) => ({
43
+ id: m.id,
44
+ content: m.content,
45
+ metadata: m.metadata,
46
+ createdAt: m.createdAt.toISOString(),
47
+ })),
48
+ count: memories.length,
49
+ });
50
+ }
51
+ catch (error) {
52
+ const message = error instanceof Error ? error.message : "Unknown error";
53
+ return c.json({ error: message }, 500);
54
+ }
55
+ });
56
+ // Store endpoint
57
+ app.post("/store", async (c) => {
58
+ try {
59
+ const body = await c.req.json();
60
+ const { content, metadata, embeddingText } = body;
61
+ if (!content || typeof content !== "string") {
62
+ return c.json({ error: "Missing or invalid 'content' field" }, 400);
63
+ }
64
+ const memory = await memoryService.store(content, metadata ?? {}, embeddingText);
65
+ return c.json({
66
+ id: memory.id,
67
+ createdAt: memory.createdAt.toISOString(),
68
+ });
69
+ }
70
+ catch (error) {
71
+ const message = error instanceof Error ? error.message : "Unknown error";
72
+ return c.json({ error: message }, 500);
73
+ }
74
+ });
75
+ // Delete endpoint
76
+ app.delete("/memories/:id", async (c) => {
77
+ try {
78
+ const id = c.req.param("id");
79
+ const deleted = await memoryService.delete(id);
80
+ if (!deleted) {
81
+ return c.json({ error: "Memory not found" }, 404);
82
+ }
83
+ return c.json({ deleted: true });
84
+ }
85
+ catch (error) {
86
+ const message = error instanceof Error ? error.message : "Unknown error";
87
+ return c.json({ error: message }, 500);
88
+ }
89
+ });
90
+ // Get latest handoff
91
+ app.get("/handoff", async (c) => {
92
+ try {
93
+ const handoff = await memoryService.getLatestHandoff();
94
+ if (!handoff) {
95
+ return c.json({ error: "No handoff found" }, 404);
96
+ }
97
+ // Fetch referenced memories if any
98
+ const memoryIds = handoff.metadata.memory_ids ?? [];
99
+ const referencedMemories = [];
100
+ for (const id of memoryIds) {
101
+ const memory = await memoryService.get(id);
102
+ if (memory && !isDeleted(memory)) {
103
+ referencedMemories.push({ id: memory.id, content: memory.content });
104
+ }
105
+ }
106
+ return c.json({
107
+ content: handoff.content,
108
+ metadata: handoff.metadata,
109
+ referencedMemories,
110
+ updatedAt: handoff.updatedAt.toISOString(),
111
+ });
112
+ }
113
+ catch (error) {
114
+ const message = error instanceof Error ? error.message : "Unknown error";
115
+ return c.json({ error: message }, 500);
116
+ }
117
+ });
118
+ // Get single memory
119
+ app.get("/memories/:id", async (c) => {
120
+ try {
121
+ const id = c.req.param("id");
122
+ const memory = await memoryService.get(id);
123
+ if (!memory || isDeleted(memory)) {
124
+ return c.json({ error: "Memory not found" }, 404);
125
+ }
126
+ return c.json({
127
+ id: memory.id,
128
+ content: memory.content,
129
+ metadata: memory.metadata,
130
+ createdAt: memory.createdAt.toISOString(),
131
+ updatedAt: memory.updatedAt.toISOString(),
132
+ });
133
+ }
134
+ catch (error) {
135
+ const message = error instanceof Error ? error.message : "Unknown error";
136
+ return c.json({ error: message }, 500);
137
+ }
138
+ });
139
+ return app;
140
+ }
141
+ export async function startHttpServer(memoryService, config) {
142
+ const app = createHttpApp(memoryService, config);
143
+ if (isBun) {
144
+ // Use Bun's native server
145
+ const server = Bun.serve({
146
+ port: config.httpPort,
147
+ hostname: config.httpHost,
148
+ fetch: app.fetch,
149
+ });
150
+ console.error(`[vector-memory-mcp] HTTP server listening on http://${config.httpHost}:${config.httpPort}`);
151
+ return {
152
+ stop: () => server.stop(),
153
+ };
154
+ }
155
+ else {
156
+ // Use Node.js server via @hono/node-server
157
+ const server = nodeServe({
158
+ fetch: app.fetch,
159
+ port: config.httpPort,
160
+ hostname: config.httpHost,
161
+ });
162
+ console.error(`[vector-memory-mcp] HTTP server listening on http://${config.httpHost}:${config.httpPort}`);
163
+ return {
164
+ stop: () => server.close(),
165
+ };
166
+ }
167
+ }
168
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/http/server.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":""}
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env node
2
+ import { loadConfig, parseCliArgs } from "./config/index.js";
3
+ import { connectToDatabase } from "./db/connection.js";
4
+ import { MemoryRepository } from "./db/memory.repository.js";
5
+ import { EmbeddingsService } from "./services/embeddings.service.js";
6
+ import { MemoryService } from "./services/memory.service.js";
7
+ import { startServer } from "./mcp/server.js";
8
+ import { startHttpServer } from "./http/server.js";
9
+ async function main() {
10
+ const args = process.argv.slice(2);
11
+ // Check for warmup command
12
+ if (args[0] === "warmup") {
13
+ const { warmup } = await import("../scripts/warmup.js");
14
+ await warmup();
15
+ return;
16
+ }
17
+ // Parse CLI args and load config
18
+ const overrides = parseCliArgs(args);
19
+ const config = loadConfig(overrides);
20
+ // Initialize database
21
+ const db = await connectToDatabase(config.dbPath);
22
+ // Initialize layers
23
+ const repository = new MemoryRepository(db);
24
+ const embeddings = new EmbeddingsService(config.embeddingModel, config.embeddingDimension);
25
+ const memoryService = new MemoryService(repository, embeddings);
26
+ // Track cleanup functions
27
+ let httpStop = null;
28
+ // Graceful shutdown handler
29
+ const shutdown = () => {
30
+ console.error("[vector-memory-mcp] Shutting down...");
31
+ if (httpStop)
32
+ httpStop();
33
+ db.close();
34
+ process.exit(0);
35
+ };
36
+ // Handle signals and stdin close (parent process exit)
37
+ process.on("SIGTERM", shutdown);
38
+ process.on("SIGINT", shutdown);
39
+ process.stdin.on("close", shutdown);
40
+ process.stdin.on("end", shutdown);
41
+ // Start HTTP server if transport mode includes it
42
+ if (config.enableHttp) {
43
+ const http = await startHttpServer(memoryService, config);
44
+ httpStop = http.stop;
45
+ console.error(`[vector-memory-mcp] MCP available at http://${config.httpHost}:${config.httpPort}/mcp`);
46
+ }
47
+ // Start stdio transport unless in HTTP-only mode
48
+ if (config.transportMode !== "http") {
49
+ await startServer(memoryService);
50
+ }
51
+ else {
52
+ // In HTTP-only mode, keep the process running
53
+ console.error("[vector-memory-mcp] Running in HTTP-only mode (no stdio)");
54
+ // Keep process alive - the HTTP server runs indefinitely
55
+ await new Promise(() => { });
56
+ }
57
+ }
58
+ main().catch(console.error);
59
+ //# 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,11 @@
1
+ import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
2
+ import type { MemoryService } from "../services/memory.service.js";
3
+ export declare function handleStoreMemories(args: Record<string, unknown> | undefined, service: MemoryService): Promise<CallToolResult>;
4
+ export declare function handleDeleteMemories(args: Record<string, unknown> | undefined, service: MemoryService): Promise<CallToolResult>;
5
+ export declare function handleUpdateMemories(args: Record<string, unknown> | undefined, service: MemoryService): Promise<CallToolResult>;
6
+ export declare function handleSearchMemories(args: Record<string, unknown> | undefined, service: MemoryService): Promise<CallToolResult>;
7
+ export declare function handleGetMemories(args: Record<string, unknown> | undefined, service: MemoryService): Promise<CallToolResult>;
8
+ export declare function handleStoreHandoff(args: Record<string, unknown> | undefined, service: MemoryService): Promise<CallToolResult>;
9
+ export declare function handleGetHandoff(_args: Record<string, unknown> | undefined, service: MemoryService): Promise<CallToolResult>;
10
+ export declare function handleToolCall(name: string, args: Record<string, unknown> | undefined, service: MemoryService): Promise<CallToolResult>;
11
+ //# sourceMappingURL=handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/mcp/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEnE,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACzC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,CAAC,CA4BzB;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACzC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,CAAC,CAmBzB;AAGD,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACzC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,CAAC,CAgCzB;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACzC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,CAAC,CA0BzB;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACzC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,CAAC,CAgCzB;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACzC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,CAAC,CAgBzB;AAED,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC1C,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,CAAC,CA6BzB;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACzC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,CAAC,CAsBzB"}
@@ -0,0 +1,175 @@
1
+ export async function handleStoreMemories(args, service) {
2
+ const memories = args?.memories;
3
+ const ids = [];
4
+ for (const item of memories) {
5
+ const memory = await service.store(item.content, item.metadata ?? {}, item.embedding_text);
6
+ ids.push(memory.id);
7
+ }
8
+ return {
9
+ content: [
10
+ {
11
+ type: "text",
12
+ text: ids.length === 1
13
+ ? `Memory stored with ID: ${ids[0]}`
14
+ : `Stored ${ids.length} memories:\n${ids.map((id) => `- ${id}`).join("\n")}`,
15
+ },
16
+ ],
17
+ };
18
+ }
19
+ export async function handleDeleteMemories(args, service) {
20
+ const ids = args?.ids;
21
+ const results = [];
22
+ for (const id of ids) {
23
+ const success = await service.delete(id);
24
+ results.push(success ? `Memory ${id} deleted successfully` : `Memory ${id} not found`);
25
+ }
26
+ return {
27
+ content: [
28
+ {
29
+ type: "text",
30
+ text: results.join("\n"),
31
+ },
32
+ ],
33
+ };
34
+ }
35
+ export async function handleUpdateMemories(args, service) {
36
+ const updates = args?.updates;
37
+ const results = [];
38
+ for (const update of updates) {
39
+ const memory = await service.update(update.id, {
40
+ content: update.content,
41
+ embeddingText: update.embedding_text,
42
+ metadata: update.metadata,
43
+ });
44
+ if (memory) {
45
+ results.push(`Memory ${update.id} updated successfully`);
46
+ }
47
+ else {
48
+ results.push(`Memory ${update.id} not found`);
49
+ }
50
+ }
51
+ return {
52
+ content: [
53
+ {
54
+ type: "text",
55
+ text: results.join("\n"),
56
+ },
57
+ ],
58
+ };
59
+ }
60
+ export async function handleSearchMemories(args, service) {
61
+ const query = args?.query;
62
+ const limit = args?.limit ?? 10;
63
+ const includeDeleted = args?.include_deleted ?? false;
64
+ const memories = await service.search(query, limit, includeDeleted);
65
+ if (memories.length === 0) {
66
+ return {
67
+ content: [{ type: "text", text: "No memories found matching your query." }],
68
+ };
69
+ }
70
+ const results = memories.map((mem) => {
71
+ let result = `ID: ${mem.id}\nContent: ${mem.content}`;
72
+ if (Object.keys(mem.metadata).length > 0) {
73
+ result += `\nMetadata: ${JSON.stringify(mem.metadata)}`;
74
+ }
75
+ if (includeDeleted && mem.supersededBy) {
76
+ result += `\n[DELETED]`;
77
+ }
78
+ return result;
79
+ });
80
+ return {
81
+ content: [{ type: "text", text: results.join("\n\n---\n\n") }],
82
+ };
83
+ }
84
+ export async function handleGetMemories(args, service) {
85
+ const ids = args?.ids;
86
+ const format = (memoryId, memory) => {
87
+ if (!memory) {
88
+ return `Memory ${memoryId} not found`;
89
+ }
90
+ let result = `ID: ${memory.id}\nContent: ${memory.content}`;
91
+ if (Object.keys(memory.metadata).length > 0) {
92
+ result += `\nMetadata: ${JSON.stringify(memory.metadata)}`;
93
+ }
94
+ result += `\nCreated: ${memory.createdAt.toISOString()}`;
95
+ result += `\nUpdated: ${memory.updatedAt.toISOString()}`;
96
+ if (memory.supersededBy) {
97
+ result += `\nSuperseded by: ${memory.supersededBy}`;
98
+ }
99
+ return result;
100
+ };
101
+ const blocks = [];
102
+ for (const id of ids) {
103
+ const memory = await service.get(id);
104
+ blocks.push(format(id, memory));
105
+ }
106
+ return {
107
+ content: [{ type: "text", text: blocks.join("\n\n---\n\n") }],
108
+ };
109
+ }
110
+ export async function handleStoreHandoff(args, service) {
111
+ const memory = await service.storeHandoff({
112
+ project: args?.project,
113
+ branch: args?.branch,
114
+ summary: args?.summary,
115
+ completed: args?.completed ?? [],
116
+ in_progress_blocked: args?.in_progress_blocked ?? [],
117
+ key_decisions: args?.key_decisions ?? [],
118
+ next_steps: args?.next_steps ?? [],
119
+ memory_ids: args?.memory_ids ?? [],
120
+ metadata: args?.metadata ?? {},
121
+ });
122
+ return {
123
+ content: [{ type: "text", text: `Handoff stored with memory ID: ${memory.id}` }],
124
+ };
125
+ }
126
+ export async function handleGetHandoff(_args, service) {
127
+ const handoff = await service.getLatestHandoff();
128
+ if (!handoff) {
129
+ return {
130
+ content: [{ type: "text", text: "No stored handoff found." }],
131
+ };
132
+ }
133
+ // Fetch referenced memories if any
134
+ const memoryIds = handoff.metadata.memory_ids ?? [];
135
+ let memoriesSection = "";
136
+ if (memoryIds.length > 0) {
137
+ const memories = [];
138
+ for (const id of memoryIds) {
139
+ const memory = await service.get(id);
140
+ if (memory) {
141
+ memories.push(`### Memory: ${id}\n${memory.content}`);
142
+ }
143
+ }
144
+ if (memories.length > 0) {
145
+ memoriesSection = `\n\n## Referenced Memories\n\n${memories.join("\n\n")}`;
146
+ }
147
+ }
148
+ return {
149
+ content: [{ type: "text", text: handoff.content + memoriesSection }],
150
+ };
151
+ }
152
+ export async function handleToolCall(name, args, service) {
153
+ switch (name) {
154
+ case "store_memories":
155
+ return handleStoreMemories(args, service);
156
+ case "update_memories":
157
+ return handleUpdateMemories(args, service);
158
+ case "delete_memories":
159
+ return handleDeleteMemories(args, service);
160
+ case "search_memories":
161
+ return handleSearchMemories(args, service);
162
+ case "get_memories":
163
+ return handleGetMemories(args, service);
164
+ case "store_handoff":
165
+ return handleStoreHandoff(args, service);
166
+ case "get_handoff":
167
+ return handleGetHandoff(args, service);
168
+ default:
169
+ return {
170
+ content: [{ type: "text", text: `Unknown tool: ${name}` }],
171
+ isError: true,
172
+ };
173
+ }
174
+ }
175
+ //# sourceMappingURL=handlers.js.map