@usex/mikrotik-mcp 4.17.0 → 4.18.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 +5 -1
- package/dist/index.js +1 -1
- package/dist/shared/{cli-1ftjz1jx.js → cli-7jxnfmp0.js} +1 -1
- package/dist/shared/{cli-v75jtv6p.js → cli-dv2kmsh2.js} +51 -12
- package/dist/shared/{library-ydfn3v4j.js → library-77r1j24d.js} +1 -1
- package/dist/shared/{library-qma8metz.js → library-7m2c1g1y.js} +23 -11
- package/dist/ui/observability.html +25 -25
- package/package.json +1 -1
- package/schemas/tool-catalog.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -81,6 +81,7 @@ import {
|
|
|
81
81
|
moduleCatalog,
|
|
82
82
|
normalizeExport,
|
|
83
83
|
openSnapshotStore,
|
|
84
|
+
parseDisks,
|
|
84
85
|
parseKeyValues,
|
|
85
86
|
parseLeadingNumber,
|
|
86
87
|
parseRecords,
|
|
@@ -122,7 +123,7 @@ import {
|
|
|
122
123
|
updateAaaEntity,
|
|
123
124
|
updateSummaryLine,
|
|
124
125
|
writeBackup
|
|
125
|
-
} from "./shared/cli-
|
|
126
|
+
} from "./shared/cli-dv2kmsh2.js";
|
|
126
127
|
|
|
127
128
|
// src/cli.ts
|
|
128
129
|
import { existsSync as existsSync2 } from "fs";
|
|
@@ -764,6 +765,9 @@ async function probeDevice(name, dc) {
|
|
|
764
765
|
try {
|
|
765
766
|
neighbors.set(name, parseNeighbors(await client.run("/ip neighbor print detail")));
|
|
766
767
|
} catch {}
|
|
768
|
+
try {
|
|
769
|
+
status.disks = parseDisks(await client.run("/disk print detail"));
|
|
770
|
+
} catch {}
|
|
767
771
|
}
|
|
768
772
|
} catch (e) {
|
|
769
773
|
status = {
|
package/dist/index.js
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
selectToolModules,
|
|
30
30
|
setConfig,
|
|
31
31
|
updateSummaryLine
|
|
32
|
-
} from "./shared/library-
|
|
32
|
+
} from "./shared/library-7m2c1g1y.js";
|
|
33
33
|
// src/server.ts
|
|
34
34
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
35
35
|
import { ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
@@ -1802,9 +1802,16 @@ function parseFlagLegend(text) {
|
|
|
1802
1802
|
}
|
|
1803
1803
|
function parseKvTokens(chunk) {
|
|
1804
1804
|
const out = {};
|
|
1805
|
-
const re = /([A-Za-z][\w.-]*)=("(?:[^"\\]|\\.)*"|[^\s]*)/g;
|
|
1805
|
+
const re = /(\.?[A-Za-z][\w.-]*)=("(?:[^"\\]|\\.)*"|[^\s]*)/g;
|
|
1806
|
+
let prefix = "";
|
|
1806
1807
|
for (const m of chunk.matchAll(re)) {
|
|
1807
|
-
|
|
1808
|
+
let key = m[1];
|
|
1809
|
+
if (key.startsWith(".")) {
|
|
1810
|
+
key = prefix + key;
|
|
1811
|
+
} else {
|
|
1812
|
+
const dot = key.indexOf(".");
|
|
1813
|
+
prefix = dot > 0 ? key.slice(0, dot) : "";
|
|
1814
|
+
}
|
|
1808
1815
|
let value = m[2];
|
|
1809
1816
|
if (value.startsWith('"') && value.endsWith('"')) {
|
|
1810
1817
|
value = value.slice(1, -1).replace(/\\(.)/g, "$1");
|
|
@@ -1984,6 +1991,33 @@ function parseSizeToBytes(value) {
|
|
|
1984
1991
|
};
|
|
1985
1992
|
return n * (factor[unit] ?? 1);
|
|
1986
1993
|
}
|
|
1994
|
+
function parseDisks(text) {
|
|
1995
|
+
const collapsed = text.replace(/(\d) (?=\d)/g, "$1");
|
|
1996
|
+
const { rows } = parseRecords(collapsed);
|
|
1997
|
+
const disks = [];
|
|
1998
|
+
for (const r of rows) {
|
|
1999
|
+
const slot = r.slot ?? r.name ?? "";
|
|
2000
|
+
if (!slot)
|
|
2001
|
+
continue;
|
|
2002
|
+
if (/E/.test(r.flags ?? ""))
|
|
2003
|
+
continue;
|
|
2004
|
+
const size = parseLeadingNumber(r.size);
|
|
2005
|
+
if (size == null || size <= 0)
|
|
2006
|
+
continue;
|
|
2007
|
+
const free = parseLeadingNumber(r.free);
|
|
2008
|
+
const usePct = parseLeadingNumber(r.use);
|
|
2009
|
+
disks.push({
|
|
2010
|
+
slot,
|
|
2011
|
+
model: r.model,
|
|
2012
|
+
fs: r.fs,
|
|
2013
|
+
size,
|
|
2014
|
+
free: free ?? undefined,
|
|
2015
|
+
mountPoint: r["mount-point"],
|
|
2016
|
+
usedPct: usePct ?? (free != null && size > 0 ? Math.round((size - free) / size * 100) : undefined)
|
|
2017
|
+
});
|
|
2018
|
+
}
|
|
2019
|
+
return disks;
|
|
2020
|
+
}
|
|
1987
2021
|
|
|
1988
2022
|
// src/core/ui-meta.ts
|
|
1989
2023
|
var UI_META_KEY = "ui";
|
|
@@ -8995,7 +9029,7 @@ var cache = null;
|
|
|
8995
9029
|
async function gateway() {
|
|
8996
9030
|
if (cache)
|
|
8997
9031
|
return cache;
|
|
8998
|
-
const { moduleCatalog } = await import("./cli-
|
|
9032
|
+
const { moduleCatalog } = await import("./cli-7jxnfmp0.js");
|
|
8999
9033
|
const forIndex = [];
|
|
9000
9034
|
const byName = new Map;
|
|
9001
9035
|
for (const mod of moduleCatalog) {
|
|
@@ -31752,12 +31786,12 @@ function num2(v) {
|
|
|
31752
31786
|
return Number.isFinite(n) ? n : undefined;
|
|
31753
31787
|
}
|
|
31754
31788
|
function bandFromRow(row) {
|
|
31755
|
-
const b = (row.band ?? row["configuration.
|
|
31789
|
+
const b = (row["channel.band"] ?? row.band ?? row.bands ?? row["configuration.band"] ?? "").toLowerCase();
|
|
31756
31790
|
if (b.includes("2ghz") || b.includes("2.4"))
|
|
31757
31791
|
return "2ghz";
|
|
31758
31792
|
if (b.includes("5ghz") || b.includes("5."))
|
|
31759
31793
|
return "5ghz";
|
|
31760
|
-
const ch = num2(row.
|
|
31794
|
+
const ch = num2(row["channel.frequency"] ?? row.channel ?? row.frequency);
|
|
31761
31795
|
if (ch != null) {
|
|
31762
31796
|
if (ch >= 5000 || ch >= 36 && ch <= 177)
|
|
31763
31797
|
return "5ghz";
|
|
@@ -31767,7 +31801,7 @@ function bandFromRow(row) {
|
|
|
31767
31801
|
return "unknown";
|
|
31768
31802
|
}
|
|
31769
31803
|
function channelOf(row) {
|
|
31770
|
-
return num2(row.
|
|
31804
|
+
return num2(row["channel.frequency"] ?? row.channel ?? row.frequency);
|
|
31771
31805
|
}
|
|
31772
31806
|
function normalizeCapsmanState(raw) {
|
|
31773
31807
|
if (!raw)
|
|
@@ -31778,9 +31812,12 @@ function normalizeCapsmanState(raw) {
|
|
|
31778
31812
|
if (rid)
|
|
31779
31813
|
clientsByRadio.set(rid, (clientsByRadio.get(rid) ?? 0) + 1);
|
|
31780
31814
|
}
|
|
31781
|
-
const
|
|
31782
|
-
|
|
31783
|
-
|
|
31815
|
+
const interfaceRows = raw.interfaces ?? [];
|
|
31816
|
+
const useInterfaces = interfaceRows.length > 0;
|
|
31817
|
+
const radioRows = useInterfaces ? interfaceRows : raw.radios;
|
|
31818
|
+
const radios = radioRows.map((row) => {
|
|
31819
|
+
const cap = useInterfaces ? row.name ?? row["radio-mac"] ?? "?" : row["remote-cap-identity"] ?? row.identity ?? row["cap-name"] ?? row.name ?? "?";
|
|
31820
|
+
const radioId = useInterfaces ? row.name ?? row["radio-mac"] ?? cap : row.interface ?? row.name ?? row["radio-mac"] ?? cap;
|
|
31784
31821
|
const tag = parseFloorTag(`${cap} ${row.comment ?? ""}`);
|
|
31785
31822
|
const res = raw.resources[cap] ?? {};
|
|
31786
31823
|
return {
|
|
@@ -31788,7 +31825,7 @@ function normalizeCapsmanState(raw) {
|
|
|
31788
31825
|
radioId,
|
|
31789
31826
|
band: bandFromRow(row),
|
|
31790
31827
|
channel: channelOf(row),
|
|
31791
|
-
width: row.width ?? row
|
|
31828
|
+
width: row["channel.width"] ?? row.width,
|
|
31792
31829
|
txPower: num2(row["tx-power"] ?? row["tx-power-dbm"]),
|
|
31793
31830
|
clientCount: clientsByRadio.get(radioId) ?? num2(row["registered-clients"]) ?? 0,
|
|
31794
31831
|
floor: tag.floor,
|
|
@@ -31865,10 +31902,11 @@ async function fetchCapsmanState(ctx) {
|
|
|
31865
31902
|
if (!path)
|
|
31866
31903
|
return normalizeCapsmanState(null);
|
|
31867
31904
|
const isCapsman = path === "/caps-man";
|
|
31868
|
-
const [manager, remoteCaps, radios, registrations, securityConfigs, accessList] = await Promise.all([
|
|
31905
|
+
const [manager, remoteCaps, radios, interfaces, registrations, securityConfigs, accessList] = await Promise.all([
|
|
31869
31906
|
fetchKv(isCapsman ? "/caps-man manager print" : `${path} capsman print`, ctx),
|
|
31870
31907
|
fetchRows(isCapsman ? "/caps-man remote-cap print detail" : `${path} capsman remote-cap print detail`, ctx),
|
|
31871
31908
|
fetchRows(isCapsman ? "/caps-man radio print detail" : `${path} radio print detail`, ctx),
|
|
31909
|
+
isCapsman ? Promise.resolve([]) : fetchRows(`${path} print detail`, ctx),
|
|
31872
31910
|
fetchRows(isCapsman ? "/caps-man registration-table print detail" : `${path} registration-table print detail`, ctx),
|
|
31873
31911
|
fetchRows(isCapsman ? "/caps-man security print detail" : `${path} security print detail`, ctx),
|
|
31874
31912
|
fetchRows(isCapsman ? "/caps-man access-list print detail" : `${path} access-list print detail`, ctx)
|
|
@@ -31878,6 +31916,7 @@ async function fetchCapsmanState(ctx) {
|
|
|
31878
31916
|
manager,
|
|
31879
31917
|
remoteCaps,
|
|
31880
31918
|
radios,
|
|
31919
|
+
interfaces,
|
|
31881
31920
|
registrations,
|
|
31882
31921
|
securityConfigs,
|
|
31883
31922
|
accessList,
|
|
@@ -33266,4 +33305,4 @@ function selectToolModules(filter = {}, catalog = moduleCatalog) {
|
|
|
33266
33305
|
}).map((m) => m.tools);
|
|
33267
33306
|
}
|
|
33268
33307
|
|
|
33269
|
-
export { __require, DEFAULT_SNAPSHOT_DB, DEFAULT_CONFIG_HISTORY_DIR, DeviceConfigSchema, ToolFilterSchema, MikrotikConfigSchema, getConfigSource, loadConfig, logger, setConfig, getConfig, listDevices, deviceLabels, resolveDeviceName, deviceDirectory, isMacTelnetDevice, createDeviceClient, describeTransport, isPoolEnabled, closeAll, poolStatus, getMemoryStore, closeMemoryStore, reopenMemoryStore, executeMikrotikCommand, createContext, Cmd, isEmpty, looksLikeError, commandUnsupported, parseKeyValues, parseRouterosDate, parseSize, parseSystemResource, parseRecords, parseLeadingNumber, riskOf, REDACTED, redact, configureRecorder, getEventStore, subscribe, subscriberCount, registerTools, fetchDevices, sampleDeviceTraffic, sampleAllTraffic, setDeviceLimits, blockDevice, allowDevice, makeDeviceStatic, setDeviceIp, setDeviceLabel, removeDeviceLease, devicesView, PROMPTS_DIR, UI_DIST_DIR, registerUiResources, backupDir, listBackups, readBackup, writeBackup, deleteBackup, renameBackup, createLocalBackup, restoreLocalBackup, isS3Configured, getS3Client, presignExpiresIn, s3Target, splitCommands, buildChangePlan, renderPlan, diffLines, normalizeExport, analyzeDrift, attributeChanges, openSnapshotStore, applyWritesSafely, captureSnapshot, DEFAULT_TZSP_PORT, capture2 as capture, AAA_ENTITIES, listAaaEntity, addAaaEntity, updateAaaEntity, removeAaaEntity, toggleAaaEntity, getRadiusIncoming, setRadiusIncoming, resetRadiusCounters, getUmSettings, setUmSettings, VERSION, WEBSITE_URL, LOGO_URL, SERVER_TITLE, SERVER_DESCRIPTION, SERVER_NAME, PKG_META, loadFileCacheSync, fetchLatestRelease, checkForUpdate, updateSummaryLine, fetchAllReleases, buildChannelPlanCommands, reportWeakClients, runCapsmanAudit, steerAlreadyPresent, buildSteerCommands, loadBalancePlan, buildLoadBalanceCommands, buildFtCommands, buildHaCommands, haGuidance, capsmanOverview, fetchCapsmanState, moduleCatalog, allToolModules, ALWAYS_ON_MODULES, selectToolModules };
|
|
33308
|
+
export { __require, DEFAULT_SNAPSHOT_DB, DEFAULT_CONFIG_HISTORY_DIR, DeviceConfigSchema, ToolFilterSchema, MikrotikConfigSchema, getConfigSource, loadConfig, logger, setConfig, getConfig, listDevices, deviceLabels, resolveDeviceName, deviceDirectory, isMacTelnetDevice, createDeviceClient, describeTransport, isPoolEnabled, closeAll, poolStatus, getMemoryStore, closeMemoryStore, reopenMemoryStore, executeMikrotikCommand, createContext, Cmd, isEmpty, looksLikeError, commandUnsupported, parseKeyValues, parseRouterosDate, parseSize, parseSystemResource, parseRecords, parseLeadingNumber, parseDisks, riskOf, REDACTED, redact, configureRecorder, getEventStore, subscribe, subscriberCount, registerTools, fetchDevices, sampleDeviceTraffic, sampleAllTraffic, setDeviceLimits, blockDevice, allowDevice, makeDeviceStatic, setDeviceIp, setDeviceLabel, removeDeviceLease, devicesView, PROMPTS_DIR, UI_DIST_DIR, registerUiResources, backupDir, listBackups, readBackup, writeBackup, deleteBackup, renameBackup, createLocalBackup, restoreLocalBackup, isS3Configured, getS3Client, presignExpiresIn, s3Target, splitCommands, buildChangePlan, renderPlan, diffLines, normalizeExport, analyzeDrift, attributeChanges, openSnapshotStore, applyWritesSafely, captureSnapshot, DEFAULT_TZSP_PORT, capture2 as capture, AAA_ENTITIES, listAaaEntity, addAaaEntity, updateAaaEntity, removeAaaEntity, toggleAaaEntity, getRadiusIncoming, setRadiusIncoming, resetRadiusCounters, getUmSettings, setUmSettings, VERSION, WEBSITE_URL, LOGO_URL, SERVER_TITLE, SERVER_DESCRIPTION, SERVER_NAME, PKG_META, loadFileCacheSync, fetchLatestRelease, checkForUpdate, updateSummaryLine, fetchAllReleases, buildChannelPlanCommands, reportWeakClients, runCapsmanAudit, steerAlreadyPresent, buildSteerCommands, loadBalancePlan, buildLoadBalanceCommands, buildFtCommands, buildHaCommands, haGuidance, capsmanOverview, fetchCapsmanState, moduleCatalog, allToolModules, ALWAYS_ON_MODULES, selectToolModules };
|
|
@@ -1783,9 +1783,16 @@ function parseFlagLegend(text) {
|
|
|
1783
1783
|
}
|
|
1784
1784
|
function parseKvTokens(chunk) {
|
|
1785
1785
|
const out = {};
|
|
1786
|
-
const re = /([A-Za-z][\w.-]*)=("(?:[^"\\]|\\.)*"|[^\s]*)/g;
|
|
1786
|
+
const re = /(\.?[A-Za-z][\w.-]*)=("(?:[^"\\]|\\.)*"|[^\s]*)/g;
|
|
1787
|
+
let prefix = "";
|
|
1787
1788
|
for (const m of chunk.matchAll(re)) {
|
|
1788
|
-
|
|
1789
|
+
let key = m[1];
|
|
1790
|
+
if (key.startsWith(".")) {
|
|
1791
|
+
key = prefix + key;
|
|
1792
|
+
} else {
|
|
1793
|
+
const dot = key.indexOf(".");
|
|
1794
|
+
prefix = dot > 0 ? key.slice(0, dot) : "";
|
|
1795
|
+
}
|
|
1789
1796
|
let value = m[2];
|
|
1790
1797
|
if (value.startsWith('"') && value.endsWith('"')) {
|
|
1791
1798
|
value = value.slice(1, -1).replace(/\\(.)/g, "$1");
|
|
@@ -8804,7 +8811,7 @@ var cache = null;
|
|
|
8804
8811
|
async function gateway() {
|
|
8805
8812
|
if (cache)
|
|
8806
8813
|
return cache;
|
|
8807
|
-
const { moduleCatalog } = await import("./library-
|
|
8814
|
+
const { moduleCatalog } = await import("./library-77r1j24d.js");
|
|
8808
8815
|
const forIndex = [];
|
|
8809
8816
|
const byName = new Map;
|
|
8810
8817
|
for (const mod of moduleCatalog) {
|
|
@@ -31482,12 +31489,12 @@ function num2(v) {
|
|
|
31482
31489
|
return Number.isFinite(n) ? n : undefined;
|
|
31483
31490
|
}
|
|
31484
31491
|
function bandFromRow(row) {
|
|
31485
|
-
const b = (row.band ?? row["configuration.
|
|
31492
|
+
const b = (row["channel.band"] ?? row.band ?? row.bands ?? row["configuration.band"] ?? "").toLowerCase();
|
|
31486
31493
|
if (b.includes("2ghz") || b.includes("2.4"))
|
|
31487
31494
|
return "2ghz";
|
|
31488
31495
|
if (b.includes("5ghz") || b.includes("5."))
|
|
31489
31496
|
return "5ghz";
|
|
31490
|
-
const ch = num2(row.
|
|
31497
|
+
const ch = num2(row["channel.frequency"] ?? row.channel ?? row.frequency);
|
|
31491
31498
|
if (ch != null) {
|
|
31492
31499
|
if (ch >= 5000 || ch >= 36 && ch <= 177)
|
|
31493
31500
|
return "5ghz";
|
|
@@ -31497,7 +31504,7 @@ function bandFromRow(row) {
|
|
|
31497
31504
|
return "unknown";
|
|
31498
31505
|
}
|
|
31499
31506
|
function channelOf(row) {
|
|
31500
|
-
return num2(row.
|
|
31507
|
+
return num2(row["channel.frequency"] ?? row.channel ?? row.frequency);
|
|
31501
31508
|
}
|
|
31502
31509
|
function normalizeCapsmanState(raw) {
|
|
31503
31510
|
if (!raw)
|
|
@@ -31508,9 +31515,12 @@ function normalizeCapsmanState(raw) {
|
|
|
31508
31515
|
if (rid)
|
|
31509
31516
|
clientsByRadio.set(rid, (clientsByRadio.get(rid) ?? 0) + 1);
|
|
31510
31517
|
}
|
|
31511
|
-
const
|
|
31512
|
-
|
|
31513
|
-
|
|
31518
|
+
const interfaceRows = raw.interfaces ?? [];
|
|
31519
|
+
const useInterfaces = interfaceRows.length > 0;
|
|
31520
|
+
const radioRows = useInterfaces ? interfaceRows : raw.radios;
|
|
31521
|
+
const radios = radioRows.map((row) => {
|
|
31522
|
+
const cap = useInterfaces ? row.name ?? row["radio-mac"] ?? "?" : row["remote-cap-identity"] ?? row.identity ?? row["cap-name"] ?? row.name ?? "?";
|
|
31523
|
+
const radioId = useInterfaces ? row.name ?? row["radio-mac"] ?? cap : row.interface ?? row.name ?? row["radio-mac"] ?? cap;
|
|
31514
31524
|
const tag = parseFloorTag(`${cap} ${row.comment ?? ""}`);
|
|
31515
31525
|
const res = raw.resources[cap] ?? {};
|
|
31516
31526
|
return {
|
|
@@ -31518,7 +31528,7 @@ function normalizeCapsmanState(raw) {
|
|
|
31518
31528
|
radioId,
|
|
31519
31529
|
band: bandFromRow(row),
|
|
31520
31530
|
channel: channelOf(row),
|
|
31521
|
-
width: row.width ?? row
|
|
31531
|
+
width: row["channel.width"] ?? row.width,
|
|
31522
31532
|
txPower: num2(row["tx-power"] ?? row["tx-power-dbm"]),
|
|
31523
31533
|
clientCount: clientsByRadio.get(radioId) ?? num2(row["registered-clients"]) ?? 0,
|
|
31524
31534
|
floor: tag.floor,
|
|
@@ -31595,10 +31605,11 @@ async function fetchCapsmanState(ctx) {
|
|
|
31595
31605
|
if (!path)
|
|
31596
31606
|
return normalizeCapsmanState(null);
|
|
31597
31607
|
const isCapsman = path === "/caps-man";
|
|
31598
|
-
const [manager, remoteCaps, radios, registrations, securityConfigs, accessList] = await Promise.all([
|
|
31608
|
+
const [manager, remoteCaps, radios, interfaces, registrations, securityConfigs, accessList] = await Promise.all([
|
|
31599
31609
|
fetchKv(isCapsman ? "/caps-man manager print" : `${path} capsman print`, ctx),
|
|
31600
31610
|
fetchRows(isCapsman ? "/caps-man remote-cap print detail" : `${path} capsman remote-cap print detail`, ctx),
|
|
31601
31611
|
fetchRows(isCapsman ? "/caps-man radio print detail" : `${path} radio print detail`, ctx),
|
|
31612
|
+
isCapsman ? Promise.resolve([]) : fetchRows(`${path} print detail`, ctx),
|
|
31602
31613
|
fetchRows(isCapsman ? "/caps-man registration-table print detail" : `${path} registration-table print detail`, ctx),
|
|
31603
31614
|
fetchRows(isCapsman ? "/caps-man security print detail" : `${path} security print detail`, ctx),
|
|
31604
31615
|
fetchRows(isCapsman ? "/caps-man access-list print detail" : `${path} access-list print detail`, ctx)
|
|
@@ -31608,6 +31619,7 @@ async function fetchCapsmanState(ctx) {
|
|
|
31608
31619
|
manager,
|
|
31609
31620
|
remoteCaps,
|
|
31610
31621
|
radios,
|
|
31622
|
+
interfaces,
|
|
31611
31623
|
registrations,
|
|
31612
31624
|
securityConfigs,
|
|
31613
31625
|
accessList,
|