@mithung/vunet-mcp-server 2.1.0 → 2.2.0

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.
Files changed (3) hide show
  1. package/README.md +6 -2
  2. package/index.js +108 -2
  3. package/package.json +4 -4
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  Query metrics, traces, logs, and data models from your Vunet tenants using natural language through AI assistants like Claude, GitHub Copilot, or any MCP-compatible client.
10
10
 
11
- > **Latest Version:** 2.1.0 - Authentication improvements with proxy support.
11
+ > **Latest Version:** 2.1.1 - Updated repository URLs, authentication improvements with proxy support.
12
12
 
13
13
  ---
14
14
 
@@ -277,6 +277,10 @@ npm list -g @mithung/vunet-mcp-server
277
277
 
278
278
  ## 📄 Changelog
279
279
 
280
+ ### v2.1.1 (2026-02-18)
281
+ - ✅ Updated repository URLs to correct GitHub organization
282
+ - ✅ Fixed package metadata
283
+
280
284
  ### v2.1.0 (2026-02-17)
281
285
  - ✅ Authentication improvements with proxy support
282
286
  - ✅ Auto-reconnect on session expiry
@@ -307,7 +311,7 @@ MIT License - see [LICENSE](LICENSE) file.
307
311
 
308
312
  ## 📧 Support
309
313
 
310
- - **GitHub Issues:** [https://github.com/mithung/vunet-mcp-server/issues](https://github.com/mithung/vunet-mcp-server/issues)
314
+ - **GitHub Issues:** [https://github.com/mithung-vunet/vunet-mcp-server/issues](https://github.com/mithung-vunet/vunet-mcp-server/issues)
311
315
  - **npm Package:** [https://www.npmjs.com/package/@mithung/vunet-mcp-server](https://www.npmjs.com/package/@mithung/vunet-mcp-server)
312
316
 
313
317
  ---
package/index.js CHANGED
@@ -222,6 +222,42 @@ class VunetMCPServer {
222
222
  /**
223
223
  * Query a metric/data model
224
224
  */
225
+ /**
226
+ * Fetch datamodels from the VuNet tenant with pagination and optional search/filter.
227
+ * Automatically re-authenticates on 401.
228
+ */
229
+ async fetchDataModels({ limit = 10, offset = 0, search = "", signal_type = "", ordering = "" } = {}) {
230
+ await this.ensureAuthenticated();
231
+
232
+ const params = new URLSearchParams({ ordering, limit, offset, search });
233
+ if (signal_type) params.set("signal_type", signal_type);
234
+
235
+ const url = `${this.normalizeTenantUrl(this.tenantUrl)}/api/vuaccel/datamodel/?${params.toString()}`;
236
+
237
+ try {
238
+ const response = await axios.get(url, {
239
+ headers: { Authorization: `Bearer ${this.sessionToken}` },
240
+ httpsAgent: this.httpsAgent,
241
+ });
242
+ return response.data;
243
+ } catch (error) {
244
+ if (error.response?.status === 401) {
245
+ // Token expired — re-authenticate and retry once
246
+ this.isAuthenticated = false;
247
+ await this.ensureAuthenticated();
248
+ const retryResponse = await axios.get(url, {
249
+ headers: { Authorization: `Bearer ${this.sessionToken}` },
250
+ httpsAgent: this.httpsAgent,
251
+ });
252
+ return retryResponse.data;
253
+ }
254
+ const errorDetails = error.response?.data
255
+ ? JSON.stringify(error.response.data)
256
+ : error.message;
257
+ throw new Error(`Failed to fetch datamodels: ${errorDetails}`);
258
+ }
259
+ }
260
+
225
261
  async queryMetric(metricName, queryParams) {
226
262
  await this.ensureAuthenticated();
227
263
 
@@ -355,6 +391,36 @@ class VunetMCPServer {
355
391
  },
356
392
  },
357
393
  },
394
+ {
395
+ name: "vunet_fetch_datamodels",
396
+ description: "Fetch the actual live DataModels (signals) configured in this VuNet tenant by calling /api/vuaccel/datamodel/. Returns real signal names, types (Metric/Event/Log), data sources, and column details. Use this to discover what data is available before querying with vunet_query_metric.",
397
+ inputSchema: {
398
+ type: "object",
399
+ properties: {
400
+ limit: {
401
+ type: "number",
402
+ description: "Number of results to return per page (default: 10, max: 100)",
403
+ },
404
+ offset: {
405
+ type: "number",
406
+ description: "Pagination offset — number of records to skip (default: 0)",
407
+ },
408
+ search: {
409
+ type: "string",
410
+ description: "Search keyword to filter data models by name (e.g., 'UPI', 'CPU', 'transaction')",
411
+ },
412
+ signal_type: {
413
+ type: "string",
414
+ description: "Filter by signal type: 'Metric', 'Event', or 'Log'",
415
+ enum: ["Metric", "Event", "Log"],
416
+ },
417
+ ordering: {
418
+ type: "string",
419
+ description: "Field to sort results by (e.g., 'signal_name', '-creation_time')",
420
+ },
421
+ },
422
+ },
423
+ },
358
424
  ],
359
425
  }));
