memory-journal-mcp 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/.dockerignore +88 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +76 -0
  3. package/.github/ISSUE_TEMPLATE/config.yml +11 -0
  4. package/.github/ISSUE_TEMPLATE/feature_request.md +89 -0
  5. package/.github/ISSUE_TEMPLATE/question.md +63 -0
  6. package/.github/dependabot.yml +110 -0
  7. package/.github/pull_request_template.md +110 -0
  8. package/.github/workflows/DOCKER_DEPLOYMENT_SETUP.md +346 -0
  9. package/.github/workflows/codeql.yml +45 -0
  10. package/.github/workflows/dependabot-auto-merge.yml +42 -0
  11. package/.github/workflows/docker-publish.yml +277 -0
  12. package/.github/workflows/lint-and-test.yml +58 -0
  13. package/.github/workflows/publish-npm.yml +75 -0
  14. package/.github/workflows/secrets-scanning.yml +32 -0
  15. package/.github/workflows/security-update.yml +99 -0
  16. package/.memory-journal-team.db +0 -0
  17. package/.trivyignore +18 -0
  18. package/CHANGELOG.md +19 -0
  19. package/CODE_OF_CONDUCT.md +128 -0
  20. package/CONTRIBUTING.md +209 -0
  21. package/DOCKER_README.md +377 -0
  22. package/Dockerfile +64 -0
  23. package/LICENSE +21 -0
  24. package/README.md +461 -0
  25. package/SECURITY.md +200 -0
  26. package/VERSION +1 -0
  27. package/dist/cli.d.ts +5 -0
  28. package/dist/cli.d.ts.map +1 -0
  29. package/dist/cli.js +42 -0
  30. package/dist/cli.js.map +1 -0
  31. package/dist/constants/ServerInstructions.d.ts +8 -0
  32. package/dist/constants/ServerInstructions.d.ts.map +1 -0
  33. package/dist/constants/ServerInstructions.js +26 -0
  34. package/dist/constants/ServerInstructions.js.map +1 -0
  35. package/dist/database/SqliteAdapter.d.ts +198 -0
  36. package/dist/database/SqliteAdapter.d.ts.map +1 -0
  37. package/dist/database/SqliteAdapter.js +736 -0
  38. package/dist/database/SqliteAdapter.js.map +1 -0
  39. package/dist/filtering/ToolFilter.d.ts +63 -0
  40. package/dist/filtering/ToolFilter.d.ts.map +1 -0
  41. package/dist/filtering/ToolFilter.js +242 -0
  42. package/dist/filtering/ToolFilter.js.map +1 -0
  43. package/dist/github/GitHubIntegration.d.ts +91 -0
  44. package/dist/github/GitHubIntegration.d.ts.map +1 -0
  45. package/dist/github/GitHubIntegration.js +317 -0
  46. package/dist/github/GitHubIntegration.js.map +1 -0
  47. package/dist/handlers/prompts/index.d.ts +28 -0
  48. package/dist/handlers/prompts/index.d.ts.map +1 -0
  49. package/dist/handlers/prompts/index.js +366 -0
  50. package/dist/handlers/prompts/index.js.map +1 -0
  51. package/dist/handlers/resources/index.d.ts +27 -0
  52. package/dist/handlers/resources/index.d.ts.map +1 -0
  53. package/dist/handlers/resources/index.js +453 -0
  54. package/dist/handlers/resources/index.js.map +1 -0
  55. package/dist/handlers/tools/index.d.ts +26 -0
  56. package/dist/handlers/tools/index.d.ts.map +1 -0
  57. package/dist/handlers/tools/index.js +982 -0
  58. package/dist/handlers/tools/index.js.map +1 -0
  59. package/dist/index.d.ts +11 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +13 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/server/McpServer.d.ts +18 -0
  64. package/dist/server/McpServer.d.ts.map +1 -0
  65. package/dist/server/McpServer.js +171 -0
  66. package/dist/server/McpServer.js.map +1 -0
  67. package/dist/types/index.d.ts +300 -0
  68. package/dist/types/index.d.ts.map +1 -0
  69. package/dist/types/index.js +15 -0
  70. package/dist/types/index.js.map +1 -0
  71. package/dist/utils/McpLogger.d.ts +61 -0
  72. package/dist/utils/McpLogger.d.ts.map +1 -0
  73. package/dist/utils/McpLogger.js +113 -0
  74. package/dist/utils/McpLogger.js.map +1 -0
  75. package/dist/utils/logger.d.ts +30 -0
  76. package/dist/utils/logger.d.ts.map +1 -0
  77. package/dist/utils/logger.js +70 -0
  78. package/dist/utils/logger.js.map +1 -0
  79. package/dist/vector/VectorSearchManager.d.ts +63 -0
  80. package/dist/vector/VectorSearchManager.d.ts.map +1 -0
  81. package/dist/vector/VectorSearchManager.js +235 -0
  82. package/dist/vector/VectorSearchManager.js.map +1 -0
  83. package/docker-compose.yml +37 -0
  84. package/eslint.config.js +86 -0
  85. package/mcp-config-example.json +21 -0
  86. package/package.json +71 -0
  87. package/releases/release-notes-v2.2.0.md +165 -0
  88. package/releases/release-notes.md +214 -0
  89. package/releases/v3.0.0.md +236 -0
  90. package/server.json +42 -0
  91. package/src/cli.ts +52 -0
  92. package/src/constants/ServerInstructions.ts +25 -0
  93. package/src/database/SqliteAdapter.ts +952 -0
  94. package/src/filtering/ToolFilter.ts +271 -0
  95. package/src/github/GitHubIntegration.ts +409 -0
  96. package/src/handlers/prompts/index.ts +420 -0
  97. package/src/handlers/resources/index.ts +529 -0
  98. package/src/handlers/tools/index.ts +1081 -0
  99. package/src/index.ts +53 -0
  100. package/src/server/McpServer.ts +230 -0
  101. package/src/types/index.ts +435 -0
  102. package/src/types/sql.js.d.ts +34 -0
  103. package/src/utils/McpLogger.ts +155 -0
  104. package/src/utils/logger.ts +98 -0
  105. package/src/vector/VectorSearchManager.ts +277 -0
  106. package/tools.json +300 -0
  107. package/tsconfig.json +51 -0
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Memory Journal MCP Server - MCP Protocol Logger
3
+ *
4
+ * Logging that sends structured messages via MCP notifications/message.
5
+ * Falls back to stderr when MCP server is not connected.
6
+ * Follows RFC 5424 severity levels as per MCP spec.
7
+ */
8
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
9
+ /**
10
+ * MCP log levels per RFC 5424
11
+ */
12
+ export type McpLogLevel = 'debug' | 'info' | 'notice' | 'warning' | 'error' | 'critical' | 'alert' | 'emergency';
13
+ interface LogData {
14
+ message: string;
15
+ module?: string;
16
+ operation?: string;
17
+ [key: string]: unknown;
18
+ }
19
+ /**
20
+ * MCP Protocol Logger
21
+ *
22
+ * Sends structured log messages via MCP notifications/message protocol.
23
+ * Falls back to stderr when server not connected.
24
+ */
25
+ export declare class McpLogger {
26
+ private server;
27
+ private minLevel;
28
+ /**
29
+ * Connect to MCP server for protocol logging
30
+ */
31
+ setServer(server: McpServer): void;
32
+ /**
33
+ * Set minimum log level (from logging/setLevel request)
34
+ */
35
+ setLevel(level: McpLogLevel): void;
36
+ /**
37
+ * Get current minimum log level
38
+ */
39
+ getLevel(): McpLogLevel;
40
+ /**
41
+ * Check if a level should be logged
42
+ */
43
+ private shouldLog;
44
+ /**
45
+ * Format message for stderr fallback
46
+ */
47
+ private formatForStderr;
48
+ /**
49
+ * Send log message via MCP protocol or fallback to stderr
50
+ */
51
+ log(level: McpLogLevel, loggerName: string, data: LogData): void;
52
+ debug(loggerName: string, message: string, context?: Record<string, unknown>): void;
53
+ info(loggerName: string, message: string, context?: Record<string, unknown>): void;
54
+ notice(loggerName: string, message: string, context?: Record<string, unknown>): void;
55
+ warning(loggerName: string, message: string, context?: Record<string, unknown>): void;
56
+ error(loggerName: string, message: string, context?: Record<string, unknown>): void;
57
+ critical(loggerName: string, message: string, context?: Record<string, unknown>): void;
58
+ }
59
+ export declare const mcpLogger: McpLogger;
60
+ export {};
61
+ //# sourceMappingURL=McpLogger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpLogger.d.ts","sourceRoot":"","sources":["../../src/utils/McpLogger.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE;;GAEG;AACH,MAAM,MAAM,WAAW,GACjB,OAAO,GACP,MAAM,GACN,QAAQ,GACR,SAAS,GACT,OAAO,GACP,UAAU,GACV,OAAO,GACP,WAAW,CAAC;AAalB,UAAU,OAAO;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED;;;;;GAKG;AACH,qBAAa,SAAS;IAClB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,QAAQ,CAAuB;IAEvC;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAIlC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAMlC;;OAEG;IACH,QAAQ,IAAI,WAAW;IAIvB;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,OAAO,CAAC,eAAe;IAmBvB;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAsBhE,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAInF,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIlF,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIpF,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIrF,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAInF,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAGzF;AAGD,eAAO,MAAM,SAAS,WAAkB,CAAC"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Memory Journal MCP Server - MCP Protocol Logger
3
+ *
4
+ * Logging that sends structured messages via MCP notifications/message.
5
+ * Falls back to stderr when MCP server is not connected.
6
+ * Follows RFC 5424 severity levels as per MCP spec.
7
+ */
8
+ const LOG_LEVEL_PRIORITY = {
9
+ emergency: 0,
10
+ alert: 1,
11
+ critical: 2,
12
+ error: 3,
13
+ warning: 4,
14
+ notice: 5,
15
+ info: 6,
16
+ debug: 7,
17
+ };
18
+ /**
19
+ * MCP Protocol Logger
20
+ *
21
+ * Sends structured log messages via MCP notifications/message protocol.
22
+ * Falls back to stderr when server not connected.
23
+ */
24
+ export class McpLogger {
25
+ server = null;
26
+ minLevel = 'info';
27
+ /**
28
+ * Connect to MCP server for protocol logging
29
+ */
30
+ setServer(server) {
31
+ this.server = server;
32
+ }
33
+ /**
34
+ * Set minimum log level (from logging/setLevel request)
35
+ */
36
+ setLevel(level) {
37
+ if (level in LOG_LEVEL_PRIORITY) {
38
+ this.minLevel = level;
39
+ }
40
+ }
41
+ /**
42
+ * Get current minimum log level
43
+ */
44
+ getLevel() {
45
+ return this.minLevel;
46
+ }
47
+ /**
48
+ * Check if a level should be logged
49
+ */
50
+ shouldLog(level) {
51
+ return LOG_LEVEL_PRIORITY[level] <= LOG_LEVEL_PRIORITY[this.minLevel];
52
+ }
53
+ /**
54
+ * Format message for stderr fallback
55
+ */
56
+ formatForStderr(level, loggerName, data) {
57
+ const timestamp = new Date().toISOString();
58
+ const levelUpper = level.toUpperCase().padEnd(9);
59
+ const module = loggerName ? `[${loggerName}]` : '';
60
+ let formatted = `[${timestamp}] [${levelUpper}] ${module} ${data.message}`;
61
+ // Add extra context (filter out message and module)
62
+ const extras = Object.fromEntries(Object.entries(data).filter(([key]) => key !== 'message' && key !== 'module'));
63
+ if (Object.keys(extras).length > 0) {
64
+ formatted += ` ${JSON.stringify(extras)}`;
65
+ }
66
+ return formatted;
67
+ }
68
+ /**
69
+ * Send log message via MCP protocol or fallback to stderr
70
+ */
71
+ log(level, loggerName, data) {
72
+ if (!this.shouldLog(level))
73
+ return;
74
+ // Send via MCP protocol if server connected
75
+ if (this.server) {
76
+ try {
77
+ void this.server.sendLoggingMessage({
78
+ level,
79
+ logger: loggerName,
80
+ data,
81
+ });
82
+ }
83
+ catch {
84
+ // Fallback to stderr if MCP send fails
85
+ console.error(this.formatForStderr(level, loggerName, data));
86
+ }
87
+ }
88
+ // Always also log to stderr for local debugging
89
+ console.error(this.formatForStderr(level, loggerName, data));
90
+ }
91
+ // Convenience methods
92
+ debug(loggerName, message, context) {
93
+ this.log('debug', loggerName, { message, ...context });
94
+ }
95
+ info(loggerName, message, context) {
96
+ this.log('info', loggerName, { message, ...context });
97
+ }
98
+ notice(loggerName, message, context) {
99
+ this.log('notice', loggerName, { message, ...context });
100
+ }
101
+ warning(loggerName, message, context) {
102
+ this.log('warning', loggerName, { message, ...context });
103
+ }
104
+ error(loggerName, message, context) {
105
+ this.log('error', loggerName, { message, ...context });
106
+ }
107
+ critical(loggerName, message, context) {
108
+ this.log('critical', loggerName, { message, ...context });
109
+ }
110
+ }
111
+ // Singleton instance
112
+ export const mcpLogger = new McpLogger();
113
+ //# sourceMappingURL=McpLogger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpLogger.js","sourceRoot":"","sources":["../../src/utils/McpLogger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Memory Journal MCP Server - Logger
3
+ *
4
+ * Centralized logging to stderr only (stdout reserved for MCP protocol).
5
+ * Follows RFC 5424 severity levels.
6
+ */
7
+ type LogLevel = 'debug' | 'info' | 'notice' | 'warning' | 'error' | 'critical';
8
+ interface LogContext {
9
+ module?: string;
10
+ operation?: string;
11
+ entityId?: string | number;
12
+ [key: string]: unknown;
13
+ }
14
+ declare class Logger {
15
+ private minLevel;
16
+ constructor(level?: LogLevel);
17
+ private shouldLog;
18
+ private formatMessage;
19
+ private log;
20
+ debug(message: string, context?: LogContext): void;
21
+ info(message: string, context?: LogContext): void;
22
+ notice(message: string, context?: LogContext): void;
23
+ warning(message: string, context?: LogContext): void;
24
+ error(message: string, context?: LogContext): void;
25
+ critical(message: string, context?: LogContext): void;
26
+ setLevel(level: LogLevel): void;
27
+ }
28
+ export declare const logger: Logger;
29
+ export {};
30
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,KAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;AAE/E,UAAU,UAAU;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAWD,cAAM,MAAM;IACR,OAAO,CAAC,QAAQ,CAAS;gBAEb,KAAK,GAAE,QAAiB;IAIpC,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,GAAG;IASX,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIlD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIjD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAInD,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIpD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIlD,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIrD,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;CAGlC;AAKD,eAAO,MAAM,MAAM,QAAuB,CAAC"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Memory Journal MCP Server - Logger
3
+ *
4
+ * Centralized logging to stderr only (stdout reserved for MCP protocol).
5
+ * Follows RFC 5424 severity levels.
6
+ */
7
+ const LOG_LEVELS = {
8
+ debug: 7,
9
+ info: 6,
10
+ notice: 5,
11
+ warning: 4,
12
+ error: 3,
13
+ critical: 2,
14
+ };
15
+ class Logger {
16
+ minLevel;
17
+ constructor(level = 'info') {
18
+ this.minLevel = LOG_LEVELS[level];
19
+ }
20
+ shouldLog(level) {
21
+ return LOG_LEVELS[level] <= this.minLevel;
22
+ }
23
+ formatMessage(level, message, context) {
24
+ const timestamp = new Date().toISOString();
25
+ const levelUpper = level.toUpperCase().padEnd(8);
26
+ const module = context?.module ? `[${context.module}]` : '';
27
+ const operation = context?.operation ? `[${context.operation}]` : '';
28
+ let formatted = `[${timestamp}] [${levelUpper}] ${module}${operation} ${message}`;
29
+ // Add context as JSON if there are additional fields
30
+ const extras = { ...context };
31
+ delete extras.module;
32
+ delete extras.operation;
33
+ if (Object.keys(extras).length > 0) {
34
+ formatted += ` ${JSON.stringify(extras)}`;
35
+ }
36
+ return formatted;
37
+ }
38
+ log(level, message, context) {
39
+ if (!this.shouldLog(level))
40
+ return;
41
+ const formatted = this.formatMessage(level, message, context);
42
+ // Always write to stderr (stdout is reserved for MCP protocol)
43
+ console.error(formatted);
44
+ }
45
+ debug(message, context) {
46
+ this.log('debug', message, context);
47
+ }
48
+ info(message, context) {
49
+ this.log('info', message, context);
50
+ }
51
+ notice(message, context) {
52
+ this.log('notice', message, context);
53
+ }
54
+ warning(message, context) {
55
+ this.log('warning', message, context);
56
+ }
57
+ error(message, context) {
58
+ this.log('error', message, context);
59
+ }
60
+ critical(message, context) {
61
+ this.log('critical', message, context);
62
+ }
63
+ setLevel(level) {
64
+ this.minLevel = LOG_LEVELS[level];
65
+ }
66
+ }
67
+ // Get log level from environment
68
+ const envLevel = (process.env['LOG_LEVEL'] ?? 'info');
69
+ export const logger = new Logger(envLevel);
70
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Memory Journal MCP Server - Vector Search Manager
3
+ *
4
+ * Semantic search using @xenova/transformers for embeddings
5
+ * and vectra for vector indexing.
6
+ */
7
+ import type { SqliteAdapter } from '../database/SqliteAdapter.js';
8
+ import type { JournalEntry } from '../types/index.js';
9
+ /** Search result with similarity score */
10
+ export interface SemanticSearchResult {
11
+ entryId: number;
12
+ score: number;
13
+ entry?: JournalEntry;
14
+ }
15
+ /**
16
+ * VectorSearchManager - Handles semantic search with local embeddings
17
+ */
18
+ export declare class VectorSearchManager {
19
+ private embedder;
20
+ private index;
21
+ private readonly indexPath;
22
+ private readonly modelName;
23
+ private initialized;
24
+ private initializing;
25
+ constructor(dbPath: string, modelName?: string);
26
+ /**
27
+ * Check if vector search is initialized
28
+ */
29
+ isInitialized(): boolean;
30
+ /**
31
+ * Initialize the vector search manager (lazy loading)
32
+ */
33
+ initialize(): Promise<void>;
34
+ /**
35
+ * Generate embedding for text
36
+ */
37
+ generateEmbedding(text: string): Promise<number[]>;
38
+ /**
39
+ * Add an entry to the vector index (upsert - replaces if exists)
40
+ */
41
+ addEntry(entryId: number, content: string): Promise<boolean>;
42
+ /**
43
+ * Perform semantic search
44
+ */
45
+ search(query: string, limit?: number, similarityThreshold?: number): Promise<SemanticSearchResult[]>;
46
+ /**
47
+ * Remove an entry from the vector index
48
+ */
49
+ removeEntry(entryId: number): Promise<boolean>;
50
+ /**
51
+ * Rebuild index from database entries
52
+ */
53
+ rebuildIndex(db: SqliteAdapter): Promise<number>;
54
+ /**
55
+ * Get index statistics
56
+ */
57
+ getStats(): Promise<{
58
+ itemCount: number;
59
+ modelName: string;
60
+ dimensions: number;
61
+ }>;
62
+ }
63
+ //# sourceMappingURL=VectorSearchManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VectorSearchManager.d.ts","sourceRoot":"","sources":["../../src/vector/VectorSearchManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAQtD,0CAA0C;AAC1C,MAAM,WAAW,oBAAoB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,YAAY,CAAC;CACxB;AAED;;GAEG;AACH,qBAAa,mBAAmB;IAE5B,OAAO,CAAC,QAAQ,CAAwF;IACxG,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAS;gBAEjB,MAAM,EAAE,MAAM,EAAE,SAAS,SAAgB;IAOrD;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA2CjC;;OAEG;IACG,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiBxD;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA2ClE;;OAEG;IACG,MAAM,CACR,KAAK,EAAE,MAAM,EACb,KAAK,SAAK,EACV,mBAAmB,SAAM,GAC1B,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAmClC;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYpD;;OAEG;IACG,YAAY,CAAC,EAAE,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IA+BtD;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAgB1F"}
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Memory Journal MCP Server - Vector Search Manager
3
+ *
4
+ * Semantic search using @xenova/transformers for embeddings
5
+ * and vectra for vector indexing.
6
+ */
7
+ import { pipeline } from '@xenova/transformers';
8
+ import { LocalIndex } from 'vectra';
9
+ import * as path from 'node:path';
10
+ import * as fs from 'node:fs';
11
+ import { logger } from '../utils/logger.js';
12
+ /** Default model for embeddings (same as Python version) */
13
+ const DEFAULT_MODEL = 'Xenova/all-MiniLM-L6-v2';
14
+ /** Embedding dimensions for all-MiniLM-L6-v2 */
15
+ const EMBEDDING_DIMENSIONS = 384;
16
+ /**
17
+ * VectorSearchManager - Handles semantic search with local embeddings
18
+ */
19
+ export class VectorSearchManager {
20
+ // Use a more flexible type since FeatureExtractionPipeline doesn't fully implement Pipeline
21
+ embedder = null;
22
+ index = null;
23
+ indexPath;
24
+ modelName;
25
+ initialized = false;
26
+ initializing = false;
27
+ constructor(dbPath, modelName = DEFAULT_MODEL) {
28
+ // Store index in same directory as database
29
+ const dbDir = path.dirname(dbPath);
30
+ this.indexPath = path.join(dbDir, '.vectra_index');
31
+ this.modelName = modelName;
32
+ }
33
+ /**
34
+ * Check if vector search is initialized
35
+ */
36
+ isInitialized() {
37
+ return this.initialized;
38
+ }
39
+ /**
40
+ * Initialize the vector search manager (lazy loading)
41
+ */
42
+ async initialize() {
43
+ if (this.initialized || this.initializing)
44
+ return;
45
+ this.initializing = true;
46
+ try {
47
+ logger.info('Initializing vector search...', { module: 'VectorSearch' });
48
+ // Load embedding model (downloads on first use, ~23MB)
49
+ logger.info(`Loading embedding model: ${this.modelName}`, { module: 'VectorSearch' });
50
+ this.embedder = await pipeline('feature-extraction', this.modelName, {
51
+ quantized: true, // Use quantized model for faster inference
52
+ });
53
+ logger.info('Embedding model loaded', { module: 'VectorSearch' });
54
+ // Create or load vectra index
55
+ if (!fs.existsSync(this.indexPath)) {
56
+ fs.mkdirSync(this.indexPath, { recursive: true });
57
+ }
58
+ this.index = new LocalIndex(this.indexPath);
59
+ // Check if index exists
60
+ if (!await this.index.isIndexCreated()) {
61
+ await this.index.createIndex();
62
+ logger.info('Created new vector index', { module: 'VectorSearch' });
63
+ }
64
+ else {
65
+ logger.info('Loaded existing vector index', { module: 'VectorSearch' });
66
+ }
67
+ this.initialized = true;
68
+ this.initializing = false;
69
+ logger.info('Vector search initialized successfully', { module: 'VectorSearch' });
70
+ }
71
+ catch (error) {
72
+ this.initializing = false;
73
+ logger.error('Failed to initialize vector search', {
74
+ module: 'VectorSearch',
75
+ error: error instanceof Error ? error.message : String(error)
76
+ });
77
+ throw error;
78
+ }
79
+ }
80
+ /**
81
+ * Generate embedding for text
82
+ */
83
+ async generateEmbedding(text) {
84
+ if (!this.embedder) {
85
+ throw new Error('Vector search not initialized');
86
+ }
87
+ // Generate embedding using feature-extraction pipeline
88
+ // The pipeline returns a Tensor with a data property containing the embeddings
89
+ const output = await this.embedder(text, {
90
+ pooling: 'mean',
91
+ normalize: true,
92
+ });
93
+ // Convert to number array
94
+ const embedding = Array.from(output.data);
95
+ return embedding;
96
+ }
97
+ /**
98
+ * Add an entry to the vector index (upsert - replaces if exists)
99
+ */
100
+ async addEntry(entryId, content) {
101
+ if (!this.initialized) {
102
+ await this.initialize();
103
+ }
104
+ if (!this.index) {
105
+ return false;
106
+ }
107
+ try {
108
+ // Delete existing item first to support upsert behavior
109
+ try {
110
+ await this.index.deleteItem(String(entryId));
111
+ }
112
+ catch {
113
+ // Item may not exist, ignore
114
+ }
115
+ // Generate embedding
116
+ const embedding = await this.generateEmbedding(content);
117
+ // Add to vectra index with entry ID as metadata
118
+ await this.index.insertItem({
119
+ id: String(entryId),
120
+ vector: embedding,
121
+ metadata: { entryId, contentPreview: content.slice(0, 100) }
122
+ });
123
+ logger.debug('Added entry to vector index', {
124
+ module: 'VectorSearch',
125
+ entityId: entryId
126
+ });
127
+ return true;
128
+ }
129
+ catch (error) {
130
+ logger.error('Failed to add entry to vector index', {
131
+ module: 'VectorSearch',
132
+ entityId: entryId,
133
+ error: error instanceof Error ? error.message : String(error)
134
+ });
135
+ return false;
136
+ }
137
+ }
138
+ /**
139
+ * Perform semantic search
140
+ */
141
+ async search(query, limit = 10, similarityThreshold = 0.3) {
142
+ if (!this.initialized) {
143
+ await this.initialize();
144
+ }
145
+ if (!this.index) {
146
+ return [];
147
+ }
148
+ try {
149
+ // Generate query embedding
150
+ const queryEmbedding = await this.generateEmbedding(query);
151
+ // Search vectra index
152
+ const results = await this.index.queryItems(queryEmbedding, limit * 2);
153
+ // Filter by threshold and map to our format
154
+ const filteredResults = results
155
+ .filter(r => r.score >= similarityThreshold)
156
+ .slice(0, limit)
157
+ .map(r => ({
158
+ entryId: r.item.metadata.entryId,
159
+ score: r.score
160
+ }));
161
+ return filteredResults;
162
+ }
163
+ catch (error) {
164
+ logger.error('Semantic search failed', {
165
+ module: 'VectorSearch',
166
+ error: error instanceof Error ? error.message : String(error)
167
+ });
168
+ return [];
169
+ }
170
+ }
171
+ /**
172
+ * Remove an entry from the vector index
173
+ */
174
+ async removeEntry(entryId) {
175
+ if (!this.index)
176
+ return false;
177
+ try {
178
+ await this.index.deleteItem(String(entryId));
179
+ return true;
180
+ }
181
+ catch {
182
+ // Item might not exist in index
183
+ return false;
184
+ }
185
+ }
186
+ /**
187
+ * Rebuild index from database entries
188
+ */
189
+ async rebuildIndex(db) {
190
+ if (!this.initialized) {
191
+ await this.initialize();
192
+ }
193
+ if (!this.index) {
194
+ return 0;
195
+ }
196
+ logger.info('Rebuilding vector index from database...', { module: 'VectorSearch' });
197
+ // Get all entries
198
+ const entries = db.getRecentEntries(10000); // Get up to 10k entries
199
+ let indexed = 0;
200
+ for (const entry of entries) {
201
+ // Delete existing item first to avoid "already exists" error
202
+ try {
203
+ await this.index.deleteItem(String(entry.id));
204
+ }
205
+ catch {
206
+ // Item may not exist, ignore
207
+ }
208
+ const success = await this.addEntry(entry.id, entry.content);
209
+ if (success)
210
+ indexed++;
211
+ }
212
+ logger.info(`Rebuilt vector index with ${String(indexed)} entries`, { module: 'VectorSearch' });
213
+ return indexed;
214
+ }
215
+ /**
216
+ * Get index statistics
217
+ */
218
+ async getStats() {
219
+ if (!this.index) {
220
+ return { itemCount: 0, modelName: this.modelName, dimensions: EMBEDDING_DIMENSIONS };
221
+ }
222
+ try {
223
+ const items = await this.index.listItems();
224
+ return {
225
+ itemCount: items.length,
226
+ modelName: this.modelName,
227
+ dimensions: EMBEDDING_DIMENSIONS
228
+ };
229
+ }
230
+ catch {
231
+ return { itemCount: 0, modelName: this.modelName, dimensions: EMBEDDING_DIMENSIONS };
232
+ }
233
+ }
234
+ }
235
+ //# sourceMappingURL=VectorSearchManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VectorSearchManager.js","sourceRoot":"","sources":["../../src/vector/VectorSearchManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ version: '3.8'
2
+
3
+ services:
4
+ memory-journal-mcp:
5
+ build: .
6
+ container_name: memory-journal-mcp
7
+ volumes:
8
+ # Mount local data directory for persistent SQLite database
9
+ - ./data:/app/data
10
+ # Mount git config for context bundle functionality
11
+ - ${HOME}/.gitconfig:/root/.gitconfig:ro
12
+ # Mount SSH keys for GitHub access (optional)
13
+ - ${HOME}/.ssh:/root/.ssh:ro
14
+ environment:
15
+ - DB_PATH=/app/data/memory_journal.db
16
+ - PYTHONPATH=/app
17
+ stdin_open: true
18
+ tty: true
19
+ # For MCP stdio communication
20
+ command: python src/server.py
21
+ restart: unless-stopped
22
+
23
+ # Alternative service for testing without git/ssh mounts
24
+ memory-journal-mcp-basic:
25
+ build: .
26
+ container_name: memory-journal-mcp-basic
27
+ volumes:
28
+ - ./data:/app/data
29
+ environment:
30
+ - DB_PATH=/app/data/memory_journal.db
31
+ - PYTHONPATH=/app
32
+ stdin_open: true
33
+ tty: true
34
+ command: python src/server.py
35
+ restart: unless-stopped
36
+ profiles:
37
+ - basic