Skip to main content
Glama

server_metrics

Monitor server performance metrics and health status to ensure optimal operation of media management services.

Instructions

Get server performance metrics and health status

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
detailedNo
serviceNo

Implementation Reference

  • The primary handler logic for the 'server_metrics' tool. It handles both service-specific metrics and global server metrics, including health status and optional detailed information using the metricsCollector.
    case "server_metrics": { { if (input.service) { const serviceMetrics = metricsCollector.getServiceMetrics( input.service, ); if (!serviceMetrics) { throw new McpError( ErrorCode.InvalidParams, `No metrics found for service: ${input.service}`, ); } return { ok: true, data: { service: input.service, ...serviceMetrics, health: metricsCollector.getHealthStatus(), }, }; } const summary = metricsCollector.getSummary(); const health = metricsCollector.getHealthStatus(); return { ok: true, data: { ...summary, health, ...(input.detailed && { recentOperations: metricsCollector.getRecentOperations(10), exportedMetrics: metricsCollector.exportMetrics(), }), }, }; } }
  • src/index.ts:171-182 (registration)
    Registration of the 'server_metrics' tool in the MCP tools list, defining its name, description, and input schema.
    { name: "server_metrics", description: "Get server performance metrics and health status", inputSchema: { type: "object", properties: { service: { type: "string" }, detailed: { type: "boolean" }, }, required: [], }, },
  • The MetricsCollector class and its instance 'metricsCollector' provide all the underlying metrics collection, summary, service metrics, health status, and export functionality used by the server_metrics handler.
    class MetricsCollector { private metrics: GlobalMetrics = { startTime: Date.now(), totalRequests: 0, services: {}, recentEntries: [], }; private readonly maxRecentEntries = 100; /** * Record a service operation execution */ recordOperation( service: string, operation: string, duration: number, success: boolean, error?: string, ): void { const entry: MetricEntry = { timestamp: Date.now(), service, operation, duration, success, error, }; // Add to recent entries (with rotation) this.metrics.recentEntries.push(entry); if (this.metrics.recentEntries.length > this.maxRecentEntries) { this.metrics.recentEntries.shift(); } // Update global counters this.metrics.totalRequests++; // Initialize service metrics if needed if (!this.metrics.services[service]) { this.metrics.services[service] = { totalRequests: 0, successfulRequests: 0, failedRequests: 0, averageResponseTime: 0, lastRequest: 0, operations: {}, }; } const serviceMetrics = this.metrics.services[service]; // Update service-level metrics serviceMetrics.totalRequests++; serviceMetrics.lastRequest = entry.timestamp; if (success) { serviceMetrics.successfulRequests++; } else { serviceMetrics.failedRequests++; } // Update average response time (rolling average) serviceMetrics.averageResponseTime = (serviceMetrics.averageResponseTime * (serviceMetrics.totalRequests - 1) + duration) / serviceMetrics.totalRequests; // Initialize operation metrics if needed if (!serviceMetrics.operations[operation]) { serviceMetrics.operations[operation] = { count: 0, totalDuration: 0, failures: 0, }; } const opMetrics = serviceMetrics.operations[operation]; opMetrics.count++; opMetrics.totalDuration += duration; if (!success) { opMetrics.failures++; } debug("metrics.recorded", { service, operation, duration, success, totalRequests: this.metrics.totalRequests, }); } /** * Get summary metrics for all services */ getSummary(): { uptime: number; totalRequests: number; successRate: number; averageResponseTime: number; serviceCount: number; topErrors: Array<{ error: string; count: number }>; } { const uptime = Date.now() - this.metrics.startTime; const successfulRequests = Object.values(this.metrics.services).reduce( (sum, s) => sum + s.successfulRequests, 0, ); const totalRequests = this.metrics.totalRequests; const successRate = totalRequests > 0 ? (successfulRequests / totalRequests) * 100 : 100; // Calculate overall average response time const totalDuration = Object.values(this.metrics.services).reduce( (sum, s) => sum + s.averageResponseTime * s.totalRequests, 0, ); const averageResponseTime = totalRequests > 0 ? totalDuration / totalRequests : 0; // Count error frequencies const errorCounts = new Map<string, number>(); for (const e of this.metrics.recentEntries) { if (!e.success && e.error) { const error = e.error; errorCounts.set(error, (errorCounts.get(error) || 0) + 1); } } const topErrors = Array.from(errorCounts.entries()) .map(([error, count]) => ({ error, count })) .sort((a, b) => b.count - a.count) .slice(0, 5); return { uptime, totalRequests, successRate, averageResponseTime, serviceCount: Object.keys(this.metrics.services).length, topErrors, }; } /** * Get detailed metrics for a specific service */ getServiceMetrics(serviceName: string): ServiceMetrics | null { return this.metrics.services[serviceName] || null; } /** * Get recent operation history */ getRecentOperations(limit = 20): MetricEntry[] { return this.metrics.recentEntries .slice(-limit) .sort((a, b) => b.timestamp - a.timestamp); } /** * Get health status based on recent operations */ getHealthStatus(): { status: "healthy" | "degraded" | "unhealthy"; issues: string[]; recentFailureRate: number; } { const recentEntries = this.metrics.recentEntries.slice(-20); const recentFailures = recentEntries.filter((e) => !e.success).length; const recentFailureRate = recentEntries.length > 0 ? (recentFailures / recentEntries.length) * 100 : 0; const issues: string[] = []; let status: "healthy" | "degraded" | "unhealthy" = "healthy"; // Check failure rate if (recentFailureRate > 50) { status = "unhealthy"; issues.push(`High failure rate: ${recentFailureRate.toFixed(1)}%`); } else if (recentFailureRate > 20) { status = "degraded"; issues.push(`Elevated failure rate: ${recentFailureRate.toFixed(1)}%`); } // Check for slow responses const recentDurations = recentEntries.map((e) => e.duration); if (recentDurations.length > 0) { const avgDuration = recentDurations.reduce((a, b) => a + b, 0) / recentDurations.length; if (avgDuration > 10000) { // 10 seconds if (status === "healthy") status = "degraded"; issues.push(`Slow responses: ${avgDuration.toFixed(0)}ms average`); } } // Check for service availability const activeServices = Object.keys(this.metrics.services).length; if (activeServices === 0) { status = "unhealthy"; issues.push("No active services"); } return { status, issues, recentFailureRate, }; } /** * Reset all metrics (useful for testing) */ reset(): void { this.metrics = { startTime: Date.now(), totalRequests: 0, services: {}, recentEntries: [], }; debug("metrics.reset"); } /** * Export metrics for external monitoring (JSON serializable) */ exportMetrics(): Record<string, unknown> { return { ...this.getSummary(), services: Object.fromEntries( Object.entries(this.metrics.services).map(([name, metrics]) => [ name, { ...metrics, operations: Object.fromEntries( Object.entries(metrics.operations).map(([op, opMetrics]) => [ op, { ...opMetrics, averageDuration: opMetrics.count > 0 ? opMetrics.totalDuration / opMetrics.count : 0, failureRate: opMetrics.count > 0 ? (opMetrics.failures / opMetrics.count) * 100 : 0, }, ]), ), }, ]), ), health: this.getHealthStatus(), }; } }
  • getSummary method that computes global metrics summary including uptime, success rate, average response time, and top errors.
    getSummary(): { uptime: number; totalRequests: number; successRate: number; averageResponseTime: number; serviceCount: number; topErrors: Array<{ error: string; count: number }>; } { const uptime = Date.now() - this.metrics.startTime; const successfulRequests = Object.values(this.metrics.services).reduce( (sum, s) => sum + s.successfulRequests, 0, ); const totalRequests = this.metrics.totalRequests; const successRate = totalRequests > 0 ? (successfulRequests / totalRequests) * 100 : 100; // Calculate overall average response time const totalDuration = Object.values(this.metrics.services).reduce( (sum, s) => sum + s.averageResponseTime * s.totalRequests, 0, ); const averageResponseTime = totalRequests > 0 ? totalDuration / totalRequests : 0; // Count error frequencies const errorCounts = new Map<string, number>(); for (const e of this.metrics.recentEntries) { if (!e.success && e.error) { const error = e.error; errorCounts.set(error, (errorCounts.get(error) || 0) + 1); } } const topErrors = Array.from(errorCounts.entries()) .map(([error, count]) => ({ error, count })) .sort((a, b) => b.count - a.count) .slice(0, 5); return { uptime, totalRequests, successRate, averageResponseTime, serviceCount: Object.keys(this.metrics.services).length, topErrors, };
  • getHealthStatus method that determines overall health status based on recent failure rates and response times.
    getHealthStatus(): { status: "healthy" | "degraded" | "unhealthy"; issues: string[]; recentFailureRate: number; } { const recentEntries = this.metrics.recentEntries.slice(-20); const recentFailures = recentEntries.filter((e) => !e.success).length; const recentFailureRate = recentEntries.length > 0 ? (recentFailures / recentEntries.length) * 100 : 0; const issues: string[] = []; let status: "healthy" | "degraded" | "unhealthy" = "healthy"; // Check failure rate if (recentFailureRate > 50) { status = "unhealthy"; issues.push(`High failure rate: ${recentFailureRate.toFixed(1)}%`); } else if (recentFailureRate > 20) { status = "degraded"; issues.push(`Elevated failure rate: ${recentFailureRate.toFixed(1)}%`); } // Check for slow responses const recentDurations = recentEntries.map((e) => e.duration); if (recentDurations.length > 0) { const avgDuration = recentDurations.reduce((a, b) => a + b, 0) / recentDurations.length; if (avgDuration > 10000) { // 10 seconds if (status === "healthy") status = "degraded"; issues.push(`Slow responses: ${avgDuration.toFixed(0)}ms average`); } } // Check for service availability const activeServices = Object.keys(this.metrics.services).length; if (activeServices === 0) { status = "unhealthy"; issues.push("No active services"); } return { status, issues, recentFailureRate, };

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/thesammykins/FlixBridge'

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