@grec0/memory-bank-mcp 0.0.2 → 0.0.4

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.
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Vector store for Memory Bank using LanceDB
3
3
  * Manages storage and retrieval of code embeddings
4
+ * Uses snake_case for field names for LanceDB SQL compatibility
4
5
  */
5
6
  import * as lancedb from "@lancedb/lancedb";
6
7
  import * as fs from "fs";
@@ -130,7 +131,8 @@ export class VectorStore {
130
131
  return;
131
132
  }
132
133
  try {
133
- await this.table.delete(`filePath = '${filePath}'`);
134
+ // Use snake_case field name for LanceDB SQL compatibility
135
+ await this.table.delete(`file_path = '${filePath}'`);
134
136
  console.error(`Deleted all chunks from file: ${filePath}`);
135
137
  }
136
138
  catch (error) {
@@ -152,15 +154,18 @@ export class VectorStore {
152
154
  try {
153
155
  // Start with vector search
154
156
  let query = this.table.search(queryVector).limit(topK);
155
- // Apply filters if specified
157
+ // Apply filters if specified (using snake_case field names)
156
158
  if (options.filterByFile) {
157
- query = query.where(`filePath LIKE '%${options.filterByFile}%'`);
159
+ query = query.where(`file_path LIKE '%${options.filterByFile}%'`);
158
160
  }
159
161
  if (options.filterByLanguage) {
160
162
  query = query.where(`language = '${options.filterByLanguage}'`);
161
163
  }
162
164
  if (options.filterByType) {
163
- query = query.where(`chunkType = '${options.filterByType}'`);
165
+ query = query.where(`chunk_type = '${options.filterByType}'`);
166
+ }
167
+ if (options.filterByProject) {
168
+ query = query.where(`project_id = '${options.filterByProject}'`);
164
169
  }
165
170
  // Execute search
166
171
  const results = await query.toArray();
@@ -174,16 +179,17 @@ export class VectorStore {
174
179
  chunk: {
175
180
  id: result.id,
176
181
  vector: result.vector,
177
- filePath: result.filePath,
182
+ file_path: result.file_path,
178
183
  content: result.content,
179
- startLine: result.startLine,
180
- endLine: result.endLine,
181
- chunkType: result.chunkType,
184
+ start_line: result.start_line,
185
+ end_line: result.end_line,
186
+ chunk_type: result.chunk_type,
182
187
  name: result.name,
183
188
  language: result.language,
184
- fileHash: result.fileHash,
189
+ file_hash: result.file_hash,
185
190
  timestamp: result.timestamp,
186
191
  context: result.context,
192
+ project_id: result.project_id,
187
193
  },
188
194
  score,
189
195
  distance,
@@ -207,21 +213,23 @@ export class VectorStore {
207
213
  }
208
214
  try {
209
215
  const results = await this.table
210
- .where(`filePath = '${filePath}'`)
216
+ .query()
217
+ .where(`file_path = '${filePath}'`)
211
218
  .toArray();
212
219
  return results.map((r) => ({
213
220
  id: r.id,
214
221
  vector: r.vector,
215
- filePath: r.filePath,
222
+ file_path: r.file_path,
216
223
  content: r.content,
217
- startLine: r.startLine,
218
- endLine: r.endLine,
219
- chunkType: r.chunkType,
224
+ start_line: r.start_line,
225
+ end_line: r.end_line,
226
+ chunk_type: r.chunk_type,
220
227
  name: r.name,
221
228
  language: r.language,
222
- fileHash: r.fileHash,
229
+ file_hash: r.file_hash,
223
230
  timestamp: r.timestamp,
224
231
  context: r.context,
232
+ project_id: r.project_id,
225
233
  }));
226
234
  }
227
235
  catch (error) {
@@ -229,6 +237,56 @@ export class VectorStore {
229
237
  return [];
230
238
  }
231
239
  }
240
+ /**
241
+ * Gets all chunks, optionally filtered by project
242
+ */
243
+ async getAllChunks(projectId) {
244
+ await this.ensureInitialized();
245
+ if (!this.table) {
246
+ console.error("getAllChunks: No table exists");
247
+ return [];
248
+ }
249
+ try {
250
+ let query = this.table.query();
251
+ // Apply project filter using snake_case field name
252
+ if (projectId) {
253
+ query = query.where(`project_id = '${projectId}'`);
254
+ console.error(`getAllChunks: Filtering by project_id='${projectId}'`);
255
+ }
256
+ const results = await query.toArray();
257
+ console.error(`getAllChunks: Got ${results.length} results`);
258
+ // Debug: Check first result's content
259
+ if (results.length > 0) {
260
+ const first = results[0];
261
+ console.error(`getAllChunks: First result file_path=${first.file_path}, content length=${first.content?.length || 0}`);
262
+ }
263
+ return results.map((r) => ({
264
+ id: r.id,
265
+ vector: r.vector,
266
+ file_path: r.file_path,
267
+ content: r.content,
268
+ start_line: r.start_line,
269
+ end_line: r.end_line,
270
+ chunk_type: r.chunk_type,
271
+ name: r.name,
272
+ language: r.language,
273
+ file_hash: r.file_hash,
274
+ timestamp: r.timestamp,
275
+ context: r.context,
276
+ project_id: r.project_id,
277
+ }));
278
+ }
279
+ catch (error) {
280
+ console.error(`Error getting all chunks: ${error}`);
281
+ return [];
282
+ }
283
+ }
284
+ /**
285
+ * Gets chunks by project ID
286
+ */
287
+ async getChunksByProject(projectId) {
288
+ return this.getAllChunks(projectId);
289
+ }
232
290
  /**
233
291
  * Gets statistics about the vector store
234
292
  */
@@ -243,16 +301,15 @@ export class VectorStore {
243
301
  };
244
302
  }
245
303
  try {
246
- // Use query().toArray() instead of direct toArray()
247
304
  const allChunks = await this.table.query().toArray();
248
305
  const uniqueFiles = new Set();
249
306
  const languageCounts = {};
250
307
  const typeCounts = {};
251
308
  let latestTimestamp = 0;
252
309
  for (const chunk of allChunks) {
253
- uniqueFiles.add(chunk.filePath);
310
+ uniqueFiles.add(chunk.file_path);
254
311
  languageCounts[chunk.language] = (languageCounts[chunk.language] || 0) + 1;
255
- typeCounts[chunk.chunkType] = (typeCounts[chunk.chunkType] || 0) + 1;
312
+ typeCounts[chunk.chunk_type] = (typeCounts[chunk.chunk_type] || 0) + 1;
256
313
  if (chunk.timestamp > latestTimestamp) {
257
314
  latestTimestamp = chunk.timestamp;
258
315
  }
@@ -307,12 +364,11 @@ export class VectorStore {
307
364
  return new Map();
308
365
  }
309
366
  try {
310
- // Use query().toArray() instead of direct toArray()
311
367
  const allChunks = await this.table.query().toArray();
312
368
  const fileHashes = new Map();
313
369
  for (const chunk of allChunks) {
314
- if (!fileHashes.has(chunk.filePath)) {
315
- fileHashes.set(chunk.filePath, chunk.fileHash);
370
+ if (!fileHashes.has(chunk.file_path)) {
371
+ fileHashes.set(chunk.file_path, chunk.file_hash);
316
372
  }
317
373
  }
318
374
  return fileHashes;
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ import { z } from "zod";
10
10
  import { createEmbeddingService } from "./common/embeddingService.js";
11
11
  import { createVectorStore } from "./common/vectorStore.js";
12
12
  import { createIndexManager } from "./common/indexManager.js";
13
+ import { createProjectKnowledgeService } from "./common/projectKnowledgeService.js";
13
14
  // Import tools
14
15
  import { indexCode } from "./tools/indexCode.js";
15
16
  import { searchMemory } from "./tools/searchMemory.js";
@@ -17,11 +18,14 @@ import { readFile } from "./tools/readFile.js";
17
18
  import { writeFile } from "./tools/writeFile.js";
18
19
  import { getStats } from "./tools/getStats.js";
19
20
  import { analyzeCoverage } from "./tools/analyzeCoverage.js";
21
+ import { generateProjectDocs, generateProjectDocsToolDefinition } from "./tools/generateProjectDocs.js";
22
+ import { getProjectDocs, getProjectDocsToolDefinition } from "./tools/getProjectDocs.js";
20
23
  import { VERSION } from "./common/version.js";
21
24
  // Global services
22
25
  let embeddingService;
23
26
  let vectorStore;
24
27
  let indexManager;
28
+ let projectKnowledgeService;
25
29
  let workspaceRoot;
26
30
  // Create the MCP Server
27
31
  const server = new McpServer({
@@ -67,8 +71,8 @@ server.tool("memorybank_search", "Busca código relevante mediante búsqueda sem
67
71
  minScore: z
68
72
  .number()
69
73
  .optional()
70
- .default(0.7)
71
- .describe("Puntuación mínima de similitud (0-1). Valores más altos = resultados más relevantes"),
74
+ .default(0.4)
75
+ .describe("Puntuación mínima de similitud (0-1). por defecto usa 0.4 y basado en el resultado ajusta el valor"),
72
76
  filterByFile: z
73
77
  .string()
74
78
  .optional()
@@ -184,6 +188,47 @@ server.tool("memorybank_analyze_coverage", "Analiza la cobertura de indexación
184
188
  };
185
189
  }
186
190
  });
191
+ // Tool: Generate Project Docs
192
+ server.tool(generateProjectDocsToolDefinition.name, generateProjectDocsToolDefinition.description, {
193
+ projectId: z
194
+ .string()
195
+ .optional()
196
+ .describe("ID del proyecto (opcional, usa 'default' si no se especifica)"),
197
+ force: z
198
+ .boolean()
199
+ .optional()
200
+ .default(false)
201
+ .describe("Forzar regeneración de todos los documentos aunque no hayan cambiado"),
202
+ }, async (args) => {
203
+ const result = await generateProjectDocs({
204
+ projectId: args.projectId,
205
+ force: args.force,
206
+ }, projectKnowledgeService, vectorStore);
207
+ return {
208
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
209
+ };
210
+ });
211
+ // Tool: Get Project Docs
212
+ server.tool(getProjectDocsToolDefinition.name, getProjectDocsToolDefinition.description, {
213
+ document: z
214
+ .string()
215
+ .optional()
216
+ .default("summary")
217
+ .describe("Documento específico a recuperar: projectBrief, productContext, systemPatterns, techContext, activeContext, progress, all, summary"),
218
+ format: z
219
+ .enum(["full", "summary"])
220
+ .optional()
221
+ .default("full")
222
+ .describe("Formato de salida: 'full' devuelve contenido completo, 'summary' devuelve resumen de todos los docs"),
223
+ }, async (args) => {
224
+ const result = await getProjectDocs({
225
+ document: args.document,
226
+ format: args.format,
227
+ }, projectKnowledgeService);
228
+ return {
229
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
230
+ };
231
+ });
187
232
  /**
188
233
  * Validates and initializes environment
189
234
  */
@@ -208,6 +253,12 @@ async function validateEnvironment() {
208
253
  const embeddingModel = process.env.MEMORYBANK_EMBEDDING_MODEL || "text-embedding-3-small";
209
254
  const embeddingDimensions = process.env.MEMORYBANK_EMBEDDING_DIMENSIONS || "1536";
210
255
  console.error(`✓ Embedding model: ${embeddingModel} (${embeddingDimensions} dimensions)`);
256
+ // Project Knowledge Layer configuration
257
+ const reasoningModel = process.env.MEMORYBANK_REASONING_MODEL || "gpt-5-mini";
258
+ const reasoningEffort = process.env.MEMORYBANK_REASONING_EFFORT || "medium";
259
+ const autoUpdateDocs = process.env.MEMORYBANK_AUTO_UPDATE_DOCS === "true";
260
+ console.error(`✓ Reasoning model: ${reasoningModel} (effort: ${reasoningEffort})`);
261
+ console.error(`✓ Auto-update docs: ${autoUpdateDocs}`);
211
262
  // Initialize services
212
263
  console.error("\nInitializing services...");
213
264
  try {
@@ -218,6 +269,19 @@ async function validateEnvironment() {
218
269
  console.error("✓ Vector store initialized");
219
270
  indexManager = createIndexManager(embeddingService, vectorStore);
220
271
  console.error("✓ Index manager initialized");
272
+ // Initialize Project Knowledge Service
273
+ try {
274
+ projectKnowledgeService = createProjectKnowledgeService();
275
+ console.error("✓ Project Knowledge service initialized");
276
+ // Connect to Index Manager for auto-update hooks
277
+ indexManager.setProjectKnowledgeService(projectKnowledgeService);
278
+ indexManager.setAutoUpdateDocs(autoUpdateDocs);
279
+ console.error("✓ Project Knowledge service connected to Index Manager");
280
+ }
281
+ catch (error) {
282
+ console.error(`⚠ Warning: Project Knowledge service not available: ${error}`);
283
+ console.error(" Project documentation features will be disabled.");
284
+ }
221
285
  }
222
286
  catch (error) {
223
287
  console.error(`ERROR: Failed to initialize services: ${error}`);
@@ -241,12 +305,16 @@ async function startStdioServer() {
241
305
  await server.connect(transport);
242
306
  console.error("\n=== MCP Server Ready ===");
243
307
  console.error("Available tools:");
244
- console.error(" - memorybank_index_code: Indexar código semánticamente");
245
- console.error(" - memorybank_search: Buscar código por similitud semántica");
246
- console.error(" - memorybank_read_file: Leer archivos del workspace");
247
- console.error(" - memorybank_write_file: Escribir archivos y reindexar");
248
- console.error(" - memorybank_get_stats: Obtener estadísticas del índice");
249
- console.error(" - memorybank_analyze_coverage: Analizar cobertura de indexación");
308
+ console.error(" Core Memory Bank:");
309
+ console.error(" - memorybank_index_code: Indexar código semánticamente");
310
+ console.error(" - memorybank_search: Buscar código por similitud semántica");
311
+ console.error(" - memorybank_read_file: Leer archivos del workspace");
312
+ console.error(" - memorybank_write_file: Escribir archivos y reindexar");
313
+ console.error(" - memorybank_get_stats: Obtener estadísticas del índice");
314
+ console.error(" - memorybank_analyze_coverage: Analizar cobertura de indexación");
315
+ console.error(" Project Knowledge Layer:");
316
+ console.error(" - memorybank_generate_project_docs: Generar documentación con IA");
317
+ console.error(" - memorybank_get_project_docs: Leer documentación del proyecto");
250
318
  console.error("");
251
319
  console.error("Ready to accept requests...\n");
252
320
  }
@@ -256,7 +256,7 @@ export async function analyzeCoverage(indexManager, vectorStore, workspaceRoot)
256
256
  if (indexed) {
257
257
  // Check if file hash matches
258
258
  const chunks = await vectorStore.getChunksByFile(file.path);
259
- if (chunks.length > 0 && chunks[0].fileHash !== file.hash) {
259
+ if (chunks.length > 0 && chunks[0].file_hash !== file.hash) {
260
260
  pendingFiles.add(file.path);
261
261
  }
262
262
  }
@@ -0,0 +1,133 @@
1
+ /**
2
+ * @fileoverview Tool for generating project documentation
3
+ * Uses the Project Knowledge Service to create structured markdown docs
4
+ */
5
+ /**
6
+ * Generates project documentation using AI reasoning
7
+ */
8
+ export async function generateProjectDocs(params, projectKnowledgeService, vectorStore) {
9
+ try {
10
+ console.error("\n=== Generating Project Documentation ===");
11
+ console.error(`Project ID: ${params.projectId || "default"}`);
12
+ console.error(`Force regeneration: ${params.force || false}`);
13
+ // Get all chunks from the vector store
14
+ const chunks = await vectorStore.getAllChunks(params.projectId);
15
+ if (chunks.length === 0) {
16
+ return {
17
+ success: false,
18
+ message: "No indexed code found. Please run memorybank_index_code first to index your project.",
19
+ result: {
20
+ success: false,
21
+ documentsGenerated: [],
22
+ documentsUpdated: [],
23
+ documentsSkipped: [],
24
+ totalReasoningTokens: 0,
25
+ totalOutputTokens: 0,
26
+ errors: ["No chunks available for documentation generation"],
27
+ },
28
+ tokenUsage: {
29
+ reasoningTokens: 0,
30
+ outputTokens: 0,
31
+ estimatedCost: "$0.00",
32
+ },
33
+ };
34
+ }
35
+ console.error(`Found ${chunks.length} code chunks to analyze`);
36
+ // Generate documents
37
+ const result = await projectKnowledgeService.generateAllDocuments(chunks, params.force || false);
38
+ // Calculate estimated cost (approximate rates for gpt-5-mini)
39
+ // Reasoning tokens are typically more expensive
40
+ const reasoningCostPer1K = 0.003; // $0.003 per 1K reasoning tokens
41
+ const outputCostPer1K = 0.012; // $0.012 per 1K output tokens
42
+ const reasoningCost = (result.totalReasoningTokens / 1000) * reasoningCostPer1K;
43
+ const outputCost = (result.totalOutputTokens / 1000) * outputCostPer1K;
44
+ const totalCost = reasoningCost + outputCost;
45
+ // Build response message
46
+ let message = "";
47
+ if (result.documentsGenerated.length > 0) {
48
+ message += `Generated ${result.documentsGenerated.length} new document(s): ${result.documentsGenerated.join(", ")}. `;
49
+ }
50
+ if (result.documentsUpdated.length > 0) {
51
+ message += `Updated ${result.documentsUpdated.length} document(s): ${result.documentsUpdated.join(", ")}. `;
52
+ }
53
+ if (result.documentsSkipped.length > 0) {
54
+ message += `Skipped ${result.documentsSkipped.length} unchanged document(s). `;
55
+ }
56
+ if (result.errors.length > 0) {
57
+ message += `Errors: ${result.errors.join("; ")}`;
58
+ }
59
+ if (!message) {
60
+ message = "All documents are up to date.";
61
+ }
62
+ console.error(`\nGeneration complete:`);
63
+ console.error(` - Generated: ${result.documentsGenerated.length}`);
64
+ console.error(` - Updated: ${result.documentsUpdated.length}`);
65
+ console.error(` - Skipped: ${result.documentsSkipped.length}`);
66
+ console.error(` - Reasoning tokens: ${result.totalReasoningTokens}`);
67
+ console.error(` - Output tokens: ${result.totalOutputTokens}`);
68
+ console.error(` - Estimated cost: $${totalCost.toFixed(4)}`);
69
+ return {
70
+ success: result.success,
71
+ message,
72
+ result,
73
+ tokenUsage: {
74
+ reasoningTokens: result.totalReasoningTokens,
75
+ outputTokens: result.totalOutputTokens,
76
+ estimatedCost: `$${totalCost.toFixed(4)}`,
77
+ },
78
+ };
79
+ }
80
+ catch (error) {
81
+ console.error(`Error generating project docs: ${error.message}`);
82
+ return {
83
+ success: false,
84
+ message: `Failed to generate project documentation: ${error.message}`,
85
+ result: {
86
+ success: false,
87
+ documentsGenerated: [],
88
+ documentsUpdated: [],
89
+ documentsSkipped: [],
90
+ totalReasoningTokens: 0,
91
+ totalOutputTokens: 0,
92
+ errors: [error.message],
93
+ },
94
+ tokenUsage: {
95
+ reasoningTokens: 0,
96
+ outputTokens: 0,
97
+ estimatedCost: "$0.00",
98
+ },
99
+ };
100
+ }
101
+ }
102
+ /**
103
+ * Tool definition for MCP
104
+ */
105
+ export const generateProjectDocsToolDefinition = {
106
+ name: "memorybank_generate_project_docs",
107
+ description: `Genera documentación estructurada del proyecto usando IA con razonamiento avanzado (gpt-5-mini).
108
+
109
+ Crea 6 documentos markdown que proporcionan una visión global del proyecto:
110
+ - projectBrief.md: Descripción general del proyecto
111
+ - productContext.md: Perspectiva de negocio y usuarios
112
+ - systemPatterns.md: Patrones de arquitectura y diseño
113
+ - techContext.md: Stack tecnológico y dependencias
114
+ - activeContext.md: Estado actual de desarrollo
115
+ - progress.md: Seguimiento de cambios
116
+
117
+ Esta herramienta complementa la búsqueda semántica precisa con conocimiento global del proyecto.
118
+ Útil para que agentes menos avanzados comprendan mejor el contexto completo.`,
119
+ inputSchema: {
120
+ type: "object",
121
+ properties: {
122
+ projectId: {
123
+ type: "string",
124
+ description: "ID del proyecto (opcional, usa 'default' si no se especifica)",
125
+ },
126
+ force: {
127
+ type: "boolean",
128
+ description: "Forzar regeneración de todos los documentos aunque no hayan cambiado",
129
+ default: false,
130
+ },
131
+ },
132
+ },
133
+ };
@@ -0,0 +1,126 @@
1
+ /**
2
+ * @fileoverview Tool for reading project documentation
3
+ * Retrieves generated markdown documents for project context
4
+ */
5
+ const VALID_DOC_TYPES = [
6
+ "projectBrief",
7
+ "productContext",
8
+ "systemPatterns",
9
+ "techContext",
10
+ "activeContext",
11
+ "progress",
12
+ ];
13
+ /**
14
+ * Retrieves project documentation
15
+ */
16
+ export async function getProjectDocs(params, projectKnowledgeService) {
17
+ try {
18
+ const format = params.format || "full";
19
+ const requestedDoc = params.document?.toLowerCase();
20
+ // Check if any documents exist
21
+ if (!projectKnowledgeService.hasDocuments()) {
22
+ return {
23
+ success: false,
24
+ message: "No project documentation has been generated yet. Run memorybank_generate_project_docs first.",
25
+ stats: {
26
+ documentCount: 0,
27
+ totalReasoningTokens: 0,
28
+ totalOutputTokens: 0,
29
+ },
30
+ };
31
+ }
32
+ // Get stats
33
+ const stats = projectKnowledgeService.getStats();
34
+ const statsResult = {
35
+ documentCount: stats.documentCount,
36
+ totalReasoningTokens: stats.totalReasoningTokens,
37
+ totalOutputTokens: stats.totalOutputTokens,
38
+ lastGenerated: stats.lastGenerated?.toISOString(),
39
+ };
40
+ // Handle summary request
41
+ if (requestedDoc === "summary" || format === "summary") {
42
+ const summary = projectKnowledgeService.getDocumentsSummary();
43
+ return {
44
+ success: true,
45
+ message: `Retrieved summary of ${stats.documentCount} project documents.`,
46
+ summary,
47
+ stats: statsResult,
48
+ };
49
+ }
50
+ // Handle "all" or no specific document
51
+ if (!requestedDoc || requestedDoc === "all") {
52
+ const documents = projectKnowledgeService.getAllDocuments();
53
+ return {
54
+ success: true,
55
+ message: `Retrieved ${documents.length} project documents.`,
56
+ documents,
57
+ stats: statsResult,
58
+ };
59
+ }
60
+ // Handle specific document request
61
+ // Normalize document name (allow both "projectBrief" and "projectbrief")
62
+ const normalizedDoc = VALID_DOC_TYPES.find(t => t.toLowerCase() === requestedDoc.replace(".md", "").replace("_", ""));
63
+ if (!normalizedDoc) {
64
+ return {
65
+ success: false,
66
+ message: `Invalid document type: "${params.document}". Valid types are: ${VALID_DOC_TYPES.join(", ")}`,
67
+ stats: statsResult,
68
+ };
69
+ }
70
+ const document = projectKnowledgeService.getDocument(normalizedDoc);
71
+ if (!document) {
72
+ return {
73
+ success: false,
74
+ message: `Document "${normalizedDoc}" has not been generated yet.`,
75
+ stats: statsResult,
76
+ };
77
+ }
78
+ return {
79
+ success: true,
80
+ message: `Retrieved document: ${normalizedDoc}`,
81
+ documents: [document],
82
+ stats: statsResult,
83
+ };
84
+ }
85
+ catch (error) {
86
+ console.error(`Error getting project docs: ${error.message}`);
87
+ return {
88
+ success: false,
89
+ message: `Failed to retrieve project documentation: ${error.message}`,
90
+ };
91
+ }
92
+ }
93
+ /**
94
+ * Tool definition for MCP
95
+ */
96
+ export const getProjectDocsToolDefinition = {
97
+ name: "memorybank_get_project_docs",
98
+ description: `Lee la documentación del proyecto generada por IA.
99
+
100
+ Recupera documentos markdown estructurados que proporcionan contexto global del proyecto:
101
+ - projectBrief: Descripción general del proyecto
102
+ - productContext: Perspectiva de negocio y usuarios
103
+ - systemPatterns: Patrones de arquitectura y diseño
104
+ - techContext: Stack tecnológico y dependencias
105
+ - activeContext: Estado actual de desarrollo
106
+ - progress: Seguimiento de cambios
107
+
108
+ Usa esta herramienta al inicio de cada sesión para cargar contexto global.
109
+ Complementa la búsqueda semántica precisa (memorybank_search) con visión de alto nivel.`,
110
+ inputSchema: {
111
+ type: "object",
112
+ properties: {
113
+ document: {
114
+ type: "string",
115
+ description: "Documento específico a recuperar. Opciones: projectBrief, productContext, systemPatterns, techContext, activeContext, progress, all, summary",
116
+ default: "summary",
117
+ },
118
+ format: {
119
+ type: "string",
120
+ enum: ["full", "summary"],
121
+ description: "Formato de salida: 'full' devuelve contenido completo, 'summary' devuelve resumen de todos los docs",
122
+ default: "full",
123
+ },
124
+ },
125
+ },
126
+ };
@@ -10,3 +10,6 @@ export * from "./readFile.js";
10
10
  export * from "./writeFile.js";
11
11
  export * from "./getStats.js";
12
12
  export * from "./analyzeCoverage.js";
13
+ // Export Project Knowledge Layer tools
14
+ export * from "./generateProjectDocs.js";
15
+ export * from "./getProjectDocs.js";
@@ -18,7 +18,7 @@ export async function searchMemory(params, indexManager) {
18
18
  }
19
19
  console.error(`\nSearching Memory Bank for: "${params.query}"`);
20
20
  console.error(`Top K: ${params.topK || 10}`);
21
- console.error(`Min score: ${params.minScore || 0.7}`);
21
+ console.error(`Min score: ${params.minScore || 0.4}`);
22
22
  if (params.filterByFile) {
23
23
  console.error(`Filter by file: ${params.filterByFile}`);
24
24
  }
@@ -28,7 +28,7 @@ export async function searchMemory(params, indexManager) {
28
28
  // Search
29
29
  const results = await indexManager.search(params.query, {
30
30
  topK: params.topK || 10,
31
- minScore: params.minScore !== undefined ? params.minScore : 0.7,
31
+ minScore: params.minScore !== undefined ? params.minScore : 0.4,
32
32
  filterByFile: params.filterByFile,
33
33
  filterByLanguage: params.filterByLanguage,
34
34
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grec0/memory-bank-mcp",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "MCP server for semantic code indexing with Memory Bank - AI-powered codebase understanding",
5
5
  "license": "MIT",
6
6
  "author": "@grec0",
@@ -40,6 +40,7 @@
40
40
  "@lancedb/lancedb": "^0.9.0",
41
41
  "@modelcontextprotocol/sdk": "1.6.1",
42
42
  "@types/node": "^22",
43
+ "gpt-tokenizer": "3.4.0",
43
44
  "ignore": "^5.3.0",
44
45
  "openai": "^4.0.0",
45
46
  "zod": "^3.22.4",