@grec0/memory-bank-mcp 0.1.0 → 0.1.2
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 +189 -4
- package/dist/common/projectKnowledgeService.js +74 -0
- package/dist/index.js +355 -2
- 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/README.md
CHANGED
|
@@ -40,12 +40,19 @@ Con Memory Bank, las IAs:
|
|
|
40
40
|
- **🔒 Privacidad**: Vector store local, respeta .gitignore y .memoryignore
|
|
41
41
|
- **🔀 Multi-Proyecto**: Consulta cualquier proyecto indexado usando su `projectId`
|
|
42
42
|
|
|
43
|
-
### Project Knowledge Layer (Conocimiento Global)
|
|
43
|
+
### Project Knowledge Layer (Conocimiento Global)
|
|
44
44
|
- **📄 Documentación Automática**: Genera 6 documentos markdown estructurados del proyecto
|
|
45
45
|
- **🧠 IA con Razonamiento**: Usa OpenAI Responses API con modelos de razonamiento (gpt-5-mini)
|
|
46
46
|
- **🔄 Actualización Inteligente**: Solo regenera documentos afectados por cambios
|
|
47
47
|
- **📚 Contexto Global**: Complementa búsqueda precisa con visión de alto nivel
|
|
48
48
|
|
|
49
|
+
### Context Management (Gestión de Sesión) 🆕
|
|
50
|
+
- **🚀 Inicialización Rápida**: Crea estructura de Memory Bank con plantillas iniciales (sin IA)
|
|
51
|
+
- **📝 Tracking de Sesión**: Registra contexto activo, cambios recientes y próximos pasos
|
|
52
|
+
- **📋 Log de Decisiones**: Documenta decisiones técnicas con rationale y alternativas
|
|
53
|
+
- **📊 Seguimiento de Progreso**: Gestiona tareas, milestones y blockers
|
|
54
|
+
- **📡 MCP Resources**: Acceso directo de solo lectura a documentos via URIs
|
|
55
|
+
|
|
49
56
|
## 📋 Requisitos
|
|
50
57
|
|
|
51
58
|
- **Node.js** >= 18.0.0
|
|
@@ -446,6 +453,153 @@ Lee la documentación del proyecto generada por IA.
|
|
|
446
453
|
|
|
447
454
|
---
|
|
448
455
|
|
|
456
|
+
## 🔄 Herramientas de Gestión de Contexto (Cline-style)
|
|
457
|
+
|
|
458
|
+
Estas herramientas permiten gestionar el contexto del proyecto de forma manual, complementando la generación automática con IA.
|
|
459
|
+
|
|
460
|
+
### `memorybank_initialize`
|
|
461
|
+
|
|
462
|
+
Inicializa el Memory Bank para un proyecto nuevo. Crea la estructura de directorios y 7 documentos markdown con plantillas iniciales. **No usa IA**.
|
|
463
|
+
|
|
464
|
+
**Parámetros:**
|
|
465
|
+
- `projectId` **(REQUERIDO)**: Identificador único del proyecto
|
|
466
|
+
- `projectPath` **(REQUERIDO)**: Ruta absoluta del proyecto
|
|
467
|
+
- `projectName` (opcional): Nombre legible del proyecto
|
|
468
|
+
- `description` (opcional): Descripción inicial del proyecto
|
|
469
|
+
|
|
470
|
+
**Ejemplo:**
|
|
471
|
+
```json
|
|
472
|
+
{
|
|
473
|
+
"projectId": "my-project",
|
|
474
|
+
"projectPath": "C:/workspaces/my-project",
|
|
475
|
+
"projectName": "My Awesome Project",
|
|
476
|
+
"description": "A web application for..."
|
|
477
|
+
}
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
**Documentos creados:**
|
|
481
|
+
- `projectBrief.md` - Descripción general
|
|
482
|
+
- `productContext.md` - Contexto de producto
|
|
483
|
+
- `systemPatterns.md` - Patrones de arquitectura
|
|
484
|
+
- `techContext.md` - Stack tecnológico
|
|
485
|
+
- `activeContext.md` - Contexto de sesión
|
|
486
|
+
- `progress.md` - Seguimiento de progreso
|
|
487
|
+
- `decisionLog.md` - Log de decisiones
|
|
488
|
+
|
|
489
|
+
### `memorybank_update_context`
|
|
490
|
+
|
|
491
|
+
Actualiza el contexto activo con información de la sesión actual. Mantiene historial de las últimas 10 sesiones. **No usa IA**.
|
|
492
|
+
|
|
493
|
+
**Parámetros:**
|
|
494
|
+
- `projectId` **(REQUERIDO)**: Identificador del proyecto
|
|
495
|
+
- `currentSession` (opcional): Información de sesión (date, mode, task)
|
|
496
|
+
- `recentChanges` (opcional): Lista de cambios recientes
|
|
497
|
+
- `openQuestions` (opcional): Preguntas pendientes
|
|
498
|
+
- `nextSteps` (opcional): Próximos pasos planificados
|
|
499
|
+
- `notes` (opcional): Notas adicionales
|
|
500
|
+
|
|
501
|
+
**Ejemplo:**
|
|
502
|
+
```json
|
|
503
|
+
{
|
|
504
|
+
"projectId": "my-project",
|
|
505
|
+
"currentSession": {
|
|
506
|
+
"mode": "development",
|
|
507
|
+
"task": "Implementing authentication"
|
|
508
|
+
},
|
|
509
|
+
"recentChanges": ["Added JWT middleware", "Created user model"],
|
|
510
|
+
"nextSteps": ["Add refresh token", "Create login endpoint"]
|
|
511
|
+
}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### `memorybank_record_decision`
|
|
515
|
+
|
|
516
|
+
Registra decisiones técnicas con rationale en el log de decisiones. **No usa IA**.
|
|
517
|
+
|
|
518
|
+
**Parámetros:**
|
|
519
|
+
- `projectId` **(REQUERIDO)**: Identificador del proyecto
|
|
520
|
+
- `decision` **(REQUERIDO)**: Objeto con información de la decisión
|
|
521
|
+
- `title` **(REQUERIDO)**: Título de la decisión
|
|
522
|
+
- `description` **(REQUERIDO)**: Qué se decidió
|
|
523
|
+
- `rationale` **(REQUERIDO)**: Por qué se tomó esta decisión
|
|
524
|
+
- `alternatives` (opcional): Alternativas consideradas
|
|
525
|
+
- `impact` (opcional): Impacto esperado
|
|
526
|
+
- `category` (opcional): architecture, technology, dependencies, etc.
|
|
527
|
+
|
|
528
|
+
**Ejemplo:**
|
|
529
|
+
```json
|
|
530
|
+
{
|
|
531
|
+
"projectId": "my-project",
|
|
532
|
+
"decision": {
|
|
533
|
+
"title": "JWT Authentication",
|
|
534
|
+
"description": "Use JWT tokens for API authentication",
|
|
535
|
+
"rationale": "Stateless, scalable, works well with microservices",
|
|
536
|
+
"alternatives": ["Session-based auth", "OAuth only"],
|
|
537
|
+
"category": "architecture"
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### `memorybank_track_progress`
|
|
543
|
+
|
|
544
|
+
Actualiza el seguimiento de progreso con tareas, milestones y blockers. **No usa IA**.
|
|
545
|
+
|
|
546
|
+
**Parámetros:**
|
|
547
|
+
- `projectId` **(REQUERIDO)**: Identificador del proyecto
|
|
548
|
+
- `progress` (opcional): Tareas a actualizar
|
|
549
|
+
- `completed`: Tareas completadas
|
|
550
|
+
- `inProgress`: Tareas en progreso
|
|
551
|
+
- `blocked`: Tareas bloqueadas
|
|
552
|
+
- `upcoming`: Próximas tareas
|
|
553
|
+
- `milestone` (opcional): Milestone a añadir/actualizar (name, status, targetDate, notes)
|
|
554
|
+
- `blockers` (opcional): Lista de blockers con severidad (low/medium/high)
|
|
555
|
+
- `phase` (opcional): Fase actual del proyecto
|
|
556
|
+
- `phaseStatus` (opcional): Estado de la fase
|
|
557
|
+
|
|
558
|
+
**Ejemplo:**
|
|
559
|
+
```json
|
|
560
|
+
{
|
|
561
|
+
"projectId": "my-project",
|
|
562
|
+
"progress": {
|
|
563
|
+
"completed": ["Setup project structure", "Configure ESLint"],
|
|
564
|
+
"inProgress": ["Implement user authentication"],
|
|
565
|
+
"upcoming": ["Add unit tests"]
|
|
566
|
+
},
|
|
567
|
+
"milestone": {
|
|
568
|
+
"name": "MVP",
|
|
569
|
+
"status": "in_progress",
|
|
570
|
+
"targetDate": "2026-02-01"
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
## 📡 MCP Resources (Acceso Directo)
|
|
578
|
+
|
|
579
|
+
Memory Bank expone recursos MCP para acceso directo de solo lectura a los documentos del proyecto.
|
|
580
|
+
|
|
581
|
+
| Resource URI | Contenido |
|
|
582
|
+
|--------------|-----------|
|
|
583
|
+
| `memory://{projectId}/active` | Contexto activo de sesión |
|
|
584
|
+
| `memory://{projectId}/progress` | Seguimiento de progreso |
|
|
585
|
+
| `memory://{projectId}/decisions` | Log de decisiones técnicas |
|
|
586
|
+
| `memory://{projectId}/context` | Contexto del proyecto (brief + tech) |
|
|
587
|
+
| `memory://{projectId}/patterns` | Patrones de sistema |
|
|
588
|
+
| `memory://{projectId}/brief` | Descripción del proyecto |
|
|
589
|
+
|
|
590
|
+
**Ejemplo de uso:**
|
|
591
|
+
```
|
|
592
|
+
// Acceder al contexto activo del proyecto "my-project"
|
|
593
|
+
memory://my-project/active
|
|
594
|
+
|
|
595
|
+
// Acceder al log de decisiones
|
|
596
|
+
memory://my-project/decisions
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
Los recursos son de solo lectura. Para modificar documentos, usa las herramientas correspondientes (`memorybank_update_context`, `memorybank_record_decision`, etc.).
|
|
600
|
+
|
|
601
|
+
---
|
|
602
|
+
|
|
449
603
|
## 📋 Plantillas de Instrucciones para Agentes
|
|
450
604
|
|
|
451
605
|
Memory Bank incluye plantillas de instrucciones en dos formatos para configurar el comportamiento del agente:
|
|
@@ -805,10 +959,41 @@ Si `pendingFiles` muestra archivos pendientes:
|
|
|
805
959
|
|
|
806
960
|
## 🎓 Inspiración
|
|
807
961
|
|
|
808
|
-
Este proyecto
|
|
962
|
+
Este proyecto combina los mejores conceptos de dos enfoques complementarios:
|
|
963
|
+
|
|
964
|
+
### Cursor IDE - Indexación Semántica
|
|
965
|
+
|
|
966
|
+
El sistema de indexación vectorial y búsqueda semántica está inspirado en cómo Cursor IDE maneja la memoria de código:
|
|
967
|
+
|
|
968
|
+
- [Advanced Cursor: Use the Memory Bank](https://medium.com/codetodeploy/advanced-cursor-use-the-memory-bank-to-eliminate-hallucination-affd3fbeefa3) - Eliminar alucinaciones con memoria persistente
|
|
969
|
+
- [How Cursor Indexes Codebases Fast](https://read.engineerscodex.com/p/how-cursor-indexes-codebases-fast) - Técnicas de indexación eficiente
|
|
970
|
+
|
|
971
|
+
### Cline - Documentación Estructurada del Proyecto
|
|
972
|
+
|
|
973
|
+
El sistema de **Project Knowledge Layer** (documentos markdown estructurados) está inspirado en el enfoque de Cline Memory Bank:
|
|
974
|
+
|
|
975
|
+
- [Cline MCP Memory Bank](https://github.com/dazeb/cline-mcp-memory-bank) - Implementación de referencia del Memory Bank para Cline
|
|
976
|
+
- [Cline Memory Bank Custom Instructions](https://gist.github.com/zoharbabin/441e8e8b719a444f26b34bd0b189b283) - Instrucciones personalizadas para usar el Memory Bank
|
|
977
|
+
|
|
978
|
+
**Documentos del enfoque Cline que adoptamos:**
|
|
979
|
+
| Documento | Propósito |
|
|
980
|
+
|-----------|-----------|
|
|
981
|
+
| `projectBrief.md` | Requisitos y alcance del proyecto |
|
|
982
|
+
| `productContext.md` | Propósito, usuarios objetivo, problemas que resuelve |
|
|
983
|
+
| `activeContext.md` | Tareas actuales, cambios recientes, próximos pasos |
|
|
984
|
+
| `systemPatterns.md` | Decisiones arquitectónicas, patrones, relaciones |
|
|
985
|
+
| `techContext.md` | Stack tecnológico, dependencias, configuraciones |
|
|
986
|
+
| `progress.md` | Hitos, estado general, problemas conocidos |
|
|
987
|
+
|
|
988
|
+
### Nuestra Contribución
|
|
989
|
+
|
|
990
|
+
Memory Bank MCP **fusiona ambos enfoques**:
|
|
991
|
+
|
|
992
|
+
1. **Búsqueda Semántica** (estilo Cursor): Embeddings vectoriales + LanceDB para encontrar código relevante instantáneamente
|
|
993
|
+
2. **Documentación Estructurada** (estilo Cline): 6 documentos markdown generados con IA que proporcionan contexto global
|
|
994
|
+
3. **Multi-Proyecto**: Capacidad única de consultar múltiples proyectos indexados desde cualquier workspace
|
|
809
995
|
|
|
810
|
-
|
|
811
|
-
- [How Cursor Indexes Codebases Fast](https://read.engineerscodex.com/p/how-cursor-indexes-codebases-fast)
|
|
996
|
+
Esta combinación permite que los agentes tengan tanto **precisión** (búsqueda semántica) como **comprensión global** (documentación estructurada)
|
|
812
997
|
|
|
813
998
|
---
|
|
814
999
|
|
|
@@ -607,6 +607,80 @@ ${chunk.content}
|
|
|
607
607
|
documents: documents,
|
|
608
608
|
};
|
|
609
609
|
}
|
|
610
|
+
// ==========================================
|
|
611
|
+
// Project-specific document methods (for MCP Resources)
|
|
612
|
+
// ==========================================
|
|
613
|
+
/**
|
|
614
|
+
* Gets the docs path for a specific project
|
|
615
|
+
*/
|
|
616
|
+
getProjectDocsPath(projectId) {
|
|
617
|
+
const storagePath = process.env.MEMORYBANK_STORAGE_PATH || ".memorybank";
|
|
618
|
+
return path.join(storagePath, "projects", projectId, "docs");
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Checks if a project's Memory Bank is initialized
|
|
622
|
+
*/
|
|
623
|
+
isProjectInitialized(projectId) {
|
|
624
|
+
const docsPath = this.getProjectDocsPath(projectId);
|
|
625
|
+
return fs.existsSync(docsPath);
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Reads a specific document for a project (for MCP Resources)
|
|
629
|
+
*/
|
|
630
|
+
getProjectDocument(projectId, docName) {
|
|
631
|
+
const docsPath = this.getProjectDocsPath(projectId);
|
|
632
|
+
// Map document names to filenames
|
|
633
|
+
const docMap = {
|
|
634
|
+
"projectBrief": "projectBrief.md",
|
|
635
|
+
"productContext": "productContext.md",
|
|
636
|
+
"systemPatterns": "systemPatterns.md",
|
|
637
|
+
"techContext": "techContext.md",
|
|
638
|
+
"activeContext": "activeContext.md",
|
|
639
|
+
"progress": "progress.md",
|
|
640
|
+
"decisionLog": "decisionLog.md",
|
|
641
|
+
"decisions": "decisionLog.md", // Alias
|
|
642
|
+
"active": "activeContext.md", // Alias
|
|
643
|
+
"context": "projectBrief.md", // Alias - returns project brief
|
|
644
|
+
"patterns": "systemPatterns.md", // Alias
|
|
645
|
+
"brief": "projectBrief.md", // Alias
|
|
646
|
+
"tech": "techContext.md", // Alias
|
|
647
|
+
"product": "productContext.md", // Alias
|
|
648
|
+
};
|
|
649
|
+
const filename = docMap[docName] || `${docName}.md`;
|
|
650
|
+
const filePath = path.join(docsPath, filename);
|
|
651
|
+
if (!fs.existsSync(filePath)) {
|
|
652
|
+
return null;
|
|
653
|
+
}
|
|
654
|
+
return fs.readFileSync(filePath, "utf-8");
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Gets combined project context (projectBrief + techContext)
|
|
658
|
+
*/
|
|
659
|
+
getProjectContext(projectId) {
|
|
660
|
+
const brief = this.getProjectDocument(projectId, "projectBrief");
|
|
661
|
+
const tech = this.getProjectDocument(projectId, "techContext");
|
|
662
|
+
if (!brief && !tech)
|
|
663
|
+
return null;
|
|
664
|
+
let content = "# Project Context\n\n";
|
|
665
|
+
if (brief) {
|
|
666
|
+
content += brief + "\n\n---\n\n";
|
|
667
|
+
}
|
|
668
|
+
if (tech) {
|
|
669
|
+
content += tech;
|
|
670
|
+
}
|
|
671
|
+
return content;
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Lists all available documents for a project
|
|
675
|
+
*/
|
|
676
|
+
listProjectDocuments(projectId) {
|
|
677
|
+
const docsPath = this.getProjectDocsPath(projectId);
|
|
678
|
+
if (!fs.existsSync(docsPath)) {
|
|
679
|
+
return [];
|
|
680
|
+
}
|
|
681
|
+
const files = fs.readdirSync(docsPath);
|
|
682
|
+
return files.filter(f => f.endsWith(".md"));
|
|
683
|
+
}
|
|
610
684
|
}
|
|
611
685
|
/**
|
|
612
686
|
* Creates a Project Knowledge Service from environment variables
|
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;
|
|
@@ -252,6 +257,341 @@ server.tool(getProjectDocsToolDefinition.name, getProjectDocsToolDefinition.desc
|
|
|
252
257
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
253
258
|
};
|
|
254
259
|
});
|
|
260
|
+
// ==========================================
|
|
261
|
+
// Context Management Tools (Cline-style)
|
|
262
|
+
// ==========================================
|
|
263
|
+
// Tool: Initialize Memory Bank
|
|
264
|
+
server.tool(initializeMemoryBankToolDefinition.name, initializeMemoryBankToolDefinition.description, {
|
|
265
|
+
projectId: z
|
|
266
|
+
.string()
|
|
267
|
+
.describe("Identificador único del proyecto (OBLIGATORIO)"),
|
|
268
|
+
projectPath: z
|
|
269
|
+
.string()
|
|
270
|
+
.describe("Ruta absoluta del proyecto"),
|
|
271
|
+
projectName: z
|
|
272
|
+
.string()
|
|
273
|
+
.optional()
|
|
274
|
+
.describe("Nombre legible del proyecto (opcional)"),
|
|
275
|
+
description: z
|
|
276
|
+
.string()
|
|
277
|
+
.optional()
|
|
278
|
+
.describe("Descripción inicial del proyecto (opcional)"),
|
|
279
|
+
}, async (args) => {
|
|
280
|
+
const storagePath = process.env.MEMORYBANK_STORAGE_PATH || ".memorybank";
|
|
281
|
+
const result = await initializeMemoryBank({
|
|
282
|
+
projectId: args.projectId,
|
|
283
|
+
projectPath: args.projectPath,
|
|
284
|
+
projectName: args.projectName,
|
|
285
|
+
description: args.description,
|
|
286
|
+
}, storagePath);
|
|
287
|
+
return {
|
|
288
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
289
|
+
};
|
|
290
|
+
});
|
|
291
|
+
// Tool: Update Context
|
|
292
|
+
server.tool(updateContextToolDefinition.name, updateContextToolDefinition.description, {
|
|
293
|
+
projectId: z
|
|
294
|
+
.string()
|
|
295
|
+
.describe("Identificador único del proyecto (OBLIGATORIO)"),
|
|
296
|
+
currentSession: z
|
|
297
|
+
.object({
|
|
298
|
+
date: z.string().optional().describe("Fecha de la sesión (YYYY-MM-DD)"),
|
|
299
|
+
mode: z.string().optional().describe("Modo de trabajo: development, debugging, refactoring, etc."),
|
|
300
|
+
task: z.string().optional().describe("Descripción de la tarea actual"),
|
|
301
|
+
})
|
|
302
|
+
.optional()
|
|
303
|
+
.describe("Información de la sesión actual"),
|
|
304
|
+
recentChanges: z
|
|
305
|
+
.array(z.string())
|
|
306
|
+
.optional()
|
|
307
|
+
.describe("Lista de cambios recientes realizados"),
|
|
308
|
+
openQuestions: z
|
|
309
|
+
.array(z.string())
|
|
310
|
+
.optional()
|
|
311
|
+
.describe("Preguntas pendientes de resolver"),
|
|
312
|
+
nextSteps: z
|
|
313
|
+
.array(z.string())
|
|
314
|
+
.optional()
|
|
315
|
+
.describe("Próximos pasos planificados"),
|
|
316
|
+
notes: z
|
|
317
|
+
.string()
|
|
318
|
+
.optional()
|
|
319
|
+
.describe("Notas adicionales o consideraciones"),
|
|
320
|
+
}, async (args) => {
|
|
321
|
+
const storagePath = process.env.MEMORYBANK_STORAGE_PATH || ".memorybank";
|
|
322
|
+
const result = await updateContext({
|
|
323
|
+
projectId: args.projectId,
|
|
324
|
+
currentSession: args.currentSession,
|
|
325
|
+
recentChanges: args.recentChanges,
|
|
326
|
+
openQuestions: args.openQuestions,
|
|
327
|
+
nextSteps: args.nextSteps,
|
|
328
|
+
notes: args.notes,
|
|
329
|
+
}, storagePath);
|
|
330
|
+
return {
|
|
331
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
332
|
+
};
|
|
333
|
+
});
|
|
334
|
+
// Tool: Record Decision
|
|
335
|
+
server.tool(recordDecisionToolDefinition.name, recordDecisionToolDefinition.description, {
|
|
336
|
+
projectId: z
|
|
337
|
+
.string()
|
|
338
|
+
.describe("Identificador único del proyecto (OBLIGATORIO)"),
|
|
339
|
+
decision: z
|
|
340
|
+
.object({
|
|
341
|
+
title: z.string().describe("Título corto y descriptivo de la decisión"),
|
|
342
|
+
description: z.string().describe("Descripción detallada de lo que se decidió"),
|
|
343
|
+
rationale: z.string().describe("Por qué se tomó esta decisión"),
|
|
344
|
+
alternatives: z.array(z.string()).optional().describe("Alternativas consideradas"),
|
|
345
|
+
impact: z.string().optional().describe("Impacto esperado de la decisión"),
|
|
346
|
+
category: z.string().optional().describe("Categoría: architecture, technology, dependencies, etc."),
|
|
347
|
+
date: z.string().optional().describe("Fecha de la decisión (YYYY-MM-DD)"),
|
|
348
|
+
})
|
|
349
|
+
.describe("Información de la decisión a registrar"),
|
|
350
|
+
}, async (args) => {
|
|
351
|
+
const storagePath = process.env.MEMORYBANK_STORAGE_PATH || ".memorybank";
|
|
352
|
+
const result = await recordDecision({
|
|
353
|
+
projectId: args.projectId,
|
|
354
|
+
decision: args.decision,
|
|
355
|
+
}, storagePath);
|
|
356
|
+
return {
|
|
357
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
358
|
+
};
|
|
359
|
+
});
|
|
360
|
+
// Tool: Track Progress
|
|
361
|
+
server.tool(trackProgressToolDefinition.name, trackProgressToolDefinition.description, {
|
|
362
|
+
projectId: z
|
|
363
|
+
.string()
|
|
364
|
+
.describe("Identificador único del proyecto (OBLIGATORIO)"),
|
|
365
|
+
progress: z
|
|
366
|
+
.object({
|
|
367
|
+
completed: z.array(z.string()).optional().describe("Tareas completadas"),
|
|
368
|
+
inProgress: z.array(z.string()).optional().describe("Tareas en progreso"),
|
|
369
|
+
blocked: z.array(z.string()).optional().describe("Tareas bloqueadas"),
|
|
370
|
+
upcoming: z.array(z.string()).optional().describe("Próximas tareas"),
|
|
371
|
+
})
|
|
372
|
+
.optional()
|
|
373
|
+
.describe("Tareas a actualizar"),
|
|
374
|
+
milestone: z
|
|
375
|
+
.object({
|
|
376
|
+
name: z.string().describe("Nombre del milestone"),
|
|
377
|
+
status: z.enum(["pending", "in_progress", "completed"]).describe("Estado del milestone"),
|
|
378
|
+
targetDate: z.string().optional().describe("Fecha objetivo"),
|
|
379
|
+
notes: z.string().optional().describe("Notas adicionales"),
|
|
380
|
+
})
|
|
381
|
+
.optional()
|
|
382
|
+
.describe("Milestone a añadir o actualizar"),
|
|
383
|
+
blockers: z
|
|
384
|
+
.array(z.object({
|
|
385
|
+
description: z.string().describe("Descripción del blocker"),
|
|
386
|
+
severity: z.enum(["low", "medium", "high"]).describe("Severidad"),
|
|
387
|
+
}))
|
|
388
|
+
.optional()
|
|
389
|
+
.describe("Blockers a registrar"),
|
|
390
|
+
phase: z
|
|
391
|
+
.string()
|
|
392
|
+
.optional()
|
|
393
|
+
.describe("Fase actual del proyecto"),
|
|
394
|
+
phaseStatus: z
|
|
395
|
+
.string()
|
|
396
|
+
.optional()
|
|
397
|
+
.describe("Estado de la fase"),
|
|
398
|
+
}, async (args) => {
|
|
399
|
+
const storagePath = process.env.MEMORYBANK_STORAGE_PATH || ".memorybank";
|
|
400
|
+
const result = await trackProgress({
|
|
401
|
+
projectId: args.projectId,
|
|
402
|
+
progress: args.progress,
|
|
403
|
+
milestone: args.milestone,
|
|
404
|
+
blockers: args.blockers,
|
|
405
|
+
phase: args.phase,
|
|
406
|
+
phaseStatus: args.phaseStatus,
|
|
407
|
+
}, storagePath);
|
|
408
|
+
return {
|
|
409
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
410
|
+
};
|
|
411
|
+
});
|
|
412
|
+
// ==========================================
|
|
413
|
+
// MCP Resources (Direct document access)
|
|
414
|
+
// ==========================================
|
|
415
|
+
// Resource: Project Active Context
|
|
416
|
+
server.resource("memory://*/active", "Contexto activo del proyecto: sesión actual, cambios recientes, próximos pasos", async (uri) => {
|
|
417
|
+
const projectId = uri.pathname.split("/")[0] || uri.host;
|
|
418
|
+
if (!projectKnowledgeService) {
|
|
419
|
+
return {
|
|
420
|
+
contents: [{
|
|
421
|
+
uri: uri.href,
|
|
422
|
+
mimeType: "text/plain",
|
|
423
|
+
text: "Error: Project Knowledge Service not initialized",
|
|
424
|
+
}],
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
const content = projectKnowledgeService.getProjectDocument(projectId, "activeContext");
|
|
428
|
+
if (!content) {
|
|
429
|
+
return {
|
|
430
|
+
contents: [{
|
|
431
|
+
uri: uri.href,
|
|
432
|
+
mimeType: "text/plain",
|
|
433
|
+
text: `No active context found for project "${projectId}". Run memorybank_initialize first.`,
|
|
434
|
+
}],
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
return {
|
|
438
|
+
contents: [{
|
|
439
|
+
uri: uri.href,
|
|
440
|
+
mimeType: "text/markdown",
|
|
441
|
+
text: content,
|
|
442
|
+
}],
|
|
443
|
+
};
|
|
444
|
+
});
|
|
445
|
+
// Resource: Project Progress
|
|
446
|
+
server.resource("memory://*/progress", "Seguimiento de progreso: tareas completadas, en progreso, bloqueadas y milestones", async (uri) => {
|
|
447
|
+
const projectId = uri.pathname.split("/")[0] || uri.host;
|
|
448
|
+
if (!projectKnowledgeService) {
|
|
449
|
+
return {
|
|
450
|
+
contents: [{
|
|
451
|
+
uri: uri.href,
|
|
452
|
+
mimeType: "text/plain",
|
|
453
|
+
text: "Error: Project Knowledge Service not initialized",
|
|
454
|
+
}],
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
const content = projectKnowledgeService.getProjectDocument(projectId, "progress");
|
|
458
|
+
if (!content) {
|
|
459
|
+
return {
|
|
460
|
+
contents: [{
|
|
461
|
+
uri: uri.href,
|
|
462
|
+
mimeType: "text/plain",
|
|
463
|
+
text: `No progress tracking found for project "${projectId}". Run memorybank_initialize first.`,
|
|
464
|
+
}],
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
return {
|
|
468
|
+
contents: [{
|
|
469
|
+
uri: uri.href,
|
|
470
|
+
mimeType: "text/markdown",
|
|
471
|
+
text: content,
|
|
472
|
+
}],
|
|
473
|
+
};
|
|
474
|
+
});
|
|
475
|
+
// Resource: Project Decisions
|
|
476
|
+
server.resource("memory://*/decisions", "Log de decisiones técnicas: historial de decisiones arquitectónicas y técnicas", async (uri) => {
|
|
477
|
+
const projectId = uri.pathname.split("/")[0] || uri.host;
|
|
478
|
+
if (!projectKnowledgeService) {
|
|
479
|
+
return {
|
|
480
|
+
contents: [{
|
|
481
|
+
uri: uri.href,
|
|
482
|
+
mimeType: "text/plain",
|
|
483
|
+
text: "Error: Project Knowledge Service not initialized",
|
|
484
|
+
}],
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
const content = projectKnowledgeService.getProjectDocument(projectId, "decisionLog");
|
|
488
|
+
if (!content) {
|
|
489
|
+
return {
|
|
490
|
+
contents: [{
|
|
491
|
+
uri: uri.href,
|
|
492
|
+
mimeType: "text/plain",
|
|
493
|
+
text: `No decision log found for project "${projectId}". Run memorybank_initialize first.`,
|
|
494
|
+
}],
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
return {
|
|
498
|
+
contents: [{
|
|
499
|
+
uri: uri.href,
|
|
500
|
+
mimeType: "text/markdown",
|
|
501
|
+
text: content,
|
|
502
|
+
}],
|
|
503
|
+
};
|
|
504
|
+
});
|
|
505
|
+
// Resource: Project Context (Brief + Tech)
|
|
506
|
+
server.resource("memory://*/context", "Contexto completo del proyecto: descripción general y stack tecnológico", async (uri) => {
|
|
507
|
+
const projectId = uri.pathname.split("/")[0] || uri.host;
|
|
508
|
+
if (!projectKnowledgeService) {
|
|
509
|
+
return {
|
|
510
|
+
contents: [{
|
|
511
|
+
uri: uri.href,
|
|
512
|
+
mimeType: "text/plain",
|
|
513
|
+
text: "Error: Project Knowledge Service not initialized",
|
|
514
|
+
}],
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
const content = projectKnowledgeService.getProjectContext(projectId);
|
|
518
|
+
if (!content) {
|
|
519
|
+
return {
|
|
520
|
+
contents: [{
|
|
521
|
+
uri: uri.href,
|
|
522
|
+
mimeType: "text/plain",
|
|
523
|
+
text: `No project context found for project "${projectId}". Run memorybank_initialize first.`,
|
|
524
|
+
}],
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
return {
|
|
528
|
+
contents: [{
|
|
529
|
+
uri: uri.href,
|
|
530
|
+
mimeType: "text/markdown",
|
|
531
|
+
text: content,
|
|
532
|
+
}],
|
|
533
|
+
};
|
|
534
|
+
});
|
|
535
|
+
// Resource: System Patterns
|
|
536
|
+
server.resource("memory://*/patterns", "Patrones de sistema: arquitectura, patrones de diseño y organización del código", async (uri) => {
|
|
537
|
+
const projectId = uri.pathname.split("/")[0] || uri.host;
|
|
538
|
+
if (!projectKnowledgeService) {
|
|
539
|
+
return {
|
|
540
|
+
contents: [{
|
|
541
|
+
uri: uri.href,
|
|
542
|
+
mimeType: "text/plain",
|
|
543
|
+
text: "Error: Project Knowledge Service not initialized",
|
|
544
|
+
}],
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
const content = projectKnowledgeService.getProjectDocument(projectId, "systemPatterns");
|
|
548
|
+
if (!content) {
|
|
549
|
+
return {
|
|
550
|
+
contents: [{
|
|
551
|
+
uri: uri.href,
|
|
552
|
+
mimeType: "text/plain",
|
|
553
|
+
text: `No system patterns found for project "${projectId}". Run memorybank_initialize or memorybank_generate_project_docs first.`,
|
|
554
|
+
}],
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
return {
|
|
558
|
+
contents: [{
|
|
559
|
+
uri: uri.href,
|
|
560
|
+
mimeType: "text/markdown",
|
|
561
|
+
text: content,
|
|
562
|
+
}],
|
|
563
|
+
};
|
|
564
|
+
});
|
|
565
|
+
// Resource: Project Brief
|
|
566
|
+
server.resource("memory://*/brief", "Descripción del proyecto: propósito, objetivos y audiencia", async (uri) => {
|
|
567
|
+
const projectId = uri.pathname.split("/")[0] || uri.host;
|
|
568
|
+
if (!projectKnowledgeService) {
|
|
569
|
+
return {
|
|
570
|
+
contents: [{
|
|
571
|
+
uri: uri.href,
|
|
572
|
+
mimeType: "text/plain",
|
|
573
|
+
text: "Error: Project Knowledge Service not initialized",
|
|
574
|
+
}],
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
const content = projectKnowledgeService.getProjectDocument(projectId, "projectBrief");
|
|
578
|
+
if (!content) {
|
|
579
|
+
return {
|
|
580
|
+
contents: [{
|
|
581
|
+
uri: uri.href,
|
|
582
|
+
mimeType: "text/plain",
|
|
583
|
+
text: `No project brief found for project "${projectId}". Run memorybank_initialize or memorybank_generate_project_docs first.`,
|
|
584
|
+
}],
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
return {
|
|
588
|
+
contents: [{
|
|
589
|
+
uri: uri.href,
|
|
590
|
+
mimeType: "text/markdown",
|
|
591
|
+
text: content,
|
|
592
|
+
}],
|
|
593
|
+
};
|
|
594
|
+
});
|
|
255
595
|
/**
|
|
256
596
|
* Validates and initializes environment
|
|
257
597
|
*/
|
|
@@ -328,16 +668,29 @@ async function startStdioServer() {
|
|
|
328
668
|
await server.connect(transport);
|
|
329
669
|
console.error("\n=== MCP Server Ready ===");
|
|
330
670
|
console.error("Available tools:");
|
|
331
|
-
console.error(" Core Memory Bank:");
|
|
671
|
+
console.error(" Core Memory Bank (Cursor-style):");
|
|
332
672
|
console.error(" - memorybank_index_code: Indexar código semánticamente");
|
|
333
673
|
console.error(" - memorybank_search: Buscar código por similitud semántica");
|
|
334
674
|
console.error(" - memorybank_read_file: Leer archivos del workspace");
|
|
335
675
|
console.error(" - memorybank_write_file: Escribir archivos y reindexar");
|
|
336
676
|
console.error(" - memorybank_get_stats: Obtener estadísticas del índice");
|
|
337
677
|
console.error(" - memorybank_analyze_coverage: Analizar cobertura de indexación");
|
|
338
|
-
console.error(" Project Knowledge Layer:");
|
|
678
|
+
console.error(" Project Knowledge Layer (AI Docs):");
|
|
339
679
|
console.error(" - memorybank_generate_project_docs: Generar documentación con IA");
|
|
340
680
|
console.error(" - memorybank_get_project_docs: Leer documentación del proyecto");
|
|
681
|
+
console.error(" Context Management (Cline-style):");
|
|
682
|
+
console.error(" - memorybank_initialize: Inicializar Memory Bank para un proyecto");
|
|
683
|
+
console.error(" - memorybank_update_context: Actualizar contexto de sesión");
|
|
684
|
+
console.error(" - memorybank_record_decision: Registrar decisiones técnicas");
|
|
685
|
+
console.error(" - memorybank_track_progress: Actualizar progreso del proyecto");
|
|
686
|
+
console.error("");
|
|
687
|
+
console.error("Available resources:");
|
|
688
|
+
console.error(" - memory://{projectId}/active: Contexto activo");
|
|
689
|
+
console.error(" - memory://{projectId}/progress: Seguimiento de progreso");
|
|
690
|
+
console.error(" - memory://{projectId}/decisions: Log de decisiones");
|
|
691
|
+
console.error(" - memory://{projectId}/context: Contexto del proyecto");
|
|
692
|
+
console.error(" - memory://{projectId}/patterns: Patrones de sistema");
|
|
693
|
+
console.error(" - memory://{projectId}/brief: Descripción del proyecto");
|
|
341
694
|
console.error("");
|
|
342
695
|
console.error("Ready to accept requests...\n");
|
|
343
696
|
}
|