@mrxkun/mcfast-mcp 4.0.11 → 4.0.14
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/package.json +1 -1
- package/src/index.js +156 -10
- package/src/memory/memory-engine.js +40 -5
- package/src/utils/parallel-search.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrxkun/mcfast-mcp",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.14",
|
|
4
4
|
"description": "Ultra-fast code editing with WASM acceleration, fuzzy patching, multi-layer caching, and 8 unified tools. Optimized for AI code assistants with 80-98% latency reduction. Phase 4: ML Intelligence Layer.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/index.js
CHANGED
|
@@ -54,16 +54,69 @@ const VERBOSE = process.env.MCFAST_VERBOSE !== 'false'; // Default: true
|
|
|
54
54
|
|
|
55
55
|
// Memory Engine (initialized lazily)
|
|
56
56
|
let memoryEngine = null;
|
|
57
|
+
let memoryEngineInitPromise = null;
|
|
58
|
+
let memoryEngineReady = false;
|
|
57
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Start background initialization of memory engine
|
|
62
|
+
* Call this on server startup to pre-initialize
|
|
63
|
+
*/
|
|
64
|
+
async function backgroundInitializeMemoryEngine() {
|
|
65
|
+
if (memoryEngineInitPromise) return memoryEngineInitPromise;
|
|
66
|
+
|
|
67
|
+
memoryEngineInitPromise = (async () => {
|
|
68
|
+
try {
|
|
69
|
+
memoryEngine = new MemoryEngine({
|
|
70
|
+
apiKey: TOKEN,
|
|
71
|
+
enableSync: true
|
|
72
|
+
});
|
|
73
|
+
// Use a shorter timeout for initialization
|
|
74
|
+
const initTimeout = new Promise((_, reject) => {
|
|
75
|
+
setTimeout(() => reject(new Error('Memory engine init timeout')), 25000);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
await Promise.race([
|
|
79
|
+
memoryEngine.initialize(process.cwd()),
|
|
80
|
+
initTimeout
|
|
81
|
+
]);
|
|
82
|
+
|
|
83
|
+
memoryEngineReady = true;
|
|
84
|
+
console.error(`${colors.cyan}[Memory]${colors.reset} Engine initialized successfully`);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error(`${colors.yellow}[Memory]${colors.reset} Engine initialization failed: ${error.message}`);
|
|
87
|
+
// Don't throw - allow partial initialization
|
|
88
|
+
memoryEngineReady = false;
|
|
89
|
+
}
|
|
90
|
+
})();
|
|
91
|
+
|
|
92
|
+
return memoryEngineInitPromise;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Get memory engine - waits for initialization with timeout
|
|
97
|
+
*/
|
|
58
98
|
async function getMemoryEngine() {
|
|
99
|
+
if (memoryEngine && memoryEngineReady) {
|
|
100
|
+
return memoryEngine;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Wait for initialization with timeout
|
|
104
|
+
if (memoryEngineInitPromise) {
|
|
105
|
+
try {
|
|
106
|
+
await Promise.race([
|
|
107
|
+
memoryEngineInitPromise,
|
|
108
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 5000))
|
|
109
|
+
]);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error(`${colors.yellow}[Memory]${colors.reset} Waiting for engine: ${error.message}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// If still not ready, try to initialize now
|
|
59
116
|
if (!memoryEngine) {
|
|
60
|
-
|
|
61
|
-
apiKey: TOKEN,
|
|
62
|
-
enableSync: true
|
|
63
|
-
});
|
|
64
|
-
await memoryEngine.initialize(process.cwd());
|
|
65
|
-
console.error(`${colors.cyan}[Memory]${colors.reset} Engine initialized`);
|
|
117
|
+
await backgroundInitializeMemoryEngine();
|
|
66
118
|
}
|
|
119
|
+
|
|
67
120
|
return memoryEngine;
|
|
68
121
|
}
|
|
69
122
|
|
|
@@ -282,6 +335,28 @@ const TOOL_ALIASES = {
|
|
|
282
335
|
'list_files_fast': 'list_files',
|
|
283
336
|
'read_file': 'read',
|
|
284
337
|
'goto_definition': 'search', // redirected
|
|
338
|
+
// VSCode MCP client adds prefixes
|
|
339
|
+
'mcp--mcfast--edit': 'edit',
|
|
340
|
+
'mcp--mcfast--search': 'search',
|
|
341
|
+
'mcp--mcfast--read': 'read',
|
|
342
|
+
'mcp--mcfast--list_files': 'list_files',
|
|
343
|
+
'mcp--mcfast--reapply': 'reapply',
|
|
344
|
+
'mcp--mcfast--memory_search': 'memory_search',
|
|
345
|
+
'mcp--mcfast--memory_get': 'memory_get',
|
|
346
|
+
'mcp--mcfast--detect_patterns': 'detect_patterns',
|
|
347
|
+
'mcp--mcfast--get_suggestions': 'get_suggestions',
|
|
348
|
+
'mcp--mcfast--select_strategy': 'select_strategy',
|
|
349
|
+
// Alternative format with double dashes
|
|
350
|
+
'mcfast_edit': 'edit',
|
|
351
|
+
'mcfast_search': 'search',
|
|
352
|
+
'mcfast_read': 'read',
|
|
353
|
+
'mcfast_list_files': 'list_files',
|
|
354
|
+
'mcfast_reapply': 'reapply',
|
|
355
|
+
'mcfast_memory_search': 'memory_search',
|
|
356
|
+
'mcfast_memory_get': 'memory_get',
|
|
357
|
+
'mcfast_detect_patterns': 'detect_patterns',
|
|
358
|
+
'mcfast_get_suggestions': 'get_suggestions',
|
|
359
|
+
'mcfast_select_strategy': 'select_strategy',
|
|
285
360
|
};
|
|
286
361
|
|
|
287
362
|
/**
|
|
@@ -1107,7 +1182,8 @@ async function handleSearchFilesystem({ query, path: searchPath, isRegex = false
|
|
|
1107
1182
|
lines.forEach((line, idx) => {
|
|
1108
1183
|
if (line.includes(query)) {
|
|
1109
1184
|
matches.push({
|
|
1110
|
-
|
|
1185
|
+
file,
|
|
1186
|
+
lineNumber: idx + 1,
|
|
1111
1187
|
content: line.trim()
|
|
1112
1188
|
});
|
|
1113
1189
|
}
|
|
@@ -1152,7 +1228,7 @@ async function handleSearchFilesystem({ query, path: searchPath, isRegex = false
|
|
|
1152
1228
|
contentMatches.slice(0, 10).forEach(({ file, matches }) => {
|
|
1153
1229
|
output += `\n${colors.yellow}${file}${colors.reset}\n`;
|
|
1154
1230
|
matches.forEach(match => {
|
|
1155
|
-
output += ` ${colors.dim}${match.
|
|
1231
|
+
output += ` ${colors.dim}${match.lineNumber}:${colors.reset} ${match.content}\n`;
|
|
1156
1232
|
});
|
|
1157
1233
|
});
|
|
1158
1234
|
}
|
|
@@ -1233,6 +1309,22 @@ async function handleReapply({ instruction, files, errorContext = "", attempt =
|
|
|
1233
1309
|
*/
|
|
1234
1310
|
async function handleEdit({ instruction, files, code_edit, dryRun = false }) {
|
|
1235
1311
|
const editStartTime = Date.now();
|
|
1312
|
+
|
|
1313
|
+
// Validate required parameters
|
|
1314
|
+
if (!instruction) {
|
|
1315
|
+
return {
|
|
1316
|
+
content: [{ type: "text", text: "❌ Error: 'instruction' parameter is required" }],
|
|
1317
|
+
isError: true
|
|
1318
|
+
};
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
if (!files || Object.keys(files).length === 0) {
|
|
1322
|
+
return {
|
|
1323
|
+
content: [{ type: "text", text: "❌ Error: 'files' parameter is required and must contain at least one file" }],
|
|
1324
|
+
isError: true
|
|
1325
|
+
};
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1236
1328
|
const firstFile = Object.keys(files)[0];
|
|
1237
1329
|
|
|
1238
1330
|
// 1. Retrieve memory context for enhanced understanding
|
|
@@ -1243,7 +1335,7 @@ async function handleEdit({ instruction, files, code_edit, dryRun = false }) {
|
|
|
1243
1335
|
console.error(`${colors.cyan}[MEMORY]${colors.reset} Retrieved context for edit`);
|
|
1244
1336
|
}
|
|
1245
1337
|
} catch (error) {
|
|
1246
|
-
console.error(`${colors.yellow}[
|
|
1338
|
+
console.error(`${colors.yellow}[Memory]${colors.reset} Context retrieval failed: ${error.message}`);
|
|
1247
1339
|
}
|
|
1248
1340
|
|
|
1249
1341
|
// 2. Analyze impact for rename operations
|
|
@@ -2489,7 +2581,7 @@ async function handleApplyFast({ instruction, files, dryRun, toolName }) {
|
|
|
2489
2581
|
if (!TOKEN) {
|
|
2490
2582
|
return {
|
|
2491
2583
|
content: [{ type: "text", text: "❌ Error: MCFAST_TOKEN is missing. Please set it in your MCP config." }],
|
|
2492
|
-
isError: true
|
|
2584
|
+
isError: true,
|
|
2493
2585
|
};
|
|
2494
2586
|
}
|
|
2495
2587
|
try {
|
|
@@ -2858,6 +2950,18 @@ async function handleMemorySearch({ query, type = 'all', maxResults = 6, minScor
|
|
|
2858
2950
|
*/
|
|
2859
2951
|
async function handleMemoryGet({ type }) {
|
|
2860
2952
|
const start = Date.now();
|
|
2953
|
+
|
|
2954
|
+
// Early return if memory engine not ready
|
|
2955
|
+
if (!memoryEngineReady) {
|
|
2956
|
+
return {
|
|
2957
|
+
content: [{
|
|
2958
|
+
type: "text",
|
|
2959
|
+
text: `⏳ Memory engine is still initializing. Please try again in a few seconds.`
|
|
2960
|
+
}],
|
|
2961
|
+
isError: true
|
|
2962
|
+
};
|
|
2963
|
+
}
|
|
2964
|
+
|
|
2861
2965
|
try {
|
|
2862
2966
|
const engine = await getMemoryEngine();
|
|
2863
2967
|
let output = '';
|
|
@@ -2923,6 +3027,18 @@ async function handleMemoryGet({ type }) {
|
|
|
2923
3027
|
*/
|
|
2924
3028
|
async function handleDetectPatterns() {
|
|
2925
3029
|
const start = Date.now();
|
|
3030
|
+
|
|
3031
|
+
// Early return if memory engine not ready
|
|
3032
|
+
if (!memoryEngineReady) {
|
|
3033
|
+
return {
|
|
3034
|
+
content: [{
|
|
3035
|
+
type: "text",
|
|
3036
|
+
text: `⏳ Memory engine is still initializing. Please try again in a few seconds.`
|
|
3037
|
+
}],
|
|
3038
|
+
isError: true
|
|
3039
|
+
};
|
|
3040
|
+
}
|
|
3041
|
+
|
|
2926
3042
|
try {
|
|
2927
3043
|
const engine = await getMemoryEngine();
|
|
2928
3044
|
const patterns = await engine.detectPatterns();
|
|
@@ -2970,6 +3086,18 @@ async function handleDetectPatterns() {
|
|
|
2970
3086
|
*/
|
|
2971
3087
|
async function handleGetSuggestions({ currentFile, currentLine }) {
|
|
2972
3088
|
const start = Date.now();
|
|
3089
|
+
|
|
3090
|
+
// Early return if memory engine not ready
|
|
3091
|
+
if (!memoryEngineReady) {
|
|
3092
|
+
return {
|
|
3093
|
+
content: [{
|
|
3094
|
+
type: "text",
|
|
3095
|
+
text: `⏳ Memory engine is still initializing. Please try again in a few seconds.`
|
|
3096
|
+
}],
|
|
3097
|
+
isError: true
|
|
3098
|
+
};
|
|
3099
|
+
}
|
|
3100
|
+
|
|
2973
3101
|
try {
|
|
2974
3102
|
const engine = await getMemoryEngine();
|
|
2975
3103
|
const suggestions = await engine.getSuggestions({
|
|
@@ -3023,6 +3151,18 @@ async function handleGetSuggestions({ currentFile, currentLine }) {
|
|
|
3023
3151
|
*/
|
|
3024
3152
|
async function handleSelectStrategy({ instruction, files = [] }) {
|
|
3025
3153
|
const start = Date.now();
|
|
3154
|
+
|
|
3155
|
+
// Early return if memory engine not ready
|
|
3156
|
+
if (!memoryEngineReady) {
|
|
3157
|
+
return {
|
|
3158
|
+
content: [{
|
|
3159
|
+
type: "text",
|
|
3160
|
+
text: `⏳ Memory engine is still initializing. Please try again in a few seconds.`
|
|
3161
|
+
}],
|
|
3162
|
+
isError: true
|
|
3163
|
+
};
|
|
3164
|
+
}
|
|
3165
|
+
|
|
3026
3166
|
try {
|
|
3027
3167
|
const engine = await getMemoryEngine();
|
|
3028
3168
|
const result = await engine.selectStrategy(instruction, { files });
|
|
@@ -3067,5 +3207,11 @@ async function handleSelectStrategy({ instruction, files = [] }) {
|
|
|
3067
3207
|
* Start Server
|
|
3068
3208
|
*/
|
|
3069
3209
|
const transport = new StdioServerTransport();
|
|
3210
|
+
|
|
3211
|
+
// Pre-initialize memory engine in background
|
|
3212
|
+
backgroundInitializeMemoryEngine().catch(err => {
|
|
3213
|
+
console.error(`${colors.yellow}[Memory]${colors.reset} Background init error: ${err.message}`);
|
|
3214
|
+
});
|
|
3215
|
+
|
|
3070
3216
|
await server.connect(transport);
|
|
3071
3217
|
console.error("mcfast MCP v1.0.0 running on stdio");
|
|
@@ -104,12 +104,47 @@ export class MemoryEngine {
|
|
|
104
104
|
console.log(`[MemoryEngine] Smart Routing: ${this.smartRoutingEnabled ? 'ENABLED' : 'DISABLED'}`);
|
|
105
105
|
console.log(`[MemoryEngine] Intelligence Layer: ${this.intelligenceEnabled ? 'ENABLED' : 'DISABLED'}`);
|
|
106
106
|
|
|
107
|
-
//
|
|
107
|
+
// Initialize intelligence engines if enabled
|
|
108
108
|
if (this.intelligenceEnabled) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
try {
|
|
110
|
+
const { PatternDetector, SuggestionEngine, StrategySelector } = await import('../intelligence/index.js');
|
|
111
|
+
this.patternDetector = new PatternDetector({ memoryEngine: this });
|
|
112
|
+
this.suggestionEngine = new SuggestionEngine({ memoryEngine: this });
|
|
113
|
+
this.strategySelector = new StrategySelector({ memoryEngine: this });
|
|
114
|
+
console.log('[MemoryEngine] Intelligence engines initialized');
|
|
115
|
+
} catch (error) {
|
|
116
|
+
console.warn('[MemoryEngine] Failed to initialize intelligence engines:', error.message);
|
|
117
|
+
this.intelligenceEnabled = false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Load intelligence models - run in background to not block initialization
|
|
122
|
+
if (this.intelligenceEnabled) {
|
|
123
|
+
// Start model loading in background without awaiting
|
|
124
|
+
(async () => {
|
|
125
|
+
try {
|
|
126
|
+
const loadPromises = [
|
|
127
|
+
this.patternDetector.loadModel?.(),
|
|
128
|
+
this.suggestionEngine.loadModel?.(),
|
|
129
|
+
this.strategySelector.loadModel?.()
|
|
130
|
+
].filter(Boolean);
|
|
131
|
+
|
|
132
|
+
// Add timeout to prevent hanging
|
|
133
|
+
const timeoutPromise = new Promise((_, reject) =>
|
|
134
|
+
setTimeout(() => reject(new Error('Model loading timeout')), 5000)
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
await Promise.race([
|
|
138
|
+
Promise.all(loadPromises),
|
|
139
|
+
timeoutPromise
|
|
140
|
+
]);
|
|
141
|
+
|
|
142
|
+
console.log('[MemoryEngine] ✅ Intelligence models loaded');
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.warn('[MemoryEngine] Model loading failed or timed out:', error.message);
|
|
145
|
+
// Don't disable intelligence - models are optional
|
|
146
|
+
}
|
|
147
|
+
})();
|
|
113
148
|
}
|
|
114
149
|
}
|
|
115
150
|
|