Skip to main content
Glama

atlas-mcp-server

index.ts7.66 kB
#!/usr/bin/env node // Imports MUST be at the top level import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import http from "http"; import { config, environment } from "./config/index.js"; // This loads .env via dotenv.config() import { initializeAndStartServer } from "./mcp/server.js"; import { closeNeo4jConnection } from "./services/neo4j/index.js"; import { logger, McpLogLevel, requestContextService } from "./utils/index.js"; /** * The main MCP server instance, stored if transport is stdio for shutdown. * Or the HTTP server instance if transport is http. * @type {McpServer | http.Server | undefined} */ let serverInstance: McpServer | http.Server | undefined; /** * Gracefully shuts down the main MCP server and related services. * Handles process termination signals (SIGTERM, SIGINT) and critical errors. * * @param signal - The signal or event name that triggered the shutdown (e.g., "SIGTERM", "uncaughtException"). */ const shutdown = async (signal: string) => { // Create a proper RequestContext for shutdown operations const shutdownContext = requestContextService.createRequestContext({ operation: "Shutdown", signal, appName: config.mcpServerName, }); logger.info( `Received ${signal}. Starting graceful shutdown for ${config.mcpServerName}...`, shutdownContext, ); try { if (serverInstance) { if (serverInstance instanceof McpServer) { logger.info("Closing main MCP server (stdio) instance...", shutdownContext); await serverInstance.close(); logger.info( "Main MCP server (stdio) instance closed successfully.", shutdownContext, ); } else if (serverInstance instanceof http.Server) { logger.info("Closing HTTP server instance...", shutdownContext); const currentHttpServer = serverInstance; await new Promise<void>((resolve, reject) => { currentHttpServer.close((err?: Error) => { if (err) { logger.error("Error closing HTTP server", err, shutdownContext); return reject(err); } logger.info("HTTP server instance closed successfully.", shutdownContext); resolve(); }); }); } } else { logger.info( "No global MCP server instance to close (expected for HTTP transport or if not yet initialized).", shutdownContext, ); } logger.info("Closing Neo4j driver connection...", shutdownContext); await closeNeo4jConnection(); logger.info( "Neo4j driver connection closed successfully.", shutdownContext, ); logger.info( `Graceful shutdown for ${config.mcpServerName} completed successfully. Exiting.`, shutdownContext, ); process.exit(0); } catch (error) { // Pass the error object directly as the second argument to logger.error logger.error("Critical error during shutdown", error as Error, { ...shutdownContext, // error message and stack are now part of the Error object passed to logger }); process.exit(1); } }; /** * Initializes and starts the main MCP server. * Sets up logging, request context, initializes the server instance, starts the transport, * and registers signal handlers for graceful shutdown and error handling. */ const start = async () => { // --- Logger Initialization --- const validMcpLogLevels: McpLogLevel[] = [ "debug", "info", "notice", "warning", "error", "crit", "alert", "emerg", ]; const initialLogLevelConfig = config.logLevel; let validatedMcpLogLevel: McpLogLevel = "info"; // Default if (validMcpLogLevels.includes(initialLogLevelConfig as McpLogLevel)) { validatedMcpLogLevel = initialLogLevelConfig as McpLogLevel; } else { // Use console.warn here as logger isn't fully initialized yet, only if TTY if (process.stdout.isTTY) { console.warn( `Invalid MCP_LOG_LEVEL "${initialLogLevelConfig}" provided via config/env. Defaulting to "info".`, ); } } // Initialize the logger with the validated MCP level and wait for it to complete. await logger.initialize(validatedMcpLogLevel); // The logger.initialize() method itself logs its status, so no redundant log here. // --- End Logger Initialization --- const configLoadContext = requestContextService.createRequestContext({ operation: "ConfigLoad", }); logger.debug("Configuration loaded successfully", { ...configLoadContext, configValues: config, }); // Spread context and add specific data const transportType = config.mcpTransportType; const startupContext = requestContextService.createRequestContext({ operation: `AtlasServerStartup_${transportType}`, appName: config.mcpServerName, appVersion: config.mcpServerVersion, environment: environment, }); logger.info( `Starting ${config.mcpServerName} v${config.mcpServerVersion} (Transport: ${transportType})...`, startupContext, ); try { logger.debug( "Initializing and starting MCP server transport...", startupContext, ); const potentialServer = await initializeAndStartServer(); if (transportType === "stdio" && potentialServer instanceof McpServer) { serverInstance = potentialServer; logger.debug( "Stored McpServer instance for stdio transport.", startupContext, ); } else if (transportType === "http" && potentialServer instanceof http.Server) { serverInstance = potentialServer; logger.debug( "Stored HTTP server instance. MCP sessions are per-request.", startupContext, ); } else if (transportType === "http" && !potentialServer) { logger.debug( "HTTP transport started. Server instance not returned by initializeAndStartServer. MCP sessions are per-request.", startupContext, ); } logger.info( `${config.mcpServerName} is running with ${transportType} transport.`, { ...startupContext, startTime: new Date().toISOString(), }, ); // --- Signal and Error Handling Setup --- process.on("SIGTERM", () => shutdown("SIGTERM")); process.on("SIGINT", () => shutdown("SIGINT")); process.on("uncaughtException", async (error) => { const errorContext = { ...startupContext, event: "uncaughtException", error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, }; logger.error( "Uncaught exception detected. Initiating shutdown...", errorContext, ); await shutdown("uncaughtException"); }); process.on("unhandledRejection", async (reason: unknown) => { const rejectionContext = { ...startupContext, event: "unhandledRejection", reason: reason instanceof Error ? reason.message : String(reason), stack: reason instanceof Error ? reason.stack : undefined, }; logger.error( "Unhandled promise rejection detected. Initiating shutdown...", rejectionContext, ); await shutdown("unhandledRejection"); }); } catch (error) { logger.error("Critical error during ATLAS MCP Server startup, exiting.", { ...startupContext, finalErrorContext: "Startup Failure", error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, }); process.exit(1); } }; // --- Async IIFE to allow top-level await --- (async () => { await start(); })();

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/cyanheads/atlas-mcp-server'

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