atlas-mcp-server
Version:
ATLAS (Adaptive Task & Logic Automation System): An MCP server enabling LLM agents to manage projects, tasks, and knowledge via a Neo4j-backed, three-tier architecture. Facilitates complex workflow automation and project management through LLM Agents.
188 lines (187 loc) • 9.38 kB
JavaScript
/**
* Main entry point for the MCP (Model Context Protocol) server.
* This file orchestrates the server's lifecycle:
* 1. Initializes the core McpServer instance with its identity and capabilities.
* 2. Registers available resources and tools, making them discoverable and usable by clients.
* 3. Selects and starts the appropriate communication transport (stdio or Streamable HTTP)
* based on configuration.
* 4. Handles top-level error management during startup.
*
* MCP Specification References:
* - Lifecycle: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-03-26/basic/lifecycle.mdx
* - Overview (Capabilities): https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-03-26/basic/index.mdx
* - Transports: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-03-26/basic/transports.mdx
*/
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
// Import validated configuration and environment details.
import { config, environment } from "../config/index.js";
// Import core utilities: ErrorHandler, logger, requestContextService.
import { initializeNeo4jSchema } from "../services/neo4j/index.js"; // Corrected path
import { ErrorHandler, logger, requestContextService } from "../utils/index.js"; // Corrected path
// Import tool registrations
import { registerAtlasDatabaseCleanTool } from "./tools/atlas_database_clean/index.js";
import { registerAtlasDeepResearchTool } from "./tools/atlas_deep_research/index.js";
import { registerAtlasKnowledgeAddTool } from "./tools/atlas_knowledge_add/index.js";
import { registerAtlasKnowledgeDeleteTool } from "./tools/atlas_knowledge_delete/index.js";
import { registerAtlasKnowledgeListTool } from "./tools/atlas_knowledge_list/index.js";
import { registerAtlasProjectCreateTool } from "./tools/atlas_project_create/index.js";
import { registerAtlasProjectDeleteTool } from "./tools/atlas_project_delete/index.js";
import { registerAtlasProjectListTool } from "./tools/atlas_project_list/index.js";
import { registerAtlasProjectUpdateTool } from "./tools/atlas_project_update/index.js";
import { registerAtlasTaskCreateTool } from "./tools/atlas_task_create/index.js";
import { registerAtlasTaskDeleteTool } from "./tools/atlas_task_delete/index.js";
import { registerAtlasTaskListTool } from "./tools/atlas_task_list/index.js";
import { registerAtlasTaskUpdateTool } from "./tools/atlas_task_update/index.js";
import { registerAtlasUnifiedSearchTool } from "./tools/atlas_unified_search/index.js";
// Import resource registrations
import { registerMcpResources } from "./resources/index.js"; // Adjusted path
// Import transport setup functions.
import { startHttpTransport } from "./transports/httpTransport.js";
import { connectStdioTransport } from "./transports/stdioTransport.js";
/**
* Creates and configures a new instance of the McpServer.
*
* This function is central to defining the server's identity and functionality
* as presented to connecting clients during the MCP initialization phase.
*/
async function createMcpServerInstance() {
const context = requestContextService.createRequestContext({
operation: "createMcpServerInstance",
});
logger.info("Initializing MCP server instance for ATLAS MCP Server", context);
// Configure the request context service (used for correlating logs/errors).
requestContextService.configure({
appName: config.mcpServerName,
appVersion: config.mcpServerVersion,
environment,
});
// Initialize Neo4j database and services
logger.info("Initializing Neo4j schema...", context);
await initializeNeo4jSchema();
logger.info("Neo4j schema initialized successfully", context);
// Instantiate the core McpServer using the SDK.
logger.debug("Instantiating McpServer with capabilities", {
...context,
serverInfo: {
name: config.mcpServerName,
version: config.mcpServerVersion,
},
capabilities: {
logging: {}, // Indicates support for logging control and notifications
resources: { listChanged: true }, // Supports dynamic resource lists
tools: {
listChanged: true, // Supports dynamic tool lists
requestContext: true, // Enable request context for all tools
rateLimit: {
// Default rate limit settings for tools
windowMs: config.security.rateLimitWindowMs || 60 * 1000, // Use config or default
maxRequests: config.security.rateLimitMaxRequests || 100, // Use config or default
},
permissions: {
// Permissions requirements for tools
required: config.security.authRequired,
},
},
},
});
const server = new McpServer({ name: config.mcpServerName, version: config.mcpServerVersion }, {
capabilities: {
logging: {},
resources: { listChanged: true },
tools: {
listChanged: true,
requestContext: true,
rateLimit: {
windowMs: config.security.rateLimitWindowMs || 60 * 1000,
maxRequests: config.security.rateLimitMaxRequests || 100,
},
permissions: {
required: config.security.authRequired,
},
},
},
});
try {
logger.debug("Registering ATLAS resources and tools...", context);
// Register Atlas resources
await registerMcpResources(server);
// Register Atlas tools
await registerAtlasProjectCreateTool(server);
await registerAtlasProjectListTool(server);
await registerAtlasProjectUpdateTool(server);
await registerAtlasProjectDeleteTool(server);
await registerAtlasTaskCreateTool(server);
await registerAtlasTaskDeleteTool(server);
await registerAtlasTaskListTool(server);
await registerAtlasTaskUpdateTool(server);
await registerAtlasDatabaseCleanTool(server);
await registerAtlasKnowledgeAddTool(server);
await registerAtlasKnowledgeDeleteTool(server);
await registerAtlasKnowledgeListTool(server);
await registerAtlasUnifiedSearchTool(server);
await registerAtlasDeepResearchTool(server);
logger.info("ATLAS Resources and tools registered successfully", context);
}
catch (err) {
logger.error("Failed to register ATLAS resources/tools", {
...context,
error: err instanceof Error ? err.message : String(err),
stack: err instanceof Error ? err.stack : undefined,
});
throw err;
}
return server;
}
/**
* Selects, sets up, and starts the appropriate MCP transport layer based on configuration.
*/
async function startTransport() {
const transportType = config.mcpTransportType;
const parentContext = requestContextService.createRequestContext({
operation: "startTransport",
transport: transportType,
});
logger.info(`Starting transport for ATLAS MCP Server: ${transportType}`, parentContext);
if (transportType === "http") {
logger.debug("Delegating to startHttpTransport for ATLAS MCP Server...", parentContext);
const httpServerInstance = await startHttpTransport(createMcpServerInstance, parentContext);
return httpServerInstance;
}
if (transportType === "stdio") {
logger.debug("Creating single McpServer instance for stdio transport (ATLAS MCP Server)...", parentContext);
const server = await createMcpServerInstance();
logger.debug("Delegating to connectStdioTransport for ATLAS MCP Server...", parentContext);
await connectStdioTransport(server, parentContext);
return server;
}
logger.fatal(`Unsupported transport type configured for ATLAS MCP Server: ${transportType}`, parentContext);
throw new Error(`Unsupported transport type: ${transportType}. Must be 'stdio' or 'http'.`);
}
/**
* Main application entry point. Initializes and starts the MCP server.
*/
export async function initializeAndStartServer() {
const context = requestContextService.createRequestContext({
operation: "initializeAndStartServer",
});
logger.info("ATLAS MCP Server initialization sequence started.", context);
try {
const result = await startTransport();
logger.info("ATLAS MCP Server initialization sequence completed successfully.", context);
return result;
}
catch (err) {
logger.fatal("Critical error during ATLAS MCP server initialization.", {
...context,
error: err instanceof Error ? err.message : String(err),
stack: err instanceof Error ? err.stack : undefined,
});
ErrorHandler.handleError(err, {
operation: "initializeAndStartServer", // More specific operation
context: context, // Pass the existing context
critical: true, // This is a critical failure
});
logger.info("Exiting process due to critical initialization error (ATLAS MCP Server).", context);
process.exit(1);
}
}