@dollhousemcp/mcp-server
Version:
DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.
51 lines • 7.84 kB
JavaScript
/**
* Health API route for the unified dev console.
*
* GET /api/health — Aggregated health: uptime, sink stats, SSE client counts
*/
import { Router } from 'express';
import { homedir } from 'node:os';
import { getPermissionHookAuditSummary, summarizePermissionHookHealth, } from '../../utils/permissionHooks.js';
export function createHealthRoutes(options) {
const router = Router();
const startTime = Date.now();
router.get('/health', async (_req, res) => {
const health = {
status: 'ok',
uptime: Math.floor((Date.now() - startTime) / 1000),
logs: {
stats: options.memorySink.getStats(),
sseClients: options.logClientCount(),
},
};
if (options.metricsSink) {
health['metrics'] = {
stats: options.metricsSink.getStats(),
sseClients: options.metricsClientCount(),
};
}
try {
const permissionHookAudit = await (options.getPermissionHookAuditSummaryFn ?? getPermissionHookAuditSummary)(options.permissionHooksHomeDir ?? homedir());
health['permissionHooks'] = {
...summarizePermissionHookHealth(permissionHookAudit),
installedHosts: permissionHookAudit.installedHosts,
currentHosts: permissionHookAudit.currentHosts,
needsRepairHosts: permissionHookAudit.needsRepairHosts,
diagnosticsPath: permissionHookAudit.diagnosticsPath,
lastDiagnostic: permissionHookAudit.lastDiagnostic,
lastStartupRepair: permissionHookAudit.lastStartupRepair,
};
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
health['status'] = 'degraded';
health['permissionHooks'] = {
status: 'error',
message: `Failed to audit permission hook status: ${message}`,
};
}
res.json(health);
});
return router;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhbHRoUm91dGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3dlYi9yb3V0ZXMvaGVhbHRoUm91dGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFFSCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBRWpDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFHbEMsT0FBTyxFQUNMLDZCQUE2QixFQUM3Qiw2QkFBNkIsR0FFOUIsTUFBTSxnQ0FBZ0MsQ0FBQztBQVd4QyxNQUFNLFVBQVUsa0JBQWtCLENBQUMsT0FBNEI7SUFDN0QsTUFBTSxNQUFNLEdBQUcsTUFBTSxFQUFFLENBQUM7SUFDeEIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBRTdCLE1BQU0sQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxJQUFhLEVBQUUsR0FBYSxFQUFFLEVBQUU7UUFDM0QsTUFBTSxNQUFNLEdBQTRCO1lBQ3RDLE1BQU0sRUFBRSxJQUFJO1lBQ1osTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUyxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQ25ELElBQUksRUFBRTtnQkFDSixLQUFLLEVBQUUsT0FBTyxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUU7Z0JBQ3BDLFVBQVUsRUFBRSxPQUFPLENBQUMsY0FBYyxFQUFFO2FBQ3JDO1NBQ0YsQ0FBQztRQUVGLElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3hCLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRztnQkFDbEIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFO2dCQUNyQyxVQUFVLEVBQUUsT0FBTyxDQUFDLGtCQUFrQixFQUFFO2FBQ3pDLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxtQkFBbUIsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLCtCQUErQixJQUFJLDZCQUE2QixDQUFDLENBQzFHLE9BQU8sQ0FBQyxzQkFBc0IsSUFBSSxPQUFPLEVBQUUsQ0FDNUMsQ0FBQztZQUNGLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHO2dCQUMxQixHQUFHLDZCQUE2QixDQUFDLG1CQUFtQixDQUFDO2dCQUNyRCxjQUFjLEVBQUUsbUJBQW1CLENBQUMsY0FBYztnQkFDbEQsWUFBWSxFQUFFLG1CQUFtQixDQUFDLFlBQVk7Z0JBQzlDLGdCQUFnQixFQUFFLG1CQUFtQixDQUFDLGdCQUFnQjtnQkFDdEQsZUFBZSxFQUFFLG1CQUFtQixDQUFDLGVBQWU7Z0JBQ3BELGNBQWMsRUFBRSxtQkFBbUIsQ0FBQyxjQUFjO2dCQUNsRCxpQkFBaUIsRUFBRSxtQkFBbUIsQ0FBQyxpQkFBaUI7YUFDekQsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxPQUFPLEdBQUcsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3ZFLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxVQUFVLENBQUM7WUFDOUIsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEdBQUc7Z0JBQzFCLE1BQU0sRUFBRSxPQUFPO2dCQUNmLE9BQU8sRUFBRSwyQ0FBMkMsT0FBTyxFQUFFO2FBQzlELENBQUM7UUFDSixDQUFDO1FBRUQsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNuQixDQUFDLENBQUMsQ0FBQztJQUVILE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEhlYWx0aCBBUEkgcm91dGUgZm9yIHRoZSB1bmlmaWVkIGRldiBjb25zb2xlLlxuICpcbiAqIEdFVCAvYXBpL2hlYWx0aCDigJQgQWdncmVnYXRlZCBoZWFsdGg6IHVwdGltZSwgc2luayBzdGF0cywgU1NFIGNsaWVudCBjb3VudHNcbiAqL1xuXG5pbXBvcnQgeyBSb3V0ZXIgfSBmcm9tICdleHByZXNzJztcbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IGhvbWVkaXIgfSBmcm9tICdub2RlOm9zJztcbmltcG9ydCB0eXBlIHsgTWVtb3J5TG9nU2luayB9IGZyb20gJy4uLy4uL2xvZ2dpbmcvc2lua3MvTWVtb3J5TG9nU2luay5qcyc7XG5pbXBvcnQgdHlwZSB7IE1lbW9yeU1ldHJpY3NTaW5rIH0gZnJvbSAnLi4vLi4vbWV0cmljcy9zaW5rcy9NZW1vcnlNZXRyaWNzU2luay5qcyc7XG5pbXBvcnQge1xuICBnZXRQZXJtaXNzaW9uSG9va0F1ZGl0U3VtbWFyeSxcbiAgc3VtbWFyaXplUGVybWlzc2lvbkhvb2tIZWFsdGgsXG4gIHR5cGUgUGVybWlzc2lvbkhvb2tBdWRpdFN1bW1hcnksXG59IGZyb20gJy4uLy4uL3V0aWxzL3Blcm1pc3Npb25Ib29rcy5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSGVhbHRoUm91dGVzT3B0aW9ucyB7XG4gIG1lbW9yeVNpbms6IE1lbW9yeUxvZ1Npbms7XG4gIG1ldHJpY3NTaW5rPzogTWVtb3J5TWV0cmljc1Npbms7XG4gIGxvZ0NsaWVudENvdW50OiAoKSA9PiBudW1iZXI7XG4gIG1ldHJpY3NDbGllbnRDb3VudDogKCkgPT4gbnVtYmVyO1xuICBwZXJtaXNzaW9uSG9va3NIb21lRGlyPzogc3RyaW5nO1xuICBnZXRQZXJtaXNzaW9uSG9va0F1ZGl0U3VtbWFyeUZuPzogKGhvbWVEaXI6IHN0cmluZykgPT4gUHJvbWlzZTxQZXJtaXNzaW9uSG9va0F1ZGl0U3VtbWFyeT47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVIZWFsdGhSb3V0ZXMob3B0aW9uczogSGVhbHRoUm91dGVzT3B0aW9ucyk6IFJvdXRlciB7XG4gIGNvbnN0IHJvdXRlciA9IFJvdXRlcigpO1xuICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gIHJvdXRlci5nZXQoJy9oZWFsdGgnLCBhc3luYyAoX3JlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgIGNvbnN0IGhlYWx0aDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7XG4gICAgICBzdGF0dXM6ICdvaycsXG4gICAgICB1cHRpbWU6IE1hdGguZmxvb3IoKERhdGUubm93KCkgLSBzdGFydFRpbWUpIC8gMTAwMCksXG4gICAgICBsb2dzOiB7XG4gICAgICAgIHN0YXRzOiBvcHRpb25zLm1lbW9yeVNpbmsuZ2V0U3RhdHMoKSxcbiAgICAgICAgc3NlQ2xpZW50czogb3B0aW9ucy5sb2dDbGllbnRDb3VudCgpLFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgaWYgKG9wdGlvbnMubWV0cmljc1NpbmspIHtcbiAgICAgIGhlYWx0aFsnbWV0cmljcyddID0ge1xuICAgICAgICBzdGF0czogb3B0aW9ucy5tZXRyaWNzU2luay5nZXRTdGF0cygpLFxuICAgICAgICBzc2VDbGllbnRzOiBvcHRpb25zLm1ldHJpY3NDbGllbnRDb3VudCgpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGVybWlzc2lvbkhvb2tBdWRpdCA9IGF3YWl0IChvcHRpb25zLmdldFBlcm1pc3Npb25Ib29rQXVkaXRTdW1tYXJ5Rm4gPz8gZ2V0UGVybWlzc2lvbkhvb2tBdWRpdFN1bW1hcnkpKFxuICAgICAgICBvcHRpb25zLnBlcm1pc3Npb25Ib29rc0hvbWVEaXIgPz8gaG9tZWRpcigpLFxuICAgICAgKTtcbiAgICAgIGhlYWx0aFsncGVybWlzc2lvbkhvb2tzJ10gPSB7XG4gICAgICAgIC4uLnN1bW1hcml6ZVBlcm1pc3Npb25Ib29rSGVhbHRoKHBlcm1pc3Npb25Ib29rQXVkaXQpLFxuICAgICAgICBpbnN0YWxsZWRIb3N0czogcGVybWlzc2lvbkhvb2tBdWRpdC5pbnN0YWxsZWRIb3N0cyxcbiAgICAgICAgY3VycmVudEhvc3RzOiBwZXJtaXNzaW9uSG9va0F1ZGl0LmN1cnJlbnRIb3N0cyxcbiAgICAgICAgbmVlZHNSZXBhaXJIb3N0czogcGVybWlzc2lvbkhvb2tBdWRpdC5uZWVkc1JlcGFpckhvc3RzLFxuICAgICAgICBkaWFnbm9zdGljc1BhdGg6IHBlcm1pc3Npb25Ib29rQXVkaXQuZGlhZ25vc3RpY3NQYXRoLFxuICAgICAgICBsYXN0RGlhZ25vc3RpYzogcGVybWlzc2lvbkhvb2tBdWRpdC5sYXN0RGlhZ25vc3RpYyxcbiAgICAgICAgbGFzdFN0YXJ0dXBSZXBhaXI6IHBlcm1pc3Npb25Ib29rQXVkaXQubGFzdFN0YXJ0dXBSZXBhaXIsXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICAgICAgaGVhbHRoWydzdGF0dXMnXSA9ICdkZWdyYWRlZCc7XG4gICAgICBoZWFsdGhbJ3Blcm1pc3Npb25Ib29rcyddID0ge1xuICAgICAgICBzdGF0dXM6ICdlcnJvcicsXG4gICAgICAgIG1lc3NhZ2U6IGBGYWlsZWQgdG8gYXVkaXQgcGVybWlzc2lvbiBob29rIHN0YXR1czogJHttZXNzYWdlfWAsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJlcy5qc29uKGhlYWx0aCk7XG4gIH0pO1xuXG4gIHJldHVybiByb3V0ZXI7XG59XG4iXX0=