Skip to main content
Glama

Neo4j MCP Server

index.ts6.88 kB
#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js"; import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js"; import neo4j from 'neo4j-driver'; import dotenv from "dotenv"; import { fileURLToPath } from 'url'; import { dirname, resolve } from 'path'; // Load environment variables const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const envPath = resolve(__dirname, '..', '..', '.env'); dotenv.config({ path: envPath }); // Parse connection string if provided const connectionString = process.env.NEO4J_CONNECTION; if (connectionString) { const [uri, user, password] = connectionString.split(','); process.env.NEO4J_URI = uri; process.env.NEO4J_USER = user; process.env.NEO4J_PASSWORD = password; } // Verify required environment variables const requiredEnvVars = ['NEO4J_URI', 'NEO4J_USER', 'NEO4J_PASSWORD']; const missingVars = requiredEnvVars.filter(envVar => !process.env[envVar]); if (missingVars.length > 0) { console.error(` Error: Missing required environment variables: ${missingVars.join(', ')} You can provide these variables in two ways: 1. Using separate environment variables: NEO4J_URI=<your-uri> NEO4J_USER=<your-user> NEO4J_PASSWORD=<your-password> npx neo4j-mcpserver 2. Using a single connection string: NEO4J_CONNECTION=<uri>,<user>,<password> npx neo4j-mcpserver Example: NEO4J_CONNECTION=neo4j+s://example.databases.neo4j.io,neo4j,your-password npx neo4j-mcpserver `); process.exit(1); } class Neo4jClient { server: Server; driver: neo4j.Driver; constructor() { this.server = new Server({ name: "neo4j-mcp", version: "1.0.2", }, { capabilities: { resources: {}, tools: {}, prompts: {}, }, }); // Initialize Neo4j driver this.driver = neo4j.driver( process.env.NEO4J_URI!, neo4j.auth.basic(process.env.NEO4J_USER!, process.env.NEO4J_PASSWORD!) ); this.setupHandlers(); this.setupErrorHandling(); } setupErrorHandling() { this.server.onerror = (error) => { console.error("[MCP Error]", error); }; process.on('SIGINT', async () => { await this.cleanup(); process.exit(0); }); } async cleanup() { await this.driver.close(); await this.server.close(); } setupHandlers() { this.setupToolHandlers(); } setupToolHandlers() { this.server.setRequestHandler(ListToolsRequestSchema, async () => { const tools = [ { name: "neo4j-query", description: "Execute a Cypher query against the Neo4j database", inputSchema: { type: "object", properties: { query: { type: "string", description: "The Cypher query to execute" }, parameters: { type: "object", description: "Query parameters (optional)", additionalProperties: true } }, required: ["query"] } } ]; return { tools }; }); this.server.setRequestHandler(CallToolRequestSchema, async (request) => { try { let response; const args = request.params.arguments ?? {}; switch (request.params.name) { case "neo4j-query": response = await this.executeQuery( args.query as string, args.parameters as Record<string, any> ); break; default: throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`); } return { content: [{ type: "text", text: formatResults(response) }] }; } catch (error) { if (error instanceof Error) { return { content: [{ type: "text", text: `Neo4j error: ${error.message}` }], isError: true, }; } throw error; } }); } async executeQuery(query: string, parameters: Record<string, any> = {}) { const session = this.driver.session(); try { const result = await session.run(query, parameters); return result.records; } finally { await session.close(); } } async run() { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error("Neo4j MCP server running on stdio"); } } function formatResults(records: neo4j.Record[]) { if (!records || records.length === 0) { return "No results found."; } const output: string[] = ["Results:"]; records.forEach((record, index) => { output.push(`\nRecord ${index + 1}:`); record.keys.forEach(key => { const value = record.get(key); output.push(`${String(key)}: ${formatValue(value)}`); }); }); return output.join('\n'); } function formatValue(value: any): string { if (value === null || value === undefined) { return 'null'; } if (neo4j.isNode(value)) { return `Node(id=${value.identity}, labels=[${value.labels.join(', ')}], properties=${JSON.stringify(value.properties)})`; } if (neo4j.isRelationship(value)) { return `Relationship(id=${value.identity}, type=${value.type}, properties=${JSON.stringify(value.properties)})`; } if (neo4j.isPath(value)) { return `Path(length=${value.segments.length}, nodes=${value.segments.length + 1})`; } if (Array.isArray(value)) { return `[${value.map(formatValue).join(', ')}]`; } if (typeof value === 'object') { return JSON.stringify(value); } return String(value); } const server = new Neo4jClient(); server.run().catch(console.error);

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Tobarrientos2/neo4j-mcpserver'

If you have feedback or need assistance with the MCP directory API, please join our Discord server