@owine/unifi-network-mcp 2.15.0 → 3.0.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/LICENSE +21 -0
- package/README.md +226 -73
- package/dist/client.d.ts +13 -1
- package/dist/client.js +142 -16
- package/dist/config.d.ts +11 -0
- package/dist/config.js +102 -3
- package/dist/guard.d.ts +46 -0
- package/dist/guard.js +171 -0
- package/dist/index.js +15 -4
- package/dist/instructions.d.ts +9 -0
- package/dist/instructions.js +32 -0
- package/dist/tls.d.ts +14 -0
- package/dist/tls.js +58 -0
- package/dist/tools/acl.js +123 -50
- package/dist/tools/client-history.js +20 -10
- package/dist/tools/clients.js +10 -9
- package/dist/tools/devices.js +21 -20
- package/dist/tools/dns-policies.js +27 -27
- package/dist/tools/firewall.d.ts +2 -1
- package/dist/tools/firewall.js +200 -75
- package/dist/tools/hotspot.js +35 -28
- package/dist/tools/index.d.ts +13 -1
- package/dist/tools/index.js +63 -4
- package/dist/tools/networks.d.ts +2 -1
- package/dist/tools/networks.js +44 -31
- package/dist/tools/sites.js +2 -2
- package/dist/tools/supporting.js +22 -21
- package/dist/tools/switching.js +16 -15
- package/dist/tools/system.js +1 -1
- package/dist/tools/traffic-matching.d.ts +2 -1
- package/dist/tools/traffic-matching.js +22 -20
- package/dist/tools/wifi.js +76 -30
- package/dist/utils/full-put.d.ts +11 -2
- package/dist/utils/full-put.js +25 -2
- package/dist/utils/output-schemas.d.ts +26 -4
- package/dist/utils/output-schemas.js +80 -48
- package/dist/utils/params.d.ts +7 -0
- package/dist/utils/params.js +12 -0
- package/dist/utils/responses.d.ts +2 -0
- package/dist/utils/responses.js +28 -2
- package/dist/utils/safety.d.ts +35 -1
- package/dist/utils/safety.js +53 -3
- package/dist/utils/secrets.js +3 -0
- package/dist/utils/wan-exposure.d.ts +69 -0
- package/dist/utils/wan-exposure.js +245 -0
- package/dist/write-log.d.ts +52 -0
- package/dist/write-log.js +178 -0
- package/dist/write-tools.d.ts +27 -0
- package/dist/write-tools.js +50 -0
- package/package.json +17 -13
package/dist/tools/devices.js
CHANGED
|
@@ -6,26 +6,27 @@ const responses_js_1 = require("../utils/responses.js");
|
|
|
6
6
|
const query_js_1 = require("../utils/query.js");
|
|
7
7
|
const safety_js_1 = require("../utils/safety.js");
|
|
8
8
|
const output_schemas_js_1 = require("../utils/output-schemas.js");
|
|
9
|
+
const params_js_1 = require("../utils/params.js");
|
|
9
10
|
// Adopt echoes the adopted device — reuse the device detail schema.
|
|
10
11
|
const adoptDeviceOutputSchema = output_schemas_js_1.getDeviceOutputSchema;
|
|
11
12
|
function registerDeviceTools(server, client, readOnly = false) {
|
|
12
13
|
server.registerTool("unifi_list_devices", {
|
|
13
14
|
description: "List all adopted devices (gateways, switches, APs) at a site. Returns: id, name, model, macAddress, ipAddress, state (ONLINE/OFFLINE/etc), supported, firmwareVersion, firmwareUpdatable, features[] (capability tags, e.g. ['switching'] or ['accessPoint']), interfaces[] (e.g. ['ports'] or ['radios']). NOTE: features/interfaces are string arrays here; unifi_get_device expands them into objects. Use for: device inventory; pair with unifi_get_device for full config (port table, radios) and unifi_get_device_statistics for live metrics.",
|
|
14
15
|
inputSchema: {
|
|
15
|
-
siteId:
|
|
16
|
+
siteId: (0, params_js_1.resourceId)().describe("Site ID"),
|
|
16
17
|
offset: zod_1.z
|
|
17
18
|
.number()
|
|
18
19
|
.int()
|
|
19
20
|
.nonnegative()
|
|
20
21
|
.optional()
|
|
21
|
-
.describe("Number of records to skip
|
|
22
|
+
.describe("Number of records to skip"),
|
|
22
23
|
limit: zod_1.z
|
|
23
24
|
.number()
|
|
24
25
|
.int()
|
|
25
26
|
.min(0)
|
|
26
27
|
.max(200)
|
|
27
28
|
.optional()
|
|
28
|
-
.describe("Number of records to return (default: 25
|
|
29
|
+
.describe("Number of records to return (API default: 25)"),
|
|
29
30
|
filter: zod_1.z.string().optional().describe("Filter expression. Filterable: name (supports like), model, state, macAddress, ipAddress, firmwareVersion, supported, firmwareUpdatable, features/interfaces (sets: contains/containsAny/containsAll). like is rejected on model. Example: features.contains('accessPoint')"),
|
|
30
31
|
},
|
|
31
32
|
outputSchema: output_schemas_js_1.listDevicesOutputSchema,
|
|
@@ -43,8 +44,8 @@ function registerDeviceTools(server, client, readOnly = false) {
|
|
|
43
44
|
server.registerTool("unifi_get_device", {
|
|
44
45
|
description: "Get full configuration for a device. Returns (in addition to list fields): adoptedAt, provisionedAt, configurationId, uplink.deviceId (absent on the ISP modem), features (object keyed by capability: switching {lags[]} / accessPoint {}), interfaces.ports[] for switches, gateways and modems ({idx, state, connector, maxSpeedMbps, speedMbps (may be omitted on DOWN ports), poe:{standard, type, enabled, state} on PoE ports only}), interfaces.radios[] for APs ({wlanStandard, frequencyGHz, channelWidthMHz, channel}). Some devices (e.g. 5G modems) return empty features/interfaces objects. NOTE: in the LIST endpoint, features/interfaces are capability-tag string arrays instead. Use for: switch port layout/PoE state, AP radio config, uplink topology. For live throughput/CPU/memory, use unifi_get_device_statistics.",
|
|
45
46
|
inputSchema: {
|
|
46
|
-
siteId:
|
|
47
|
-
deviceId:
|
|
47
|
+
siteId: (0, params_js_1.resourceId)().describe("Site ID"),
|
|
48
|
+
deviceId: (0, params_js_1.resourceId)().describe("Device ID"),
|
|
48
49
|
},
|
|
49
50
|
outputSchema: output_schemas_js_1.getDeviceOutputSchema,
|
|
50
51
|
annotations: safety_js_1.READ_ONLY,
|
|
@@ -60,8 +61,8 @@ function registerDeviceTools(server, client, readOnly = false) {
|
|
|
60
61
|
server.registerTool("unifi_get_device_statistics", {
|
|
61
62
|
description: "Get latest live statistics for a device. Returns: uptimeSec, lastHeartbeatAt, nextHeartbeatAt, loadAverage1/5/15Min, cpuUtilizationPct, memoryUtilizationPct, uplink (txRateBps, rxRateBps; absent on e.g. the ISP modem), interfaces.radios[] for APs ({frequencyGHz, txRetriesPct}; interfaces is {} for non-AP devices). NOTE: verified against 11.0.83 — the Integration API does NOT expose per-switch-port byte/error/PoE-power counters here; port-level live stats are unavailable. Use for: device health and AP radio metrics. For config (channel, power, port assignment), use unifi_get_device.",
|
|
62
63
|
inputSchema: {
|
|
63
|
-
siteId:
|
|
64
|
-
deviceId:
|
|
64
|
+
siteId: (0, params_js_1.resourceId)().describe("Site ID"),
|
|
65
|
+
deviceId: (0, params_js_1.resourceId)().describe("Device ID"),
|
|
65
66
|
},
|
|
66
67
|
outputSchema: output_schemas_js_1.getDeviceStatisticsOutputSchema,
|
|
67
68
|
annotations: safety_js_1.READ_ONLY,
|
|
@@ -82,14 +83,14 @@ function registerDeviceTools(server, client, readOnly = false) {
|
|
|
82
83
|
.int()
|
|
83
84
|
.nonnegative()
|
|
84
85
|
.optional()
|
|
85
|
-
.describe("Number of records to skip
|
|
86
|
+
.describe("Number of records to skip"),
|
|
86
87
|
limit: zod_1.z
|
|
87
88
|
.number()
|
|
88
89
|
.int()
|
|
89
90
|
.min(0)
|
|
90
91
|
.max(200)
|
|
91
92
|
.optional()
|
|
92
|
-
.describe("Number of records to return (default: 25
|
|
93
|
+
.describe("Number of records to return (API default: 25)"),
|
|
93
94
|
filter: zod_1.z.string().optional().describe("Filter expression, e.g. model.eq('U7 Pro')"),
|
|
94
95
|
},
|
|
95
96
|
outputSchema: output_schemas_js_1.listPendingDevicesOutputSchema,
|
|
@@ -109,14 +110,14 @@ function registerDeviceTools(server, client, readOnly = false) {
|
|
|
109
110
|
server.registerTool("unifi_adopt_device", {
|
|
110
111
|
description: "Adopt a pending device into a site by MAC address. The device must already appear in unifi_list_pending_devices. Idempotency: not safe to retry — re-adopting may error or duplicate.",
|
|
111
112
|
inputSchema: {
|
|
112
|
-
siteId:
|
|
113
|
+
siteId: (0, params_js_1.resourceId)().describe("Site ID"),
|
|
113
114
|
macAddress: zod_1.z.string().describe("MAC address of the device"),
|
|
114
115
|
// Required by the API; kept optional here and defaulted to false below
|
|
115
116
|
// so callers need not pass it explicitly.
|
|
116
117
|
ignoreDeviceLimit: zod_1.z.boolean().optional().describe("Ignore device limit when adopting (required by the API; sent as false when omitted)"),
|
|
117
118
|
dryRun: zod_1.z.boolean().optional().describe("Preview this action without executing it"),
|
|
118
119
|
},
|
|
119
|
-
outputSchema: adoptDeviceOutputSchema,
|
|
120
|
+
outputSchema: (0, output_schemas_js_1.writeResult)(adoptDeviceOutputSchema),
|
|
120
121
|
annotations: safety_js_1.WRITE_NOT_IDEMPOTENT,
|
|
121
122
|
}, async ({ siteId, macAddress, ignoreDeviceLimit, dryRun }) => {
|
|
122
123
|
const body = {
|
|
@@ -136,18 +137,18 @@ function registerDeviceTools(server, client, readOnly = false) {
|
|
|
136
137
|
server.registerTool("unifi_remove_device", {
|
|
137
138
|
description: "DESTRUCTIVE: Remove (unadopt) a device from a site. If the device is online, it will be reset to factory defaults",
|
|
138
139
|
inputSchema: {
|
|
139
|
-
siteId:
|
|
140
|
-
deviceId:
|
|
141
|
-
confirm:
|
|
140
|
+
siteId: (0, params_js_1.resourceId)().describe("Site ID"),
|
|
141
|
+
deviceId: (0, params_js_1.resourceId)().describe("Device ID"),
|
|
142
|
+
confirm: (0, safety_js_1.confirmDestructive)(),
|
|
142
143
|
dryRun: zod_1.z.boolean().optional().describe("Preview this action without executing it"),
|
|
143
144
|
},
|
|
144
145
|
annotations: safety_js_1.DESTRUCTIVE,
|
|
145
146
|
}, async ({ siteId, deviceId, confirm, dryRun }) => {
|
|
146
|
-
const guard = (0, safety_js_1.requireConfirmation)(confirm, "This will remove the device from the site. If the device is online, it will be reset to factory defaults");
|
|
147
|
+
const guard = dryRun ? null : (0, safety_js_1.requireConfirmation)(confirm, "This will remove the device from the site. If the device is online, it will be reset to factory defaults");
|
|
147
148
|
if (guard)
|
|
148
149
|
return guard;
|
|
149
150
|
if (dryRun)
|
|
150
|
-
return (0, safety_js_1.formatDryRun)("DELETE", `/sites/${siteId}/devices/${deviceId}
|
|
151
|
+
return (0, safety_js_1.formatDryRun)("DELETE", `/sites/${siteId}/devices/${deviceId}`);
|
|
151
152
|
try {
|
|
152
153
|
const data = await client.delete(`/sites/${siteId}/devices/${deviceId}`);
|
|
153
154
|
return (0, responses_js_1.formatSuccess)(data);
|
|
@@ -159,8 +160,8 @@ function registerDeviceTools(server, client, readOnly = false) {
|
|
|
159
160
|
server.registerTool("unifi_restart_device", {
|
|
160
161
|
description: "Restart (reboot) a device. The device will be unreachable for ~1–3 minutes. Not idempotent: each call triggers a fresh reboot.",
|
|
161
162
|
inputSchema: {
|
|
162
|
-
siteId:
|
|
163
|
-
deviceId:
|
|
163
|
+
siteId: (0, params_js_1.resourceId)().describe("Site ID"),
|
|
164
|
+
deviceId: (0, params_js_1.resourceId)().describe("Device ID"),
|
|
164
165
|
dryRun: zod_1.z.boolean().optional().describe("Preview this action without executing it"),
|
|
165
166
|
},
|
|
166
167
|
annotations: safety_js_1.WRITE_NOT_IDEMPOTENT,
|
|
@@ -179,8 +180,8 @@ function registerDeviceTools(server, client, readOnly = false) {
|
|
|
179
180
|
server.registerTool("unifi_power_cycle_port", {
|
|
180
181
|
description: "Power-cycle PoE on a specific switch port (briefly drops then restores power). portIdx is the port number (1-based) as shown in unifi_get_device interfaces.ports[].idx. Use for: rebooting a PoE-powered camera/AP without touching the device.",
|
|
181
182
|
inputSchema: {
|
|
182
|
-
siteId:
|
|
183
|
-
deviceId:
|
|
183
|
+
siteId: (0, params_js_1.resourceId)().describe("Site ID"),
|
|
184
|
+
deviceId: (0, params_js_1.resourceId)().describe("Device ID"),
|
|
184
185
|
portIdx: zod_1.z.number().int().min(1).describe("Port index number (1-based)"),
|
|
185
186
|
dryRun: zod_1.z.boolean().optional().describe("Preview this action without executing it"),
|
|
186
187
|
},
|
|
@@ -7,6 +7,7 @@ const query_js_1 = require("../utils/query.js");
|
|
|
7
7
|
const safety_js_1 = require("../utils/safety.js");
|
|
8
8
|
const full_put_js_1 = require("../utils/full-put.js");
|
|
9
9
|
const output_schemas_js_1 = require("../utils/output-schemas.js");
|
|
10
|
+
const params_js_1 = require("../utils/params.js");
|
|
10
11
|
// Type-specific request-body fields, from the 11.0.83 POST/PUT schemas (every
|
|
11
12
|
// type also takes type, enabled, domain). MX/TXT/SRV/FORWARD_DOMAIN have no TTL.
|
|
12
13
|
const DNS_TYPE_FIELDS = {
|
|
@@ -83,20 +84,20 @@ function registerDnsPolicyTools(server, client, readOnly = false) {
|
|
|
83
84
|
server.registerTool("unifi_list_dns_policies", {
|
|
84
85
|
description: "List DNS policies (local DNS records and forward rules served by the gateway) at a site. Returns: id, type (A_RECORD, AAAA_RECORD, CNAME_RECORD, MX_RECORD, TXT_RECORD, SRV_RECORD, FORWARD_DOMAIN), enabled, domain, metadata.origin, plus type-specific fields: A ipv4Address+ttlSeconds; AAAA ipv6Address+ttlSeconds; CNAME targetDomain+ttlSeconds; MX mailServerDomain+priority; TXT text; SRV serverDomain/service/protocol/port/priority/weight; FORWARD_DOMAIN ipAddress (per 11.0.83 response samples).",
|
|
85
86
|
inputSchema: {
|
|
86
|
-
siteId:
|
|
87
|
+
siteId: (0, params_js_1.resourceId)().describe("Site ID"),
|
|
87
88
|
offset: zod_1.z
|
|
88
89
|
.number()
|
|
89
90
|
.int()
|
|
90
91
|
.nonnegative()
|
|
91
92
|
.optional()
|
|
92
|
-
.describe("Number of records to skip
|
|
93
|
+
.describe("Number of records to skip"),
|
|
93
94
|
limit: zod_1.z
|
|
94
95
|
.number()
|
|
95
96
|
.int()
|
|
96
97
|
.min(0)
|
|
97
98
|
.max(200)
|
|
98
99
|
.optional()
|
|
99
|
-
.describe("Number of records to return (default: 25
|
|
100
|
+
.describe("Number of records to return (API default: 25)"),
|
|
100
101
|
filter: zod_1.z
|
|
101
102
|
.string()
|
|
102
103
|
.optional()
|
|
@@ -117,8 +118,8 @@ function registerDnsPolicyTools(server, client, readOnly = false) {
|
|
|
117
118
|
server.registerTool("unifi_get_dns_policy", {
|
|
118
119
|
description: "Get a specific DNS policy by ID (same fields as the list entry).",
|
|
119
120
|
inputSchema: {
|
|
120
|
-
siteId:
|
|
121
|
-
dnsPolicyId:
|
|
121
|
+
siteId: (0, params_js_1.resourceId)().describe("Site ID"),
|
|
122
|
+
dnsPolicyId: (0, params_js_1.resourceId)().describe("DNS policy ID"),
|
|
122
123
|
},
|
|
123
124
|
outputSchema: output_schemas_js_1.dnsPolicyOutputSchema,
|
|
124
125
|
annotations: safety_js_1.READ_ONLY,
|
|
@@ -136,7 +137,7 @@ function registerDnsPolicyTools(server, client, readOnly = false) {
|
|
|
136
137
|
server.registerTool("unifi_create_dns_policy", {
|
|
137
138
|
description: `Create a new DNS policy. Every type takes type, enabled, domain; the rest depends on type (per 11.0.83 docs): ${DNS_TYPES_DOC} Fields belonging to other types are rejected. Idempotency: not safe to retry — re-running creates a duplicate record.`,
|
|
138
139
|
inputSchema: {
|
|
139
|
-
siteId:
|
|
140
|
+
siteId: (0, params_js_1.resourceId)().describe("Site ID"),
|
|
140
141
|
...dnsFields,
|
|
141
142
|
type: dnsType,
|
|
142
143
|
enabled: zod_1.z.boolean().describe("Whether the DNS policy is enabled"),
|
|
@@ -146,7 +147,7 @@ function registerDnsPolicyTools(server, client, readOnly = false) {
|
|
|
146
147
|
.optional()
|
|
147
148
|
.describe("Preview this action without executing it"),
|
|
148
149
|
},
|
|
149
|
-
outputSchema: output_schemas_js_1.dnsPolicyOutputSchema,
|
|
150
|
+
outputSchema: (0, output_schemas_js_1.writeResult)(output_schemas_js_1.dnsPolicyOutputSchema),
|
|
150
151
|
annotations: safety_js_1.WRITE_NOT_IDEMPOTENT,
|
|
151
152
|
}, async ({ siteId, dryRun, ...fields }) => {
|
|
152
153
|
try {
|
|
@@ -164,8 +165,8 @@ function registerDnsPolicyTools(server, client, readOnly = false) {
|
|
|
164
165
|
server.registerTool("unifi_update_dns_policy", {
|
|
165
166
|
description: `Update a DNS policy. Pass only the fields to change. The API's PUT replaces the whole policy, so this tool reads the current policy, keeps the documented fields for the (possibly new) type, overlays your changes and sends the full body. Changing type drops the old type's fields, so supply the new type's required fields: ${DNS_TYPES_DOC} dryRun shows the merged body.`,
|
|
166
167
|
inputSchema: {
|
|
167
|
-
siteId:
|
|
168
|
-
dnsPolicyId:
|
|
168
|
+
siteId: (0, params_js_1.resourceId)().describe("Site ID"),
|
|
169
|
+
dnsPolicyId: (0, params_js_1.resourceId)().describe("DNS policy ID"),
|
|
169
170
|
...dnsFields,
|
|
170
171
|
type: dnsType.optional(),
|
|
171
172
|
enabled: zod_1.z.boolean().optional().describe("Whether the DNS policy is enabled"),
|
|
@@ -175,20 +176,22 @@ function registerDnsPolicyTools(server, client, readOnly = false) {
|
|
|
175
176
|
.optional()
|
|
176
177
|
.describe("Preview the merged PUT body without executing it (still reads the current policy)"),
|
|
177
178
|
},
|
|
178
|
-
outputSchema: output_schemas_js_1.dnsPolicyOutputSchema,
|
|
179
|
+
outputSchema: (0, output_schemas_js_1.writeResult)(output_schemas_js_1.dnsPolicyOutputSchema),
|
|
179
180
|
annotations: safety_js_1.WRITE,
|
|
180
181
|
}, async ({ siteId, dnsPolicyId, dryRun, ...fields }) => {
|
|
181
182
|
try {
|
|
182
183
|
const path = `/sites/${siteId}/dns/policies/${dnsPolicyId}`;
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
184
|
+
return await (0, full_put_js_1.withResourceLock)(path, async () => {
|
|
185
|
+
const current = (0, full_put_js_1.asObject)(await client.get(path), "the current DNS policy");
|
|
186
|
+
const updates = (0, full_put_js_1.definedEntries)(fields);
|
|
187
|
+
const { allowed } = fieldsForDnsType(updates.type ?? current.type);
|
|
188
|
+
const body = (0, full_put_js_1.mergeForPut)(current, updates, allowed);
|
|
189
|
+
checkDnsBody(body, updates);
|
|
190
|
+
if (dryRun)
|
|
191
|
+
return (0, safety_js_1.formatDryRun)("PUT", path, body);
|
|
192
|
+
const data = await client.put(path, body);
|
|
193
|
+
return (0, responses_js_1.formatSuccess)(data, { structured: true });
|
|
194
|
+
});
|
|
192
195
|
}
|
|
193
196
|
catch (err) {
|
|
194
197
|
return (0, responses_js_1.formatError)(err);
|
|
@@ -197,12 +200,9 @@ function registerDnsPolicyTools(server, client, readOnly = false) {
|
|
|
197
200
|
server.registerTool("unifi_delete_dns_policy", {
|
|
198
201
|
description: "DESTRUCTIVE: Delete a DNS policy",
|
|
199
202
|
inputSchema: {
|
|
200
|
-
siteId:
|
|
201
|
-
dnsPolicyId:
|
|
202
|
-
confirm:
|
|
203
|
-
.boolean()
|
|
204
|
-
.optional()
|
|
205
|
-
.describe("Must be true to execute this destructive action"),
|
|
203
|
+
siteId: (0, params_js_1.resourceId)().describe("Site ID"),
|
|
204
|
+
dnsPolicyId: (0, params_js_1.resourceId)().describe("DNS policy ID"),
|
|
205
|
+
confirm: (0, safety_js_1.confirmDestructive)(),
|
|
206
206
|
dryRun: zod_1.z
|
|
207
207
|
.boolean()
|
|
208
208
|
.optional()
|
|
@@ -210,12 +210,12 @@ function registerDnsPolicyTools(server, client, readOnly = false) {
|
|
|
210
210
|
},
|
|
211
211
|
annotations: safety_js_1.DESTRUCTIVE,
|
|
212
212
|
}, async ({ siteId, dnsPolicyId, confirm, dryRun }) => {
|
|
213
|
-
const guard = (0, safety_js_1.requireConfirmation)(confirm, "This will delete the DNS policy");
|
|
213
|
+
const guard = dryRun ? null : (0, safety_js_1.requireConfirmation)(confirm, "This will delete the DNS policy");
|
|
214
214
|
if (guard)
|
|
215
215
|
return guard;
|
|
216
216
|
try {
|
|
217
217
|
if (dryRun)
|
|
218
|
-
return (0, safety_js_1.formatDryRun)("DELETE", `/sites/${siteId}/dns/policies/${dnsPolicyId}
|
|
218
|
+
return (0, safety_js_1.formatDryRun)("DELETE", `/sites/${siteId}/dns/policies/${dnsPolicyId}`);
|
|
219
219
|
const data = await client.delete(`/sites/${siteId}/dns/policies/${dnsPolicyId}`);
|
|
220
220
|
return (0, responses_js_1.formatSuccess)(data);
|
|
221
221
|
}
|
package/dist/tools/firewall.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { NetworkClient } from "../client.js";
|
|
3
|
-
|
|
3
|
+
import { type WanPolicy } from "../utils/wan-exposure.js";
|
|
4
|
+
export declare function registerFirewallTools(server: McpServer, client: NetworkClient, readOnly?: boolean, wan?: WanPolicy): void;
|