mikromcp 1.6.1 → 1.7.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
@@ -12,12 +12,12 @@
12
12
 
13
13
  [![CI](https://github.com/AliKarami/MikroMCP/actions/workflows/ci.yml/badge.svg)](https://github.com/AliKarami/MikroMCP/actions/workflows/ci.yml)
14
14
  [![Release](https://github.com/AliKarami/MikroMCP/actions/workflows/release.yml/badge.svg)](https://github.com/AliKarami/MikroMCP/actions/workflows/release.yml)
15
- [![Version](https://img.shields.io/badge/version-v1.6.1-EA580C)](package.json)
15
+ [![Version](https://img.shields.io/badge/version-v1.7.0-EA580C)](package.json)
16
16
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
17
17
  [![Node.js >= 22](https://img.shields.io/badge/node-%3E%3D22-339933)](package.json)
18
18
  [![RouterOS 7.x](https://img.shields.io/badge/RouterOS-7.x-293239)](https://help.mikrotik.com/docs/display/ROS/REST+API)
19
19
  [![MCP Server](https://img.shields.io/badge/MCP-server-6f42c1)](https://modelcontextprotocol.io)
20
- [![Tools](https://img.shields.io/badge/MCP%20tools-117-0f766e)](https://github.com/AliKarami/MikroMCP/wiki/Available-Tools)
20
+ [![Tools](https://img.shields.io/badge/MCP%20tools-118-0f766e)](https://github.com/AliKarami/MikroMCP/wiki/Available-Tools)
21
21
  [![MikroMCP MCP server](https://glama.ai/mcp/servers/AliKarami/MikroMCP/badges/score.svg)](https://glama.ai/mcp/servers/AliKarami/MikroMCP)
22
22
 
23
23
  MikroMCP exists because raw router CLI access is the wrong abstraction for AI agents. RouterOS is powerful, but asking an LLM to improvise shell commands against production network gear is risky. MikroMCP gives agents a controlled tool surface: strict schemas, idempotent writes, dry-run previews, per-router circuit breakers, retry policies, RBAC, audit logs, snapshots, and rollback-aware change workflows.
@@ -53,7 +53,7 @@ That's the whole setup for a single-router stdio deployment. For standalone bina
53
53
  | 🤖 **AI-agent fit** | Human-readable responses plus structured JSON content for reasoning, chaining, and automation; server advertises an `instructions` string on MCP initialize so clients self-configure; optional [`routerId` resolved via `MIKROMCP_DEFAULT_ROUTER`](https://github.com/AliKarami/MikroMCP/wiki/Configuration) for single-router setups; [usage skill](docs/wiki/Using-the-Skill.md) for safe, guided tool use in Claude Code |
54
54
  | 🧩 **MCP compatibility** | stdio for desktop clients, Streamable HTTP and legacy SSE for remote or service-style clients |
55
55
 
56
- **117 typed tools** in total — browse the full catalog with parameters, defaults, and copy-paste example prompts in **[Available Tools](https://github.com/AliKarami/MikroMCP/wiki/Available-Tools)**.
56
+ **118 typed tools** in total — browse the full catalog with parameters, defaults, and copy-paste example prompts in **[Available Tools](https://github.com/AliKarami/MikroMCP/wiki/Available-Tools)**.
57
57
 
58
58
  ---
59
59
 
@@ -139,7 +139,7 @@ AI assistants can use MikroMCP to:
139
139
 
140
140
  ### What is MikroMCP?
141
141
 
142
- MikroMCP is an open-source [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that exposes MikroTik RouterOS as 117 typed, auditable tools — letting AI assistants inspect, diagnose, and safely operate routers in natural language instead of improvising CLI commands.
142
+ MikroMCP is an open-source [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that exposes MikroTik RouterOS as 118 typed, auditable tools — letting AI assistants inspect, diagnose, and safely operate routers in natural language instead of improvising CLI commands.
143
143
 
144
144
  ### MikroMCP vs RouterOS API
145
145
 
@@ -188,7 +188,7 @@ The README stays intentionally short. Everything below is documented in depth in
188
188
  | [Connecting to Claude Desktop](https://github.com/AliKarami/MikroMCP/wiki/Connecting-to-Claude-Desktop) | Register MikroMCP in Claude Desktop |
189
189
  | [Connecting to AI Assistants](https://github.com/AliKarami/MikroMCP/wiki/Connecting-to-AI-Assistants) | Claude Code, Cursor, Codex, HTTP/Docker/systemd |
190
190
  | [Using the Skill](docs/wiki/Using-the-Skill.md) | Install the MikroMCP usage skill so your assistant drives the tools safely |
191
- | [Available Tools](https://github.com/AliKarami/MikroMCP/wiki/Available-Tools) | All 117 tools — parameters and example prompts |
191
+ | [Available Tools](https://github.com/AliKarami/MikroMCP/wiki/Available-Tools) | All 118 tools — parameters and example prompts |
192
192
  | [Architecture](https://github.com/AliKarami/MikroMCP/wiki/Architecture) | System layers, request pipeline, auth model |
193
193
  | [Error Handling](https://github.com/AliKarami/MikroMCP/wiki/Error-Handling) | Error categories, retry engine, circuit breaker |
194
194
  | [Security](https://github.com/AliKarami/MikroMCP/wiki/Security) | Threat model, hardening checklist, vulnerability reporting |
package/dist/main.js CHANGED
@@ -11160,6 +11160,54 @@ var bulkExecuteInputSchema = z46.object({
11160
11160
  "Fleet confirmation token from a prior APPROVAL_REQUIRED response. Required to fan out a destructive tool."
11161
11161
  )
11162
11162
  }).strict();
11163
+ var listRoutersInputSchema = z46.object({
11164
+ tags: z46.array(z46.string()).optional().describe('Only return routers having any of these tags (e.g. ["edge", "prod"])')
11165
+ }).strict();
11166
+ var listRoutersTool = {
11167
+ name: "list_routers",
11168
+ title: "List Routers",
11169
+ description: "List the routers configured in the registry (routers.yaml): id, host, port, TLS status, tags, ROS version, and which is the default. Read-only reflection of local config \u2014 no RouterOS API call, no credentials in the response. Use it to discover valid routerId values and tags for targeting other tools (including bulk_execute).",
11170
+ inputSchema: listRoutersInputSchema,
11171
+ annotations: {
11172
+ readOnlyHint: true,
11173
+ destructiveHint: false,
11174
+ idempotentHint: true,
11175
+ openWorldHint: false
11176
+ },
11177
+ skipRouterContext: true,
11178
+ async handler(params, context) {
11179
+ const parsed = listRoutersInputSchema.parse(params);
11180
+ const { identity, appConfig } = context;
11181
+ const defaultRouter = appConfig.defaultRouter;
11182
+ log47.info({ tags: parsed.tags, identityId: identity.id }, "Listing routers");
11183
+ let routers = context.routerRegistry.listRouters(parsed.tags);
11184
+ if (identity.allowedRouters.length > 0) {
11185
+ routers = routers.filter((r) => identity.allowedRouters.includes(r.id));
11186
+ }
11187
+ const soleDefaultId = defaultRouter === void 0 && routers.length === 1 ? routers[0].id : void 0;
11188
+ const rows = routers.map((r) => ({
11189
+ id: r.id,
11190
+ host: r.host,
11191
+ port: r.port,
11192
+ tlsEnabled: r.tls.enabled,
11193
+ tags: r.tags,
11194
+ rosVersion: r.rosVersion,
11195
+ isDefault: defaultRouter !== void 0 ? r.id === defaultRouter : r.id === soleDefaultId
11196
+ }));
11197
+ const total = rows.length;
11198
+ const header = `Routers: ${total === 0 ? "none" : `1-${total} of ${total}`}.`;
11199
+ const lines = rows.map(
11200
+ (r) => ` ${compactFields(
11201
+ { ...r, tags: r.tags.join(",") },
11202
+ ["id", "host", "port", "tlsEnabled", "tags", "rosVersion", "isDefault"]
11203
+ )}`
11204
+ );
11205
+ return {
11206
+ content: total === 0 ? header : [header, ...lines].join("\n"),
11207
+ structuredContent: { routers: rows, total, returned: total }
11208
+ };
11209
+ }
11210
+ };
11163
11211
  function createFleetTools(baseTools2) {
11164
11212
  const toolMap = new Map(baseTools2.map((t) => [t.name, t]));
11165
11213
  const checkRouterHealthTool = {
@@ -11466,7 +11514,7 @@ function createFleetTools(baseTools2) {
11466
11514
  };
11467
11515
  }
11468
11516
  };
11469
- return [checkRouterHealthTool, bulkExecuteTool];
11517
+ return [checkRouterHealthTool, bulkExecuteTool, listRoutersTool];
11470
11518
  }
11471
11519
 
11472
11520
  // src/domain/tools/index.ts
@@ -12498,7 +12546,7 @@ var ConnectionPool = class {
12498
12546
  };
12499
12547
 
12500
12548
  // src/version.ts
12501
- var VERSION = "1.6.1";
12549
+ var VERSION = "1.7.0";
12502
12550
 
12503
12551
  // src/mcp/server.ts
12504
12552
  var SERVER_INSTRUCTIONS = [
@@ -12909,7 +12957,7 @@ import { existsSync as existsSync3, readFileSync as readFileSync5 } from "fs";
12909
12957
  import { homedir as homedir2 } from "os";
12910
12958
  import * as net from "net";
12911
12959
  import chalk from "chalk";
12912
- var localVersion = "1.6.1";
12960
+ var localVersion = "1.7.0";
12913
12961
  var results = [];
12914
12962
  function ok(msg) {
12915
12963
  console.log(chalk.green("\u2705 ") + msg);
@@ -13621,7 +13669,7 @@ async function runInit() {
13621
13669
  }
13622
13670
 
13623
13671
  // src/cli/index.ts
13624
- var program = new Command().name("mikromcp").description("MikroTik RouterOS MCP server").version("1.6.1");
13672
+ var program = new Command().name("mikromcp").description("MikroTik RouterOS MCP server").version("1.7.0");
13625
13673
  program.command("serve", { isDefault: true }).description("Start the MCP server (default)").action(runServe);
13626
13674
  program.command("doctor").description("Check config, connectivity, and permissions").action(runDoctor);
13627
13675
  program.command("init").description("Interactive setup wizard").action(runInit);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mikromcp",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "mcpName": "io.github.AliKarami/mikromcp",
5
5
  "description": "Production-grade MCP server for MikroTik RouterOS",
6
6
  "type": "module",