360
426
 
@@ -373,6 +439,9 @@ class VunetMCPServer {
373
439
  case "vunet_list_data_models":
374
440
  return await this.handleListDataModels(args);
375
441
 
442
+ case "vunet_fetch_datamodels":
443
+ return await this.handleFetchDataModels(args);
444
+
376
445
  default:
377
446
  throw new Error(`Unknown tool: ${name}`);
378
447
  }
@@ -430,8 +499,7 @@ class VunetMCPServer {
430
499
  };
431
500
  }
432
501
 
433
- async handleListDataModels(args = {}) {
434
- const category = args.category || "all";
502
+ async handleListDataModels(args = {}) { const category = args.category || "all";
435
503
 
436
504
  const dataModels = {
437
505
  apm: [
@@ -544,6 +612,44 @@ class VunetMCPServer {
544
612
  };
545
613
  }
546
614
 
615
+ async handleFetchDataModels(args = {}) {
616
+ const { limit = 10, offset = 0, search = "", signal_type = "", ordering = "" } = args;
617
+
618
+ const data = await this.fetchDataModels({ limit, offset, search, signal_type, ordering });
619
+
620
+ // Shape a clean, LLM-friendly summary
621
+ const models = (data.results || []).map((m) => ({
622
+ signal_id: m.signal_id,
623
+ signal_name: m.signal_name,
624
+ signal_type: m.signal_type,
625
+ description: m.description || "",
626
+ sources: m.source_names || [],
627
+ columns: (m.metric_column_details || []).map((c) => c.column_name || c.name || c),
628
+ created_by: m.created_by,
629
+ last_modified: m.last_modified_time,
630
+ }));
631
+
632
+ const result = {
633
+ tenant: this.tenantUrl,
634
+ total_count: data.count,
635
+ returned: models.length,
636
+ offset,
637
+ has_more: offset + models.length < data.count,
638
+ next_offset: offset + models.length < data.count ? offset + models.length : null,
639
+ tip: "Use signal_name values with the vunet_query_metric tool to fetch actual data.",
640
+ datamodels: models,
641
+ };
642
+
643
+ return {
644
+ content: [
645
+ {
646
+ type: "text",
647
+ text: JSON.stringify(result, null, 2),
648
+ },
649
+ ],
650
+ };
651
+ }
652
+
547
653
  async run() {
548
654
  console.error("Vunet MCP Server starting...");
549
655
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mithung/vunet-mcp-server",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "Model Context Protocol (MCP) Server for Vunet vuSmartMaps - Multi-tenant observability platform integration",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -42,12 +42,12 @@
42
42
  },
43
43
  "repository": {
44
44
  "type": "git",
45
- "url": "https://github.com/mithung/vunet-mcp-server.git"
45
+ "url": "https://github.com/mithung-vunet/vunet-mcp-server.git"
46
46
  },
47
47
  "bugs": {
48
- "url": "https://github.com/mithung/vunet-mcp-server/issues"
48
+ "url": "https://github.com/mithung-vunet/vunet-mcp-server/issues"
49
49
  },
50
- "homepage": "https://github.com/mithung/vunet-mcp-server#readme",
50
+ "homepage": "https://github.com/mithung-vunet/vunet-mcp-server#readme",
51
51
  "license": "MIT",
52
52
  "dependencies": {
53
53
  "@modelcontextprotocol/sdk": "^1.26.0",