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
156 lines (155 loc) • 6.2 kB
JavaScript
import { parseVMNames } from "./vm-parsing.js";
// Intent recognition system for natural language processing
export function parseVMIntent(naturalLanguageInput) {
const input = naturalLanguageInput.toLowerCase().trim();
const result = {
action: 'unknown',
confidence: 0,
entities: {},
originalText: naturalLanguageInput
};
// Intent Classification with confidence scoring
const intentPatterns = {
create: [
/\b(create|provision|deploy|launch|start|build|make|setup)\b/,
/\bneed\s+(\d+\s+)?(vm|server|machine)/,
/\bcan\s+you\s+(create|provision|deploy)/
],
modify: [
/\b(modify|change|update|edit|alter|resize|scale)\b/,
/\badd\s+(more\s+)?(cpu|memory|disk|storage)/,
/\bchange\s+the\s+(size|plan|configuration)/
],
monitor: [
/\b(show|list|display|check|status|monitor|view)\b(?!.*\b(available|options|resources|templates|plans)\b)/,
/\bwhat\s+(vm|server|machine)/,
/\bhow\s+many\s+(vm|server|machine)/
],
destroy: [
/\b(delete|remove|destroy|terminate|stop|kill)\b/,
/\btear\s+down/,
/\bshut\s+down/
],
discover: [
/\b(available|options|resources|templates|plans)\b/,
/\bshow\s+me\s+(all|available)/,
/\bwhat\s+(are|is)\s+(available|possible)/,
/\bwhat\s+can\s+i\s+(create|do)/
]
};
// Calculate confidence for each intent
let maxConfidence = 0;
let detectedAction = 'unknown';
for (const [action, patterns] of Object.entries(intentPatterns)) {
let matches = 0;
for (const pattern of patterns) {
if (pattern.test(input)) {
matches++;
}
}
const confidence = patterns.length > 0 ? matches / patterns.length : 0;
if (confidence > maxConfidence) {
maxConfidence = confidence;
detectedAction = action;
}
}
result.action = detectedAction;
result.confidence = maxConfidence;
// Entity Extraction for VM creation
if (result.action === 'create') {
// Extract VM names and count
const namePatterns = [
/\b(?:vm|server|machine)s?\s+(?:named\s+)?["']?([a-zA-Z0-9\-_]+(?:\s*->\s*[a-zA-Z0-9\-_]+)?)["']?/,
/\b(?:named\s+)?["']?([a-zA-Z0-9\-_]+(?:\s*->\s*[a-zA-Z0-9\-_]+)?)["']?\s+(?:vm|server|machine)/,
/\bcreate\s+(?:(?:vm|server|machine)s?\s+)?["']?([a-zA-Z0-9\-_]+(?:\s*->\s*[a-zA-Z0-9\-_]+)?)["']?/,
/\b(?:vm|server|machine)\s+named\s+["']?([a-zA-Z0-9\-_]+(?:\s*->\s*[a-zA-Z0-9\-_]+)?)["']?/
];
for (const pattern of namePatterns) {
const match = input.match(pattern);
if (match) {
const nameInput = match[1] || match[2];
result.entities.vmNames = parseVMNames(nameInput);
break;
}
}
// Extract count
const countMatch = input.match(/\b(\d+)\s+(?:vm|server|machine)/);
if (countMatch) {
result.entities.count = parseInt(countMatch[1]);
}
// Extract OS template
const osPatterns = [
/\b(ubuntu|rocky|centos|debian|rhel|red\s*hat|alma|almalinux)(?:\s+(\d+(?:\.\d+)?))?/,
/\busing\s+([a-zA-Z0-9\-_]+)\s+(?:template|os|operating)/,
/\b(?:template|os|operating)\s+([a-zA-Z0-9\-_]+)/
];
for (const pattern of osPatterns) {
const match = input.match(pattern);
if (match) {
result.entities.osTemplate = match[0];
break;
}
}
// Extract size/memory
const sizePatterns = [
/\b(small|medium|large|tiny)\b/,
/\b(\d+)\s*gb\s+(?:memory|ram)\b/,
/\b(\d+)\s*cpu[s]?\s*,?\s*(\d+)\s*gb/,
/\bwith\s+(\d+(?:gb|cpu))\b/,
/\b(\d+gb)\b/
];
for (const pattern of sizePatterns) {
const match = input.match(pattern);
if (match) {
result.entities.size = match[0];
break;
}
}
// Extract group/environment
const groupPatterns = [
/\bin\s+(?:the\s+)?([a-zA-Z0-9\-_]+)\s+(?:group|environment|site)/,
/\b(?:group|environment|site)\s+([a-zA-Z0-9\-_]+)/,
/\bfor\s+([a-zA-Z0-9\-_]+)\s+(?:environment|testing|production)/
];
for (const pattern of groupPatterns) {
const match = input.match(pattern);
if (match) {
result.entities.group = match[1];
break;
}
}
// Extract zone/cloud
const zonePatterns = [
/\bon\s+([a-zA-Z0-9\-_]+)\s+(?:zone|cloud)/,
/\b(?:zone|cloud)\s+([a-zA-Z0-9\-_]+)/,
/\bin\s+([a-zA-Z0-9\-_]+)\s+(?:zone|cloud)/,
/\b(?:deploy|launch|create)\s+(?:in\s+)?([a-zA-Z0-9\-_]+)\s+zone/
];
for (const pattern of zonePatterns) {
const match = input.match(pattern);
if (match) {
result.entities.zone = match[1];
break;
}
}
// Extract distribution strategy
if (input.includes('spread') || input.includes('distribute') || input.includes('across')) {
result.entities.distribution = 'spread';
}
else if (input.includes('each node') || input.includes('all nodes')) {
result.entities.distribution = 'spread';
}
else if (input.includes('node') && input.match(/node[s]?\s*[\d,\s]+/)) {
const nodeMatch = input.match(/node[s]?\s*([\d,\s]+)/);
if (nodeMatch) {
result.entities.distribution = nodeMatch[1].replace(/\s+/g, '');
}
}
// Boost confidence if we extracted entities
const entityCount = Object.keys(result.entities).length;
if (entityCount > 0) {
result.confidence = Math.min(0.95, result.confidence + (entityCount * 0.1));
}
}
return result;
}