@usex/mikrotik-mcp 3.16.0 → 3.17.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 CHANGED
@@ -13070,6 +13070,152 @@ ${result}`;
13070
13070
  ${details}`;
13071
13071
  }
13072
13072
  }),
13073
+ defineTool({
13074
+ name: "add_ovpn_server",
13075
+ title: "Add Named OpenVPN Server",
13076
+ annotations: WRITE,
13077
+ description: "Add a named inbound OpenVPN server instance (`/interface ovpn-server server add`) \u2014 the" + " RouterOS 7.17+ multi-server model, where several OVPN servers can run side by side, each on" + " its own port/certificate/profile. Provide a unique name; port defaults to 1194. Supports" + " protocol (tcp/udp), ip or ethernet mode, certificate, auth/cipher algorithm lists, netmask," + " max_mtu, default_profile, mac_address (ethernet mode) and require_client_certificate. For the" + " legacy single-server (selector-less) menu on older RouterOS use set_ovpn_server. To remove a" + " named server use remove_ovpn_server; to list them use list_ovpn_servers. For outbound tunnels" + " use create_ovpn_client. Returns the created server's detail including its name.",
13078
+ inputSchema: {
13079
+ name: z68.string().describe("Unique name for the new OpenVPN server instance"),
13080
+ port: z68.number().int().default(1194),
13081
+ protocol: z68.enum(["tcp", "udp"]).optional(),
13082
+ mode: z68.enum(["ip", "ethernet"]).optional(),
13083
+ netmask: z68.number().int().optional(),
13084
+ mac_address: z68.string().optional().describe("Server MAC for ethernet mode"),
13085
+ certificate: z68.string().optional(),
13086
+ auth: z68.string().optional().describe("Comma-separated, e.g. 'sha256,sha1'"),
13087
+ cipher: z68.string().optional().describe("Comma-separated, e.g. 'aes256-cbc,aes256-gcm'"),
13088
+ max_mtu: z68.number().int().optional(),
13089
+ default_profile: z68.string().optional(),
13090
+ require_client_certificate: z68.boolean().optional(),
13091
+ comment: z68.string().optional(),
13092
+ disabled: z68.boolean().default(false)
13093
+ },
13094
+ async handler(a, ctx) {
13095
+ ctx.info(`Adding OpenVPN server: name=${a.name}`);
13096
+ const cmd = new Cmd("/interface ovpn-server server add").set("name", a.name).opt("port", a.port).opt("protocol", a.protocol).opt("mode", a.mode).opt("netmask", a.netmask).opt("mac-address", a.mac_address).opt("certificate", a.certificate).opt("auth", a.auth).opt("cipher", a.cipher).opt("max-mtu", a.max_mtu).opt("default-profile", a.default_profile).bool("require-client-certificate", a.require_client_certificate).opt("comment", a.comment).flag("disabled", a.disabled).build();
13097
+ const result = await executeMikrotikCommand(cmd, ctx);
13098
+ if (containsRawParserError(result)) {
13099
+ return "Failed to add OpenVPN server: this RouterOS build does not support named OpenVPN" + " server instances (the multi-server model requires RouterOS 7.17+). Use set_ovpn_server" + ` to configure the single legacy server instead.
13100
+
13101
+ ${result}`;
13102
+ }
13103
+ if (looksLikeError(result))
13104
+ return `Failed to add OpenVPN server: ${result}`;
13105
+ const details = await executeMikrotikCommand(`/interface ovpn-server server print detail where name="${a.name}"`, ctx);
13106
+ return details.trim() ? `OpenVPN server '${a.name}' added successfully:
13107
+
13108
+ ${details}` : "OpenVPN server creation completed but unable to verify.";
13109
+ }
13110
+ }),
13111
+ defineTool({
13112
+ name: "list_ovpn_servers",
13113
+ title: "List Named OpenVPN Servers",
13114
+ annotations: READ,
13115
+ description: "`list_ovpn_servers` \u2014 READ / list / show / inspect all named OpenVPN server instances" + " (`/interface ovpn-server server print detail`) on the RouterOS 7.17+ multi-server model," + " optionally filtered by partial name (name_filter). Returns each server's name, port, protocol," + " certificate, profile and disabled state. Pass a name_filter to fetch one server's full detail" + " (this doubles as get-by-name). The `.id`/name values feed update_ovpn_server," + " remove_ovpn_server, enable_ovpn_server and disable_ovpn_server. For the legacy single-server" + " menu use get_ovpn_server; for outbound tunnels use list_ovpn_clients.",
13116
+ inputSchema: {
13117
+ name_filter: z68.string().optional().describe("Partial name match")
13118
+ },
13119
+ async handler(a, ctx) {
13120
+ ctx.info("Listing OpenVPN servers");
13121
+ const filters = [];
13122
+ if (a.name_filter)
13123
+ filters.push(`name~"${a.name_filter}"`);
13124
+ const result = await executeMikrotikCommand(`/interface ovpn-server server print detail${whereClause(filters)}`, ctx);
13125
+ return isEmpty(result) ? "No named OpenVPN servers found (the device may use the legacy single-server menu \u2014 try get_ovpn_server)." : `OPENVPN SERVERS:
13126
+
13127
+ ${result}`;
13128
+ }
13129
+ }),
13130
+ defineTool({
13131
+ name: "update_ovpn_server",
13132
+ title: "Update Named OpenVPN Server",
13133
+ annotations: WRITE_IDEMPOTENT,
13134
+ description: "Modify a named OpenVPN server instance (`/interface ovpn-server server set [find name=...]`) on" + " the RouterOS 7.17+ multi-server model \u2014 change port, protocol, mode, certificate, auth/cipher," + " netmask, max_mtu, default_profile, mac_address, comment or require_client_certificate without" + " recreating it. To toggle only the enabled state use enable_ovpn_server / disable_ovpn_server." + " To create a server use add_ovpn_server; to remove one use remove_ovpn_server. For the legacy" + " single-server menu use set_ovpn_server. Returns the updated server's detail.",
13135
+ inputSchema: {
13136
+ name: z68.string().describe("Existing OpenVPN server instance name"),
13137
+ port: z68.number().int().optional(),
13138
+ protocol: z68.enum(["tcp", "udp"]).optional(),
13139
+ mode: z68.enum(["ip", "ethernet"]).optional(),
13140
+ netmask: z68.number().int().optional(),
13141
+ mac_address: z68.string().optional(),
13142
+ certificate: z68.string().optional(),
13143
+ auth: z68.string().optional(),
13144
+ cipher: z68.string().optional(),
13145
+ max_mtu: z68.number().int().optional(),
13146
+ default_profile: z68.string().optional(),
13147
+ require_client_certificate: z68.boolean().optional(),
13148
+ comment: z68.string().optional()
13149
+ },
13150
+ async handler(a, ctx) {
13151
+ ctx.info(`Updating OpenVPN server: name=${a.name}`);
13152
+ const base = `/interface ovpn-server server set [find name="${a.name}"]`;
13153
+ const cmd = new Cmd(base).opt("port", a.port).opt("protocol", a.protocol).opt("mode", a.mode).opt("netmask", a.netmask).opt("mac-address", a.mac_address).opt("certificate", a.certificate).opt("auth", a.auth).opt("cipher", a.cipher).opt("max-mtu", a.max_mtu).opt("default-profile", a.default_profile).bool("require-client-certificate", a.require_client_certificate).opt("comment", a.comment).build();
13154
+ if (cmd === base)
13155
+ return "No updates specified.";
13156
+ const count = await executeMikrotikCommand(`/interface ovpn-server server print count-only where name="${a.name}"`, ctx);
13157
+ if (count.trim() === "0")
13158
+ return `OpenVPN server '${a.name}' not found.`;
13159
+ const result = await executeMikrotikCommand(cmd, ctx);
13160
+ if (looksLikeError(result))
13161
+ return `Failed to update OpenVPN server: ${result}`;
13162
+ const details = await executeMikrotikCommand(`/interface ovpn-server server print detail where name="${a.name}"`, ctx);
13163
+ return `OpenVPN server '${a.name}' updated successfully:
13164
+
13165
+ ${details}`;
13166
+ }
13167
+ }),
13168
+ defineTool({
13169
+ name: "remove_ovpn_server",
13170
+ title: "Remove Named OpenVPN Server",
13171
+ annotations: DESTRUCTIVE,
13172
+ description: "Permanently delete a named OpenVPN server instance (`/interface ovpn-server server remove" + " [find name=...]`) on the RouterOS 7.17+ multi-server model \u2014 verifies existence with a" + " count-only check before deleting. Use list_ovpn_servers to confirm the name. To stop a server" + " without deleting it use disable_ovpn_server. This does not touch the legacy single-server menu" + " (use set_ovpn_server with enabled=false for that) or any OVPN clients. Returns a success or" + " not-found message.",
13173
+ inputSchema: { name: z68.string() },
13174
+ async handler(a, ctx) {
13175
+ ctx.info(`Removing OpenVPN server: name=${a.name}`);
13176
+ const count = await executeMikrotikCommand(`/interface ovpn-server server print count-only where name="${a.name}"`, ctx);
13177
+ if (count.trim() === "0")
13178
+ return `OpenVPN server '${a.name}' not found.`;
13179
+ const result = await executeMikrotikCommand(`/interface ovpn-server server remove [find name="${a.name}"]`, ctx);
13180
+ if (looksLikeError(result))
13181
+ return `Failed to remove OpenVPN server: ${result}`;
13182
+ return `OpenVPN server '${a.name}' removed successfully.`;
13183
+ }
13184
+ }),
13185
+ defineTool({
13186
+ name: "enable_ovpn_server",
13187
+ title: "Enable Named OpenVPN Server",
13188
+ annotations: WRITE_IDEMPOTENT,
13189
+ description: "Enable a disabled named OpenVPN server instance (`/interface ovpn-server server enable" + " [find name=...]`) on the RouterOS 7.17+ multi-server model, so it starts accepting clients." + " Use list_ovpn_servers to confirm the name. To deactivate use disable_ovpn_server; to delete" + " use remove_ovpn_server. For the legacy single-server menu use set_ovpn_server with" + " enabled=true. Returns a success or error message.",
13190
+ inputSchema: { name: z68.string() },
13191
+ async handler(a, ctx) {
13192
+ ctx.info(`Enabling OpenVPN server: name=${a.name}`);
13193
+ const count = await executeMikrotikCommand(`/interface ovpn-server server print count-only where name="${a.name}"`, ctx);
13194
+ if (count.trim() === "0")
13195
+ return `OpenVPN server '${a.name}' not found.`;
13196
+ const result = await executeMikrotikCommand(`/interface ovpn-server server enable [find name="${a.name}"]`, ctx);
13197
+ if (looksLikeError(result))
13198
+ return `Failed to enable OpenVPN server: ${result}`;
13199
+ return `OpenVPN server '${a.name}' enabled successfully.`;
13200
+ }
13201
+ }),
13202
+ defineTool({
13203
+ name: "disable_ovpn_server",
13204
+ title: "Disable Named OpenVPN Server",
13205
+ annotations: WRITE_IDEMPOTENT,
13206
+ description: "Disable an active named OpenVPN server instance (`/interface ovpn-server server disable" + " [find name=...]`) on the RouterOS 7.17+ multi-server model, stopping it without deleting its" + " configuration. Use list_ovpn_servers to confirm the name. To re-activate use" + " enable_ovpn_server; to delete use remove_ovpn_server. For the legacy single-server menu use" + " set_ovpn_server with enabled=false. Returns a success or error message.",
13207
+ inputSchema: { name: z68.string() },
13208
+ async handler(a, ctx) {
13209
+ ctx.info(`Disabling OpenVPN server: name=${a.name}`);
13210
+ const count = await executeMikrotikCommand(`/interface ovpn-server server print count-only where name="${a.name}"`, ctx);
13211
+ if (count.trim() === "0")
13212
+ return `OpenVPN server '${a.name}' not found.`;
13213
+ const result = await executeMikrotikCommand(`/interface ovpn-server server disable [find name="${a.name}"]`, ctx);
13214
+ if (looksLikeError(result))
13215
+ return `Failed to disable OpenVPN server: ${result}`;
13216
+ return `OpenVPN server '${a.name}' disabled successfully.`;
13217
+ }
13218
+ }),
13073
13219
  defineTool({
13074
13220
  name: "create_ovpn_client",
13075
13221
  title: "Create OpenVPN Client Interface",
@@ -21701,7 +21847,7 @@ var moduleCatalog = [
21701
21847
  label: "OpenVPN",
21702
21848
  slug: "openvpn",
21703
21849
  group: "VPN & Tunneling",
21704
- description: "OpenVPN server + clients (`/interface ovpn-*`).",
21850
+ description: "OpenVPN servers \u2014 legacy single + RouterOS 7.17 multi-server \u2014 and clients (`/interface ovpn-*`).",
21705
21851
  tools: openvpnTools
21706
21852
  },
21707
21853
  {
@@ -23622,7 +23768,7 @@ function registerPrompts(server) {
23622
23768
  // package.json
23623
23769
  var package_default = {
23624
23770
  name: "@usex/mikrotik-mcp",
23625
- version: "3.16.0",
23771
+ version: "3.17.0",
23626
23772
  description: "MCP server for MikroTik RouterOS \u2014 660+ tools over SSH for firewall, NAT, routing, DHCP, DNS, WireGuard, wireless, QoS and more.",
23627
23773
  keywords: [
23628
23774
  "ai",
package/dist/index.js CHANGED
@@ -13082,6 +13082,152 @@ ${result}`;
13082
13082
  ${details}`;
13083
13083
  }
13084
13084
  }),
13085
+ defineTool({
13086
+ name: "add_ovpn_server",
13087
+ title: "Add Named OpenVPN Server",
13088
+ annotations: WRITE,
13089
+ description: "Add a named inbound OpenVPN server instance (`/interface ovpn-server server add`) \u2014 the" + " RouterOS 7.17+ multi-server model, where several OVPN servers can run side by side, each on" + " its own port/certificate/profile. Provide a unique name; port defaults to 1194. Supports" + " protocol (tcp/udp), ip or ethernet mode, certificate, auth/cipher algorithm lists, netmask," + " max_mtu, default_profile, mac_address (ethernet mode) and require_client_certificate. For the" + " legacy single-server (selector-less) menu on older RouterOS use set_ovpn_server. To remove a" + " named server use remove_ovpn_server; to list them use list_ovpn_servers. For outbound tunnels" + " use create_ovpn_client. Returns the created server's detail including its name.",
13090
+ inputSchema: {
13091
+ name: z69.string().describe("Unique name for the new OpenVPN server instance"),
13092
+ port: z69.number().int().default(1194),
13093
+ protocol: z69.enum(["tcp", "udp"]).optional(),
13094
+ mode: z69.enum(["ip", "ethernet"]).optional(),
13095
+ netmask: z69.number().int().optional(),
13096
+ mac_address: z69.string().optional().describe("Server MAC for ethernet mode"),
13097
+ certificate: z69.string().optional(),
13098
+ auth: z69.string().optional().describe("Comma-separated, e.g. 'sha256,sha1'"),
13099
+ cipher: z69.string().optional().describe("Comma-separated, e.g. 'aes256-cbc,aes256-gcm'"),
13100
+ max_mtu: z69.number().int().optional(),
13101
+ default_profile: z69.string().optional(),
13102
+ require_client_certificate: z69.boolean().optional(),
13103
+ comment: z69.string().optional(),
13104
+ disabled: z69.boolean().default(false)
13105
+ },
13106
+ async handler(a, ctx) {
13107
+ ctx.info(`Adding OpenVPN server: name=${a.name}`);
13108
+ const cmd = new Cmd("/interface ovpn-server server add").set("name", a.name).opt("port", a.port).opt("protocol", a.protocol).opt("mode", a.mode).opt("netmask", a.netmask).opt("mac-address", a.mac_address).opt("certificate", a.certificate).opt("auth", a.auth).opt("cipher", a.cipher).opt("max-mtu", a.max_mtu).opt("default-profile", a.default_profile).bool("require-client-certificate", a.require_client_certificate).opt("comment", a.comment).flag("disabled", a.disabled).build();
13109
+ const result = await executeMikrotikCommand(cmd, ctx);
13110
+ if (containsRawParserError(result)) {
13111
+ return "Failed to add OpenVPN server: this RouterOS build does not support named OpenVPN" + " server instances (the multi-server model requires RouterOS 7.17+). Use set_ovpn_server" + ` to configure the single legacy server instead.
13112
+
13113
+ ${result}`;
13114
+ }
13115
+ if (looksLikeError(result))
13116
+ return `Failed to add OpenVPN server: ${result}`;
13117
+ const details = await executeMikrotikCommand(`/interface ovpn-server server print detail where name="${a.name}"`, ctx);
13118
+ return details.trim() ? `OpenVPN server '${a.name}' added successfully:
13119
+
13120
+ ${details}` : "OpenVPN server creation completed but unable to verify.";
13121
+ }
13122
+ }),
13123
+ defineTool({
13124
+ name: "list_ovpn_servers",
13125
+ title: "List Named OpenVPN Servers",
13126
+ annotations: READ,
13127
+ description: "`list_ovpn_servers` \u2014 READ / list / show / inspect all named OpenVPN server instances" + " (`/interface ovpn-server server print detail`) on the RouterOS 7.17+ multi-server model," + " optionally filtered by partial name (name_filter). Returns each server's name, port, protocol," + " certificate, profile and disabled state. Pass a name_filter to fetch one server's full detail" + " (this doubles as get-by-name). The `.id`/name values feed update_ovpn_server," + " remove_ovpn_server, enable_ovpn_server and disable_ovpn_server. For the legacy single-server" + " menu use get_ovpn_server; for outbound tunnels use list_ovpn_clients.",
13128
+ inputSchema: {
13129
+ name_filter: z69.string().optional().describe("Partial name match")
13130
+ },
13131
+ async handler(a, ctx) {
13132
+ ctx.info("Listing OpenVPN servers");
13133
+ const filters = [];
13134
+ if (a.name_filter)
13135
+ filters.push(`name~"${a.name_filter}"`);
13136
+ const result = await executeMikrotikCommand(`/interface ovpn-server server print detail${whereClause(filters)}`, ctx);
13137
+ return isEmpty(result) ? "No named OpenVPN servers found (the device may use the legacy single-server menu \u2014 try get_ovpn_server)." : `OPENVPN SERVERS:
13138
+
13139
+ ${result}`;
13140
+ }
13141
+ }),
13142
+ defineTool({
13143
+ name: "update_ovpn_server",
13144
+ title: "Update Named OpenVPN Server",
13145
+ annotations: WRITE_IDEMPOTENT,
13146
+ description: "Modify a named OpenVPN server instance (`/interface ovpn-server server set [find name=...]`) on" + " the RouterOS 7.17+ multi-server model \u2014 change port, protocol, mode, certificate, auth/cipher," + " netmask, max_mtu, default_profile, mac_address, comment or require_client_certificate without" + " recreating it. To toggle only the enabled state use enable_ovpn_server / disable_ovpn_server." + " To create a server use add_ovpn_server; to remove one use remove_ovpn_server. For the legacy" + " single-server menu use set_ovpn_server. Returns the updated server's detail.",
13147
+ inputSchema: {
13148
+ name: z69.string().describe("Existing OpenVPN server instance name"),
13149
+ port: z69.number().int().optional(),
13150
+ protocol: z69.enum(["tcp", "udp"]).optional(),
13151
+ mode: z69.enum(["ip", "ethernet"]).optional(),
13152
+ netmask: z69.number().int().optional(),
13153
+ mac_address: z69.string().optional(),
13154
+ certificate: z69.string().optional(),
13155
+ auth: z69.string().optional(),
13156
+ cipher: z69.string().optional(),
13157
+ max_mtu: z69.number().int().optional(),
13158
+ default_profile: z69.string().optional(),
13159
+ require_client_certificate: z69.boolean().optional(),
13160
+ comment: z69.string().optional()
13161
+ },
13162
+ async handler(a, ctx) {
13163
+ ctx.info(`Updating OpenVPN server: name=${a.name}`);
13164
+ const base = `/interface ovpn-server server set [find name="${a.name}"]`;
13165
+ const cmd = new Cmd(base).opt("port", a.port).opt("protocol", a.protocol).opt("mode", a.mode).opt("netmask", a.netmask).opt("mac-address", a.mac_address).opt("certificate", a.certificate).opt("auth", a.auth).opt("cipher", a.cipher).opt("max-mtu", a.max_mtu).opt("default-profile", a.default_profile).bool("require-client-certificate", a.require_client_certificate).opt("comment", a.comment).build();
13166
+ if (cmd === base)
13167
+ return "No updates specified.";
13168
+ const count = await executeMikrotikCommand(`/interface ovpn-server server print count-only where name="${a.name}"`, ctx);
13169
+ if (count.trim() === "0")
13170
+ return `OpenVPN server '${a.name}' not found.`;
13171
+ const result = await executeMikrotikCommand(cmd, ctx);
13172
+ if (looksLikeError(result))
13173
+ return `Failed to update OpenVPN server: ${result}`;
13174
+ const details = await executeMikrotikCommand(`/interface ovpn-server server print detail where name="${a.name}"`, ctx);
13175
+ return `OpenVPN server '${a.name}' updated successfully:
13176
+
13177
+ ${details}`;
13178
+ }
13179
+ }),
13180
+ defineTool({
13181
+ name: "remove_ovpn_server",
13182
+ title: "Remove Named OpenVPN Server",
13183
+ annotations: DESTRUCTIVE,
13184
+ description: "Permanently delete a named OpenVPN server instance (`/interface ovpn-server server remove" + " [find name=...]`) on the RouterOS 7.17+ multi-server model \u2014 verifies existence with a" + " count-only check before deleting. Use list_ovpn_servers to confirm the name. To stop a server" + " without deleting it use disable_ovpn_server. This does not touch the legacy single-server menu" + " (use set_ovpn_server with enabled=false for that) or any OVPN clients. Returns a success or" + " not-found message.",
13185
+ inputSchema: { name: z69.string() },
13186
+ async handler(a, ctx) {
13187
+ ctx.info(`Removing OpenVPN server: name=${a.name}`);
13188
+ const count = await executeMikrotikCommand(`/interface ovpn-server server print count-only where name="${a.name}"`, ctx);
13189
+ if (count.trim() === "0")
13190
+ return `OpenVPN server '${a.name}' not found.`;
13191
+ const result = await executeMikrotikCommand(`/interface ovpn-server server remove [find name="${a.name}"]`, ctx);
13192
+ if (looksLikeError(result))
13193
+ return `Failed to remove OpenVPN server: ${result}`;
13194
+ return `OpenVPN server '${a.name}' removed successfully.`;
13195
+ }
13196
+ }),
13197
+ defineTool({
13198
+ name: "enable_ovpn_server",
13199
+ title: "Enable Named OpenVPN Server",
13200
+ annotations: WRITE_IDEMPOTENT,
13201
+ description: "Enable a disabled named OpenVPN server instance (`/interface ovpn-server server enable" + " [find name=...]`) on the RouterOS 7.17+ multi-server model, so it starts accepting clients." + " Use list_ovpn_servers to confirm the name. To deactivate use disable_ovpn_server; to delete" + " use remove_ovpn_server. For the legacy single-server menu use set_ovpn_server with" + " enabled=true. Returns a success or error message.",
13202
+ inputSchema: { name: z69.string() },
13203
+ async handler(a, ctx) {
13204
+ ctx.info(`Enabling OpenVPN server: name=${a.name}`);
13205
+ const count = await executeMikrotikCommand(`/interface ovpn-server server print count-only where name="${a.name}"`, ctx);
13206
+ if (count.trim() === "0")
13207
+ return `OpenVPN server '${a.name}' not found.`;
13208
+ const result = await executeMikrotikCommand(`/interface ovpn-server server enable [find name="${a.name}"]`, ctx);
13209
+ if (looksLikeError(result))
13210
+ return `Failed to enable OpenVPN server: ${result}`;
13211
+ return `OpenVPN server '${a.name}' enabled successfully.`;
13212
+ }
13213
+ }),
13214
+ defineTool({
13215
+ name: "disable_ovpn_server",
13216
+ title: "Disable Named OpenVPN Server",
13217
+ annotations: WRITE_IDEMPOTENT,
13218
+ description: "Disable an active named OpenVPN server instance (`/interface ovpn-server server disable" + " [find name=...]`) on the RouterOS 7.17+ multi-server model, stopping it without deleting its" + " configuration. Use list_ovpn_servers to confirm the name. To re-activate use" + " enable_ovpn_server; to delete use remove_ovpn_server. For the legacy single-server menu use" + " set_ovpn_server with enabled=false. Returns a success or error message.",
13219
+ inputSchema: { name: z69.string() },
13220
+ async handler(a, ctx) {
13221
+ ctx.info(`Disabling OpenVPN server: name=${a.name}`);
13222
+ const count = await executeMikrotikCommand(`/interface ovpn-server server print count-only where name="${a.name}"`, ctx);
13223
+ if (count.trim() === "0")
13224
+ return `OpenVPN server '${a.name}' not found.`;
13225
+ const result = await executeMikrotikCommand(`/interface ovpn-server server disable [find name="${a.name}"]`, ctx);
13226
+ if (looksLikeError(result))
13227
+ return `Failed to disable OpenVPN server: ${result}`;
13228
+ return `OpenVPN server '${a.name}' disabled successfully.`;
13229
+ }
13230
+ }),
13085
13231
  defineTool({
13086
13232
  name: "create_ovpn_client",
13087
13233
  title: "Create OpenVPN Client Interface",
@@ -21713,7 +21859,7 @@ var moduleCatalog = [
21713
21859
  label: "OpenVPN",
21714
21860
  slug: "openvpn",
21715
21861
  group: "VPN & Tunneling",
21716
- description: "OpenVPN server + clients (`/interface ovpn-*`).",
21862
+ description: "OpenVPN servers \u2014 legacy single + RouterOS 7.17 multi-server \u2014 and clients (`/interface ovpn-*`).",
21717
21863
  tools: openvpnTools
21718
21864
  },
21719
21865
  {
@@ -22025,7 +22171,7 @@ function selectToolModules(filter = {}, catalog = moduleCatalog) {
22025
22171
  // package.json
22026
22172
  var package_default = {
22027
22173
  name: "@usex/mikrotik-mcp",
22028
- version: "3.16.0",
22174
+ version: "3.17.0",
22029
22175
  description: "MCP server for MikroTik RouterOS \u2014 660+ tools over SSH for firewall, NAT, routing, DHCP, DNS, WireGuard, wireless, QoS and more.",
22030
22176
  keywords: [
22031
22177
  "ai",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usex/mikrotik-mcp",
3
- "version": "3.16.0",
3
+ "version": "3.17.0",
4
4
  "description": "MCP server for MikroTik RouterOS — 660+ tools over SSH for firewall, NAT, routing, DHCP, DNS, WireGuard, wireless, QoS and more.",
5
5
  "keywords": [
6
6
  "ai",
package/schemas/README.md CHANGED
@@ -7,7 +7,7 @@ edit by hand — regenerate instead.
7
7
  | File | Contents |
8
8
  | -------------------- | ------------------------------------------------------------------------------------------ |
9
9
  | `config.schema.json` | The runtime configuration object (env vars / CLI flags). |
10
- | `tool-catalog.json` | Every one of the 715 tools: `name`, `risk`, `title`, `description`, and input JSON Schema. |
10
+ | `tool-catalog.json` | Every one of the 721 tools: `name`, `risk`, `title`, `description`, and input JSON Schema. |
11
11
  | `tools/<name>.json` | The input JSON Schema for a single tool. |
12
12
 
13
13
  `risk` is derived from the MCP tool annotations:
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "version": "3.15.0",
3
+ "version": "3.16.0",
4
4
  "generated": "by scripts/gen-schemas.ts — do not edit by hand",
5
- "toolCount": 715,
5
+ "toolCount": 721,
6
6
  "tools": [
7
7
  {
8
8
  "name": "list_interfaces",
@@ -14539,6 +14539,235 @@
14539
14539
  "additionalProperties": false
14540
14540
  }
14541
14541
  },
14542
+ {
14543
+ "name": "add_ovpn_server",
14544
+ "title": "Add Named OpenVPN Server",
14545
+ "risk": "write",
14546
+ "annotations": {
14547
+ "destructiveHint": false,
14548
+ "openWorldHint": false
14549
+ },
14550
+ "description": "Add a named inbound OpenVPN server instance (`/interface ovpn-server server add`) — the RouterOS 7.17+ multi-server model, where several OVPN servers can run side by side, each on its own port/certificate/profile. Provide a unique name; port defaults to 1194. Supports protocol (tcp/udp), ip or ethernet mode, certificate, auth/cipher algorithm lists, netmask, max_mtu, default_profile, mac_address (ethernet mode) and require_client_certificate. For the legacy single-server (selector-less) menu on older RouterOS use set_ovpn_server. To remove a named server use remove_ovpn_server; to list them use list_ovpn_servers. For outbound tunnels use create_ovpn_client. Returns the created server's detail including its name.",
14551
+ "inputSchema": {
14552
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
14553
+ "type": "object",
14554
+ "properties": {
14555
+ "name": {
14556
+ "type": "string",
14557
+ "description": "Unique name for the new OpenVPN server instance"
14558
+ },
14559
+ "port": {
14560
+ "default": 1194,
14561
+ "type": "integer",
14562
+ "minimum": -9007199254740991,
14563
+ "maximum": 9007199254740991
14564
+ },
14565
+ "protocol": {
14566
+ "type": "string",
14567
+ "enum": ["tcp", "udp"]
14568
+ },
14569
+ "mode": {
14570
+ "type": "string",
14571
+ "enum": ["ip", "ethernet"]
14572
+ },
14573
+ "netmask": {
14574
+ "type": "integer",
14575
+ "minimum": -9007199254740991,
14576
+ "maximum": 9007199254740991
14577
+ },
14578
+ "mac_address": {
14579
+ "description": "Server MAC for ethernet mode",
14580
+ "type": "string"
14581
+ },
14582
+ "certificate": {
14583
+ "type": "string"
14584
+ },
14585
+ "auth": {
14586
+ "description": "Comma-separated, e.g. 'sha256,sha1'",
14587
+ "type": "string"
14588
+ },
14589
+ "cipher": {
14590
+ "description": "Comma-separated, e.g. 'aes256-cbc,aes256-gcm'",
14591
+ "type": "string"
14592
+ },
14593
+ "max_mtu": {
14594
+ "type": "integer",
14595
+ "minimum": -9007199254740991,
14596
+ "maximum": 9007199254740991
14597
+ },
14598
+ "default_profile": {
14599
+ "type": "string"
14600
+ },
14601
+ "require_client_certificate": {
14602
+ "type": "boolean"
14603
+ },
14604
+ "comment": {
14605
+ "type": "string"
14606
+ },
14607
+ "disabled": {
14608
+ "default": false,
14609
+ "type": "boolean"
14610
+ }
14611
+ },
14612
+ "required": ["name", "port", "disabled"],
14613
+ "additionalProperties": false
14614
+ }
14615
+ },
14616
+ {
14617
+ "name": "list_ovpn_servers",
14618
+ "title": "List Named OpenVPN Servers",
14619
+ "risk": "read",
14620
+ "annotations": {
14621
+ "readOnlyHint": true,
14622
+ "idempotentHint": true,
14623
+ "openWorldHint": false
14624
+ },
14625
+ "description": "`list_ovpn_servers` — READ / list / show / inspect all named OpenVPN server instances (`/interface ovpn-server server print detail`) on the RouterOS 7.17+ multi-server model, optionally filtered by partial name (name_filter). Returns each server's name, port, protocol, certificate, profile and disabled state. Pass a name_filter to fetch one server's full detail (this doubles as get-by-name). The `.id`/name values feed update_ovpn_server, remove_ovpn_server, enable_ovpn_server and disable_ovpn_server. For the legacy single-server menu use get_ovpn_server; for outbound tunnels use list_ovpn_clients.",
14626
+ "inputSchema": {
14627
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
14628
+ "type": "object",
14629
+ "properties": {
14630
+ "name_filter": {
14631
+ "description": "Partial name match",
14632
+ "type": "string"
14633
+ }
14634
+ },
14635
+ "additionalProperties": false
14636
+ }
14637
+ },
14638
+ {
14639
+ "name": "update_ovpn_server",
14640
+ "title": "Update Named OpenVPN Server",
14641
+ "risk": "write-idempotent",
14642
+ "annotations": {
14643
+ "destructiveHint": false,
14644
+ "idempotentHint": true,
14645
+ "openWorldHint": false
14646
+ },
14647
+ "description": "Modify a named OpenVPN server instance (`/interface ovpn-server server set [find name=...]`) on the RouterOS 7.17+ multi-server model — change port, protocol, mode, certificate, auth/cipher, netmask, max_mtu, default_profile, mac_address, comment or require_client_certificate without recreating it. To toggle only the enabled state use enable_ovpn_server / disable_ovpn_server. To create a server use add_ovpn_server; to remove one use remove_ovpn_server. For the legacy single-server menu use set_ovpn_server. Returns the updated server's detail.",
14648
+ "inputSchema": {
14649
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
14650
+ "type": "object",
14651
+ "properties": {
14652
+ "name": {
14653
+ "type": "string",
14654
+ "description": "Existing OpenVPN server instance name"
14655
+ },
14656
+ "port": {
14657
+ "type": "integer",
14658
+ "minimum": -9007199254740991,
14659
+ "maximum": 9007199254740991
14660
+ },
14661
+ "protocol": {
14662
+ "type": "string",
14663
+ "enum": ["tcp", "udp"]
14664
+ },
14665
+ "mode": {
14666
+ "type": "string",
14667
+ "enum": ["ip", "ethernet"]
14668
+ },
14669
+ "netmask": {
14670
+ "type": "integer",
14671
+ "minimum": -9007199254740991,
14672
+ "maximum": 9007199254740991
14673
+ },
14674
+ "mac_address": {
14675
+ "type": "string"
14676
+ },
14677
+ "certificate": {
14678
+ "type": "string"
14679
+ },
14680
+ "auth": {
14681
+ "type": "string"
14682
+ },
14683
+ "cipher": {
14684
+ "type": "string"
14685
+ },
14686
+ "max_mtu": {
14687
+ "type": "integer",
14688
+ "minimum": -9007199254740991,
14689
+ "maximum": 9007199254740991
14690
+ },
14691
+ "default_profile": {
14692
+ "type": "string"
14693
+ },
14694
+ "require_client_certificate": {
14695
+ "type": "boolean"
14696
+ },
14697
+ "comment": {
14698
+ "type": "string"
14699
+ }
14700
+ },
14701
+ "required": ["name"],
14702
+ "additionalProperties": false
14703
+ }
14704
+ },
14705
+ {
14706
+ "name": "remove_ovpn_server",
14707
+ "title": "Remove Named OpenVPN Server",
14708
+ "risk": "destructive",
14709
+ "annotations": {
14710
+ "destructiveHint": true,
14711
+ "idempotentHint": true,
14712
+ "openWorldHint": false
14713
+ },
14714
+ "description": "Permanently delete a named OpenVPN server instance (`/interface ovpn-server server remove [find name=...]`) on the RouterOS 7.17+ multi-server model — verifies existence with a count-only check before deleting. Use list_ovpn_servers to confirm the name. To stop a server without deleting it use disable_ovpn_server. This does not touch the legacy single-server menu (use set_ovpn_server with enabled=false for that) or any OVPN clients. Returns a success or not-found message.",
14715
+ "inputSchema": {
14716
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
14717
+ "type": "object",
14718
+ "properties": {
14719
+ "name": {
14720
+ "type": "string"
14721
+ }
14722
+ },
14723
+ "required": ["name"],
14724
+ "additionalProperties": false
14725
+ }
14726
+ },
14727
+ {
14728
+ "name": "enable_ovpn_server",
14729
+ "title": "Enable Named OpenVPN Server",
14730
+ "risk": "write-idempotent",
14731
+ "annotations": {
14732
+ "destructiveHint": false,
14733
+ "idempotentHint": true,
14734
+ "openWorldHint": false
14735
+ },
14736
+ "description": "Enable a disabled named OpenVPN server instance (`/interface ovpn-server server enable [find name=...]`) on the RouterOS 7.17+ multi-server model, so it starts accepting clients. Use list_ovpn_servers to confirm the name. To deactivate use disable_ovpn_server; to delete use remove_ovpn_server. For the legacy single-server menu use set_ovpn_server with enabled=true. Returns a success or error message.",
14737
+ "inputSchema": {
14738
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
14739
+ "type": "object",
14740
+ "properties": {
14741
+ "name": {
14742
+ "type": "string"
14743
+ }
14744
+ },
14745
+ "required": ["name"],
14746
+ "additionalProperties": false
14747
+ }
14748
+ },
14749
+ {
14750
+ "name": "disable_ovpn_server",
14751
+ "title": "Disable Named OpenVPN Server",
14752
+ "risk": "write-idempotent",
14753
+ "annotations": {
14754
+ "destructiveHint": false,
14755
+ "idempotentHint": true,
14756
+ "openWorldHint": false
14757
+ },
14758
+ "description": "Disable an active named OpenVPN server instance (`/interface ovpn-server server disable [find name=...]`) on the RouterOS 7.17+ multi-server model, stopping it without deleting its configuration. Use list_ovpn_servers to confirm the name. To re-activate use enable_ovpn_server; to delete use remove_ovpn_server. For the legacy single-server menu use set_ovpn_server with enabled=false. Returns a success or error message.",
14759
+ "inputSchema": {
14760
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
14761
+ "type": "object",
14762
+ "properties": {
14763
+ "name": {
14764
+ "type": "string"
14765
+ }
14766
+ },
14767
+ "required": ["name"],
14768
+ "additionalProperties": false
14769
+ }
14770
+ },
14542
14771
  {
14543
14772
  "name": "create_ovpn_client",
14544
14773
  "title": "Create OpenVPN Client Interface",
@@ -0,0 +1,65 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "add_ovpn_server",
4
+ "type": "object",
5
+ "properties": {
6
+ "name": {
7
+ "type": "string",
8
+ "description": "Unique name for the new OpenVPN server instance"
9
+ },
10
+ "port": {
11
+ "default": 1194,
12
+ "type": "integer",
13
+ "minimum": -9007199254740991,
14
+ "maximum": 9007199254740991
15
+ },
16
+ "protocol": {
17
+ "type": "string",
18
+ "enum": ["tcp", "udp"]
19
+ },
20
+ "mode": {
21
+ "type": "string",
22
+ "enum": ["ip", "ethernet"]
23
+ },
24
+ "netmask": {
25
+ "type": "integer",
26
+ "minimum": -9007199254740991,
27
+ "maximum": 9007199254740991
28
+ },
29
+ "mac_address": {
30
+ "description": "Server MAC for ethernet mode",
31
+ "type": "string"
32
+ },
33
+ "certificate": {
34
+ "type": "string"
35
+ },
36
+ "auth": {
37
+ "description": "Comma-separated, e.g. 'sha256,sha1'",
38
+ "type": "string"
39
+ },
40
+ "cipher": {
41
+ "description": "Comma-separated, e.g. 'aes256-cbc,aes256-gcm'",
42
+ "type": "string"
43
+ },
44
+ "max_mtu": {
45
+ "type": "integer",
46
+ "minimum": -9007199254740991,
47
+ "maximum": 9007199254740991
48
+ },
49
+ "default_profile": {
50
+ "type": "string"
51
+ },
52
+ "require_client_certificate": {
53
+ "type": "boolean"
54
+ },
55
+ "comment": {
56
+ "type": "string"
57
+ },
58
+ "disabled": {
59
+ "default": false,
60
+ "type": "boolean"
61
+ }
62
+ },
63
+ "required": ["name", "port", "disabled"],
64
+ "additionalProperties": false
65
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "disable_ovpn_server",
4
+ "type": "object",
5
+ "properties": {
6
+ "name": {
7
+ "type": "string"
8
+ }
9
+ },
10
+ "required": ["name"],
11
+ "additionalProperties": false
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "enable_ovpn_server",
4
+ "type": "object",
5
+ "properties": {
6
+ "name": {
7
+ "type": "string"
8
+ }
9
+ },
10
+ "required": ["name"],
11
+ "additionalProperties": false
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "list_ovpn_servers",
4
+ "type": "object",
5
+ "properties": {
6
+ "name_filter": {
7
+ "description": "Partial name match",
8
+ "type": "string"
9
+ }
10
+ },
11
+ "additionalProperties": false
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "remove_ovpn_server",
4
+ "type": "object",
5
+ "properties": {
6
+ "name": {
7
+ "type": "string"
8
+ }
9
+ },
10
+ "required": ["name"],
11
+ "additionalProperties": false
12
+ }
@@ -0,0 +1,57 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "update_ovpn_server",
4
+ "type": "object",
5
+ "properties": {
6
+ "name": {
7
+ "type": "string",
8
+ "description": "Existing OpenVPN server instance name"
9
+ },
10
+ "port": {
11
+ "type": "integer",
12
+ "minimum": -9007199254740991,
13
+ "maximum": 9007199254740991
14
+ },
15
+ "protocol": {
16
+ "type": "string",
17
+ "enum": ["tcp", "udp"]
18
+ },
19
+ "mode": {
20
+ "type": "string",
21
+ "enum": ["ip", "ethernet"]
22
+ },
23
+ "netmask": {
24
+ "type": "integer",
25
+ "minimum": -9007199254740991,
26
+ "maximum": 9007199254740991
27
+ },
28
+ "mac_address": {
29
+ "type": "string"
30
+ },
31
+ "certificate": {
32
+ "type": "string"
33
+ },
34
+ "auth": {
35
+ "type": "string"
36
+ },
37
+ "cipher": {
38
+ "type": "string"
39
+ },
40
+ "max_mtu": {
41
+ "type": "integer",
42
+ "minimum": -9007199254740991,
43
+ "maximum": 9007199254740991
44
+ },
45
+ "default_profile": {
46
+ "type": "string"
47
+ },
48
+ "require_client_certificate": {
49
+ "type": "boolean"
50
+ },
51
+ "comment": {
52
+ "type": "string"
53
+ }
54
+ },
55
+ "required": ["name"],
56
+ "additionalProperties": false
57
+ }