@whenmoon-afk/memory-mcp 2.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.
- package/LICENSE +21 -0
- package/README.md +263 -0
- package/dist/database/connection.d.ts +47 -0
- package/dist/database/connection.d.ts.map +1 -0
- package/dist/database/connection.js +151 -0
- package/dist/database/connection.js.map +1 -0
- package/dist/database/schema.d.ts +33 -0
- package/dist/database/schema.d.ts.map +1 -0
- package/dist/database/schema.js +293 -0
- package/dist/database/schema.js.map +1 -0
- package/dist/extractors/entity-extractor.d.ts +25 -0
- package/dist/extractors/entity-extractor.d.ts.map +1 -0
- package/dist/extractors/entity-extractor.js +195 -0
- package/dist/extractors/entity-extractor.js.map +1 -0
- package/dist/extractors/fact-extractor.d.ts +38 -0
- package/dist/extractors/fact-extractor.d.ts.map +1 -0
- package/dist/extractors/fact-extractor.js +172 -0
- package/dist/extractors/fact-extractor.js.map +1 -0
- package/dist/extractors/summary-generator.d.ts +28 -0
- package/dist/extractors/summary-generator.d.ts.map +1 -0
- package/dist/extractors/summary-generator.js +149 -0
- package/dist/extractors/summary-generator.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +229 -0
- package/dist/index.js.map +1 -0
- package/dist/scoring/importance.d.ts +39 -0
- package/dist/scoring/importance.d.ts.map +1 -0
- package/dist/scoring/importance.js +150 -0
- package/dist/scoring/importance.js.map +1 -0
- package/dist/scoring/ttl-manager.d.ts +33 -0
- package/dist/scoring/ttl-manager.d.ts.map +1 -0
- package/dist/scoring/ttl-manager.js +99 -0
- package/dist/scoring/ttl-manager.js.map +1 -0
- package/dist/search/semantic-search.d.ts +15 -0
- package/dist/search/semantic-search.d.ts.map +1 -0
- package/dist/search/semantic-search.js +236 -0
- package/dist/search/semantic-search.js.map +1 -0
- package/dist/tools/memory-forget.d.ts +10 -0
- package/dist/tools/memory-forget.d.ts.map +1 -0
- package/dist/tools/memory-forget.js +34 -0
- package/dist/tools/memory-forget.js.map +1 -0
- package/dist/tools/memory-recall.d.ts +12 -0
- package/dist/tools/memory-recall.d.ts.map +1 -0
- package/dist/tools/memory-recall.js +106 -0
- package/dist/tools/memory-recall.js.map +1 -0
- package/dist/tools/memory-store.d.ts +13 -0
- package/dist/tools/memory-store.d.ts.map +1 -0
- package/dist/tools/memory-store.js +279 -0
- package/dist/tools/memory-store.js.map +1 -0
- package/dist/tools/response-formatter.d.ts +71 -0
- package/dist/tools/response-formatter.d.ts.map +1 -0
- package/dist/tools/response-formatter.js +180 -0
- package/dist/tools/response-formatter.js.map +1 -0
- package/dist/types/index.d.ts +244 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +29 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/token-estimator.d.ts +33 -0
- package/dist/utils/token-estimator.d.ts.map +1 -0
- package/dist/utils/token-estimator.js +54 -0
- package/dist/utils/token-estimator.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fact extraction from content
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Check if content qualifies as a fact
|
|
6
|
+
*/
|
|
7
|
+
export function isFact(content) {
|
|
8
|
+
const trimmed = content.trim();
|
|
9
|
+
// Too short
|
|
10
|
+
if (trimmed.length < 5) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
// Questions
|
|
14
|
+
if (/^\s*\w+\s+(is|are|do|does|can|could|would|should|will|has|have)\s+.*\?/i.test(trimmed)) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
// Commands
|
|
18
|
+
if (/^(please|kindly|can you|could you|would you)\s+/i.test(trimmed)) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
// Greetings
|
|
22
|
+
if (/^(hello|hi|hey|goodbye|bye|thanks|thank you)/i.test(trimmed)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
// Temporary dialogue
|
|
26
|
+
if (/^(let me|i think|maybe|perhaps|possibly)/i.test(trimmed)) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
// Seems like a fact
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Classify memory type based on content
|
|
34
|
+
*/
|
|
35
|
+
export function classifyMemoryType(content, entities) {
|
|
36
|
+
const trimmed = content.toLowerCase();
|
|
37
|
+
// Relationship indicators
|
|
38
|
+
const relationshipPatterns = [
|
|
39
|
+
/\b(depends on|requires|needs|uses|extends|implements)\b/i,
|
|
40
|
+
/\b(reports to|works with|manages|leads|owns)\b/i,
|
|
41
|
+
/\b(caused by|results in|leads to|triggers)\b/i,
|
|
42
|
+
/\b(related to|associated with|connected to|linked to)\b/i,
|
|
43
|
+
/\b(is a|is an|part of|member of|belongs to)\b/i,
|
|
44
|
+
];
|
|
45
|
+
const hasRelationship = relationshipPatterns.some((pattern) => pattern.test(trimmed));
|
|
46
|
+
if (hasRelationship && entities.length >= 2) {
|
|
47
|
+
return 'relationship';
|
|
48
|
+
}
|
|
49
|
+
// Entity indicators (description of a single thing)
|
|
50
|
+
const entityPatterns = [
|
|
51
|
+
/^([A-Z][a-zA-Z\s]+)\s+-\s+/, // "Name - description"
|
|
52
|
+
/^([A-Z][a-zA-Z\s]+)\s+is\s+(a|an)\s+/i, // "Name is a..."
|
|
53
|
+
/\b(person|organization|company|team|project|tool|library|framework)\b/i,
|
|
54
|
+
];
|
|
55
|
+
const hasEntityIndicator = entityPatterns.some((pattern) => pattern.test(trimmed));
|
|
56
|
+
if (hasEntityIndicator && entities.length === 1) {
|
|
57
|
+
return 'entity';
|
|
58
|
+
}
|
|
59
|
+
// Default to fact
|
|
60
|
+
return 'fact';
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Detect user preferences in content
|
|
64
|
+
*/
|
|
65
|
+
export function isUserPreference(content) {
|
|
66
|
+
const preferencePatterns = [
|
|
67
|
+
/\b(prefer|prefers|like|likes|want|wants|choose|chooses|favor|favors)\b/i,
|
|
68
|
+
/\b(my preference|my choice|i use|i usually|i typically)\b/i,
|
|
69
|
+
/\b(always|never|usually|typically|generally)\s+(use|uses|do|does)\b/i,
|
|
70
|
+
];
|
|
71
|
+
return preferencePatterns.some((pattern) => pattern.test(content));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Detect explicit vs implicit facts
|
|
75
|
+
*/
|
|
76
|
+
export function isExplicit(content) {
|
|
77
|
+
// Explicit facts use definite language
|
|
78
|
+
const explicitPatterns = [
|
|
79
|
+
/\b(is|are|was|were|will be|has|have|must|shall)\b/i,
|
|
80
|
+
/\b(definitely|certainly|absolutely|clearly|obviously)\b/i,
|
|
81
|
+
/\b(always|never|every|all|none)\b/i,
|
|
82
|
+
];
|
|
83
|
+
// Implicit facts use hedging language
|
|
84
|
+
const implicitPatterns = [
|
|
85
|
+
/\b(might|may|could|possibly|perhaps|maybe|probably)\b/i,
|
|
86
|
+
/\b(seems|appears|looks like|suggests|indicates)\b/i,
|
|
87
|
+
/\b(i think|i believe|i guess|in my opinion)\b/i,
|
|
88
|
+
];
|
|
89
|
+
const hasExplicit = explicitPatterns.some((pattern) => pattern.test(content));
|
|
90
|
+
const hasImplicit = implicitPatterns.some((pattern) => pattern.test(content));
|
|
91
|
+
// Explicit if has explicit patterns and no implicit patterns
|
|
92
|
+
return hasExplicit && !hasImplicit;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Calculate content complexity (0-1)
|
|
96
|
+
*/
|
|
97
|
+
export function calculateComplexity(content) {
|
|
98
|
+
let complexity = 0;
|
|
99
|
+
// Length factor (longer = more complex)
|
|
100
|
+
const length = content.length;
|
|
101
|
+
if (length > 100)
|
|
102
|
+
complexity += 0.3;
|
|
103
|
+
else if (length > 50)
|
|
104
|
+
complexity += 0.2;
|
|
105
|
+
else if (length > 20)
|
|
106
|
+
complexity += 0.1;
|
|
107
|
+
// Word count factor
|
|
108
|
+
const words = content.split(/\s+/).length;
|
|
109
|
+
if (words > 20)
|
|
110
|
+
complexity += 0.2;
|
|
111
|
+
else if (words > 10)
|
|
112
|
+
complexity += 0.1;
|
|
113
|
+
// Technical terms (capitalized words, acronyms, technical patterns)
|
|
114
|
+
const technicalTerms = content.match(/\b[A-Z][a-z]+|[A-Z]{2,}|[a-z]+\.[a-z]+\(\)/g) || [];
|
|
115
|
+
if (technicalTerms.length > 5)
|
|
116
|
+
complexity += 0.3;
|
|
117
|
+
else if (technicalTerms.length > 2)
|
|
118
|
+
complexity += 0.2;
|
|
119
|
+
else if (technicalTerms.length > 0)
|
|
120
|
+
complexity += 0.1;
|
|
121
|
+
// Numbers, dates, specific details
|
|
122
|
+
const specifics = content.match(/\b\d+|v\d+\.\d+|\d{4}-\d{2}-\d{2}\b/g) || [];
|
|
123
|
+
if (specifics.length > 0)
|
|
124
|
+
complexity += 0.2;
|
|
125
|
+
return Math.min(complexity, 1.0);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Normalize content for storage
|
|
129
|
+
*/
|
|
130
|
+
export function normalizeContent(content) {
|
|
131
|
+
return content
|
|
132
|
+
.trim()
|
|
133
|
+
.replace(/\s+/g, ' ') // Normalize whitespace
|
|
134
|
+
.replace(/\n+/g, ' ') // Remove newlines
|
|
135
|
+
.replace(/[""]/g, '"') // Normalize quotes
|
|
136
|
+
.replace(/['']/g, "'"); // Normalize apostrophes
|
|
137
|
+
}
|
|
138
|
+
export function validateContent(content, type) {
|
|
139
|
+
const errors = [];
|
|
140
|
+
const warnings = [];
|
|
141
|
+
// Check length
|
|
142
|
+
if (content.length < 5) {
|
|
143
|
+
errors.push('Content too short (minimum 5 characters)');
|
|
144
|
+
}
|
|
145
|
+
if (content.length > 10000) {
|
|
146
|
+
errors.push('Content too long (maximum 10,000 characters)');
|
|
147
|
+
}
|
|
148
|
+
// Check if it's actually a fact
|
|
149
|
+
if (!isFact(content)) {
|
|
150
|
+
warnings.push('Content may not be a factual statement');
|
|
151
|
+
}
|
|
152
|
+
// Type-specific validation
|
|
153
|
+
if (type === 'entity') {
|
|
154
|
+
// Entities should have a clear name
|
|
155
|
+
if (!/^[A-Z]/.test(content)) {
|
|
156
|
+
warnings.push('Entity content should start with a capital letter');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (type === 'relationship') {
|
|
160
|
+
// Relationships should mention connection
|
|
161
|
+
const hasConnection = /\b(depend|require|need|use|extend|implement|report|work|manage|lead|own|cause|result|lead|trigger|relate|associate|connect|link|is|part|member|belong)\w*\b/i.test(content);
|
|
162
|
+
if (!hasConnection) {
|
|
163
|
+
warnings.push('Relationship content should describe a connection');
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
valid: errors.length === 0,
|
|
168
|
+
errors,
|
|
169
|
+
warnings,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=fact-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fact-extractor.js","sourceRoot":"","sources":["../../src/extractors/fact-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Summary Generator - Creates concise 15-20 word summaries from memory content
|
|
3
|
+
*
|
|
4
|
+
* Target: 15-20 words (hard limit: 25 words)
|
|
5
|
+
* Strategy: Extract key entities and main idea, preserve proper nouns
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Generate a concise summary from memory content
|
|
9
|
+
*
|
|
10
|
+
* @param content - The full memory content to summarize
|
|
11
|
+
* @returns A 15-20 word summary (max 25 words)
|
|
12
|
+
*/
|
|
13
|
+
export declare function generateSummary(content: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Validate that a summary meets requirements
|
|
16
|
+
*
|
|
17
|
+
* @param summary - The summary to validate
|
|
18
|
+
* @returns true if valid, false otherwise
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateSummary(summary: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Get word count for a summary
|
|
23
|
+
*
|
|
24
|
+
* @param summary - The summary to count
|
|
25
|
+
* @returns Number of words
|
|
26
|
+
*/
|
|
27
|
+
export declare function getSummaryWordCount(summary: string): number;
|
|
28
|
+
//# sourceMappingURL=summary-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary-generator.d.ts","sourceRoot":"","sources":["../../src/extractors/summary-generator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAwCvD;AAmGD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3D"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Summary Generator - Creates concise 15-20 word summaries from memory content
|
|
3
|
+
*
|
|
4
|
+
* Target: 15-20 words (hard limit: 25 words)
|
|
5
|
+
* Strategy: Extract key entities and main idea, preserve proper nouns
|
|
6
|
+
*/
|
|
7
|
+
const MAX_WORDS = 25;
|
|
8
|
+
const TARGET_WORDS_MIN = 15;
|
|
9
|
+
const TARGET_WORDS_MAX = 20;
|
|
10
|
+
const FALLBACK_CHARS = 100;
|
|
11
|
+
/**
|
|
12
|
+
* Generate a concise summary from memory content
|
|
13
|
+
*
|
|
14
|
+
* @param content - The full memory content to summarize
|
|
15
|
+
* @returns A 15-20 word summary (max 25 words)
|
|
16
|
+
*/
|
|
17
|
+
export function generateSummary(content) {
|
|
18
|
+
if (!content || content.trim().length === 0) {
|
|
19
|
+
return 'Empty memory content';
|
|
20
|
+
}
|
|
21
|
+
const trimmedContent = content.trim();
|
|
22
|
+
// Strategy 1: Use first sentence if it's concise enough
|
|
23
|
+
const firstSentence = extractFirstSentence(trimmedContent);
|
|
24
|
+
if (firstSentence) {
|
|
25
|
+
const wordCount = countWords(firstSentence);
|
|
26
|
+
if (wordCount >= TARGET_WORDS_MIN && wordCount <= TARGET_WORDS_MAX) {
|
|
27
|
+
return firstSentence;
|
|
28
|
+
}
|
|
29
|
+
if (wordCount < MAX_WORDS) {
|
|
30
|
+
return firstSentence;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Strategy 2: For longer content, extract key information
|
|
34
|
+
const extracted = extractKeyInformation(trimmedContent);
|
|
35
|
+
if (extracted) {
|
|
36
|
+
const wordCount = countWords(extracted);
|
|
37
|
+
if (wordCount <= MAX_WORDS) {
|
|
38
|
+
return extracted;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Strategy 3: Truncate intelligently to MAX_WORDS
|
|
42
|
+
const truncated = truncateToWords(trimmedContent, TARGET_WORDS_MAX);
|
|
43
|
+
if (truncated.length > 0) {
|
|
44
|
+
return truncated;
|
|
45
|
+
}
|
|
46
|
+
// Fallback: First 100 characters
|
|
47
|
+
if (trimmedContent.length <= FALLBACK_CHARS) {
|
|
48
|
+
return trimmedContent;
|
|
49
|
+
}
|
|
50
|
+
return trimmedContent.substring(0, FALLBACK_CHARS - 3) + '...';
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extract the first complete sentence from text
|
|
54
|
+
*/
|
|
55
|
+
function extractFirstSentence(text) {
|
|
56
|
+
// Match first sentence ending with . ! ? (but not abbreviations like Dr. or Mr.)
|
|
57
|
+
const sentenceMatch = text.match(/^[^.!?]+[.!?](?=\s|$)/);
|
|
58
|
+
if (sentenceMatch) {
|
|
59
|
+
return sentenceMatch[0].trim();
|
|
60
|
+
}
|
|
61
|
+
// If no sentence delimiter, check if the whole text is short enough
|
|
62
|
+
if (text.length < 150) {
|
|
63
|
+
return text;
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Extract key information from longer text
|
|
69
|
+
* Focuses on: subject + verb + key entities/details
|
|
70
|
+
*/
|
|
71
|
+
function extractKeyInformation(text) {
|
|
72
|
+
// Split into sentences
|
|
73
|
+
const sentences = text.match(/[^.!?]+[.!?]*/g);
|
|
74
|
+
if (!sentences || sentences.length === 0) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
// Get first sentence and try to condense it
|
|
78
|
+
const firstSentence = sentences[0].trim();
|
|
79
|
+
const words = firstSentence.split(/\s+/);
|
|
80
|
+
if (words.length <= MAX_WORDS) {
|
|
81
|
+
return firstSentence;
|
|
82
|
+
}
|
|
83
|
+
// Try to extract core meaning from first sentence
|
|
84
|
+
// Remove filler words and keep essential information
|
|
85
|
+
const condensed = removeFillerWords(firstSentence);
|
|
86
|
+
const condensedWords = countWords(condensed);
|
|
87
|
+
if (condensedWords <= MAX_WORDS) {
|
|
88
|
+
return condensed;
|
|
89
|
+
}
|
|
90
|
+
// If still too long, take first MAX_WORDS words of condensed version
|
|
91
|
+
return truncateToWords(condensed, TARGET_WORDS_MAX);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Remove common filler words while preserving meaning
|
|
95
|
+
*/
|
|
96
|
+
function removeFillerWords(text) {
|
|
97
|
+
const fillerPatterns = [
|
|
98
|
+
/\b(very|really|quite|rather|somewhat|actually|basically|essentially|literally)\b/gi,
|
|
99
|
+
/\b(I think|I believe|in my opinion|it seems|it appears)\b/gi,
|
|
100
|
+
];
|
|
101
|
+
let result = text;
|
|
102
|
+
for (const pattern of fillerPatterns) {
|
|
103
|
+
result = result.replace(pattern, '');
|
|
104
|
+
}
|
|
105
|
+
// Clean up multiple spaces
|
|
106
|
+
result = result.replace(/\s+/g, ' ').trim();
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Count words in a string
|
|
111
|
+
*/
|
|
112
|
+
function countWords(text) {
|
|
113
|
+
return text.trim().split(/\s+/).length;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Truncate text to a specific number of words
|
|
117
|
+
*/
|
|
118
|
+
function truncateToWords(text, maxWords) {
|
|
119
|
+
const words = text.trim().split(/\s+/);
|
|
120
|
+
if (words.length <= maxWords) {
|
|
121
|
+
return text.trim();
|
|
122
|
+
}
|
|
123
|
+
const truncated = words.slice(0, maxWords).join(' ');
|
|
124
|
+
// Add ellipsis if we truncated
|
|
125
|
+
if (words.length > maxWords) {
|
|
126
|
+
return truncated + '...';
|
|
127
|
+
}
|
|
128
|
+
return truncated;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Validate that a summary meets requirements
|
|
132
|
+
*
|
|
133
|
+
* @param summary - The summary to validate
|
|
134
|
+
* @returns true if valid, false otherwise
|
|
135
|
+
*/
|
|
136
|
+
export function validateSummary(summary) {
|
|
137
|
+
const wordCount = countWords(summary);
|
|
138
|
+
return wordCount > 0 && wordCount <= MAX_WORDS;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get word count for a summary
|
|
142
|
+
*
|
|
143
|
+
* @param summary - The summary to count
|
|
144
|
+
* @returns Number of words
|
|
145
|
+
*/
|
|
146
|
+
export function getSummaryWordCount(summary) {
|
|
147
|
+
return countWords(summary);
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=summary-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary-generator.js","sourceRoot":"","sources":["../../src/extractors/summary-generator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Memory MCP v2.0 - Smart monolith MCP server
|
|
4
|
+
* Brain-inspired memory system with smart context loading
|
|
5
|
+
*/
|
|
6
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
7
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
8
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ErrorCode, McpError, } from '@modelcontextprotocol/sdk/types.js';
|
|
9
|
+
import { getDatabase, closeDatabase } from './database/connection.js';
|
|
10
|
+
import { memoryStore } from './tools/memory-store.js';
|
|
11
|
+
import { memoryRecall } from './tools/memory-recall.js';
|
|
12
|
+
import { memoryForget } from './tools/memory-forget.js';
|
|
13
|
+
/**
|
|
14
|
+
* Configuration from environment or defaults
|
|
15
|
+
*/
|
|
16
|
+
const config = {
|
|
17
|
+
databasePath: process.env['MEMORY_DB_PATH'] || './memory.db',
|
|
18
|
+
defaultTTLDays: parseInt(process.env['DEFAULT_TTL_DAYS'] || '90'),
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Initialize MCP server
|
|
22
|
+
*/
|
|
23
|
+
const server = new Server({
|
|
24
|
+
name: '@whenmoon-afk/memory-mcp',
|
|
25
|
+
version: '2.0.0',
|
|
26
|
+
}, {
|
|
27
|
+
capabilities: {
|
|
28
|
+
tools: {},
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
// Database instance (initialized in main)
|
|
32
|
+
let db;
|
|
33
|
+
/**
|
|
34
|
+
* Tool definitions
|
|
35
|
+
*/
|
|
36
|
+
server.setRequestHandler(ListToolsRequestSchema, () => {
|
|
37
|
+
return {
|
|
38
|
+
tools: [
|
|
39
|
+
{
|
|
40
|
+
name: 'memory_store',
|
|
41
|
+
description: 'Store or update a memory. Provide "id" to update existing memory, omit to create new. Returns standard-formatted memory (no embeddings). Supports fact, entity, relationship, and self memory types.',
|
|
42
|
+
inputSchema: {
|
|
43
|
+
type: 'object',
|
|
44
|
+
properties: {
|
|
45
|
+
id: {
|
|
46
|
+
type: 'string',
|
|
47
|
+
description: 'Memory ID to update (omit to create new memory)',
|
|
48
|
+
},
|
|
49
|
+
content: {
|
|
50
|
+
type: 'string',
|
|
51
|
+
description: 'The memory content to store',
|
|
52
|
+
},
|
|
53
|
+
type: {
|
|
54
|
+
type: 'string',
|
|
55
|
+
enum: ['fact', 'entity', 'relationship', 'self'],
|
|
56
|
+
description: 'Type of memory: fact (discrete info), entity (people/places/things), relationship (connections), self (user preferences)',
|
|
57
|
+
},
|
|
58
|
+
importance: {
|
|
59
|
+
type: 'number',
|
|
60
|
+
description: 'Importance score 0-10 (auto-calculated if not provided)',
|
|
61
|
+
minimum: 0,
|
|
62
|
+
maximum: 10,
|
|
63
|
+
},
|
|
64
|
+
entities: {
|
|
65
|
+
type: 'array',
|
|
66
|
+
items: { type: 'string' },
|
|
67
|
+
description: 'Related entity names (auto-extracted if not provided)',
|
|
68
|
+
},
|
|
69
|
+
tags: {
|
|
70
|
+
type: 'array',
|
|
71
|
+
items: { type: 'string' },
|
|
72
|
+
description: 'Tags for categorization',
|
|
73
|
+
},
|
|
74
|
+
metadata: {
|
|
75
|
+
type: 'object',
|
|
76
|
+
description: 'Additional metadata',
|
|
77
|
+
},
|
|
78
|
+
ttl_days: {
|
|
79
|
+
type: 'number',
|
|
80
|
+
description: 'Time-to-live in days (null for permanent)',
|
|
81
|
+
},
|
|
82
|
+
expires_at: {
|
|
83
|
+
type: 'string',
|
|
84
|
+
description: 'Explicit expiration timestamp (ISO format)',
|
|
85
|
+
},
|
|
86
|
+
provenance: {
|
|
87
|
+
type: 'object',
|
|
88
|
+
description: 'Provenance information (source, timestamp, context)',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
required: ['content', 'type'],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: 'memory_recall',
|
|
96
|
+
description: 'Search memories with intelligent token-aware loading. Always returns memory index (summaries) plus detailed content that fits within token budget. Skill-pattern design: see what exists, load details selectively.',
|
|
97
|
+
inputSchema: {
|
|
98
|
+
type: 'object',
|
|
99
|
+
properties: {
|
|
100
|
+
query: {
|
|
101
|
+
type: 'string',
|
|
102
|
+
description: 'Natural language search query',
|
|
103
|
+
},
|
|
104
|
+
max_tokens: {
|
|
105
|
+
type: 'number',
|
|
106
|
+
description: 'Token budget for response (default: 1000). System auto-allocates: summaries first, then fills remaining budget with full content for top matches.',
|
|
107
|
+
default: 1000,
|
|
108
|
+
minimum: 100,
|
|
109
|
+
maximum: 5000,
|
|
110
|
+
},
|
|
111
|
+
type: {
|
|
112
|
+
type: 'string',
|
|
113
|
+
enum: ['fact', 'entity', 'relationship', 'self'],
|
|
114
|
+
description: 'Optional: Filter by memory type',
|
|
115
|
+
},
|
|
116
|
+
entities: {
|
|
117
|
+
type: 'array',
|
|
118
|
+
items: { type: 'string' },
|
|
119
|
+
description: 'Optional: Filter by related entities',
|
|
120
|
+
},
|
|
121
|
+
limit: {
|
|
122
|
+
type: 'number',
|
|
123
|
+
description: 'Maximum number of results to return (default: 20, max: 50)',
|
|
124
|
+
default: 20,
|
|
125
|
+
maximum: 50,
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
required: ['query'],
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: 'memory_forget',
|
|
133
|
+
description: 'Soft-delete a memory by ID. Preserves provenance for audit trail. Memory can be recovered or permanently deleted later.',
|
|
134
|
+
inputSchema: {
|
|
135
|
+
type: 'object',
|
|
136
|
+
properties: {
|
|
137
|
+
id: {
|
|
138
|
+
type: 'string',
|
|
139
|
+
description: 'Memory ID to forget',
|
|
140
|
+
},
|
|
141
|
+
reason: {
|
|
142
|
+
type: 'string',
|
|
143
|
+
description: 'Reason for forgetting (stored in provenance)',
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
required: ['id'],
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
/**
|
|
153
|
+
* Tool execution handler
|
|
154
|
+
*/
|
|
155
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
156
|
+
try {
|
|
157
|
+
const { name, arguments: args } = request.params;
|
|
158
|
+
switch (name) {
|
|
159
|
+
case 'memory_store': {
|
|
160
|
+
const result = await memoryStore(db, args);
|
|
161
|
+
return {
|
|
162
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
case 'memory_recall': {
|
|
166
|
+
const result = await memoryRecall(db, args);
|
|
167
|
+
return {
|
|
168
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
case 'memory_forget': {
|
|
172
|
+
const { id, reason } = args;
|
|
173
|
+
const result = await memoryForget(db, id, reason);
|
|
174
|
+
return {
|
|
175
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
default:
|
|
179
|
+
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
if (error instanceof McpError) {
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
187
|
+
throw new McpError(ErrorCode.InternalError, message);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
/**
|
|
191
|
+
* Start server
|
|
192
|
+
*/
|
|
193
|
+
async function main() {
|
|
194
|
+
try {
|
|
195
|
+
// Initialize database
|
|
196
|
+
console.error('Initializing database...');
|
|
197
|
+
db = getDatabase(config.databasePath);
|
|
198
|
+
console.error('Database initialized successfully');
|
|
199
|
+
// Connect to transport
|
|
200
|
+
const transport = new StdioServerTransport();
|
|
201
|
+
await server.connect(transport);
|
|
202
|
+
// Log startup info to stderr (not stdout, which is used for MCP protocol)
|
|
203
|
+
console.error('Memory MCP v2.0 server started');
|
|
204
|
+
console.error(`Database: ${config.databasePath}`);
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
console.error('Failed to start server:', error);
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Cleanup on exit
|
|
213
|
+
*/
|
|
214
|
+
process.on('SIGINT', () => {
|
|
215
|
+
console.error('Shutting down Memory MCP server...');
|
|
216
|
+
closeDatabase();
|
|
217
|
+
process.exit(0);
|
|
218
|
+
});
|
|
219
|
+
process.on('SIGTERM', () => {
|
|
220
|
+
console.error('Shutting down Memory MCP server...');
|
|
221
|
+
closeDatabase();
|
|
222
|
+
process.exit(0);
|
|
223
|
+
});
|
|
224
|
+
// Start the server
|
|
225
|
+
main().catch((error) => {
|
|
226
|
+
console.error('Fatal error:', error);
|
|
227
|
+
process.exit(1);
|
|
228
|
+
});
|
|
229
|
+
//# 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,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Importance scoring system for memories
|
|
3
|
+
*/
|
|
4
|
+
import type { ImportanceFactors, MemoryType } from '../types/index.js';
|
|
5
|
+
/**
|
|
6
|
+
* Calculate importance score automatically (0-10)
|
|
7
|
+
*/
|
|
8
|
+
export declare function calculateImportance(content: string, type: MemoryType, entities: string[], metadata: Record<string, unknown>, hasProvenance: boolean): number;
|
|
9
|
+
/**
|
|
10
|
+
* Analyze factors that contribute to importance
|
|
11
|
+
*/
|
|
12
|
+
export declare function analyzeImportanceFactors(content: string, type: MemoryType, entities: string[], metadata: Record<string, unknown>, hasProvenance: boolean): ImportanceFactors;
|
|
13
|
+
/**
|
|
14
|
+
* Calculate importance from analyzed factors
|
|
15
|
+
*/
|
|
16
|
+
export declare function calculateImportanceFromFactors(factors: ImportanceFactors): number;
|
|
17
|
+
/**
|
|
18
|
+
* Adjust importance based on context signals
|
|
19
|
+
*/
|
|
20
|
+
export declare function adjustImportanceForContext(baseImportance: number, signals: {
|
|
21
|
+
isSecuritySensitive?: boolean;
|
|
22
|
+
isUserIdentity?: boolean;
|
|
23
|
+
isProjectRequirement?: boolean;
|
|
24
|
+
isDeprecated?: boolean;
|
|
25
|
+
userExplicitlyMarked?: boolean;
|
|
26
|
+
}): number;
|
|
27
|
+
/**
|
|
28
|
+
* Get recommended TTL for importance level
|
|
29
|
+
*/
|
|
30
|
+
export declare function getRecommendedTTL(importance: number): number | null;
|
|
31
|
+
/**
|
|
32
|
+
* Calculate effective importance (with decay over time)
|
|
33
|
+
*/
|
|
34
|
+
export declare function calculateEffectiveImportance(baseImportance: number, lastAccessed: number, now: number): number;
|
|
35
|
+
/**
|
|
36
|
+
* Boost importance on repeated access
|
|
37
|
+
*/
|
|
38
|
+
export declare function boostImportanceOnAccess(currentImportance: number, accessCount: number, daysSinceCreated: number): number;
|
|
39
|
+
//# sourceMappingURL=importance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importance.d.ts","sourceRoot":"","sources":["../../src/scoring/importance.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGvE;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,aAAa,EAAE,OAAO,GACrB,MAAM,CAGR;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,aAAa,EAAE,OAAO,GACrB,iBAAiB,CAUnB;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAmCjF;AAkBD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE;IACP,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,GACA,MAAM,CA6BR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOnE;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,MAAM,GACV,MAAM,CAcR;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,GACvB,MAAM,CAcR"}
|