@usex/mikrotik-mcp 3.55.0 → 3.56.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.
- package/dist/cli.js +38 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/shared/{cli-yxah49n1.js → cli-0ctwspf1.js} +1 -1
- package/dist/shared/{cli-44v6pb38.js → cli-thhk9f7n.js} +21 -7
- package/dist/shared/{library-cs13jqp9.js → library-jve65pzw.js} +1 -1
- package/dist/shared/{library-83q9t27c.js → library-ymtf9zyk.js} +21 -7
- package/dist/ui/observability.html +13 -13
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -96,7 +96,7 @@ import {
|
|
|
96
96
|
toggleAaaEntity,
|
|
97
97
|
updateAaaEntity,
|
|
98
98
|
writeBackup
|
|
99
|
-
} from "./shared/cli-
|
|
99
|
+
} from "./shared/cli-thhk9f7n.js";
|
|
100
100
|
|
|
101
101
|
// src/cli.ts
|
|
102
102
|
import { existsSync as existsSync2 } from "fs";
|
|
@@ -1559,6 +1559,7 @@ function devicesPayload(store) {
|
|
|
1559
1559
|
authMode: dc.mac ? "mac-telnet" : dc.keyFilename || dc.privateKey ? "key" : dc.password ? "password" : "none",
|
|
1560
1560
|
isDefault: name === cfg.defaultDevice,
|
|
1561
1561
|
description: dc.description,
|
|
1562
|
+
disabled: !!dc.disabled,
|
|
1562
1563
|
jumpVia: dc.jumpVia,
|
|
1563
1564
|
jumpHost: dc.jumpHost ? { host: dc.jumpHost.host, port: dc.jumpHost.port } : undefined,
|
|
1564
1565
|
status: getDeviceStatus(name),
|
|
@@ -2373,6 +2374,42 @@ async function runDashboard(cfg, transportLabel) {
|
|
|
2373
2374
|
if (url.pathname === "/api/devices") {
|
|
2374
2375
|
return json3(devicesPayload(db));
|
|
2375
2376
|
}
|
|
2377
|
+
if (url.pathname === "/api/devices/toggle" && req.method === "POST") {
|
|
2378
|
+
const b = await readJson(req);
|
|
2379
|
+
if (typeof b?.device !== "string" || typeof b?.disabled !== "boolean") {
|
|
2380
|
+
return json3({ error: "device (string) and disabled (boolean) are required" }, 400);
|
|
2381
|
+
}
|
|
2382
|
+
const cfg2 = getConfig();
|
|
2383
|
+
if (!(b.device in cfg2.devices))
|
|
2384
|
+
return json3({ error: `unknown device: ${b.device}` }, 404);
|
|
2385
|
+
const dc = cfg2.devices[b.device];
|
|
2386
|
+
const next = {
|
|
2387
|
+
...cfg2,
|
|
2388
|
+
devices: {
|
|
2389
|
+
...cfg2.devices,
|
|
2390
|
+
[b.device]: { ...dc, disabled: b.disabled || undefined }
|
|
2391
|
+
}
|
|
2392
|
+
};
|
|
2393
|
+
setConfig(next);
|
|
2394
|
+
let persisted = true;
|
|
2395
|
+
let warning;
|
|
2396
|
+
try {
|
|
2397
|
+
atomicWrite(getConfigSource().path, serializeConfig(next));
|
|
2398
|
+
} catch (e) {
|
|
2399
|
+
persisted = false;
|
|
2400
|
+
warning = `applied live but not saved to disk: ${e instanceof Error ? e.message : String(e)}`;
|
|
2401
|
+
}
|
|
2402
|
+
if (persisted) {
|
|
2403
|
+
recordVersion(getConfig(), "auto", Date.now(), `device ${b.disabled ? "disabled" : "enabled"}: ${b.device}`);
|
|
2404
|
+
}
|
|
2405
|
+
return json3({
|
|
2406
|
+
ok: true,
|
|
2407
|
+
persisted,
|
|
2408
|
+
requiresReconnect: true,
|
|
2409
|
+
warning,
|
|
2410
|
+
...devicesPayload(db)
|
|
2411
|
+
});
|
|
2412
|
+
}
|
|
2376
2413
|
if (url.pathname === "/api/topology") {
|
|
2377
2414
|
return json3(topologyPayload());
|
|
2378
2415
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ interface UiLink {
|
|
|
47
47
|
}
|
|
48
48
|
declare function setConfig(cfg: MikrotikConfig): void;
|
|
49
49
|
declare function getConfig(): MikrotikConfig;
|
|
50
|
-
/** Names of every configured device, plus which one is the default. */
|
|
50
|
+
/** Names of every ENABLED configured device, plus which one is the default. */
|
|
51
51
|
declare function listDevices(): {
|
|
52
52
|
names: string[];
|
|
53
53
|
default: string;
|
|
@@ -55,6 +55,7 @@ declare function listDevices(): {
|
|
|
55
55
|
/**
|
|
56
56
|
* Resolve a (possibly undefined) device name to a concrete, existing config key.
|
|
57
57
|
* Accepts a config key OR a device's free-text label; falls back to the default.
|
|
58
|
+
* Only resolves to enabled devices.
|
|
58
59
|
*
|
|
59
60
|
* Matching is EXACT (key first, then label) — never fuzzy/substring — so a name
|
|
60
61
|
* like "Ali Home" can never collapse onto a different device such as "home".
|
|
@@ -71,7 +72,7 @@ interface DeviceDirectoryEntry {
|
|
|
71
72
|
/**
|
|
72
73
|
* Return the connection config for a device by key or label (or the default when
|
|
73
74
|
* `name` is undefined). Throws if an explicit name matches neither a key nor a
|
|
74
|
-
* label.
|
|
75
|
+
* label, or if the device is disabled.
|
|
75
76
|
*/
|
|
76
77
|
declare function getDevice(name?: string): DeviceConfig;
|
|
77
78
|
/** Options threaded into every tool registration. */
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
resolveDeviceName,
|
|
23
23
|
selectToolModules,
|
|
24
24
|
setConfig
|
|
25
|
-
} from "./shared/library-
|
|
25
|
+
} from "./shared/library-ymtf9zyk.js";
|
|
26
26
|
// src/server.ts
|
|
27
27
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
28
28
|
import { ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
@@ -337,7 +337,8 @@ var DeviceConfigSchema = z.object({
|
|
|
337
337
|
sourceMac: z.string().optional(),
|
|
338
338
|
macHost: z.string().optional(),
|
|
339
339
|
macPort: z.coerce.number().int().positive().optional(),
|
|
340
|
-
description: z.string().optional()
|
|
340
|
+
description: z.string().optional(),
|
|
341
|
+
disabled: z.boolean().optional()
|
|
341
342
|
});
|
|
342
343
|
var S3ConfigSchema = z.object({
|
|
343
344
|
accessKeyId: z.string().optional(),
|
|
@@ -584,13 +585,17 @@ function setConfig(cfg) {
|
|
|
584
585
|
function getConfig() {
|
|
585
586
|
return active;
|
|
586
587
|
}
|
|
588
|
+
function isEnabled(dc) {
|
|
589
|
+
return !dc.disabled;
|
|
590
|
+
}
|
|
587
591
|
function listDevices() {
|
|
588
|
-
|
|
592
|
+
const names = Object.entries(active.devices).filter(([, dc]) => isEnabled(dc)).map(([k]) => k);
|
|
593
|
+
return { names, default: active.defaultDevice };
|
|
589
594
|
}
|
|
590
595
|
function deviceKeyForLabel(name) {
|
|
591
596
|
const target = name.trim().toLowerCase();
|
|
592
597
|
for (const [key, dc] of Object.entries(active.devices)) {
|
|
593
|
-
if (dc.description && dc.description.trim().toLowerCase() === target)
|
|
598
|
+
if (isEnabled(dc) && dc.description && dc.description.trim().toLowerCase() === target)
|
|
594
599
|
return key;
|
|
595
600
|
}
|
|
596
601
|
return;
|
|
@@ -599,6 +604,8 @@ function deviceLabels() {
|
|
|
599
604
|
const seen = new Set;
|
|
600
605
|
const out = [];
|
|
601
606
|
for (const [key, dc] of Object.entries(active.devices)) {
|
|
607
|
+
if (!isEnabled(dc))
|
|
608
|
+
continue;
|
|
602
609
|
const label = dc.description?.trim();
|
|
603
610
|
if (label && label !== key && !(label in active.devices) && !seen.has(label)) {
|
|
604
611
|
seen.add(label);
|
|
@@ -609,13 +616,17 @@ function deviceLabels() {
|
|
|
609
616
|
}
|
|
610
617
|
function resolveDeviceName(name) {
|
|
611
618
|
if (name) {
|
|
612
|
-
if (name in active.devices)
|
|
619
|
+
if (name in active.devices && isEnabled(active.devices[name]))
|
|
613
620
|
return name;
|
|
614
621
|
const byLabel = deviceKeyForLabel(name);
|
|
615
622
|
if (byLabel)
|
|
616
623
|
return byLabel;
|
|
617
624
|
}
|
|
618
|
-
|
|
625
|
+
if (active.defaultDevice in active.devices && isEnabled(active.devices[active.defaultDevice])) {
|
|
626
|
+
return active.defaultDevice;
|
|
627
|
+
}
|
|
628
|
+
const firstEnabled = Object.entries(active.devices).find(([, dc]) => isEnabled(dc));
|
|
629
|
+
return firstEnabled ? firstEnabled[0] : active.defaultDevice;
|
|
619
630
|
}
|
|
620
631
|
function deviceTarget(dc) {
|
|
621
632
|
if (!dc)
|
|
@@ -623,7 +634,7 @@ function deviceTarget(dc) {
|
|
|
623
634
|
return dc.mac ? `MAC ${dc.mac}` : `${dc.host}:${dc.port ?? 22}`;
|
|
624
635
|
}
|
|
625
636
|
function deviceDirectory() {
|
|
626
|
-
return Object.entries(active.devices).map(([key, dc]) => ({
|
|
637
|
+
return Object.entries(active.devices).filter(([, dc]) => isEnabled(dc)).map(([key, dc]) => ({
|
|
627
638
|
key,
|
|
628
639
|
label: dc.description?.trim() || undefined,
|
|
629
640
|
target: deviceTarget(dc),
|
|
@@ -643,6 +654,9 @@ function getDevice(name) {
|
|
|
643
654
|
const dc = active.devices[key];
|
|
644
655
|
if (!dc)
|
|
645
656
|
throw new Error(`No device configuration available for '${key}'.`);
|
|
657
|
+
if (dc.disabled) {
|
|
658
|
+
throw new Error(`Device '${key}' is disabled. Enable it from the dashboard or config file.`);
|
|
659
|
+
}
|
|
646
660
|
return dc;
|
|
647
661
|
}
|
|
648
662
|
|
|
@@ -8313,7 +8327,7 @@ var cache = null;
|
|
|
8313
8327
|
async function gateway() {
|
|
8314
8328
|
if (cache)
|
|
8315
8329
|
return cache;
|
|
8316
|
-
const { moduleCatalog } = await import("./cli-
|
|
8330
|
+
const { moduleCatalog } = await import("./cli-0ctwspf1.js");
|
|
8317
8331
|
const forIndex = [];
|
|
8318
8332
|
const byName = new Map;
|
|
8319
8333
|
for (const mod of moduleCatalog) {
|
|
@@ -337,7 +337,8 @@ var DeviceConfigSchema = z.object({
|
|
|
337
337
|
sourceMac: z.string().optional(),
|
|
338
338
|
macHost: z.string().optional(),
|
|
339
339
|
macPort: z.coerce.number().int().positive().optional(),
|
|
340
|
-
description: z.string().optional()
|
|
340
|
+
description: z.string().optional(),
|
|
341
|
+
disabled: z.boolean().optional()
|
|
341
342
|
});
|
|
342
343
|
var S3ConfigSchema = z.object({
|
|
343
344
|
accessKeyId: z.string().optional(),
|
|
@@ -581,13 +582,17 @@ function setConfig(cfg) {
|
|
|
581
582
|
function getConfig() {
|
|
582
583
|
return active;
|
|
583
584
|
}
|
|
585
|
+
function isEnabled(dc) {
|
|
586
|
+
return !dc.disabled;
|
|
587
|
+
}
|
|
584
588
|
function listDevices() {
|
|
585
|
-
|
|
589
|
+
const names = Object.entries(active.devices).filter(([, dc]) => isEnabled(dc)).map(([k]) => k);
|
|
590
|
+
return { names, default: active.defaultDevice };
|
|
586
591
|
}
|
|
587
592
|
function deviceKeyForLabel(name) {
|
|
588
593
|
const target = name.trim().toLowerCase();
|
|
589
594
|
for (const [key, dc] of Object.entries(active.devices)) {
|
|
590
|
-
if (dc.description && dc.description.trim().toLowerCase() === target)
|
|
595
|
+
if (isEnabled(dc) && dc.description && dc.description.trim().toLowerCase() === target)
|
|
591
596
|
return key;
|
|
592
597
|
}
|
|
593
598
|
return;
|
|
@@ -596,6 +601,8 @@ function deviceLabels() {
|
|
|
596
601
|
const seen = new Set;
|
|
597
602
|
const out = [];
|
|
598
603
|
for (const [key, dc] of Object.entries(active.devices)) {
|
|
604
|
+
if (!isEnabled(dc))
|
|
605
|
+
continue;
|
|
599
606
|
const label = dc.description?.trim();
|
|
600
607
|
if (label && label !== key && !(label in active.devices) && !seen.has(label)) {
|
|
601
608
|
seen.add(label);
|
|
@@ -606,13 +613,17 @@ function deviceLabels() {
|
|
|
606
613
|
}
|
|
607
614
|
function resolveDeviceName(name) {
|
|
608
615
|
if (name) {
|
|
609
|
-
if (name in active.devices)
|
|
616
|
+
if (name in active.devices && isEnabled(active.devices[name]))
|
|
610
617
|
return name;
|
|
611
618
|
const byLabel = deviceKeyForLabel(name);
|
|
612
619
|
if (byLabel)
|
|
613
620
|
return byLabel;
|
|
614
621
|
}
|
|
615
|
-
|
|
622
|
+
if (active.defaultDevice in active.devices && isEnabled(active.devices[active.defaultDevice])) {
|
|
623
|
+
return active.defaultDevice;
|
|
624
|
+
}
|
|
625
|
+
const firstEnabled = Object.entries(active.devices).find(([, dc]) => isEnabled(dc));
|
|
626
|
+
return firstEnabled ? firstEnabled[0] : active.defaultDevice;
|
|
616
627
|
}
|
|
617
628
|
function deviceTarget(dc) {
|
|
618
629
|
if (!dc)
|
|
@@ -620,7 +631,7 @@ function deviceTarget(dc) {
|
|
|
620
631
|
return dc.mac ? `MAC ${dc.mac}` : `${dc.host}:${dc.port ?? 22}`;
|
|
621
632
|
}
|
|
622
633
|
function deviceDirectory() {
|
|
623
|
-
return Object.entries(active.devices).map(([key, dc]) => ({
|
|
634
|
+
return Object.entries(active.devices).filter(([, dc]) => isEnabled(dc)).map(([key, dc]) => ({
|
|
624
635
|
key,
|
|
625
636
|
label: dc.description?.trim() || undefined,
|
|
626
637
|
target: deviceTarget(dc),
|
|
@@ -640,6 +651,9 @@ function getDevice(name) {
|
|
|
640
651
|
const dc = active.devices[key];
|
|
641
652
|
if (!dc)
|
|
642
653
|
throw new Error(`No device configuration available for '${key}'.`);
|
|
654
|
+
if (dc.disabled) {
|
|
655
|
+
throw new Error(`Device '${key}' is disabled. Enable it from the dashboard or config file.`);
|
|
656
|
+
}
|
|
643
657
|
return dc;
|
|
644
658
|
}
|
|
645
659
|
|
|
@@ -8243,7 +8257,7 @@ var cache = null;
|
|
|
8243
8257
|
async function gateway() {
|
|
8244
8258
|
if (cache)
|
|
8245
8259
|
return cache;
|
|
8246
|
-
const { moduleCatalog } = await import("./library-
|
|
8260
|
+
const { moduleCatalog } = await import("./library-jve65pzw.js");
|
|
8247
8261
|
const forIndex = [];
|
|
8248
8262
|
const byName = new Map;
|
|
8249
8263
|
for (const mod of moduleCatalog) {
|