@jeelidev/personal-neo4j-memory-server
Version:
Personal MCP Memory Server with Neo4j backend - Enhanced Cloudflare Access support with robust tunnel management and remove functionality
3 lines (2 loc) • 5.03 kB
JavaScript
import{a as M,b as v}from"../chunk-VKCKTY3Q.mjs";import{c as m,d as y,e as u,i as f}from"../chunk-ULWSXDW6.mjs";import{config as H}from"dotenv";import w from"express";import{randomUUID as P}from"crypto";import{McpServer as S}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as b}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as T}from"@modelcontextprotocol/sdk/types.js";var l=class{async getHandler(){if(!this.handler){let{McpDatabaseHandler:e}=await import("../mcp-handlers-JEQJTYN6.mjs");this.handler=new e}return this.handler}async handleDatabaseSwitch(e){return(await this.getHandler()).handleDatabaseSwitch(e)}},d=class{async getHandler(){if(!this.handler){let[{McpMemoryHandler:e,McpRelationHandler:r},{UnifiedMemoryStoreHandler:t}]=await Promise.all([import("../mcp-handlers-JEQJTYN6.mjs"),import("../unified-handlers-U467ZHFA.mjs")]),a=new e,s=new r;this.handler=new t(a,s)}return this.handler}async handleMemoryStore(e){return(await this.getHandler()).handleMemoryStore(e)}},c=class{async getHandler(){if(!this.handler){let[{McpMemoryHandler:e},{UnifiedMemoryFindHandler:r}]=await Promise.all([import("../mcp-handlers-JEQJTYN6.mjs"),import("../unified-handlers-U467ZHFA.mjs")]),t=new e;this.handler=new r(t)}return this.handler}async handleMemoryFind(e){return(await this.getHandler()).handleMemoryFind(e)}},p=class{async getHandler(){if(!this.handler){let[{McpMemoryHandler:e,McpObservationHandler:r,McpRelationHandler:t},{UnifiedMemoryModifyHandler:a}]=await Promise.all([import("../mcp-handlers-JEQJTYN6.mjs"),import("../unified-handlers-U467ZHFA.mjs")]),s=new e,n=new r,o=new t;this.handler=new a(s,n,o)}return this.handler}async handleMemoryModify(e){return(await this.getHandler()).handleMemoryModify(e)}};async function g(){return{databaseHandler:new l,unifiedStoreHandler:new d,unifiedFindHandler:new c,unifiedModifyHandler:new p}}H();function E(){let i=new S({name:"neo4j-memory-server",version:"3.2.0"});M(i);let e=null;return v(i,async()=>(e||(e=(async()=>{let t=await g();if(process.env.NEO4J_URI||process.env.NEO4J_USERNAME){let{DIContainer:s}=await import("../di-container-EXB4V2I7.mjs");await s.getInstance().initializeDatabase()}return t})()),e)),i}var h=class{constructor(){this.transports=new Map;this.app=w(),this.mcpServer=E(),this.setupMiddleware(),this.setupRoutes()}setupMiddleware(){this.app.use(w.json({limit:"10mb"})),this.app.use((e,r,t)=>{if(r.setHeader("Access-Control-Allow-Origin","*"),r.setHeader("Access-Control-Allow-Methods","GET, POST, DELETE, OPTIONS"),r.setHeader("Access-Control-Allow-Headers","Content-Type, Accept, Mcp-Session-Id"),r.setHeader("Access-Control-Expose-Headers","Mcp-Session-Id"),e.method==="OPTIONS"){r.status(200).send();return}t()})}setupRoutes(){this.app.get("/health",(e,r)=>{r.json({status:"healthy",sessions:this.transports.size,transport:"streamable-http"})}),this.app.all("/mcp",async(e,r)=>{try{await this.handleMCPRequest(e,r)}catch(t){let a=-32603,s="Internal server error",n;if(f(t)){let o=t;o instanceof m?(a=-32602,s=o.message,n=o.data):o instanceof y?(a=-32603,s="Database operation failed",n={category:"database"}):o instanceof u&&(a=-32603,s="Service unavailable",n={category:"service",service:o.data?.service})}r.status(500).json({jsonrpc:"2.0",error:{code:a,message:s,...n&&{data:n}},id:null})}})}async handleMCPRequest(e,r){let t=e.headers["mcp-session-id"];if(e.method==="DELETE"){if(t&&this.transports.has(t)){let a=this.transports.get(t);try{await a.close?.()}catch{}this.transports.delete(t),r.status(204).send()}else r.status(404).json({error:"Session not found"});return}if(e.method==="GET"){r.json({status:"MCP endpoint ready",protocol:"streamable-http",endpoints:{health:"/health",mcp:"/mcp"},message:"Use POST for MCP communication"});return}if(e.method==="POST"){let a,s;try{if(t&&this.transports.has(t))a=this.transports.get(t),s=t;else if(T(e.body)){s=P(),a=new b({sessionIdGenerator:()=>s}),this.transports.set(s,a);try{await this.mcpServer.connect(a)}catch(n){this.transports.delete(s);let o=n instanceof Error?n.message:String(n);r.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:"MCP server connection failed",data:{reason:o}},id:e.body?.id||null});return}}else{r.status(400).json({jsonrpc:"2.0",error:{code:-32600,message:"Missing session ID"},id:e.body?.id||null});return}s&&r.setHeader("Mcp-Session-Id",s),await a.handleRequest(e,r,e.body)}catch(n){let o=n instanceof Error?n.message:String(n);r.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:"Request handling failed",data:{reason:o}},id:e.body?.id||null})}}}async start(e=3e3){return new Promise(r=>{this.app.listen(e,"0.0.0.0",()=>{r()})})}},C=async()=>{let i=new h,e=parseInt(process.env.PORT||process.env.HTTP_PORT||"3000");try{await i.start(e);let r=()=>process.exit(0);process.on("SIGINT",r),process.on("SIGTERM",r)}catch{process.exit(1)}};import.meta.url===`file://${process.argv[1]}`&&C().catch(()=>{process.exit(1)});export{h as SimpleHTTPServer};