Skip to main content
Glama
debug.ts4.55 kB
/** * Iris MCP Module: debug * Query in-memory logs from Wonder Logger memory transport */ import { getMemoryLogs, getAllMemoryStoreNames, type ParsedLogEntry, type RawLogEntry, } from "@jenova-marie/wonder-logger"; import { getChildLogger } from "../utils/logger.js"; import { ValidationError } from "../utils/errors.js"; const logger = getChildLogger("action:debug"); export interface DebugInput { /** * Timestamp (milliseconds) to get logs since * If not provided, returns all logs in memory */ logs_since?: number; /** * Memory store name to query * If not provided, queries the default 'iris-mcp' store * Use getAllStores=true to see available store names */ storeName?: string; /** * Return format * - 'raw': Pino JSON objects as-is * - 'parsed': Human-readable format with string levels * @default 'parsed' */ format?: "raw" | "parsed"; /** * Filter by log level(s) * Single level: 'error' * Multiple levels: ['error', 'warn'] * Available levels: trace, debug, info, warn, error, fatal */ level?: string | string[]; /** * If true, returns list of all available memory store names * instead of logs */ getAllStores?: boolean; } export interface DebugOutput { /** Queried logs (if getAllStores=false) */ logs?: Array<RawLogEntry | ParsedLogEntry>; /** Number of logs returned */ logCount: number; /** Memory store name queried */ storeName?: string; /** Timestamp of query */ timestamp: number; /** Query parameters used */ query: { since?: number; format: "raw" | "parsed"; level?: string | string[]; }; /** All available memory store names (if getAllStores=true) */ availableStores?: string[]; } export async function debug(input: DebugInput): Promise<DebugOutput> { logger.debug({ input }, "Debug logs query"); try { // Validate logs_since if provided if (input.logs_since !== undefined) { if (typeof input.logs_since !== "number" || input.logs_since < 0) { throw new ValidationError( "logs_since must be a positive number (timestamp in milliseconds)", ); } // Validate logs_since is not in the future const now = Date.now(); if (input.logs_since > now) { throw new ValidationError( `logs_since (${input.logs_since}) cannot be in the future (now: ${now})`, ); } } // Validate format if provided if (input.format && !["raw", "parsed"].includes(input.format)) { throw new ValidationError('format must be either "raw" or "parsed"'); } // Validate level if provided const validLevels = ["trace", "debug", "info", "warn", "error", "fatal"]; if (input.level) { const levels = Array.isArray(input.level) ? input.level : [input.level]; for (const level of levels) { if (!validLevels.includes(level)) { throw new ValidationError( `Invalid level "${level}". Must be one of: ${validLevels.join(", ")}`, ); } } } // If getAllStores is requested, return store names if (input.getAllStores) { const availableStores = getAllMemoryStoreNames(); logger.info( { storeCount: availableStores.length, stores: availableStores }, "Retrieved memory store names", ); return { logCount: 0, timestamp: Date.now(), query: { format: input.format || "parsed", }, availableStores, }; } // Default to 'iris-mcp' store (matches wonder-logger.yaml service name) const storeName = input.storeName || "iris-mcp"; const format = input.format || "parsed"; // Query logs const logs = getMemoryLogs(storeName, { since: input.logs_since, format, level: input.level as any, // Type assertion - we validated above }); const output: DebugOutput = { logs, logCount: logs.length, storeName, timestamp: Date.now(), query: { since: input.logs_since, format, level: input.level, }, }; logger.info( { storeName, logCount: output.logCount, since: input.logs_since, format, level: input.level, }, "Memory logs retrieved", ); return output; } catch (error) { logger.error( { err: error instanceof Error ? error : new Error(String(error)), input, }, "Failed to query memory logs", ); throw error; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jenova-marie/iris-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server