@usex/mikrotik-mcp 4.10.0 → 4.12.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/README.md CHANGED
@@ -349,6 +349,10 @@ On top of the per-scope tools, the server ships higher-level workflows:
349
349
  CRL, segmentation, DNS) plus an orchestrator. Every audit is read-only; every
350
350
  fix defaults to dry-run and snapshots + Safe-Modes before writing, remediating
351
351
  by explicit `finding_id`.
352
+ - **[Port-Scan Detection](docs/port-scan-detection.md)** — detect (never block) six
353
+ port-scan signatures (psd, Nmap FIN/NULL/Xmas, SYN/FIN, SYN/RST) by tagging the
354
+ source, inside a trust-excluding `detect-portscan` jump-gate; explicit signature
355
+ selection, trust-list pre-flight, snapshot + Safe-Mode apply.
352
356
  - **[Packet Capture Studio](docs/packet-capture.md)** — stream mirrored packets to
353
357
  the host as TZSP, decode them live in the dashboard, and export `.pcap`.
354
358
  - **[Discovery](docs/discovery.md)** — `bun run discover` lists MikroTik devices on
@@ -380,6 +384,7 @@ source** (`bun run gen:schemas`) so they can never drift:
380
384
  | **[Config Snapshots](docs/config-snapshots.md)** | `/export` snapshots + time-travel diff |
381
385
  | **[Firewall Audit](docs/firewall-audit.md)** | Shadowed/broad/dead rules, risk-scored |
382
386
  | **[Security Hardening](docs/security-hardening.md)** | Per-category audit+remediate, fix by finding_id, snapshot + Safe-Mode |
387
+ | **[Port-Scan Detection](docs/port-scan-detection.md)** | Detect+tag six scan signatures behind a trust-excluding jump-gate |
383
388
  | **[Packet Capture Studio](docs/packet-capture.md)** | Live TZSP capture + pcap export |
384
389
  | **[Discovery](docs/discovery.md)** | `bun run discover`, MNDP neighbours, topology map |
385
390
  | **[Config Studio](docs/config-studio.md)** | Edit config in the dashboard with autocomplete |
package/dist/cli.js CHANGED
@@ -106,12 +106,13 @@ import {
106
106
  updateAaaEntity,
107
107
  updateSummaryLine,
108
108
  writeBackup
109
- } from "./shared/cli-vfm5c52q.js";
109
+ } from "./shared/cli-07emrpkr.js";
110
110
 
111
111
  // src/cli.ts
112
112
  import { existsSync as existsSync2 } from "fs";
113
113
 
114
114
  // src/observability/dashboard.ts
115
+ import { spawn } from "child_process";
115
116
  import { readFileSync as readFileSync2 } from "fs";
116
117
  import { homedir, networkInterfaces } from "os";
117
118
  import { dirname as dirname4, join as join2 } from "path";
@@ -1473,6 +1474,24 @@ var JSON_HEADERS3 = { "content-type": "application/json; charset=utf-8" };
1473
1474
  function json3(body, status = 200) {
1474
1475
  return new Response(JSON.stringify(body), { status, headers: JSON_HEADERS3 });
1475
1476
  }
1477
+ function restartProcess() {
1478
+ let ok = false;
1479
+ try {
1480
+ const child = spawn(process.execPath, process.argv.slice(1), {
1481
+ cwd: process.cwd(),
1482
+ env: { ...process.env, MIKROTIK_RESTART_DELAY_MS: "1500" },
1483
+ detached: true,
1484
+ stdio: "inherit"
1485
+ });
1486
+ child.unref();
1487
+ ok = true;
1488
+ logger.warn("Dashboard requested a restart \u2014 relaunched a fresh server process; this one is exiting.");
1489
+ } catch (e) {
1490
+ logger.error(`Restart relaunch failed: ${e instanceof Error ? e.message : String(e)}. Exiting anyway.`);
1491
+ }
1492
+ setTimeout(() => process.exit(0), 500);
1493
+ return ok;
1494
+ }
1476
1495
  function dashboardHtml() {
1477
1496
  try {
1478
1497
  return readFileSync2(join2(UI_DIST_DIR, "observability.html"), "utf8");
@@ -1771,6 +1790,28 @@ async function configRoutes(req, url, admin) {
1771
1790
  const rolledBack = admin.rollback(String(body?.pendingId ?? ""));
1772
1791
  return json3({ rolledBack, config: redact(getConfig()) });
1773
1792
  }
1793
+ if (p === "/api/reload" && req.method === "POST") {
1794
+ const body = await readJson(req);
1795
+ if (body?.hard === true) {
1796
+ const relaunched = restartProcess();
1797
+ return json3({
1798
+ ok: true,
1799
+ mode: "restart",
1800
+ note: relaunched ? "Restarting now \u2014 a fresh server process was launched and will bind the same port(s) in ~1.5s. Reconnect shortly." : "Could not self-relaunch; the process is exiting. It only comes back if a supervisor respawns it."
1801
+ });
1802
+ }
1803
+ try {
1804
+ const cfg = loadConfig();
1805
+ setConfig(cfg);
1806
+ const devices = Object.keys(cfg.devices);
1807
+ logger.info(`Config reloaded from source \u2014 ${devices.length} device(s): ${devices.join(", ")}`);
1808
+ return json3({ ok: true, mode: "config", count: devices.length, devices });
1809
+ } catch (e) {
1810
+ const error = e instanceof Error ? e.message : String(e);
1811
+ logger.error(`Config reload failed: ${error}`);
1812
+ return json3({ ok: false, error }, 500);
1813
+ }
1814
+ }
1774
1815
  if (p === "/api/config/history" && req.method === "GET") {
1775
1816
  const current = JSON.stringify(redact(getConfig()), null, 2);
1776
1817
  const versions = listVersions().map((v) => {
@@ -3236,6 +3277,11 @@ async function main() {
3236
3277
  if (command === "auth-check") {
3237
3278
  process.exit(await authCheck());
3238
3279
  }
3280
+ const restartDelayMs = Number.parseInt(process.env.MIKROTIK_RESTART_DELAY_MS ?? "", 10);
3281
+ if (Number.isFinite(restartDelayMs) && restartDelayMs > 0) {
3282
+ logger.info(`Restart: waiting ${restartDelayMs}ms for the previous process to release its ports\u2026`);
3283
+ await new Promise((resolve) => setTimeout(resolve, restartDelayMs));
3284
+ }
3239
3285
  const cfg = loadConfig();
3240
3286
  setConfig(cfg);
3241
3287
  await printBanner();
package/dist/index.js CHANGED
@@ -29,7 +29,7 @@ import {
29
29
  selectToolModules,
30
30
  setConfig,
31
31
  updateSummaryLine
32
- } from "./shared/library-vpg7d53z.js";
32
+ } from "./shared/library-pczgrhdt.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";