From 8c58200dcc3a291d80e32becb470b8ba2dcd829a Mon Sep 17 00:00:00 2001 From: samanhappy Date: Sun, 10 Aug 2025 16:46:22 +0800 Subject: [PATCH] feat: add health check endpoint to monitor MCP server status (#264) --- src/controllers/healthController.ts | 33 +++++++++++++++++++++++++++++ src/routes/index.ts | 4 ++++ src/services/mcpService.ts | 6 ++++-- 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/controllers/healthController.ts diff --git a/src/controllers/healthController.ts b/src/controllers/healthController.ts new file mode 100644 index 0000000..6c658f2 --- /dev/null +++ b/src/controllers/healthController.ts @@ -0,0 +1,33 @@ +import { Request, Response } from 'express'; +import { connected } from '../services/mcpService.js'; + +/** + * Health check endpoint + * Returns 200 OK when all MCPs are loaded and connected + * Returns 503 Service Unavailable when MCPs are not ready + */ +export const healthCheck = (_req: Request, res: Response): void => { + try { + const allConnected = connected(); + if (allConnected) { + res.status(200).json({ + status: 'healthy', + message: 'All enabled MCP servers are ready', + timestamp: new Date().toISOString(), + }); + } else { + res.status(503).json({ + status: 'unhealthy', + message: 'Not all enabled MCP servers are ready', + timestamp: new Date().toISOString(), + }); + } + } catch (error) { + console.error('Health check error:', error); + res.status(500).json({ + status: 'error', + message: 'Internal server error during health check', + timestamp: new Date().toISOString(), + }); + } +}; diff --git a/src/routes/index.ts b/src/routes/index.ts index da34ed4..65dc89e 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -59,11 +59,15 @@ import { getAllLogs, clearLogs, streamLogs } from '../controllers/logController. import { getRuntimeConfig, getPublicConfig } from '../controllers/configController.js'; import { callTool } from '../controllers/toolController.js'; import { uploadDxtFile, uploadMiddleware } from '../controllers/dxtController.js'; +import { healthCheck } from '../controllers/healthController.js'; import { auth } from '../middlewares/auth.js'; const router = express.Router(); export const initRoutes = (app: express.Application): void => { + // Health check endpoint (no auth required, accessible at /health) + app.get('/health', healthCheck); + // API routes protected by auth middleware in middlewares/index.ts router.get('/servers', getAllServers); router.get('/settings', getAllSettings); diff --git a/src/services/mcpService.ts b/src/services/mcpService.ts index e23ac25..d5e7ecd 100644 --- a/src/services/mcpService.ts +++ b/src/services/mcpService.ts @@ -114,9 +114,11 @@ const cleanInputSchema = (schema: any): any => { // Store all server information let serverInfos: ServerInfo[] = []; -// Returns true if all servers are connected +// Returns true if all enabled servers are connected export const connected = (): boolean => { - return serverInfos.every((serverInfo) => serverInfo.status === 'connected'); + return serverInfos + .filter((serverInfo) => serverInfo.enabled !== false) + .every((serverInfo) => serverInfo.status === 'connected'); }; // Global cleanup function to close all connections