vme-mcp-server 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/api-utils.js +251 -0
- package/dist/lib/capability-cache.js +131 -0
- package/dist/lib/capability-discovery.js +240 -0
- package/dist/lib/intent-recognition.js +159 -0
- package/dist/lib/name-resolver.js +174 -0
- package/dist/lib/session.js +59 -0
- package/dist/lib/vm-parsing.js +82 -0
- package/dist/server.js +36 -918
- package/dist/server_old.js +933 -0
- package/dist/tools/check-capability.js +84 -0
- package/dist/tools/create-vm.js +253 -0
- package/dist/tools/discover-capabilities.js +79 -0
- package/dist/tools/export-training-data.js +115 -0
- package/dist/tools/get-cache-status.js +123 -0
- package/dist/tools/get-resources.js +40 -0
- package/dist/tools/index.js +68 -0
- package/dist/tools/parse-intent.js +52 -0
- package/dist/tools/provide-feedback.js +61 -0
- package/dist/tools/query-resources.js +248 -0
- package/dist/types/interfaces.js +2 -0
- package/package.json +4 -4
@@ -0,0 +1,40 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.handleGetResources = exports.getResourcesTool = void 0;
|
4
|
+
const api_utils_js_1 = require("../lib/api-utils.js");
|
5
|
+
exports.getResourcesTool = {
|
6
|
+
name: "get_resources",
|
7
|
+
description: "Discover and explore available VME infrastructure resources with intelligent filtering",
|
8
|
+
inputSchema: {
|
9
|
+
type: "object",
|
10
|
+
properties: {
|
11
|
+
type: {
|
12
|
+
type: "string",
|
13
|
+
description: "Resource type filter: 'compute', 'network', 'storage', 'vm', or leave empty for all"
|
14
|
+
},
|
15
|
+
intent: {
|
16
|
+
type: "string",
|
17
|
+
description: "Intent-based filtering: 'create', 'provision', 'list', 'discover', or natural language description"
|
18
|
+
},
|
19
|
+
role: {
|
20
|
+
type: "string",
|
21
|
+
description: "User role for permission-aware filtering (future enhancement)"
|
22
|
+
}
|
23
|
+
},
|
24
|
+
required: []
|
25
|
+
}
|
26
|
+
};
|
27
|
+
async function handleGetResources(args) {
|
28
|
+
const { type, intent, role } = args;
|
29
|
+
const resources = await (0, api_utils_js_1.getResources)(type, intent, role);
|
30
|
+
return {
|
31
|
+
content: [
|
32
|
+
{
|
33
|
+
type: "text",
|
34
|
+
text: JSON.stringify(resources, null, 2)
|
35
|
+
}
|
36
|
+
],
|
37
|
+
isError: !!resources.error
|
38
|
+
};
|
39
|
+
}
|
40
|
+
exports.handleGetResources = handleGetResources;
|
@@ -0,0 +1,68 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.toolHandlers = exports.allTools = exports.handleQueryResources = exports.queryResourcesTool = exports.handleGetCacheStatus = exports.getCacheStatusTool = exports.handleCheckCapability = exports.checkCapabilityTool = exports.handleDiscoverCapabilities = exports.discoverCapabilitiesTool = exports.handleProvideFeedback = exports.provideFeedbackTool = exports.handleExportTrainingData = exports.exportTrainingDataTool = exports.handleCreateVM = exports.createVMTool = exports.handleParseIntent = exports.parseIntentTool = exports.handleGetResources = exports.getResourcesTool = void 0;
|
4
|
+
const parse_intent_js_1 = require("./parse-intent.js");
|
5
|
+
const create_vm_js_1 = require("./create-vm.js");
|
6
|
+
const export_training_data_js_1 = require("./export-training-data.js");
|
7
|
+
const provide_feedback_js_1 = require("./provide-feedback.js");
|
8
|
+
// Sprint 2: Capability Discovery Tools
|
9
|
+
const discover_capabilities_js_1 = require("./discover-capabilities.js");
|
10
|
+
const check_capability_js_1 = require("./check-capability.js");
|
11
|
+
const get_cache_status_js_1 = require("./get-cache-status.js");
|
12
|
+
const query_resources_js_1 = require("./query-resources.js");
|
13
|
+
// Re-export for external use
|
14
|
+
var get_resources_js_1 = require("./get-resources.js");
|
15
|
+
Object.defineProperty(exports, "getResourcesTool", { enumerable: true, get: function () { return get_resources_js_1.getResourcesTool; } });
|
16
|
+
Object.defineProperty(exports, "handleGetResources", { enumerable: true, get: function () { return get_resources_js_1.handleGetResources; } });
|
17
|
+
var parse_intent_js_2 = require("./parse-intent.js");
|
18
|
+
Object.defineProperty(exports, "parseIntentTool", { enumerable: true, get: function () { return parse_intent_js_2.parseIntentTool; } });
|
19
|
+
Object.defineProperty(exports, "handleParseIntent", { enumerable: true, get: function () { return parse_intent_js_2.handleParseIntent; } });
|
20
|
+
var create_vm_js_2 = require("./create-vm.js");
|
21
|
+
Object.defineProperty(exports, "createVMTool", { enumerable: true, get: function () { return create_vm_js_2.createVMTool; } });
|
22
|
+
Object.defineProperty(exports, "handleCreateVM", { enumerable: true, get: function () { return create_vm_js_2.handleCreateVM; } });
|
23
|
+
var export_training_data_js_2 = require("./export-training-data.js");
|
24
|
+
Object.defineProperty(exports, "exportTrainingDataTool", { enumerable: true, get: function () { return export_training_data_js_2.exportTrainingDataTool; } });
|
25
|
+
Object.defineProperty(exports, "handleExportTrainingData", { enumerable: true, get: function () { return export_training_data_js_2.handleExportTrainingData; } });
|
26
|
+
var provide_feedback_js_2 = require("./provide-feedback.js");
|
27
|
+
Object.defineProperty(exports, "provideFeedbackTool", { enumerable: true, get: function () { return provide_feedback_js_2.provideFeedbackTool; } });
|
28
|
+
Object.defineProperty(exports, "handleProvideFeedback", { enumerable: true, get: function () { return provide_feedback_js_2.handleProvideFeedback; } });
|
29
|
+
var discover_capabilities_js_2 = require("./discover-capabilities.js");
|
30
|
+
Object.defineProperty(exports, "discoverCapabilitiesTool", { enumerable: true, get: function () { return discover_capabilities_js_2.discoverCapabilitiesTool; } });
|
31
|
+
Object.defineProperty(exports, "handleDiscoverCapabilities", { enumerable: true, get: function () { return discover_capabilities_js_2.handleDiscoverCapabilities; } });
|
32
|
+
var check_capability_js_2 = require("./check-capability.js");
|
33
|
+
Object.defineProperty(exports, "checkCapabilityTool", { enumerable: true, get: function () { return check_capability_js_2.checkCapabilityTool; } });
|
34
|
+
Object.defineProperty(exports, "handleCheckCapability", { enumerable: true, get: function () { return check_capability_js_2.handleCheckCapability; } });
|
35
|
+
var get_cache_status_js_2 = require("./get-cache-status.js");
|
36
|
+
Object.defineProperty(exports, "getCacheStatusTool", { enumerable: true, get: function () { return get_cache_status_js_2.getCacheStatusTool; } });
|
37
|
+
Object.defineProperty(exports, "handleGetCacheStatus", { enumerable: true, get: function () { return get_cache_status_js_2.handleGetCacheStatus; } });
|
38
|
+
var query_resources_js_2 = require("./query-resources.js");
|
39
|
+
Object.defineProperty(exports, "queryResourcesTool", { enumerable: true, get: function () { return query_resources_js_2.queryResourcesTool; } });
|
40
|
+
Object.defineProperty(exports, "handleQueryResources", { enumerable: true, get: function () { return query_resources_js_2.handleQueryResources; } });
|
41
|
+
// Collect all tool definitions
|
42
|
+
exports.allTools = [
|
43
|
+
// Sprint 1.5 tools
|
44
|
+
// getResourcesTool, // DISABLED - caused 37K+ token responses, replaced by Sprint 2 capability discovery
|
45
|
+
parse_intent_js_1.parseIntentTool,
|
46
|
+
create_vm_js_1.createVMTool,
|
47
|
+
export_training_data_js_1.exportTrainingDataTool,
|
48
|
+
provide_feedback_js_1.provideFeedbackTool,
|
49
|
+
// Sprint 2 capability discovery tools
|
50
|
+
discover_capabilities_js_1.discoverCapabilitiesTool,
|
51
|
+
check_capability_js_1.checkCapabilityTool,
|
52
|
+
get_cache_status_js_1.getCacheStatusTool,
|
53
|
+
query_resources_js_1.queryResourcesTool
|
54
|
+
];
|
55
|
+
// Export tool handlers map for easy lookup
|
56
|
+
exports.toolHandlers = {
|
57
|
+
// Sprint 1.5 handlers
|
58
|
+
// get_resources: handleGetResources, // DISABLED - caused 37K+ token responses
|
59
|
+
parse_vm_intent: parse_intent_js_1.handleParseIntent,
|
60
|
+
create_vm: create_vm_js_1.handleCreateVM,
|
61
|
+
export_training_data: export_training_data_js_1.handleExportTrainingData,
|
62
|
+
provide_feedback: provide_feedback_js_1.handleProvideFeedback,
|
63
|
+
// Sprint 2 capability discovery handlers
|
64
|
+
discover_capabilities: discover_capabilities_js_1.handleDiscoverCapabilities,
|
65
|
+
check_capability: check_capability_js_1.handleCheckCapability,
|
66
|
+
get_cache_status: get_cache_status_js_1.handleGetCacheStatus,
|
67
|
+
query_resources: query_resources_js_1.handleQueryResources
|
68
|
+
};
|
@@ -0,0 +1,52 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.handleParseIntent = exports.parseIntentTool = void 0;
|
4
|
+
const intent_recognition_js_1 = require("../lib/intent-recognition.js");
|
5
|
+
const session_js_1 = require("../lib/session.js");
|
6
|
+
exports.parseIntentTool = {
|
7
|
+
name: "parse_vm_intent",
|
8
|
+
description: "Parse natural language VM requests into structured parameters with confidence scoring",
|
9
|
+
inputSchema: {
|
10
|
+
type: "object",
|
11
|
+
properties: {
|
12
|
+
naturalLanguageInput: {
|
13
|
+
type: "string",
|
14
|
+
description: "Natural language description of VM provisioning request"
|
15
|
+
}
|
16
|
+
},
|
17
|
+
required: ["naturalLanguageInput"]
|
18
|
+
}
|
19
|
+
};
|
20
|
+
async function handleParseIntent(args) {
|
21
|
+
const startTime = Date.now();
|
22
|
+
const { naturalLanguageInput } = args;
|
23
|
+
const sessionId = (0, session_js_1.generateSessionId)();
|
24
|
+
const parsedIntent = (0, intent_recognition_js_1.parseVMIntent)(naturalLanguageInput);
|
25
|
+
const parseTime = Date.now() - startTime;
|
26
|
+
// Log interaction for AI training (respects privacy settings)
|
27
|
+
(0, session_js_1.logInteraction)({
|
28
|
+
session_id: sessionId,
|
29
|
+
tool_name: 'parse_vm_intent',
|
30
|
+
user_input: { naturalLanguageInput },
|
31
|
+
parsed_output: parsedIntent,
|
32
|
+
success_metrics: {
|
33
|
+
operation_success: parsedIntent.action !== 'unknown',
|
34
|
+
confidence_score: parsedIntent.confidence,
|
35
|
+
entities_extracted: Object.keys(parsedIntent.entities).length
|
36
|
+
},
|
37
|
+
timing: {
|
38
|
+
parse_duration_ms: parseTime,
|
39
|
+
total_duration_ms: parseTime
|
40
|
+
}
|
41
|
+
});
|
42
|
+
return {
|
43
|
+
content: [
|
44
|
+
{
|
45
|
+
type: "text",
|
46
|
+
text: JSON.stringify(parsedIntent, null, 2)
|
47
|
+
}
|
48
|
+
],
|
49
|
+
isError: parsedIntent.action === 'unknown' && parsedIntent.confidence < 0.3
|
50
|
+
};
|
51
|
+
}
|
52
|
+
exports.handleParseIntent = handleParseIntent;
|
@@ -0,0 +1,61 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.handleProvideFeedback = exports.provideFeedbackTool = void 0;
|
4
|
+
const session_js_1 = require("../lib/session.js");
|
5
|
+
exports.provideFeedbackTool = {
|
6
|
+
name: "provide_feedback",
|
7
|
+
description: "Provide feedback on intent parsing accuracy to improve future predictions",
|
8
|
+
inputSchema: {
|
9
|
+
type: "object",
|
10
|
+
properties: {
|
11
|
+
original_input: {
|
12
|
+
type: "string",
|
13
|
+
description: "Original natural language input"
|
14
|
+
},
|
15
|
+
parsed_result: {
|
16
|
+
type: "object",
|
17
|
+
description: "The parsed result that was incorrect"
|
18
|
+
},
|
19
|
+
correct_interpretation: {
|
20
|
+
type: "object",
|
21
|
+
description: "What the correct interpretation should have been"
|
22
|
+
},
|
23
|
+
feedback_notes: {
|
24
|
+
type: "string",
|
25
|
+
description: "Additional notes about what went wrong"
|
26
|
+
}
|
27
|
+
},
|
28
|
+
required: ["original_input", "feedback_notes"]
|
29
|
+
}
|
30
|
+
};
|
31
|
+
async function handleProvideFeedback(args) {
|
32
|
+
const { original_input, parsed_result, correct_interpretation, feedback_notes } = args;
|
33
|
+
const sessionId = (0, session_js_1.generateSessionId)();
|
34
|
+
// Log feedback for future model improvements
|
35
|
+
(0, session_js_1.logInteraction)({
|
36
|
+
session_id: sessionId,
|
37
|
+
tool_name: 'provide_feedback',
|
38
|
+
user_input: { original_input, feedback_notes },
|
39
|
+
parsed_output: { parsed_result, correct_interpretation },
|
40
|
+
user_feedback: feedback_notes,
|
41
|
+
success_metrics: {
|
42
|
+
operation_success: false, // This indicates the original parsing was wrong
|
43
|
+
user_satisfaction: 0 // User had to provide feedback = dissatisfied
|
44
|
+
}
|
45
|
+
});
|
46
|
+
return {
|
47
|
+
content: [
|
48
|
+
{
|
49
|
+
type: "text",
|
50
|
+
text: JSON.stringify({
|
51
|
+
message: "Thank you for the feedback! This will help improve future intent recognition.",
|
52
|
+
feedback_recorded: true,
|
53
|
+
original_input: original_input,
|
54
|
+
feedback_notes: feedback_notes
|
55
|
+
}, null, 2)
|
56
|
+
}
|
57
|
+
],
|
58
|
+
isError: false
|
59
|
+
};
|
60
|
+
}
|
61
|
+
exports.handleProvideFeedback = handleProvideFeedback;
|
@@ -0,0 +1,248 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.handleQueryResources = exports.queryResourcesTool = void 0;
|
4
|
+
const api_utils_js_1 = require("../lib/api-utils.js");
|
5
|
+
exports.queryResourcesTool = {
|
6
|
+
name: "query_resources",
|
7
|
+
description: "Query actual infrastructure resources (VMs, hosts, networks) with natural language. Use discover_capabilities first to learn available OS types, groups, and statuses in your environment.",
|
8
|
+
inputSchema: {
|
9
|
+
type: "object",
|
10
|
+
properties: {
|
11
|
+
natural_query: {
|
12
|
+
type: "string",
|
13
|
+
description: "Natural language query like 'Windows VMs', 'stopped VMs in production', 'any VMs?', 'Ubuntu hosts', 'VMs in development group'"
|
14
|
+
},
|
15
|
+
limit: {
|
16
|
+
type: "number",
|
17
|
+
description: "Maximum number of results to return (default: 10, max: 100)",
|
18
|
+
default: 10
|
19
|
+
}
|
20
|
+
},
|
21
|
+
required: ["natural_query"]
|
22
|
+
}
|
23
|
+
};
|
24
|
+
function parseResourceQuery(query, limit = 10) {
|
25
|
+
const q = query.toLowerCase().trim();
|
26
|
+
// Determine resource type
|
27
|
+
let resource = 'instances'; // default
|
28
|
+
if (q.includes('host') || q.includes('server') || q.includes('node')) {
|
29
|
+
resource = 'hosts';
|
30
|
+
}
|
31
|
+
else if (q.includes('network')) {
|
32
|
+
resource = 'networks';
|
33
|
+
}
|
34
|
+
// Determine action
|
35
|
+
let action = 'list';
|
36
|
+
if (q.includes('how many') || q.includes('count')) {
|
37
|
+
action = 'count';
|
38
|
+
}
|
39
|
+
else if (q.includes('any ') || q.includes('summary')) {
|
40
|
+
action = 'summary';
|
41
|
+
}
|
42
|
+
// Extract filters
|
43
|
+
const filters = {};
|
44
|
+
// OS Type patterns
|
45
|
+
if (q.includes('windows'))
|
46
|
+
filters.osType = 'windows';
|
47
|
+
if (q.includes('linux'))
|
48
|
+
filters.osType = 'linux';
|
49
|
+
if (q.includes('ubuntu'))
|
50
|
+
filters.osType = 'ubuntu';
|
51
|
+
if (q.includes('centos'))
|
52
|
+
filters.osType = 'centos';
|
53
|
+
if (q.includes('rocky'))
|
54
|
+
filters.osType = 'rocky';
|
55
|
+
if (q.includes('debian'))
|
56
|
+
filters.osType = 'debian';
|
57
|
+
if (q.includes('rhel'))
|
58
|
+
filters.osType = 'rhel';
|
59
|
+
// Status patterns
|
60
|
+
if (q.includes('running'))
|
61
|
+
filters.status = 'running';
|
62
|
+
if (q.includes('stopped'))
|
63
|
+
filters.status = 'stopped';
|
64
|
+
if (q.includes('failed') || q.includes('error'))
|
65
|
+
filters.status = 'failed';
|
66
|
+
if (q.includes('provisioning'))
|
67
|
+
filters.status = 'provisioning';
|
68
|
+
// Group patterns
|
69
|
+
if (q.includes('production') || q.includes('prod'))
|
70
|
+
filters.group = 'production';
|
71
|
+
if (q.includes('development') || q.includes('dev'))
|
72
|
+
filters.group = 'development';
|
73
|
+
if (q.includes('test') || q.includes('testing'))
|
74
|
+
filters.group = 'test';
|
75
|
+
// Name patterns (exact matches)
|
76
|
+
const nameMatch = q.match(/named?\s+["']?([a-zA-Z0-9\-_]+)["']?/);
|
77
|
+
if (nameMatch) {
|
78
|
+
filters.name = nameMatch[1];
|
79
|
+
}
|
80
|
+
return { resource, action, filters, limit };
|
81
|
+
}
|
82
|
+
function filterResults(data, filters) {
|
83
|
+
return data.filter(item => {
|
84
|
+
// OS Type filtering
|
85
|
+
if (filters.osType) {
|
86
|
+
const itemOS = item.osType?.toLowerCase() || '';
|
87
|
+
const filterOS = filters.osType.toLowerCase();
|
88
|
+
if (filterOS === 'windows' && !itemOS.includes('windows'))
|
89
|
+
return false;
|
90
|
+
if (filterOS === 'linux' && !itemOS.includes('linux') && !itemOS.includes('ubuntu') && !itemOS.includes('centos') && !itemOS.includes('rocky') && !itemOS.includes('debian') && !itemOS.includes('rhel'))
|
91
|
+
return false;
|
92
|
+
if (filterOS !== 'windows' && filterOS !== 'linux' && !itemOS.includes(filterOS))
|
93
|
+
return false;
|
94
|
+
}
|
95
|
+
// Status filtering
|
96
|
+
if (filters.status) {
|
97
|
+
const itemStatus = item.status?.toLowerCase() || '';
|
98
|
+
if (!itemStatus.includes(filters.status.toLowerCase()))
|
99
|
+
return false;
|
100
|
+
}
|
101
|
+
// Group filtering
|
102
|
+
if (filters.group) {
|
103
|
+
const itemGroup = item.group?.name?.toLowerCase() || item.site?.name?.toLowerCase() || '';
|
104
|
+
if (!itemGroup.includes(filters.group.toLowerCase()))
|
105
|
+
return false;
|
106
|
+
}
|
107
|
+
// Name filtering
|
108
|
+
if (filters.name) {
|
109
|
+
const itemName = item.name?.toLowerCase() || '';
|
110
|
+
if (!itemName.includes(filters.name.toLowerCase()))
|
111
|
+
return false;
|
112
|
+
}
|
113
|
+
return true;
|
114
|
+
});
|
115
|
+
}
|
116
|
+
function formatResponse(parsedQuery, results, totalCount) {
|
117
|
+
const { action, resource, filters } = parsedQuery;
|
118
|
+
if (action === 'count') {
|
119
|
+
return {
|
120
|
+
action: 'count',
|
121
|
+
resource: resource,
|
122
|
+
filters_applied: filters,
|
123
|
+
total_count: results.length,
|
124
|
+
query_summary: `Found ${results.length} ${resource} matching criteria`
|
125
|
+
};
|
126
|
+
}
|
127
|
+
if (action === 'summary') {
|
128
|
+
const statusCounts = {};
|
129
|
+
const osCounts = {};
|
130
|
+
results.forEach(item => {
|
131
|
+
const status = item.status || 'unknown';
|
132
|
+
const os = item.osType || 'unknown';
|
133
|
+
statusCounts[status] = (statusCounts[status] || 0) + 1;
|
134
|
+
osCounts[os] = (osCounts[os] || 0) + 1;
|
135
|
+
});
|
136
|
+
return {
|
137
|
+
action: 'summary',
|
138
|
+
resource: resource,
|
139
|
+
filters_applied: filters,
|
140
|
+
total_count: results.length,
|
141
|
+
summary: {
|
142
|
+
by_status: statusCounts,
|
143
|
+
by_os_type: osCounts
|
144
|
+
},
|
145
|
+
query_summary: `Found ${results.length} ${resource} matching criteria`
|
146
|
+
};
|
147
|
+
}
|
148
|
+
// Default: list action
|
149
|
+
const limitedResults = results.slice(0, parsedQuery.limit);
|
150
|
+
return {
|
151
|
+
action: 'list',
|
152
|
+
resource: resource,
|
153
|
+
filters_applied: filters,
|
154
|
+
total_count: results.length,
|
155
|
+
returned_count: limitedResults.length,
|
156
|
+
items: limitedResults.map(item => ({
|
157
|
+
id: item.id,
|
158
|
+
name: item.name,
|
159
|
+
status: item.status,
|
160
|
+
osType: item.osType,
|
161
|
+
group: item.group?.name || item.site?.name || 'unknown',
|
162
|
+
...(resource === 'instances' && {
|
163
|
+
plan: item.plan?.name,
|
164
|
+
powerState: item.powerState,
|
165
|
+
ipAddress: item.externalIp || item.internalIp
|
166
|
+
})
|
167
|
+
})),
|
168
|
+
query_summary: `Showing ${limitedResults.length} of ${results.length} ${resource} matching criteria`
|
169
|
+
};
|
170
|
+
}
|
171
|
+
async function handleQueryResources(args) {
|
172
|
+
try {
|
173
|
+
const { natural_query, limit = 10 } = args;
|
174
|
+
if (!natural_query || typeof natural_query !== 'string') {
|
175
|
+
return {
|
176
|
+
content: [
|
177
|
+
{
|
178
|
+
type: "text",
|
179
|
+
text: JSON.stringify({
|
180
|
+
error: "Invalid input",
|
181
|
+
message: "natural_query parameter is required and must be a string",
|
182
|
+
examples: ["any VMs?", "Windows VMs", "stopped VMs in production", "Ubuntu hosts"]
|
183
|
+
}, null, 2)
|
184
|
+
}
|
185
|
+
],
|
186
|
+
isError: true
|
187
|
+
};
|
188
|
+
}
|
189
|
+
const parsedQuery = parseResourceQuery(natural_query, Math.min(limit, 100));
|
190
|
+
// Map resource type to API endpoint
|
191
|
+
const endpointMap = {
|
192
|
+
'instances': '/instances',
|
193
|
+
'hosts': '/servers',
|
194
|
+
'networks': '/networks'
|
195
|
+
};
|
196
|
+
const endpoint = endpointMap[parsedQuery.resource];
|
197
|
+
// Query the VME API
|
198
|
+
const response = await api_utils_js_1.api.get(endpoint);
|
199
|
+
// Extract data array from response
|
200
|
+
let rawData = [];
|
201
|
+
if (parsedQuery.resource === 'instances' && response.data.instances) {
|
202
|
+
rawData = response.data.instances;
|
203
|
+
}
|
204
|
+
else if (parsedQuery.resource === 'hosts' && response.data.servers) {
|
205
|
+
rawData = response.data.servers;
|
206
|
+
}
|
207
|
+
else if (parsedQuery.resource === 'networks' && response.data.networks) {
|
208
|
+
rawData = response.data.networks;
|
209
|
+
}
|
210
|
+
else {
|
211
|
+
// Fallback: try to find array in response
|
212
|
+
const possibleArrays = Object.values(response.data).filter(Array.isArray);
|
213
|
+
if (possibleArrays.length > 0) {
|
214
|
+
rawData = possibleArrays[0];
|
215
|
+
}
|
216
|
+
}
|
217
|
+
// Apply filters
|
218
|
+
const filteredResults = filterResults(rawData, parsedQuery.filters);
|
219
|
+
// Format response based on action
|
220
|
+
const formattedResponse = formatResponse(parsedQuery, filteredResults, rawData.length);
|
221
|
+
return {
|
222
|
+
content: [
|
223
|
+
{
|
224
|
+
type: "text",
|
225
|
+
text: JSON.stringify(formattedResponse, null, 2)
|
226
|
+
}
|
227
|
+
],
|
228
|
+
isError: false
|
229
|
+
};
|
230
|
+
}
|
231
|
+
catch (error) {
|
232
|
+
return {
|
233
|
+
content: [
|
234
|
+
{
|
235
|
+
type: "text",
|
236
|
+
text: JSON.stringify({
|
237
|
+
error: "Resource query failed",
|
238
|
+
message: error.message,
|
239
|
+
natural_query: args?.natural_query || "unknown",
|
240
|
+
suggestion: "Check VME API connectivity or try discover_capabilities first to see available resources"
|
241
|
+
}, null, 2)
|
242
|
+
}
|
243
|
+
],
|
244
|
+
isError: true
|
245
|
+
};
|
246
|
+
}
|
247
|
+
}
|
248
|
+
exports.handleQueryResources = handleQueryResources;
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "vme-mcp-server",
|
3
|
-
"version": "0.1.
|
4
|
-
"description": "
|
3
|
+
"version": "0.1.7",
|
4
|
+
"description": "",
|
5
5
|
"main": "dist/server.js",
|
6
6
|
"bin": {
|
7
7
|
"vme-mcp-server": "./dist/server.js"
|
@@ -47,8 +47,8 @@
|
|
47
47
|
},
|
48
48
|
"devDependencies": {
|
49
49
|
"@types/node": "^22.15.29",
|
50
|
+
"chai": "^5.2.0",
|
50
51
|
"mocha": "^10.2.0",
|
51
52
|
"nyc": "^15.1.0"
|
52
|
-
}
|
53
|
-
"description": ""
|
53
|
+
}
|
54
54
|
}
|