diff --git a/package.json b/package.json index d8b4870d4..a3adbdb3a 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "build": "npm run build --workspaces", "watch": "npm run watch --workspaces", "publish-all": "npm publish --workspaces --access public", - "link-all": "npm link --workspaces" + "link-all": "npm link --workspaces", + "inspect-memory": "${NPX} @modelcontextprotocol/inspector ${NPM} node_modules/.bin/mcp-server-memory" }, "dependencies": { "@modelcontextprotocol/server-everything": "*", diff --git a/src/memory/index.ts b/src/memory/index.ts index 982c617be..6eb8a7d2e 100644 --- a/src/memory/index.ts +++ b/src/memory/index.ts @@ -60,17 +60,17 @@ class KnowledgeGraphManager { private async saveGraph(graph: KnowledgeGraph): Promise { const lines = [ - ...graph.entities.map(e => JSON.stringify({ - type: "entity", - name: e.name, - entityType: e.entityType, - observations: e.observations + ...graph.entities.map(e => JSON.stringify({ + type: "entity", + name: e.name, + entityType: e.entityType, + observations: e.observations })), - ...graph.relations.map(r => JSON.stringify({ - type: "relation", - from: r.from, - to: r.to, - relationType: r.relationType + ...graph.relations.map(r => JSON.stringify({ + type: "relation", + from: r.from, + to: r.to, + relationType: r.relationType })), ]; await fs.writeFile(MEMORY_FILE_PATH, lines.join("\n")); @@ -86,9 +86,9 @@ class KnowledgeGraphManager { async createRelations(relations: Relation[]): Promise { const graph = await this.loadGraph(); - const newRelations = relations.filter(r => !graph.relations.some(existingRelation => - existingRelation.from === r.from && - existingRelation.to === r.to && + const newRelations = relations.filter(r => !graph.relations.some(existingRelation => + existingRelation.from === r.from && + existingRelation.to === r.to && existingRelation.relationType === r.relationType )); graph.relations.push(...newRelations); @@ -131,9 +131,9 @@ class KnowledgeGraphManager { async deleteRelations(relations: Relation[]): Promise { const graph = await this.loadGraph(); - graph.relations = graph.relations.filter(r => !relations.some(delRelation => - r.from === delRelation.from && - r.to === delRelation.to && + graph.relations = graph.relations.filter(r => !relations.some(delRelation => + r.from === delRelation.from && + r.to === delRelation.to && r.relationType === delRelation.relationType )); await this.saveGraph(graph); @@ -146,49 +146,49 @@ class KnowledgeGraphManager { // Very basic search function async searchNodes(query: string): Promise { const graph = await this.loadGraph(); - + // Filter entities - const filteredEntities = graph.entities.filter(e => - e.name.toLowerCase().includes(query.toLowerCase()) || - e.entityType.toLowerCase().includes(query.toLowerCase()) || - e.observations.some(o => o.toLowerCase().includes(query.toLowerCase())) - ); - + const filteredEntities = graph.entities.filter(e => + query.toLowerCase().includes(e.name) || + query.toLowerCase().includes(e.entityType) || + e.observations.some(o => query.toLowerCase().includes(o.toLowerCase())) + ) + // Create a Set of filtered entity names for quick lookup const filteredEntityNames = new Set(filteredEntities.map(e => e.name)); - + // Filter relations to only include those between filtered entities - const filteredRelations = graph.relations.filter(r => + const filteredRelations = graph.relations.filter(r => filteredEntityNames.has(r.from) && filteredEntityNames.has(r.to) ); - + const filteredGraph: KnowledgeGraph = { entities: filteredEntities, relations: filteredRelations, }; - + return filteredGraph; } async openNodes(names: string[]): Promise { const graph = await this.loadGraph(); - + // Filter entities const filteredEntities = graph.entities.filter(e => names.includes(e.name)); - + // Create a Set of filtered entity names for quick lookup const filteredEntityNames = new Set(filteredEntities.map(e => e.name)); - + // Filter relations to only include those between filtered entities - const filteredRelations = graph.relations.filter(r => + const filteredRelations = graph.relations.filter(r => filteredEntityNames.has(r.from) && filteredEntityNames.has(r.to) ); - + const filteredGraph: KnowledgeGraph = { entities: filteredEntities, relations: filteredRelations, }; - + return filteredGraph; } } @@ -222,8 +222,8 @@ server.setRequestHandler(ListToolsRequestSchema, async () => { properties: { name: { type: "string", description: "The name of the entity" }, entityType: { type: "string", description: "The type of the entity" }, - observations: { - type: "array", + observations: { + type: "array", items: { type: "string" }, description: "An array of observation contents associated with the entity" }, @@ -273,8 +273,8 @@ server.setRequestHandler(ListToolsRequestSchema, async () => { type: "object", properties: { entityName: { type: "string", description: "The name of the entity to add the observations to" }, - contents: { - type: "array", + contents: { + type: "array", items: { type: "string" }, description: "An array of observation contents to add" }, @@ -294,10 +294,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => { inputSchema: { type: "object", properties: { - entityNames: { - type: "array", + entityNames: { + type: "array", items: { type: "string" }, - description: "An array of entity names to delete" + description: "An array of entity names to delete" }, }, required: ["entityNames"], @@ -316,8 +316,8 @@ server.setRequestHandler(ListToolsRequestSchema, async () => { type: "object", properties: { entityName: { type: "string", description: "The name of the entity containing the observations" }, - observations: { - type: "array", + observations: { + type: "array", items: { type: "string" }, description: "An array of observations to delete" }, @@ -337,8 +337,8 @@ server.setRequestHandler(ListToolsRequestSchema, async () => { inputSchema: { type: "object", properties: { - relations: { - type: "array", + relations: { + type: "array", items: { type: "object", properties: { @@ -349,7 +349,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => { required: ["from", "to", "relationType"], additionalProperties: false, }, - description: "An array of relations to delete" + description: "An array of relations to delete" }, }, required: ["relations"],