@grec0/memory-bank-mcp 0.1.1 → 0.1.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.
- package/README.md +160 -4
- package/dist/common/projectKnowledgeService.js +74 -0
- package/dist/index.js +393 -20
- package/dist/tools/analyzeCoverage.js +1 -1
- package/dist/tools/initializeMemoryBank.js +364 -0
- package/dist/tools/recordDecision.js +208 -0
- package/dist/tools/trackProgress.js +355 -0
- package/dist/tools/updateContext.js +201 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20,6 +20,11 @@ import { getStats } from "./tools/getStats.js";
|
|
|
20
20
|
import { analyzeCoverage } from "./tools/analyzeCoverage.js";
|
|
21
21
|
import { generateProjectDocs, generateProjectDocsToolDefinition } from "./tools/generateProjectDocs.js";
|
|
22
22
|
import { getProjectDocs, getProjectDocsToolDefinition } from "./tools/getProjectDocs.js";
|
|
23
|
+
// Import new context management tools
|
|
24
|
+
import { initializeMemoryBank, initializeMemoryBankToolDefinition } from "./tools/initializeMemoryBank.js";
|
|
25
|
+
import { updateContext, updateContextToolDefinition } from "./tools/updateContext.js";
|
|
26
|
+
import { recordDecision, recordDecisionToolDefinition } from "./tools/recordDecision.js";
|
|
27
|
+
import { trackProgress, trackProgressToolDefinition } from "./tools/trackProgress.js";
|
|
23
28
|
import { VERSION } from "./common/version.js";
|
|
24
29
|
// Global services
|
|
25
30
|
let embeddingService;
|
|
@@ -33,24 +38,31 @@ const server = new McpServer({
|
|
|
33
38
|
version: VERSION,
|
|
34
39
|
});
|
|
35
40
|
// Tool: Index Code
|
|
36
|
-
server.tool("memorybank_index_code",
|
|
41
|
+
server.tool("memorybank_index_code", `Indexa semánticamente código de un DIRECTORIO para búsquedas semánticas.
|
|
42
|
+
|
|
43
|
+
⚠️ IMPORTANTE:
|
|
44
|
+
- El path debe ser una RUTA ABSOLUTA a un DIRECTORIO (no archivo)
|
|
45
|
+
- Ejemplo correcto: "C:/workspaces/mi-proyecto/src/components"
|
|
46
|
+
- Ejemplo incorrecto: "src/components" (ruta relativa)
|
|
47
|
+
- Ejemplo incorrecto: "C:/workspaces/mi-proyecto/src/file.ts" (archivo, no directorio)
|
|
48
|
+
|
|
49
|
+
Si quieres indexar un archivo específico, usa el directorio que lo contiene.`, {
|
|
37
50
|
projectId: z
|
|
38
51
|
.string()
|
|
39
|
-
.describe("Identificador único del proyecto (OBLIGATORIO). Debe coincidir con el definido en AGENTS.md
|
|
52
|
+
.describe("Identificador único del proyecto (OBLIGATORIO). Debe coincidir con el definido en AGENTS.md"),
|
|
40
53
|
path: z
|
|
41
54
|
.string()
|
|
42
|
-
.
|
|
43
|
-
.describe("Ruta relativa o absoluta del directorio/archivo a indexar (por defecto: raíz del workspace)"),
|
|
55
|
+
.describe("RUTA ABSOLUTA al DIRECTORIO a indexar. Ejemplo: 'C:/workspaces/proyecto/src'. NO usar rutas relativas. NO usar rutas a archivos."),
|
|
44
56
|
recursive: z
|
|
45
57
|
.boolean()
|
|
46
58
|
.optional()
|
|
47
59
|
.default(true)
|
|
48
|
-
.describe("Indexar recursivamente subdirectorios"),
|
|
60
|
+
.describe("Indexar recursivamente subdirectorios (default: true)"),
|
|
49
61
|
forceReindex: z
|
|
50
62
|
.boolean()
|
|
51
63
|
.optional()
|
|
52
64
|
.default(false)
|
|
53
|
-
.describe("
|
|
65
|
+
.describe("RARAMENTE NECESARIO. El sistema detecta cambios por hash automáticamente. Solo usa true si necesitas regenerar embeddings sin cambios en archivos."),
|
|
54
66
|
}, async (args) => {
|
|
55
67
|
const result = await indexCode({
|
|
56
68
|
projectId: args.projectId,
|
|
@@ -102,18 +114,21 @@ server.tool("memorybank_search", "Busca código relevante mediante búsqueda sem
|
|
|
102
114
|
};
|
|
103
115
|
});
|
|
104
116
|
// Tool: Read File
|
|
105
|
-
server.tool("memorybank_read_file",
|
|
117
|
+
server.tool("memorybank_read_file", `Lee el contenido de un archivo específico. Usa para obtener contexto adicional.
|
|
118
|
+
|
|
119
|
+
⚠️ Preferir RUTA ABSOLUTA para evitar errores.
|
|
120
|
+
Ejemplo: "C:/workspaces/proyecto/src/index.ts"`, {
|
|
106
121
|
path: z
|
|
107
122
|
.string()
|
|
108
|
-
.describe("Ruta
|
|
123
|
+
.describe("Ruta al archivo. Preferir ABSOLUTA: 'C:/workspaces/proyecto/src/file.ts'"),
|
|
109
124
|
startLine: z
|
|
110
125
|
.number()
|
|
111
126
|
.optional()
|
|
112
|
-
.describe("Línea inicial
|
|
127
|
+
.describe("Línea inicial (opcional)"),
|
|
113
128
|
endLine: z
|
|
114
129
|
.number()
|
|
115
130
|
.optional()
|
|
116
|
-
.describe("Línea final
|
|
131
|
+
.describe("Línea final (opcional)"),
|
|
117
132
|
}, async (args) => {
|
|
118
133
|
const result = await readFile({
|
|
119
134
|
path: args.path,
|
|
@@ -125,21 +140,24 @@ server.tool("memorybank_read_file", "Lee el contenido de un archivo específico
|
|
|
125
140
|
};
|
|
126
141
|
});
|
|
127
142
|
// Tool: Write File
|
|
128
|
-
server.tool("memorybank_write_file",
|
|
143
|
+
server.tool("memorybank_write_file", `Escribe un archivo y automáticamente lo reindexa en el Memory Bank.
|
|
144
|
+
|
|
145
|
+
⚠️ Preferir RUTA ABSOLUTA para evitar errores.
|
|
146
|
+
Ejemplo path: "C:/workspaces/proyecto/src/nuevo.ts"`, {
|
|
129
147
|
projectId: z
|
|
130
148
|
.string()
|
|
131
|
-
.describe("Identificador del proyecto (OBLIGATORIO)
|
|
149
|
+
.describe("Identificador del proyecto (OBLIGATORIO)"),
|
|
132
150
|
path: z
|
|
133
151
|
.string()
|
|
134
|
-
.describe("Ruta
|
|
152
|
+
.describe("Ruta al archivo. Preferir ABSOLUTA: 'C:/workspaces/proyecto/src/file.ts'"),
|
|
135
153
|
content: z
|
|
136
154
|
.string()
|
|
137
|
-
.describe("Contenido
|
|
155
|
+
.describe("Contenido COMPLETO del archivo"),
|
|
138
156
|
autoReindex: z
|
|
139
157
|
.boolean()
|
|
140
158
|
.optional()
|
|
141
159
|
.default(true)
|
|
142
|
-
.describe("
|
|
160
|
+
.describe("Auto-reindexar después de escribir (default: true)"),
|
|
143
161
|
}, async (args) => {
|
|
144
162
|
const result = await writeFile({
|
|
145
163
|
projectId: args.projectId,
|
|
@@ -159,13 +177,18 @@ server.tool("memorybank_get_stats", "Obtiene estadísticas del Memory Bank: arch
|
|
|
159
177
|
};
|
|
160
178
|
});
|
|
161
179
|
// Tool: Analyze Coverage
|
|
162
|
-
server.tool("memorybank_analyze_coverage",
|
|
180
|
+
server.tool("memorybank_analyze_coverage", `Analiza la cobertura de indexación del proyecto.
|
|
181
|
+
|
|
182
|
+
⚠️ IMPORTANTE:
|
|
183
|
+
- path debe ser RUTA ABSOLUTA al DIRECTORIO raíz del workspace
|
|
184
|
+
- Ejemplo: "C:/workspaces/mi-proyecto" (NO rutas relativas)
|
|
185
|
+
- Puede tardar en workspaces grandes`, {
|
|
163
186
|
projectId: z
|
|
164
187
|
.string()
|
|
165
|
-
.describe("Identificador del proyecto
|
|
188
|
+
.describe("Identificador del proyecto (OBLIGATORIO)"),
|
|
166
189
|
path: z
|
|
167
190
|
.string()
|
|
168
|
-
.describe("
|
|
191
|
+
.describe("RUTA ABSOLUTA al directorio raíz del workspace. Ejemplo: 'C:/workspaces/mi-proyecto'"),
|
|
169
192
|
}, async (args) => {
|
|
170
193
|
try {
|
|
171
194
|
const targetPath = args.path;
|
|
@@ -252,6 +275,343 @@ server.tool(getProjectDocsToolDefinition.name, getProjectDocsToolDefinition.desc
|
|
|
252
275
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
253
276
|
};
|
|
254
277
|
});
|
|
278
|
+
// ==========================================
|
|
279
|
+
// Context Management Tools (Cline-style)
|
|
280
|
+
// ==========================================
|
|
281
|
+
// Tool: Initialize Memory Bank
|
|
282
|
+
server.tool(initializeMemoryBankToolDefinition.name, initializeMemoryBankToolDefinition.description + `
|
|
283
|
+
|
|
284
|
+
⚠️ projectPath debe ser RUTA ABSOLUTA. Ejemplo: "C:/workspaces/mi-proyecto"`, {
|
|
285
|
+
projectId: z
|
|
286
|
+
.string()
|
|
287
|
+
.describe("Identificador único del proyecto (OBLIGATORIO)"),
|
|
288
|
+
projectPath: z
|
|
289
|
+
.string()
|
|
290
|
+
.describe("RUTA ABSOLUTA al proyecto. Ejemplo: 'C:/workspaces/mi-proyecto'"),
|
|
291
|
+
projectName: z
|
|
292
|
+
.string()
|
|
293
|
+
.optional()
|
|
294
|
+
.describe("Nombre legible del proyecto (opcional)"),
|
|
295
|
+
description: z
|
|
296
|
+
.string()
|
|
297
|
+
.optional()
|
|
298
|
+
.describe("Descripción inicial del proyecto (opcional)"),
|
|
299
|
+
}, async (args) => {
|
|
300
|
+
const storagePath = process.env.MEMORYBANK_STORAGE_PATH || ".memorybank";
|
|
301
|
+
const result = await initializeMemoryBank({
|
|
302
|
+
projectId: args.projectId,
|
|
303
|
+
projectPath: args.projectPath,
|
|
304
|
+
projectName: args.projectName,
|
|
305
|
+
description: args.description,
|
|
306
|
+
}, storagePath);
|
|
307
|
+
return {
|
|
308
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
309
|
+
};
|
|
310
|
+
});
|
|
311
|
+
// Tool: Update Context
|
|
312
|
+
server.tool(updateContextToolDefinition.name, updateContextToolDefinition.description, {
|
|
313
|
+
projectId: z
|
|
314
|
+
.string()
|
|
315
|
+
.describe("Identificador único del proyecto (OBLIGATORIO)"),
|
|
316
|
+
currentSession: z
|
|
317
|
+
.object({
|
|
318
|
+
date: z.string().optional().describe("Fecha de la sesión (YYYY-MM-DD)"),
|
|
319
|
+
mode: z.string().optional().describe("Modo de trabajo: development, debugging, refactoring, etc."),
|
|
320
|
+
task: z.string().optional().describe("Descripción de la tarea actual"),
|
|
321
|
+
})
|
|
322
|
+
.optional()
|
|
323
|
+
.describe("Información de la sesión actual"),
|
|
324
|
+
recentChanges: z
|
|
325
|
+
.array(z.string())
|
|
326
|
+
.optional()
|
|
327
|
+
.describe("Lista de cambios recientes realizados"),
|
|
328
|
+
openQuestions: z
|
|
329
|
+
.array(z.string())
|
|
330
|
+
.optional()
|
|
331
|
+
.describe("Preguntas pendientes de resolver"),
|
|
332
|
+
nextSteps: z
|
|
333
|
+
.array(z.string())
|
|
334
|
+
.optional()
|
|
335
|
+
.describe("Próximos pasos planificados"),
|
|
336
|
+
notes: z
|
|
337
|
+
.string()
|
|
338
|
+
.optional()
|
|
339
|
+
.describe("Notas adicionales o consideraciones"),
|
|
340
|
+
}, async (args) => {
|
|
341
|
+
const storagePath = process.env.MEMORYBANK_STORAGE_PATH || ".memorybank";
|
|
342
|
+
const result = await updateContext({
|
|
343
|
+
projectId: args.projectId,
|
|
344
|
+
currentSession: args.currentSession,
|
|
345
|
+
recentChanges: args.recentChanges,
|
|
346
|
+
openQuestions: args.openQuestions,
|
|
347
|
+
nextSteps: args.nextSteps,
|
|
348
|
+
notes: args.notes,
|
|
349
|
+
}, storagePath);
|
|
350
|
+
return {
|
|
351
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
352
|
+
};
|
|
353
|
+
});
|
|
354
|
+
// Tool: Record Decision
|
|
355
|
+
server.tool(recordDecisionToolDefinition.name, recordDecisionToolDefinition.description, {
|
|
356
|
+
projectId: z
|
|
357
|
+
.string()
|
|
358
|
+
.describe("Identificador único del proyecto (OBLIGATORIO)"),
|
|
359
|
+
decision: z
|
|
360
|
+
.object({
|
|
361
|
+
title: z.string().describe("Título corto y descriptivo de la decisión"),
|
|
362
|
+
description: z.string().describe("Descripción detallada de lo que se decidió"),
|
|
363
|
+
rationale: z.string().describe("Por qué se tomó esta decisión"),
|
|
364
|
+
alternatives: z.array(z.string()).optional().describe("Alternativas consideradas"),
|
|
365
|
+
impact: z.string().optional().describe("Impacto esperado de la decisión"),
|
|
366
|
+
category: z.string().optional().describe("Categoría: architecture, technology, dependencies, etc."),
|
|
367
|
+
date: z.string().optional().describe("Fecha de la decisión (YYYY-MM-DD)"),
|
|
368
|
+
})
|
|
369
|
+
.describe("Información de la decisión a registrar"),
|
|
370
|
+
}, async (args) => {
|
|
371
|
+
const storagePath = process.env.MEMORYBANK_STORAGE_PATH || ".memorybank";
|
|
372
|
+
const result = await recordDecision({
|
|
373
|
+
projectId: args.projectId,
|
|
374
|
+
decision: args.decision,
|
|
375
|
+
}, storagePath);
|
|
376
|
+
return {
|
|
377
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
378
|
+
};
|
|
379
|
+
});
|
|
380
|
+
// Tool: Track Progress
|
|
381
|
+
server.tool(trackProgressToolDefinition.name, trackProgressToolDefinition.description, {
|
|
382
|
+
projectId: z
|
|
383
|
+
.string()
|
|
384
|
+
.describe("Identificador único del proyecto (OBLIGATORIO)"),
|
|
385
|
+
progress: z
|
|
386
|
+
.object({
|
|
387
|
+
completed: z.array(z.string()).optional().describe("Tareas completadas"),
|
|
388
|
+
inProgress: z.array(z.string()).optional().describe("Tareas en progreso"),
|
|
389
|
+
blocked: z.array(z.string()).optional().describe("Tareas bloqueadas"),
|
|
390
|
+
upcoming: z.array(z.string()).optional().describe("Próximas tareas"),
|
|
391
|
+
})
|
|
392
|
+
.optional()
|
|
393
|
+
.describe("Tareas a actualizar"),
|
|
394
|
+
milestone: z
|
|
395
|
+
.object({
|
|
396
|
+
name: z.string().describe("Nombre del milestone"),
|
|
397
|
+
status: z.enum(["pending", "in_progress", "completed"]).describe("Estado del milestone"),
|
|
398
|
+
targetDate: z.string().optional().describe("Fecha objetivo"),
|
|
399
|
+
notes: z.string().optional().describe("Notas adicionales"),
|
|
400
|
+
})
|
|
401
|
+
.optional()
|
|
402
|
+
.describe("Milestone a añadir o actualizar"),
|
|
403
|
+
blockers: z
|
|
404
|
+
.array(z.object({
|
|
405
|
+
description: z.string().describe("Descripción del blocker"),
|
|
406
|
+
severity: z.enum(["low", "medium", "high"]).describe("Severidad"),
|
|
407
|
+
}))
|
|
408
|
+
.optional()
|
|
409
|
+
.describe("Blockers a registrar"),
|
|
410
|
+
phase: z
|
|
411
|
+
.string()
|
|
412
|
+
.optional()
|
|
413
|
+
.describe("Fase actual del proyecto"),
|
|
414
|
+
phaseStatus: z
|
|
415
|
+
.string()
|
|
416
|
+
.optional()
|
|
417
|
+
.describe("Estado de la fase"),
|
|
418
|
+
}, async (args) => {
|
|
419
|
+
const storagePath = process.env.MEMORYBANK_STORAGE_PATH || ".memorybank";
|
|
420
|
+
const result = await trackProgress({
|
|
421
|
+
projectId: args.projectId,
|
|
422
|
+
progress: args.progress,
|
|
423
|
+
milestone: args.milestone,
|
|
424
|
+
blockers: args.blockers,
|
|
425
|
+
phase: args.phase,
|
|
426
|
+
phaseStatus: args.phaseStatus,
|
|
427
|
+
}, storagePath);
|
|
428
|
+
return {
|
|
429
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
430
|
+
};
|
|
431
|
+
});
|
|
432
|
+
// ==========================================
|
|
433
|
+
// MCP Resources (Direct document access)
|
|
434
|
+
// ==========================================
|
|
435
|
+
// Resource: Project Active Context
|
|
436
|
+
server.resource("memory://*/active", "Contexto activo del proyecto: sesión actual, cambios recientes, próximos pasos", async (uri) => {
|
|
437
|
+
const projectId = uri.pathname.split("/")[0] || uri.host;
|
|
438
|
+
if (!projectKnowledgeService) {
|
|
439
|
+
return {
|
|
440
|
+
contents: [{
|
|
441
|
+
uri: uri.href,
|
|
442
|
+
mimeType: "text/plain",
|
|
443
|
+
text: "Error: Project Knowledge Service not initialized",
|
|
444
|
+
}],
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
const content = projectKnowledgeService.getProjectDocument(projectId, "activeContext");
|
|
448
|
+
if (!content) {
|
|
449
|
+
return {
|
|
450
|
+
contents: [{
|
|
451
|
+
uri: uri.href,
|
|
452
|
+
mimeType: "text/plain",
|
|
453
|
+
text: `No active context found for project "${projectId}". Run memorybank_initialize first.`,
|
|
454
|
+
}],
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
return {
|
|
458
|
+
contents: [{
|
|
459
|
+
uri: uri.href,
|
|
460
|
+
mimeType: "text/markdown",
|
|
461
|
+
text: content,
|
|
462
|
+
}],
|
|
463
|
+
};
|
|
464
|
+
});
|
|
465
|
+
// Resource: Project Progress
|
|
466
|
+
server.resource("memory://*/progress", "Seguimiento de progreso: tareas completadas, en progreso, bloqueadas y milestones", async (uri) => {
|
|
467
|
+
const projectId = uri.pathname.split("/")[0] || uri.host;
|
|
468
|
+
if (!projectKnowledgeService) {
|
|
469
|
+
return {
|
|
470
|
+
contents: [{
|
|
471
|
+
uri: uri.href,
|
|
472
|
+
mimeType: "text/plain",
|
|
473
|
+
text: "Error: Project Knowledge Service not initialized",
|
|
474
|
+
}],
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
const content = projectKnowledgeService.getProjectDocument(projectId, "progress");
|
|
478
|
+
if (!content) {
|
|
479
|
+
return {
|
|
480
|
+
contents: [{
|
|
481
|
+
uri: uri.href,
|
|
482
|
+
mimeType: "text/plain",
|
|
483
|
+
text: `No progress tracking found for project "${projectId}". Run memorybank_initialize first.`,
|
|
484
|
+
}],
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
return {
|
|
488
|
+
contents: [{
|
|
489
|
+
uri: uri.href,
|
|
490
|
+
mimeType: "text/markdown",
|
|
491
|
+
text: content,
|
|
492
|
+
}],
|
|
493
|
+
};
|
|
494
|
+
});
|
|
495
|
+
// Resource: Project Decisions
|
|
496
|
+
server.resource("memory://*/decisions", "Log de decisiones técnicas: historial de decisiones arquitectónicas y técnicas", async (uri) => {
|
|
497
|
+
const projectId = uri.pathname.split("/")[0] || uri.host;
|
|
498
|
+
if (!projectKnowledgeService) {
|
|
499
|
+
return {
|
|
500
|
+
contents: [{
|
|
501
|
+
uri: uri.href,
|
|
502
|
+
mimeType: "text/plain",
|
|
503
|
+
text: "Error: Project Knowledge Service not initialized",
|
|
504
|
+
}],
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
const content = projectKnowledgeService.getProjectDocument(projectId, "decisionLog");
|
|
508
|
+
if (!content) {
|
|
509
|
+
return {
|
|
510
|
+
contents: [{
|
|
511
|
+
uri: uri.href,
|
|
512
|
+
mimeType: "text/plain",
|
|
513
|
+
text: `No decision log found for project "${projectId}". Run memorybank_initialize first.`,
|
|
514
|
+
}],
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
return {
|
|
518
|
+
contents: [{
|
|
519
|
+
uri: uri.href,
|
|
520
|
+
mimeType: "text/markdown",
|
|
521
|
+
text: content,
|
|
522
|
+
}],
|
|
523
|
+
};
|
|
524
|
+
});
|
|
525
|
+
// Resource: Project Context (Brief + Tech)
|
|
526
|
+
server.resource("memory://*/context", "Contexto completo del proyecto: descripción general y stack tecnológico", async (uri) => {
|
|
527
|
+
const projectId = uri.pathname.split("/")[0] || uri.host;
|
|
528
|
+
if (!projectKnowledgeService) {
|
|
529
|
+
return {
|
|
530
|
+
contents: [{
|
|
531
|
+
uri: uri.href,
|
|
532
|
+
mimeType: "text/plain",
|
|
533
|
+
text: "Error: Project Knowledge Service not initialized",
|
|
534
|
+
}],
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
const content = projectKnowledgeService.getProjectContext(projectId);
|
|
538
|
+
if (!content) {
|
|
539
|
+
return {
|
|
540
|
+
contents: [{
|
|
541
|
+
uri: uri.href,
|
|
542
|
+
mimeType: "text/plain",
|
|
543
|
+
text: `No project context found for project "${projectId}". Run memorybank_initialize first.`,
|
|
544
|
+
}],
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
return {
|
|
548
|
+
contents: [{
|
|
549
|
+
uri: uri.href,
|
|
550
|
+
mimeType: "text/markdown",
|
|
551
|
+
text: content,
|
|
552
|
+
}],
|
|
553
|
+
};
|
|
554
|
+
});
|
|
555
|
+
// Resource: System Patterns
|
|
556
|
+
server.resource("memory://*/patterns", "Patrones de sistema: arquitectura, patrones de diseño y organización del código", async (uri) => {
|
|
557
|
+
const projectId = uri.pathname.split("/")[0] || uri.host;
|
|
558
|
+
if (!projectKnowledgeService) {
|
|
559
|
+
return {
|
|
560
|
+
contents: [{
|
|
561
|
+
uri: uri.href,
|
|
562
|
+
mimeType: "text/plain",
|
|
563
|
+
text: "Error: Project Knowledge Service not initialized",
|
|
564
|
+
}],
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
const content = projectKnowledgeService.getProjectDocument(projectId, "systemPatterns");
|
|
568
|
+
if (!content) {
|
|
569
|
+
return {
|
|
570
|
+
contents: [{
|
|
571
|
+
uri: uri.href,
|
|
572
|
+
mimeType: "text/plain",
|
|
573
|
+
text: `No system patterns found for project "${projectId}". Run memorybank_initialize or memorybank_generate_project_docs first.`,
|
|
574
|
+
}],
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
return {
|
|
578
|
+
contents: [{
|
|
579
|
+
uri: uri.href,
|
|
580
|
+
mimeType: "text/markdown",
|
|
581
|
+
text: content,
|
|
582
|
+
}],
|
|
583
|
+
};
|
|
584
|
+
});
|
|
585
|
+
// Resource: Project Brief
|
|
586
|
+
server.resource("memory://*/brief", "Descripción del proyecto: propósito, objetivos y audiencia", async (uri) => {
|
|
587
|
+
const projectId = uri.pathname.split("/")[0] || uri.host;
|
|
588
|
+
if (!projectKnowledgeService) {
|
|
589
|
+
return {
|
|
590
|
+
contents: [{
|
|
591
|
+
uri: uri.href,
|
|
592
|
+
mimeType: "text/plain",
|
|
593
|
+
text: "Error: Project Knowledge Service not initialized",
|
|
594
|
+
}],
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
const content = projectKnowledgeService.getProjectDocument(projectId, "projectBrief");
|
|
598
|
+
if (!content) {
|
|
599
|
+
return {
|
|
600
|
+
contents: [{
|
|
601
|
+
uri: uri.href,
|
|
602
|
+
mimeType: "text/plain",
|
|
603
|
+
text: `No project brief found for project "${projectId}". Run memorybank_initialize or memorybank_generate_project_docs first.`,
|
|
604
|
+
}],
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
return {
|
|
608
|
+
contents: [{
|
|
609
|
+
uri: uri.href,
|
|
610
|
+
mimeType: "text/markdown",
|
|
611
|
+
text: content,
|
|
612
|
+
}],
|
|
613
|
+
};
|
|
614
|
+
});
|
|
255
615
|
/**
|
|
256
616
|
* Validates and initializes environment
|
|
257
617
|
*/
|
|
@@ -328,16 +688,29 @@ async function startStdioServer() {
|
|
|
328
688
|
await server.connect(transport);
|
|
329
689
|
console.error("\n=== MCP Server Ready ===");
|
|
330
690
|
console.error("Available tools:");
|
|
331
|
-
console.error(" Core Memory Bank:");
|
|
691
|
+
console.error(" Core Memory Bank (Cursor-style):");
|
|
332
692
|
console.error(" - memorybank_index_code: Indexar código semánticamente");
|
|
333
693
|
console.error(" - memorybank_search: Buscar código por similitud semántica");
|
|
334
694
|
console.error(" - memorybank_read_file: Leer archivos del workspace");
|
|
335
695
|
console.error(" - memorybank_write_file: Escribir archivos y reindexar");
|
|
336
696
|
console.error(" - memorybank_get_stats: Obtener estadísticas del índice");
|
|
337
697
|
console.error(" - memorybank_analyze_coverage: Analizar cobertura de indexación");
|
|
338
|
-
console.error(" Project Knowledge Layer:");
|
|
698
|
+
console.error(" Project Knowledge Layer (AI Docs):");
|
|
339
699
|
console.error(" - memorybank_generate_project_docs: Generar documentación con IA");
|
|
340
700
|
console.error(" - memorybank_get_project_docs: Leer documentación del proyecto");
|
|
701
|
+
console.error(" Context Management (Cline-style):");
|
|
702
|
+
console.error(" - memorybank_initialize: Inicializar Memory Bank para un proyecto");
|
|
703
|
+
console.error(" - memorybank_update_context: Actualizar contexto de sesión");
|
|
704
|
+
console.error(" - memorybank_record_decision: Registrar decisiones técnicas");
|
|
705
|
+
console.error(" - memorybank_track_progress: Actualizar progreso del proyecto");
|
|
706
|
+
console.error("");
|
|
707
|
+
console.error("Available resources:");
|
|
708
|
+
console.error(" - memory://{projectId}/active: Contexto activo");
|
|
709
|
+
console.error(" - memory://{projectId}/progress: Seguimiento de progreso");
|
|
710
|
+
console.error(" - memory://{projectId}/decisions: Log de decisiones");
|
|
711
|
+
console.error(" - memory://{projectId}/context: Contexto del proyecto");
|
|
712
|
+
console.error(" - memory://{projectId}/patterns: Patrones de sistema");
|
|
713
|
+
console.error(" - memory://{projectId}/brief: Descripción del proyecto");
|
|
341
714
|
console.error("");
|
|
342
715
|
console.error("Ready to accept requests...\n");
|
|
343
716
|
}
|
|
@@ -177,7 +177,7 @@ function generateRecommendations(stats, tree) {
|
|
|
177
177
|
}
|
|
178
178
|
// Pending reindex
|
|
179
179
|
if (stats.pendingReindexFiles > 0) {
|
|
180
|
-
recommendations.push(`🔄 Hay ${stats.pendingReindexFiles} archivo(s) con cambios pendientes
|
|
180
|
+
recommendations.push(`🔄 Hay ${stats.pendingReindexFiles} archivo(s) con cambios pendientes. Ejecuta memorybank_index_code con el path del directorio - los cambios se detectan automáticamente por hash.`);
|
|
181
181
|
}
|
|
182
182
|
// Language-specific recommendations
|
|
183
183
|
const unindexedLanguages = Object.entries(stats.languageBreakdown)
|