vme-mcp-server
Version:
An intelligent Model Context Protocol (MCP) server that transforms HPE VM Essentials (VME) infrastructure management into natural language conversations. Provision VMs, manage resources, and control your infrastructure through simple English commands with
120 lines (119 loc) • 4.71 kB
JavaScript
import { capabilityCache } from "../lib/capability-cache.js";
export const getCacheStatusTool = {
name: "get_cache_status",
description: "Show freshness and status of cached capability data for transparency and debugging",
inputSchema: {
type: "object",
properties: {
field: {
type: "string",
enum: ["zones", "clusters", "service_plans", "instance_types", "virtual_images", "resource_pools", "networks", "groups"],
description: "Specific field to check (optional, shows all cached fields if omitted)"
},
include_statistics: {
type: "boolean",
description: "Include cache hit/miss statistics (default: false)",
default: false
}
},
required: []
}
};
export async function handleGetCacheStatus(args) {
try {
const { field, include_statistics = false } = args;
// Get cache status for specific field or all fields
const cacheStatuses = capabilityCache.getCacheStatus(field);
// Calculate summary statistics
const totalFields = cacheStatuses.length;
const freshFields = cacheStatuses.filter(s => s.is_fresh).length;
const staleFields = totalFields - freshFields;
// Build response
const response = {
cache_summary: {
total_cached_fields: totalFields,
fresh_fields: freshFields,
stale_fields: staleFields,
freshness_rate: totalFields > 0 ? Math.round((freshFields / totalFields) * 100) : 0
},
field_details: cacheStatuses.map(status => ({
field_name: status.field_name,
status: status.is_fresh ? "fresh" : "stale",
cached_at: new Date(status.cached_at * 1000).toISOString(),
age_seconds: status.age_seconds,
age_human: formatDuration(status.age_seconds),
ttl_seconds: status.ttl_seconds,
expires_in_seconds: status.expires_in_seconds,
expires_in_human: status.is_fresh ? formatDuration(status.expires_in_seconds) : "expired",
endpoint: status.endpoint
})),
recommendations: generateRecommendations(cacheStatuses)
};
// Include statistics if requested
if (include_statistics) {
const stats = capabilityCache.getStatistics();
response.statistics = {
cache_hits: stats.hits,
cache_misses: stats.misses,
hit_rate_percentage: Math.round(stats.hitRate * 100),
note: "Statistics tracking not yet implemented - placeholder data"
};
}
return {
content: [
{
type: "text",
text: JSON.stringify(response, null, 2)
}
],
isError: false
};
}
catch (error) {
return {
content: [
{
type: "text",
text: JSON.stringify({
error: "Cache status check failed",
message: error.message
}, null, 2)
}
],
isError: true
};
}
}
// Helper function to format duration in human-readable format
function formatDuration(seconds) {
if (seconds < 60) {
return `${seconds}s`;
}
else if (seconds < 3600) {
return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
}
else {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
return `${hours}h ${minutes}m`;
}
}
// Generate recommendations based on cache status
function generateRecommendations(statuses) {
const recommendations = [];
const staleFields = statuses.filter(s => !s.is_fresh);
const oldFields = statuses.filter(s => s.age_seconds > 3600); // > 1 hour
if (staleFields.length > 0) {
recommendations.push(`${staleFields.length} field(s) have stale data: ${staleFields.map(s => s.field_name).join(", ")}`);
}
if (oldFields.length > 0) {
recommendations.push(`Consider refreshing old data for: ${oldFields.map(s => s.field_name).join(", ")}`);
}
if (statuses.length === 0) {
recommendations.push("No cached data found. Run discover_capabilities to populate cache.");
}
if (recommendations.length === 0) {
recommendations.push("Cache is healthy - all data is fresh and within TTL limits.");
}
return recommendations;
}