MCP Neo4j Knowledge Graph Memory Server

by JovanHsu
Verified
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { z } from 'zod'; import { ConsoleLogger, LogLevel } from './logger.js'; import { Neo4jKnowledgeGraphManager } from './manager.js'; import { EntityObject, ObservationObject, RelationObject } from './types.js'; import { extractError } from './utils.js'; // 创建MCP服务器 const server = new McpServer({ name: 'neo4j-memory-server', version: '1.0.0', }); // 创建日志记录器,并设置为仅输出错误信息 const logger = new ConsoleLogger(); logger.setLevel(LogLevel.ERROR); // 创建知识图谱管理器 const knowledgeGraphManager = new Neo4jKnowledgeGraphManager( /** * 根据环境变量获取Neo4j配置 * @returns Neo4j配置 */ () => { return { uri: process.env.NEO4J_URI || 'bolt://localhost:7687', user: process.env.NEO4J_USER || 'neo4j', password: process.env.NEO4J_PASSWORD || 'password', database: process.env.NEO4J_DATABASE || 'neo4j', }; }, logger ); // 注册创建实体工具 server.tool( 'create_entities', 'Create multiple new entities in the knowledge graph', { entities: z.array(EntityObject), }, async ({ entities }) => ({ content: [ { type: 'text', text: JSON.stringify( await knowledgeGraphManager.createEntities(entities), null, 2 ), }, ], }) ); // 注册创建关系工具 server.tool( 'create_relations', 'Create multiple new relations between entities in the knowledge graph. Relations should be in active voice', { relations: z.array(RelationObject), }, async ({ relations }) => ({ content: [ { type: 'text', text: JSON.stringify( await knowledgeGraphManager.createRelations(relations), null, 2 ), }, ], }) ); // 注册添加观察工具 server.tool( 'add_observations', 'Add new observations to existing entities in the knowledge graph', { observations: z.array(ObservationObject), }, async ({ observations }) => ({ content: [ { type: 'text', text: JSON.stringify( await knowledgeGraphManager.addObservations(observations), null, 2 ), }, ], }) ); // 注册删除实体工具 server.tool( 'delete_entities', 'Delete multiple entities and their associated relations from the knowledge graph', { entityNames: z .array(z.string()) .describe('An array of entity names to delete'), }, async ({ entityNames }) => { await knowledgeGraphManager.deleteEntities(entityNames); return { content: [{ type: 'text', text: 'Entities deleted successfully' }], }; } ); // 注册删除观察工具 server.tool( 'delete_observations', 'Delete specific observations from entities in the knowledge graph', { deletions: z.array( z.object({ entityName: z .string() .describe('The name of the entity containing the observations'), contents: z .array(z.string()) .describe('An array of observations to delete'), }) ), }, async ({ deletions }) => { await knowledgeGraphManager.deleteObservations(deletions); return { content: [{ type: 'text', text: 'Observations deleted successfully' }], }; } ); // 注册删除关系工具 server.tool( 'delete_relations', 'Delete multiple relations from the knowledge graph', { relations: z .array( z.object({ from: z .string() .describe('The name of the entity where the relation starts'), to: z .string() .describe('The name of the entity where the relation ends'), relationType: z.string().describe('The type of the relation'), }) ) .describe('An array of relations to delete'), }, async ({ relations }) => { await knowledgeGraphManager.deleteRelations(relations); return { content: [{ type: 'text', text: 'Relations deleted successfully' }], }; } ); // 注册搜索节点工具 server.tool( 'search_nodes', 'Search for nodes in the knowledge graph based on a query', { query: z .string() .describe( 'The search query to match against entity names, types, and observation content' ), }, async ({ query }) => ({ content: [ { type: 'text', text: JSON.stringify( await knowledgeGraphManager.searchNodes(query), null, 2 ), }, ], }) ); // 注册打开节点工具 server.tool( 'open_nodes', 'Open specific nodes in the knowledge graph by their names', { names: z.array(z.string()).describe('An array of entity names to retrieve'), }, async ({ names }) => ({ content: [ { type: 'text', text: JSON.stringify( await knowledgeGraphManager.openNodes(names), null, 2 ), }, ], }) ); // 主函数 const main = async () => { try { // 初始化知识图谱管理器 await knowledgeGraphManager.initialize(); // 创建传输层 const transport = new StdioServerTransport(); // 连接服务器 await server.connect(transport); // 使用logger代替console.info logger.info('Neo4j Knowledge Graph MCP Server running on stdio'); } catch (error) { // 使用logger代替console.error logger.error('Failed to start server:', extractError(error)); process.exit(1); } }; // 启动服务器 main().catch((error) => { // 使用logger代替console.error logger.error('Error during server startup:', extractError(error)); process.exit(1); });