drawio-mcp-server
Version:
Provides Draw.io services to MCP Clients
117 lines (116 loc) • 4.06 kB
JavaScript
import { z } from "zod";
// Log levels (lower is more severe)
const LogLevelMap = {
emergency: 0,
alert: 1,
critical: 2,
error: 3,
warning: 4,
notice: 5,
info: 6,
debug: 7,
};
export const validLogLevels = Object.keys(LogLevelMap);
// Define the request schema for setLevels
const SetLevelsRequestSchema = z.object({
method: z.literal("logging/setLevels"),
params: z.object({
levels: z.record(z.string(), z.enum(validLogLevels).nullable()),
}),
});
// Define the request schema for setLevel
const SetLevelRequestSchema = z.object({
method: z.literal("logging/setLevel"),
params: z.object({
level: z.enum(validLogLevels),
}),
});
// Per-logger log levels (default is root `"."`)
let logLevels = {
".": LogLevelMap.info, // Start with info level
};
// Helper: Effective log level for a logger
const getEffectiveLogLevel = (loggerName) => {
return loggerName in logLevels
? logLevels[loggerName]
: (logLevels["."] ?? LogLevelMap.info);
};
// Helper: Should we log at this level?
const shouldLog = (level, loggerName) => {
const numericLevel = LogLevelMap[level];
const effectiveLevel = getEffectiveLogLevel(loggerName);
return numericLevel <= effectiveLevel;
};
// Helper: Actually send a log if allowed
const log = (server) => (level, loggerName, data) => {
if (!(level in LogLevelMap)) {
console.error(`Internal Error: Invalid log level used: ${level}`);
return;
}
if (shouldLog(level, loggerName)) {
server.server.sendLoggingMessage({
level,
logger: loggerName,
data,
});
}
};
export function create_logger(server) {
const log3 = log(server);
// 2. Register handler for logging/setLevels (only override requested loggers)
server.server.setRequestHandler(SetLevelsRequestSchema, async (request) => {
const newLevels = request.params.levels;
// Only update logLevels for specified keys; unset any set to null
for (const loggerName in newLevels) {
if (Object.prototype.hasOwnProperty.call(newLevels, loggerName)) {
const levelName = newLevels[loggerName];
if (levelName === null) {
if (loggerName !== ".") {
delete logLevels[loggerName]; // Remove override
log3("debug", "logging", {
message: `Reset log level for logger: ${loggerName}`,
});
}
}
else if (levelName &&
validLogLevels.includes(levelName)) {
logLevels[loggerName] = LogLevelMap[levelName];
log3("debug", "logging", {
message: `Set log level for logger '${loggerName}' to '${levelName}'`,
});
}
else {
log3("warning", "logging", {
message: `Invalid log level '${levelName}' received for logger '${loggerName}'`,
});
}
}
}
return {};
});
// Register handler for logging/setLevel (sets root logger level)
server.server.setRequestHandler(SetLevelRequestSchema, async (request) => {
const log3 = log(server);
const levelName = request.params.level;
if (validLogLevels.includes(levelName)) {
logLevels["."] = LogLevelMap[levelName];
log3("debug", "logging", {
message: `Set root log level to '${levelName}'`,
});
}
else {
log3("warning", "logging", {
message: `Invalid log level '${levelName}' received`,
});
}
return {};
});
return {
log: (level, message, ...data) => {
log3(level, ".", { message, data });
},
debug: (message, ...data) => {
log3("debug", ".", { message, data });
},
};
}