@usex/mikrotik-mcp 3.29.0 → 3.30.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
@@ -23,7 +23,8 @@ var McpServerSettingsSchema = z.object({
23
23
  allowedHosts: z.string().default(""),
24
24
  allowedOrigins: z.string().default(""),
25
25
  corsOrigins: z.string().default(""),
26
- toolPageSize: z.coerce.number().int().min(0).default(0)
26
+ toolPageSize: z.coerce.number().int().min(0).default(0),
27
+ appViews: z.boolean().default(true)
27
28
  });
28
29
  var DeviceConfigSchema = z.object({
29
30
  host: z.string().default("127.0.0.1"),
@@ -121,7 +122,8 @@ function parseDevicesSource(raw, fromFile) {
121
122
  const s3 = structured && obj.s3 && typeof obj.s3 === "object" ? obj.s3 : undefined;
122
123
  const dashboard = structured && obj.dashboard && typeof obj.dashboard === "object" ? obj.dashboard : undefined;
123
124
  const tools = structured && obj.tools && typeof obj.tools === "object" ? obj.tools : undefined;
124
- return { devices, defaultDevice, s3, dashboard, tools };
125
+ const mcp = structured && obj.mcp && typeof obj.mcp === "object" ? obj.mcp : undefined;
126
+ return { devices, defaultDevice, s3, dashboard, tools, mcp };
125
127
  }
126
128
  var configSource = { path: DEFAULT_CONFIG_FILE, fromFile: false };
127
129
  function getConfigSource() {
@@ -157,6 +159,7 @@ function loadConfig(argv = process.argv.slice(2)) {
157
159
  let fileS3 = {};
158
160
  let fileDashboard = {};
159
161
  let fileTools;
162
+ let fileMcp;
160
163
  if (configFile || devicesInline) {
161
164
  const src = configFile ? parseDevicesSource(configFile, true) : parseDevicesSource(devicesInline, false);
162
165
  for (const [name, dc] of Object.entries(src.devices))
@@ -168,6 +171,7 @@ function loadConfig(argv = process.argv.slice(2)) {
168
171
  fileS3 = src.s3;
169
172
  fileDashboard = src.dashboard;
170
173
  fileTools = src.tools;
174
+ fileMcp = src.mcp;
171
175
  }
172
176
  const s3 = {
173
177
  accessKeyId: pick("s3-access-key-id", "S3_ACCESS_KEY_ID", "AWS_ACCESS_KEY_ID"),
@@ -180,6 +184,8 @@ function loadConfig(argv = process.argv.slice(2)) {
180
184
  presignExpiresIn: pick("s3-presign-expires-in", "MIKROTIK_S3_PRESIGN_EXPIRES_IN"),
181
185
  ...fileS3
182
186
  };
187
+ const appViewsRaw = pick("app-views", "MIKROTIK_MCP__APP_VIEWS");
188
+ const appViewsEnv = appViewsRaw === undefined ? undefined : !/^(0|false|no|off)$/i.test(appViewsRaw);
183
189
  const mcp = {
184
190
  transport: pick("transport", "MIKROTIK_MCP__TRANSPORT", "MCP_TRANSPORT"),
185
191
  host: pick("mcp-host", "MIKROTIK_MCP__HOST"),
@@ -187,7 +193,9 @@ function loadConfig(argv = process.argv.slice(2)) {
187
193
  allowedHosts: pick("mcp-allowed-hosts", "MIKROTIK_MCP__ALLOWED_HOSTS"),
188
194
  allowedOrigins: pick("mcp-allowed-origins", "MIKROTIK_MCP__ALLOWED_ORIGINS"),
189
195
  corsOrigins: pick("mcp-cors-origins", "MIKROTIK_MCP__CORS_ORIGINS"),
190
- toolPageSize: pick("tool-page-size", "MIKROTIK_MCP__TOOL_PAGE_SIZE")
196
+ toolPageSize: pick("tool-page-size", "MIKROTIK_MCP__TOOL_PAGE_SIZE"),
197
+ appViews: appViewsEnv,
198
+ ...fileMcp
191
199
  };
192
200
  const isTruthy = (v) => /^(1|true|yes|on)$/i.test(v ?? "");
193
201
  const readOnly = isTruthy(pick("read-only", "MIKROTIK_READ_ONLY"));
@@ -1794,9 +1802,9 @@ function defineTool(def) {
1794
1802
  inputSchema: def.inputSchema,
1795
1803
  ui: def.ui,
1796
1804
  register(server, opts = {}) {
1797
- const { sendLog, deviceNames, deviceAliases, deviceDirectory: deviceDirectory2 } = opts;
1805
+ const { sendLog, deviceNames, deviceAliases, deviceDirectory: deviceDirectory2, appViews } = opts;
1798
1806
  const multiDevice = !!deviceNames && deviceNames.length > 1;
1799
- const { ui, auto } = effectiveUi(def);
1807
+ const { ui, auto } = appViews === false ? { ui: undefined, auto: false } : effectiveUi(def);
1800
1808
  const selectorNames = multiDevice && deviceNames ? [...new Set([...deviceNames, ...deviceAliases ?? []])] : [];
1801
1809
  const inputSchema = multiDevice ? {
1802
1810
  ...def.inputSchema,
@@ -27067,7 +27075,7 @@ function registerPrompts(server) {
27067
27075
  // package.json
27068
27076
  var package_default = {
27069
27077
  name: "@usex/mikrotik-mcp",
27070
- version: "3.29.0",
27078
+ version: "3.30.0",
27071
27079
  description: "MCP server for MikroTik RouterOS \u2014 660+ tools over SSH for firewall, NAT, routing, DHCP, DNS, WireGuard, wireless, QoS and more.",
27072
27080
  keywords: [
27073
27081
  "ai",
@@ -27273,6 +27281,7 @@ function createServer(opts = {}) {
27273
27281
  deviceNames: names,
27274
27282
  deviceAliases: deviceLabels(),
27275
27283
  deviceDirectory: deviceDirectory(),
27284
+ appViews: getConfig().mcp.appViews,
27276
27285
  readOnly
27277
27286
  });
27278
27287
  const promptCount = registerPrompts(server);
package/dist/index.d.ts CHANGED
@@ -94,6 +94,14 @@ interface RegisterOptions {
94
94
  */
95
95
  deviceDirectory?: DeviceDirectoryEntry[];
96
96
  /**
97
+ * Emit MCP App view metadata (`_meta.ui`) on tools. Default true. Set false for
98
+ * hosts whose tool discovery hides/deprioritises tools that carry App/
99
+ * `openai/outputTemplate` metadata — without it, every `list_*`/`get_*` read
100
+ * tool gains the auto-records view and some clients then surface only the
101
+ * (metadata-free) write tools. Disabling makes reads plain, surfacing tools.
102
+ */
103
+ appViews?: boolean;
104
+ /**
97
105
  * Read-only mode: register only tools annotated `readOnlyHint`. Used to
98
106
  * withhold every write/destructive tool from a publicly-exposed surface (e.g.
99
107
  * a ChatGPT Apps connector) until authentication is in place.
package/dist/index.js CHANGED
@@ -19,7 +19,8 @@ var McpServerSettingsSchema = z.object({
19
19
  allowedHosts: z.string().default(""),
20
20
  allowedOrigins: z.string().default(""),
21
21
  corsOrigins: z.string().default(""),
22
- toolPageSize: z.coerce.number().int().min(0).default(0)
22
+ toolPageSize: z.coerce.number().int().min(0).default(0),
23
+ appViews: z.boolean().default(true)
23
24
  });
24
25
  var DeviceConfigSchema = z.object({
25
26
  host: z.string().default("127.0.0.1"),
@@ -117,7 +118,8 @@ function parseDevicesSource(raw, fromFile) {
117
118
  const s3 = structured && obj.s3 && typeof obj.s3 === "object" ? obj.s3 : undefined;
118
119
  const dashboard = structured && obj.dashboard && typeof obj.dashboard === "object" ? obj.dashboard : undefined;
119
120
  const tools = structured && obj.tools && typeof obj.tools === "object" ? obj.tools : undefined;
120
- return { devices, defaultDevice, s3, dashboard, tools };
121
+ const mcp = structured && obj.mcp && typeof obj.mcp === "object" ? obj.mcp : undefined;
122
+ return { devices, defaultDevice, s3, dashboard, tools, mcp };
121
123
  }
122
124
  var configSource = { path: DEFAULT_CONFIG_FILE, fromFile: false };
123
125
  function loadConfig(argv = process.argv.slice(2)) {
@@ -150,6 +152,7 @@ function loadConfig(argv = process.argv.slice(2)) {
150
152
  let fileS3 = {};
151
153
  let fileDashboard = {};
152
154
  let fileTools;
155
+ let fileMcp;
153
156
  if (configFile || devicesInline) {
154
157
  const src = configFile ? parseDevicesSource(configFile, true) : parseDevicesSource(devicesInline, false);
155
158
  for (const [name, dc] of Object.entries(src.devices))
@@ -161,6 +164,7 @@ function loadConfig(argv = process.argv.slice(2)) {
161
164
  fileS3 = src.s3;
162
165
  fileDashboard = src.dashboard;
163
166
  fileTools = src.tools;
167
+ fileMcp = src.mcp;
164
168
  }
165
169
  const s3 = {
166
170
  accessKeyId: pick("s3-access-key-id", "S3_ACCESS_KEY_ID", "AWS_ACCESS_KEY_ID"),
@@ -173,6 +177,8 @@ function loadConfig(argv = process.argv.slice(2)) {
173
177
  presignExpiresIn: pick("s3-presign-expires-in", "MIKROTIK_S3_PRESIGN_EXPIRES_IN"),
174
178
  ...fileS3
175
179
  };
180
+ const appViewsRaw = pick("app-views", "MIKROTIK_MCP__APP_VIEWS");
181
+ const appViewsEnv = appViewsRaw === undefined ? undefined : !/^(0|false|no|off)$/i.test(appViewsRaw);
176
182
  const mcp = {
177
183
  transport: pick("transport", "MIKROTIK_MCP__TRANSPORT", "MCP_TRANSPORT"),
178
184
  host: pick("mcp-host", "MIKROTIK_MCP__HOST"),
@@ -180,7 +186,9 @@ function loadConfig(argv = process.argv.slice(2)) {
180
186
  allowedHosts: pick("mcp-allowed-hosts", "MIKROTIK_MCP__ALLOWED_HOSTS"),
181
187
  allowedOrigins: pick("mcp-allowed-origins", "MIKROTIK_MCP__ALLOWED_ORIGINS"),
182
188
  corsOrigins: pick("mcp-cors-origins", "MIKROTIK_MCP__CORS_ORIGINS"),
183
- toolPageSize: pick("tool-page-size", "MIKROTIK_MCP__TOOL_PAGE_SIZE")
189
+ toolPageSize: pick("tool-page-size", "MIKROTIK_MCP__TOOL_PAGE_SIZE"),
190
+ appViews: appViewsEnv,
191
+ ...fileMcp
184
192
  };
185
193
  const isTruthy = (v) => /^(1|true|yes|on)$/i.test(v ?? "");
186
194
  const readOnly = isTruthy(pick("read-only", "MIKROTIK_READ_ONLY"));
@@ -1700,9 +1708,9 @@ function defineTool(def) {
1700
1708
  inputSchema: def.inputSchema,
1701
1709
  ui: def.ui,
1702
1710
  register(server, opts = {}) {
1703
- const { sendLog, deviceNames, deviceAliases, deviceDirectory: deviceDirectory2 } = opts;
1711
+ const { sendLog, deviceNames, deviceAliases, deviceDirectory: deviceDirectory2, appViews } = opts;
1704
1712
  const multiDevice = !!deviceNames && deviceNames.length > 1;
1705
- const { ui, auto } = effectiveUi(def);
1713
+ const { ui, auto } = appViews === false ? { ui: undefined, auto: false } : effectiveUi(def);
1706
1714
  const selectorNames = multiDevice && deviceNames ? [...new Set([...deviceNames, ...deviceAliases ?? []])] : [];
1707
1715
  const inputSchema = multiDevice ? {
1708
1716
  ...def.inputSchema,
@@ -25045,7 +25053,7 @@ function selectToolModules(filter = {}, catalog = moduleCatalog) {
25045
25053
  // package.json
25046
25054
  var package_default = {
25047
25055
  name: "@usex/mikrotik-mcp",
25048
- version: "3.29.0",
25056
+ version: "3.30.0",
25049
25057
  description: "MCP server for MikroTik RouterOS \u2014 660+ tools over SSH for firewall, NAT, routing, DHCP, DNS, WireGuard, wireless, QoS and more.",
25050
25058
  keywords: [
25051
25059
  "ai",
@@ -25251,6 +25259,7 @@ function createServer(opts = {}) {
25251
25259
  deviceNames: names,
25252
25260
  deviceAliases: deviceLabels(),
25253
25261
  deviceDirectory: deviceDirectory(),
25262
+ appViews: getConfig().mcp.appViews,
25254
25263
  readOnly
25255
25264
  });
25256
25265
  const promptCount = registerPrompts(server);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usex/mikrotik-mcp",
3
- "version": "3.29.0",
3
+ "version": "3.30.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",
@@ -87,7 +87,8 @@
87
87
  "allowedHosts": "",
88
88
  "allowedOrigins": "",
89
89
  "corsOrigins": "",
90
- "toolPageSize": 0
90
+ "toolPageSize": 0,
91
+ "appViews": true
91
92
  },
92
93
  "type": "object",
93
94
  "properties": {
@@ -123,6 +124,10 @@
123
124
  "type": "integer",
124
125
  "minimum": 0,
125
126
  "maximum": 9007199254740991
127
+ },
128
+ "appViews": {
129
+ "default": true,
130
+ "type": "boolean"
126
131
  }
127
132
  },
128
133
  "required": [
@@ -132,7 +137,8 @@
132
137
  "allowedHosts",
133
138
  "allowedOrigins",
134
139
  "corsOrigins",
135
- "toolPageSize"
140
+ "toolPageSize",
141
+ "appViews"
136
142
  ],
137
143
  "additionalProperties": false
138
144
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "version": "3.28.0",
3
+ "version": "3.29.0",
4
4
  "generated": "by scripts/gen-schemas.ts — do not edit by hand",
5
5
  "toolCount": 758,
6
6
  "tools": [