Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | /**
* Main entry point for the DevContext server
*
* This module initializes the server, performs validation checks,
* connects to the database, and sets up the MCP server.
*/
import { McpServer } from "@modelcontextprotocol/sdk";
import { z } from "zod";
import config from "./config.js";
import logger from "./utils/logger.js";
import { initializeDbClient } from "./db/client.js";
import { initializeDatabaseSchema } from "./db/queries.js";
import { pingServerHandler } from "./mcp-handlers/index.js";
import GitMonitorService from "./services/git.service.js";
import initialScanService from "./services/initialScan.service.js";
/**
* Start the server
*/
async function startServer() {
try {
// Log server startup
logger.info("DevContext server starting...");
// Validate that PROJECT_PATH is a Git repository
const gitValidation = await config.validateGitRepository();
if (!gitValidation.isValid) {
// This is a critical error - log and exit with non-zero status code
logger.error(
"Critical error: PROJECT_PATH is not a valid Git repository",
{
projectPath: config.PROJECT_PATH,
error: gitValidation.error?.message || "Unknown error",
}
);
// Exit the process with a non-zero status code
process.exit(1);
}
// If we get here, the Git repository is valid
logger.info("Git repository validation completed successfully");
// Initialize database client
const dbClient = initializeDbClient();
// Verify database connection with a simple query
try {
logger.info("Verifying TursoDB connection...");
await dbClient.execute("SELECT 1");
logger.info("TursoDB connection verified successfully");
} catch (dbError) {
// This is a critical error - log and exit with non-zero status code
logger.error("Critical error: Failed to connect to TursoDB", {
error: dbError.message,
stack: dbError.stack,
databaseUrl: config.TURSO_DATABASE_URL ? "(set)" : "(not set)",
authToken: config.TURSO_AUTH_TOKEN
? "(auth token provided)"
: "(no auth token)",
});
// Exit the process with a non-zero status code
process.exit(1);
}
// Initialize database schema
try {
logger.info("Initializing database schema...");
await initializeDatabaseSchema(dbClient);
logger.info("Database schema initialization completed successfully");
} catch (schemaError) {
// This is a critical error - log and exit with non-zero status code
logger.error("Critical error: Failed to initialize database schema", {
error: schemaError.message,
stack: schemaError.stack,
});
// Exit the process with a non-zero status code
process.exit(1);
}
// Perform initial codebase scan
try {
logger.info("Initiating initial codebase scan...");
const scanResult = await initialScanService.performInitialScan();
if (scanResult.status === "success") {
logger.info("Initial codebase scan completed successfully", {
filesScanned: scanResult.filesScanned,
filesProcessed: scanResult.filesProcessed,
});
} else if (scanResult.status === "skipped") {
logger.info("Initial codebase scan skipped", {
reason: scanResult.reason,
});
} else {
logger.warn("Initial codebase scan completed with status", {
status: scanResult.status,
error: scanResult.error,
});
}
} catch (scanError) {
// Log error but don't exit - allow the system to continue
logger.error("Error during initial codebase scan", {
error: scanError.message,
stack: scanError.stack,
});
logger.warn("Continuing server startup despite initial scan failure");
}
// Initialize and start Git monitoring service
try {
logger.info("Initializing Git monitoring service...");
const gitMonitorService = new GitMonitorService(dbClient);
// Initialize the service
await gitMonitorService.initialize();
// Start the monitoring process
await gitMonitorService.startMonitoring();
logger.info("Git monitoring service started successfully");
} catch (gitMonitorError) {
// Log error but don't exit - this is not a critical service
logger.error("Error initializing Git monitoring service", {
error: gitMonitorError.message,
stack: gitMonitorError.stack,
});
logger.warn(
"Continuing server startup despite Git monitoring service failure"
);
}
// Initialize MCP server
try {
logger.info("Initializing MCP server...");
// Create the MCP server instance
const mcpServer = new McpServer({
name: "DevContext MCP Server",
version: config.VERSION || "1.0.0",
logger: logger,
});
// Register the ping_server tool using the correct method
mcpServer.tool(
"ping_server",
{}, // Empty object as we don't need input parameters
pingServerHandler
);
// Start the MCP server
await mcpServer.listen();
logger.info("MCP server initialized and listening for requests");
logger.info("DevContext server started successfully");
} catch (mcpError) {
// This is a critical error - log and exit with non-zero status code
logger.error("Critical error: Failed to initialize MCP server", {
error: mcpError.message,
stack: mcpError.stack,
});
// Exit the process with a non-zero status code
process.exit(1);
}
} catch (error) {
// Handle any unexpected errors during server startup
logger.error("Unexpected error during server startup", {
error: error.message,
stack: error.stack,
});
// Exit with a non-zero status code on critical errors
process.exit(1);
}
}
// Handle uncaught exceptions
process.on("uncaughtException", (error) => {
logger.error("Uncaught exception", {
error: error.message,
stack: error.stack,
});
process.exit(1);
});
// Handle unhandled promise rejections
process.on("unhandledRejection", (reason, promise) => {
logger.error("Unhandled promise rejection", {
reason: reason instanceof Error ? reason.message : String(reason),
stack: reason instanceof Error ? reason.stack : undefined,
});
process.exit(1);
});
// Start the server
startServer();
|