@coffeerunhobby/mcp-ha-connect 1.3.0 → 1.3.4
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/.env.example +9 -0
- package/CLAUDE.md +70 -8
- package/README.md +26 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -1
- package/dist/index.js +19 -2
- package/dist/index.js.map +1 -1
- package/dist/omadaClient/index.d.ts +29 -0
- package/dist/omadaClient/index.js +41 -0
- package/dist/omadaClient/index.js.map +1 -1
- package/dist/omadaClient/request.js +14 -1
- package/dist/omadaClient/request.js.map +1 -1
- package/dist/omadaClient/site.d.ts +16 -0
- package/dist/omadaClient/site.js +25 -0
- package/dist/omadaClient/site.js.map +1 -1
- package/dist/permissions/index.js +20 -5
- package/dist/permissions/index.js.map +1 -1
- package/dist/server/common.d.ts +3 -0
- package/dist/server/common.js +2 -1
- package/dist/server/common.js.map +1 -1
- package/dist/server/stdio.d.ts +3 -0
- package/dist/server/stdio.js.map +1 -1
- package/dist/server/stream.js +6 -1
- package/dist/server/stream.js.map +1 -1
- package/dist/tools/common.d.ts +12 -0
- package/dist/tools/common.js +15 -1
- package/dist/tools/common.js.map +1 -1
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.js +2 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/omada/graph.d.ts +22 -0
- package/dist/tools/omada/graph.js +120 -0
- package/dist/tools/omada/graph.js.map +1 -0
- package/dist/tools/omada/index.d.ts +9 -1
- package/dist/tools/omada/index.js +30 -3
- package/dist/tools/omada/index.js.map +1 -1
- package/dist/tools/omada/namespace.d.ts +89 -0
- package/dist/tools/omada/namespace.js +496 -0
- package/dist/tools/omada/namespace.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/CHANGELOG.md +63 -0
- package/openapi.json +1 -1
- package/package.json +1 -1
- package/src/config.ts +7 -0
- package/src/index.ts +19 -2
- package/src/omadaClient/index.ts +65 -0
- package/src/omadaClient/request.ts +14 -1
- package/src/omadaClient/site.ts +29 -0
- package/src/permissions/index.ts +22 -5
- package/src/server/common.ts +5 -1
- package/src/server/stdio.ts +3 -0
- package/src/server/stream.ts +6 -1
- package/src/tools/common.ts +16 -2
- package/src/tools/index.ts +5 -3
- package/src/tools/omada/graph.ts +162 -0
- package/src/tools/omada/index.ts +48 -3
- package/src/tools/omada/namespace.ts +577 -0
- package/src/version.ts +1 -1
- package/tests/config.test.ts +30 -0
- package/tests/omadaClient/site.test.ts +37 -0
- package/tests/permissions/index.test.ts +21 -0
- package/tests/tools/omada/graph.test.ts +352 -0
- package/tests/tools/omada/namespace.test.ts +256 -0
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Omada resource-graph namespace.
|
|
3
|
+
*
|
|
4
|
+
* Instead of registering one MCP tool per Omada endpoint (which explodes the
|
|
5
|
+
* tool-schema budget for small models), graph mode exposes a single discoverable
|
|
6
|
+
* namespace via `omada_browse` (navigate) + `omada_read` (fetch). This manifest is
|
|
7
|
+
* the source of truth mapping graph paths → fetch logic + per-path RBAC.
|
|
8
|
+
*
|
|
9
|
+
* Design (see the "resource graph with lazy expansion" discussion):
|
|
10
|
+
* - `browse` returns resource *types/metadata*, never instances — no enumeration,
|
|
11
|
+
* no controller calls, zero payload explosion.
|
|
12
|
+
* - `read` is where data is fetched: single leaves, collections (optionally a
|
|
13
|
+
* single member via `id`), or paginated logs (single page via page/pageSize).
|
|
14
|
+
* - Authorization is per-path: each node declares the Permission bit it needs.
|
|
15
|
+
* Most nodes are QUERY; the security subtree (`/security/threats`) requires
|
|
16
|
+
* ADMIN, demonstrating that sensitive subtrees can require a higher bit without
|
|
17
|
+
* touching the tools.
|
|
18
|
+
*
|
|
19
|
+
* `graph` mode is a complete superset of `eager` reads: every eager read getter
|
|
20
|
+
* has a corresponding graph node here, including the ADMIN-gated IDS/IPS
|
|
21
|
+
* threat-management log (`/security/threats`), which maps its mandatory epoch
|
|
22
|
+
* time-window onto the required `params.startTime`/`params.endTime` validated by
|
|
23
|
+
* `omada_read` before any controller call.
|
|
24
|
+
*/
|
|
25
|
+
import { Permission } from '../../permissions/index.js';
|
|
26
|
+
const Q = Permission.QUERY;
|
|
27
|
+
const A = Permission.ADMIN;
|
|
28
|
+
const HOUR_MS = 60 * 60 * 1000;
|
|
29
|
+
/**
|
|
30
|
+
* Resolve an epoch-MILLISECONDS time window for the event/alert log endpoints
|
|
31
|
+
* (`/sites/{siteId}/logs/{events,alerts}`), which require `filters.timeStart` and
|
|
32
|
+
* `filters.timeEnd`. Explicit `params.startTime`/`params.endTime` win; otherwise
|
|
33
|
+
* default to the last 7 days so a bare `omada_read('/events')` "just works".
|
|
34
|
+
* Exported for unit testing (inject `now` to keep tests deterministic).
|
|
35
|
+
*/
|
|
36
|
+
export function resolveLogWindowMs(params, now = Date.now()) {
|
|
37
|
+
const timeEnd = params?.endTime ? Number(params.endTime) : now;
|
|
38
|
+
const timeStart = params?.startTime ? Number(params.startTime) : timeEnd - 7 * 24 * HOUR_MS;
|
|
39
|
+
return { timeStart, timeEnd };
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Resolve an epoch-SECONDS time window for the dashboard top-usage endpoints
|
|
43
|
+
* (`top-device-cpu-usage` / `top-device-memory-usage`), which require `start` and
|
|
44
|
+
* `end`. Explicit `params.startTime`/`params.endTime` (seconds) win; otherwise
|
|
45
|
+
* default to the last 24 hours. Exported for unit testing.
|
|
46
|
+
*/
|
|
47
|
+
export function resolveUsageWindowSec(params, now = Date.now()) {
|
|
48
|
+
const end = params?.endTime ? Number(params.endTime) : Math.floor(now / 1000);
|
|
49
|
+
const start = params?.startTime ? Number(params.startTime) : end - 24 * 60 * 60;
|
|
50
|
+
return { start, end };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The Omada resource graph. Containers have no `fetch` (browse-only); collections
|
|
54
|
+
* and leaves fetch data. Existing client methods back the well-trodden reads;
|
|
55
|
+
* the generic `client.readResource(...)` backs newly-added endpoints with zero
|
|
56
|
+
* new client code.
|
|
57
|
+
*/
|
|
58
|
+
export const OMADA_RESOURCES = [
|
|
59
|
+
{
|
|
60
|
+
path: '/',
|
|
61
|
+
kind: 'container',
|
|
62
|
+
permission: Q,
|
|
63
|
+
description: 'Root of the Omada network resource graph. Browse children to discover resources.',
|
|
64
|
+
},
|
|
65
|
+
// ---- Sites -------------------------------------------------------------
|
|
66
|
+
{
|
|
67
|
+
path: '/sites',
|
|
68
|
+
kind: 'collection',
|
|
69
|
+
permission: Q,
|
|
70
|
+
estimatedSize: 'small',
|
|
71
|
+
description: 'All sites on the controller. Most resources are scoped to a site via the optional siteId argument.',
|
|
72
|
+
fetch: (c) => c.listSites(),
|
|
73
|
+
},
|
|
74
|
+
// ---- Devices (infrastructure) -----------------------------------------
|
|
75
|
+
{
|
|
76
|
+
path: '/devices',
|
|
77
|
+
kind: 'collection',
|
|
78
|
+
permission: Q,
|
|
79
|
+
estimatedSize: 'medium',
|
|
80
|
+
description: 'Network infrastructure (APs, switches, gateways). Pass id=<MAC> to look up a single device.',
|
|
81
|
+
params: [{ name: 'id', required: false, description: 'Device MAC to fetch a single device' }],
|
|
82
|
+
fetch: (c, a) => (a.id ? c.getDevice(a.id, a.siteId) : c.listDevices(a.siteId)),
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
path: '/devices/pending',
|
|
86
|
+
kind: 'collection',
|
|
87
|
+
permission: Q,
|
|
88
|
+
paginated: true,
|
|
89
|
+
defaultPageSize: 50,
|
|
90
|
+
estimatedSize: 'small',
|
|
91
|
+
description: 'Devices discovered but not yet adopted into the site (paginated). Use page/pageSize.',
|
|
92
|
+
fetch: (c, a) => c.readResource({
|
|
93
|
+
pathTemplate: '/sites/{siteId}/grid/devices/pending',
|
|
94
|
+
siteId: a.siteId,
|
|
95
|
+
paginated: true,
|
|
96
|
+
page: a.page,
|
|
97
|
+
pageSize: a.pageSize,
|
|
98
|
+
}),
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
path: '/devices/stats',
|
|
102
|
+
kind: 'collection',
|
|
103
|
+
permission: Q,
|
|
104
|
+
paginated: true,
|
|
105
|
+
defaultPageSize: 50,
|
|
106
|
+
estimatedSize: 'medium',
|
|
107
|
+
description: 'Per-device statistics (CPU, memory, traffic). Paginated — use page/pageSize.',
|
|
108
|
+
fetch: (c, a) => c.listDevicesStats({ page: a.page ?? 1, pageSize: a.pageSize ?? 50 }),
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
path: '/devices/stack',
|
|
112
|
+
kind: 'leaf',
|
|
113
|
+
permission: Q,
|
|
114
|
+
estimatedSize: 'small',
|
|
115
|
+
description: 'Switch-stack detail. Requires stackId.',
|
|
116
|
+
params: [{ name: 'stackId', required: true, description: 'Switch stack identifier' }],
|
|
117
|
+
fetch: (c, a) => c.getSwitchStackDetail(a.params?.stackId ?? '', a.siteId),
|
|
118
|
+
},
|
|
119
|
+
// ---- Clients (connected users) ----------------------------------------
|
|
120
|
+
{
|
|
121
|
+
path: '/clients',
|
|
122
|
+
kind: 'collection',
|
|
123
|
+
permission: Q,
|
|
124
|
+
estimatedSize: 'large',
|
|
125
|
+
description: 'Connected clients (phones, laptops, IoT). Pass id=<MAC> to look up a single client.',
|
|
126
|
+
params: [{ name: 'id', required: false, description: 'Client MAC to fetch a single client' }],
|
|
127
|
+
fetch: (c, a) => (a.id ? c.getClient(a.id, a.siteId) : c.listClients(a.siteId)),
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
path: '/clients/active',
|
|
131
|
+
kind: 'collection',
|
|
132
|
+
permission: Q,
|
|
133
|
+
estimatedSize: 'small',
|
|
134
|
+
description: 'Most active clients by traffic.',
|
|
135
|
+
fetch: (c, a) => c.listMostActiveClients(a.siteId),
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
path: '/clients/activity',
|
|
139
|
+
kind: 'collection',
|
|
140
|
+
permission: Q,
|
|
141
|
+
estimatedSize: 'medium',
|
|
142
|
+
description: 'Per-client activity (traffic over time). Optional time window via params.start/params.end (epoch seconds).',
|
|
143
|
+
params: [
|
|
144
|
+
{ name: 'start', required: false, description: 'Start timestamp, epoch seconds' },
|
|
145
|
+
{ name: 'end', required: false, description: 'End timestamp, epoch seconds' },
|
|
146
|
+
],
|
|
147
|
+
fetch: (c, a) => c.listClientsActivity({
|
|
148
|
+
siteId: a.siteId,
|
|
149
|
+
start: a.params?.start !== undefined ? Number(a.params.start) : undefined,
|
|
150
|
+
end: a.params?.end !== undefined ? Number(a.params.end) : undefined,
|
|
151
|
+
}),
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
path: '/clients/past-connections',
|
|
155
|
+
kind: 'collection',
|
|
156
|
+
permission: Q,
|
|
157
|
+
paginated: true,
|
|
158
|
+
defaultPageSize: 50,
|
|
159
|
+
estimatedSize: 'large',
|
|
160
|
+
description: 'Historical client connections (paginated). Use page/pageSize.',
|
|
161
|
+
fetch: (c, a) => c.listClientsPastConnections({ siteId: a.siteId, page: a.page ?? 1, pageSize: a.pageSize ?? 50 }),
|
|
162
|
+
},
|
|
163
|
+
// ---- Gateway -----------------------------------------------------------
|
|
164
|
+
{ path: '/gateway', kind: 'container', permission: Q, description: 'Gateway/router status and connectivity.' },
|
|
165
|
+
{
|
|
166
|
+
path: '/gateway/wan',
|
|
167
|
+
kind: 'leaf',
|
|
168
|
+
permission: Q,
|
|
169
|
+
estimatedSize: 'small',
|
|
170
|
+
description: 'WAN port status for a gateway: WAN IP, DNS, uptime, link speed, TX/RX. Requires gatewayMac (find via /devices).',
|
|
171
|
+
params: [{ name: 'gatewayMac', required: true, description: 'Gateway MAC address' }],
|
|
172
|
+
fetch: (c, a) => c.readResource({
|
|
173
|
+
pathTemplate: '/sites/{siteId}/gateways/{gatewayMac}/wan-status',
|
|
174
|
+
siteId: a.siteId,
|
|
175
|
+
pathParams: { gatewayMac: a.params?.gatewayMac ?? '' },
|
|
176
|
+
}),
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
path: '/gateway/health',
|
|
180
|
+
kind: 'leaf',
|
|
181
|
+
permission: Q,
|
|
182
|
+
estimatedSize: 'small',
|
|
183
|
+
description: 'Detailed per-WAN health for a gateway. Requires gatewayMac (find via /devices).',
|
|
184
|
+
params: [{ name: 'gatewayMac', required: true, description: 'Gateway MAC address' }],
|
|
185
|
+
fetch: (c, a) => c.readResource({
|
|
186
|
+
pathTemplate: '/sites/{siteId}/health/gateways/{gatewayMac}/wans/details',
|
|
187
|
+
siteId: a.siteId,
|
|
188
|
+
pathParams: { gatewayMac: a.params?.gatewayMac ?? '' },
|
|
189
|
+
}),
|
|
190
|
+
},
|
|
191
|
+
// ---- Network config ----------------------------------------------------
|
|
192
|
+
{ path: '/network', kind: 'container', permission: Q, description: 'Network configuration: internet, LANs, WLAN groups, firewall.' },
|
|
193
|
+
{
|
|
194
|
+
path: '/network/internet',
|
|
195
|
+
kind: 'leaf',
|
|
196
|
+
permission: Q,
|
|
197
|
+
estimatedSize: 'small',
|
|
198
|
+
description: 'Internet/WAN connection information for the site.',
|
|
199
|
+
fetch: (c, a) => c.getInternetInfo(a.siteId),
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
path: '/network/lan-networks',
|
|
203
|
+
kind: 'collection',
|
|
204
|
+
permission: Q,
|
|
205
|
+
estimatedSize: 'small',
|
|
206
|
+
description: 'Configured LAN networks / VLANs.',
|
|
207
|
+
fetch: (c, a) => c.getLanNetworkList(a.siteId),
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
path: '/network/lan-profiles',
|
|
211
|
+
kind: 'collection',
|
|
212
|
+
permission: Q,
|
|
213
|
+
estimatedSize: 'small',
|
|
214
|
+
description: 'LAN profiles.',
|
|
215
|
+
fetch: (c, a) => c.getLanProfileList(a.siteId),
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
path: '/network/wlan-groups',
|
|
219
|
+
kind: 'collection',
|
|
220
|
+
permission: Q,
|
|
221
|
+
estimatedSize: 'small',
|
|
222
|
+
description: 'WLAN groups.',
|
|
223
|
+
fetch: (c, a) => c.getWlanGroupList(a.siteId),
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
path: '/network/firewall',
|
|
227
|
+
kind: 'leaf',
|
|
228
|
+
permission: Q,
|
|
229
|
+
estimatedSize: 'small',
|
|
230
|
+
description: 'Gateway firewall settings for the site.',
|
|
231
|
+
fetch: (c, a) => c.getFirewallSetting(a.siteId),
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
path: '/network/port-forwarding',
|
|
235
|
+
kind: 'collection',
|
|
236
|
+
permission: Q,
|
|
237
|
+
paginated: true,
|
|
238
|
+
defaultPageSize: 10,
|
|
239
|
+
estimatedSize: 'small',
|
|
240
|
+
description: "Port-forwarding status (paginated). params.type is 'User' (default) or 'UPnP'.",
|
|
241
|
+
params: [{ name: 'type', required: false, description: "'User' (default) or 'UPnP'" }],
|
|
242
|
+
fetch: (c, a) => c.getPortForwardingStatus(a.params?.type === 'UPnP' ? 'UPnP' : 'User', a.siteId, a.page ?? 1, a.pageSize ?? 10),
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
path: '/network/rate-limit-profiles',
|
|
246
|
+
kind: 'collection',
|
|
247
|
+
permission: Q,
|
|
248
|
+
estimatedSize: 'small',
|
|
249
|
+
description: 'Configured client rate-limit profiles (input for the rate-limit write tools).',
|
|
250
|
+
fetch: (c, a) => c.getRateLimitProfiles(a.siteId),
|
|
251
|
+
},
|
|
252
|
+
// ---- WiFi / wireless security -----------------------------------------
|
|
253
|
+
{ path: '/wifi', kind: 'container', permission: Q, description: 'Wireless: SSIDs, speed tests, rogue-AP and intrusion detection.' },
|
|
254
|
+
{
|
|
255
|
+
path: '/wifi/speedtest',
|
|
256
|
+
kind: 'leaf',
|
|
257
|
+
permission: Q,
|
|
258
|
+
estimatedSize: 'small',
|
|
259
|
+
description: 'Latest speed-test result for an access point. Requires apMac (find via /devices).',
|
|
260
|
+
params: [{ name: 'apMac', required: true, description: 'Access point MAC address' }],
|
|
261
|
+
fetch: (c, a) => c.readResource({
|
|
262
|
+
pathTemplate: '/sites/{siteId}/aps/{apMac}/speed-test-result',
|
|
263
|
+
siteId: a.siteId,
|
|
264
|
+
pathParams: { apMac: a.params?.apMac ?? '' },
|
|
265
|
+
}),
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
path: '/wifi/rogue',
|
|
269
|
+
kind: 'collection',
|
|
270
|
+
permission: Q,
|
|
271
|
+
paginated: true,
|
|
272
|
+
defaultPageSize: 50,
|
|
273
|
+
estimatedSize: 'small',
|
|
274
|
+
description: 'Rogue access points detected near the site (paginated). Use page/pageSize.',
|
|
275
|
+
fetch: (c, a) => c.readResource({
|
|
276
|
+
pathTemplate: '/sites/{siteId}/insight/rogueaps',
|
|
277
|
+
siteId: a.siteId,
|
|
278
|
+
paginated: true,
|
|
279
|
+
page: a.page,
|
|
280
|
+
pageSize: a.pageSize,
|
|
281
|
+
}),
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
path: '/wifi/wids',
|
|
285
|
+
kind: 'collection',
|
|
286
|
+
permission: Q,
|
|
287
|
+
paginated: true,
|
|
288
|
+
defaultPageSize: 50,
|
|
289
|
+
estimatedSize: 'small',
|
|
290
|
+
description: 'Wireless Intrusion Detection System (WIDS) entries (paginated). Use page/pageSize. ' +
|
|
291
|
+
'Note: the controller restricts this endpoint to Omada Pro controllers/sites; on a ' +
|
|
292
|
+
'standard controller it returns a "Pro only" message rather than data.',
|
|
293
|
+
fetch: (c, a) => c.readResource({
|
|
294
|
+
pathTemplate: '/sites/{siteId}/insight/wids',
|
|
295
|
+
siteId: a.siteId,
|
|
296
|
+
paginated: true,
|
|
297
|
+
page: a.page,
|
|
298
|
+
pageSize: a.pageSize,
|
|
299
|
+
}),
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
path: '/wifi/ssids',
|
|
303
|
+
kind: 'collection',
|
|
304
|
+
permission: Q,
|
|
305
|
+
estimatedSize: 'small',
|
|
306
|
+
description: 'SSIDs in a WLAN group. Requires wlanId; pass params.ssidId too to fetch a single SSID detail.',
|
|
307
|
+
params: [
|
|
308
|
+
{ name: 'wlanId', required: true, description: 'WLAN group id (find via /network/wlan-groups)' },
|
|
309
|
+
{ name: 'ssidId', required: false, description: 'SSID id — when set, returns that SSID detail instead of the list' },
|
|
310
|
+
],
|
|
311
|
+
fetch: (c, a) => a.params?.ssidId
|
|
312
|
+
? c.getSsidDetail(a.params.wlanId ?? '', a.params.ssidId, a.siteId)
|
|
313
|
+
: c.getSsidList(a.params?.wlanId ?? '', a.siteId),
|
|
314
|
+
},
|
|
315
|
+
// ---- Events / alerts (paginated) --------------------------------------
|
|
316
|
+
{
|
|
317
|
+
path: '/events',
|
|
318
|
+
kind: 'collection',
|
|
319
|
+
permission: Q,
|
|
320
|
+
paginated: true,
|
|
321
|
+
defaultPageSize: 50,
|
|
322
|
+
estimatedSize: 'large',
|
|
323
|
+
description: 'Site event log (paginated). Use page/pageSize. The controller requires a time window: by default this ' +
|
|
324
|
+
'returns the last 7 days. Override with params.startTime / params.endTime (epoch MILLISECONDS, e.g. ' +
|
|
325
|
+
'1679297710438). Optional params.module filters by source module.',
|
|
326
|
+
params: [
|
|
327
|
+
{ name: 'startTime', required: false, description: 'Window start, epoch ms (default: 7 days ago)' },
|
|
328
|
+
{ name: 'endTime', required: false, description: 'Window end, epoch ms (default: now)' },
|
|
329
|
+
{ name: 'module', required: false, description: 'Filter by module (e.g. "Device", "Client", "User")' },
|
|
330
|
+
],
|
|
331
|
+
fetch: (c, a) => {
|
|
332
|
+
const { timeStart, timeEnd } = resolveLogWindowMs(a.params);
|
|
333
|
+
const query = { 'filters.timeStart': timeStart, 'filters.timeEnd': timeEnd };
|
|
334
|
+
if (a.params?.module) {
|
|
335
|
+
query['filters.module'] = a.params.module;
|
|
336
|
+
}
|
|
337
|
+
return c.readResource({ pathTemplate: '/sites/{siteId}/logs/events', siteId: a.siteId, paginated: true, page: a.page, pageSize: a.pageSize, query });
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
path: '/events/alerts',
|
|
342
|
+
kind: 'collection',
|
|
343
|
+
permission: Q,
|
|
344
|
+
paginated: true,
|
|
345
|
+
defaultPageSize: 50,
|
|
346
|
+
estimatedSize: 'large',
|
|
347
|
+
description: 'Site alert log (paginated). Use page/pageSize. The controller requires a time window: by default this ' +
|
|
348
|
+
'returns the last 7 days. Override with params.startTime / params.endTime (epoch MILLISECONDS). Optional ' +
|
|
349
|
+
'params.module filters by source module; params.resolved ("true"/"false") filters by resolution state.',
|
|
350
|
+
params: [
|
|
351
|
+
{ name: 'startTime', required: false, description: 'Window start, epoch ms (default: 7 days ago)' },
|
|
352
|
+
{ name: 'endTime', required: false, description: 'Window end, epoch ms (default: now)' },
|
|
353
|
+
{ name: 'module', required: false, description: 'Filter by module (e.g. "Device", "Client", "User")' },
|
|
354
|
+
{ name: 'resolved', required: false, description: '"true" or "false" to filter by resolution state' },
|
|
355
|
+
],
|
|
356
|
+
fetch: (c, a) => {
|
|
357
|
+
const { timeStart, timeEnd } = resolveLogWindowMs(a.params);
|
|
358
|
+
const query = { 'filters.timeStart': timeStart, 'filters.timeEnd': timeEnd };
|
|
359
|
+
if (a.params?.module) {
|
|
360
|
+
query['filters.module'] = a.params.module;
|
|
361
|
+
}
|
|
362
|
+
if (a.params?.resolved === 'true' || a.params?.resolved === 'false') {
|
|
363
|
+
query['filters.resolved'] = a.params.resolved;
|
|
364
|
+
}
|
|
365
|
+
return c.readResource({ pathTemplate: '/sites/{siteId}/logs/alerts', siteId: a.siteId, paginated: true, page: a.page, pageSize: a.pageSize, query });
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
// ---- Dashboard ---------------------------------------------------------
|
|
369
|
+
{
|
|
370
|
+
path: '/dashboard',
|
|
371
|
+
kind: 'leaf',
|
|
372
|
+
permission: Q,
|
|
373
|
+
estimatedSize: 'medium',
|
|
374
|
+
description: 'Site dashboard overview diagram (topology + summary).',
|
|
375
|
+
fetch: (c, a) => c.readResource({ pathTemplate: '/sites/{siteId}/dashboard/overview-diagram', siteId: a.siteId }),
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
path: '/dashboard/cpu',
|
|
379
|
+
kind: 'collection',
|
|
380
|
+
permission: Q,
|
|
381
|
+
estimatedSize: 'small',
|
|
382
|
+
description: 'Devices with the highest CPU usage over a time window (default: last 24h). Override with params.startTime / ' +
|
|
383
|
+
'params.endTime (epoch SECONDS, e.g. 1682000000).',
|
|
384
|
+
params: [
|
|
385
|
+
{ name: 'startTime', required: false, description: 'Window start, epoch seconds (default: 24h ago)' },
|
|
386
|
+
{ name: 'endTime', required: false, description: 'Window end, epoch seconds (default: now)' },
|
|
387
|
+
],
|
|
388
|
+
fetch: (c, a) => c.readResource({ pathTemplate: '/sites/{siteId}/dashboard/top-device-cpu-usage', siteId: a.siteId, query: resolveUsageWindowSec(a.params) }),
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
path: '/dashboard/memory',
|
|
392
|
+
kind: 'collection',
|
|
393
|
+
permission: Q,
|
|
394
|
+
estimatedSize: 'small',
|
|
395
|
+
description: 'Devices with the highest memory usage over a time window (default: last 24h). Override with params.startTime / ' +
|
|
396
|
+
'params.endTime (epoch SECONDS, e.g. 1682000000).',
|
|
397
|
+
params: [
|
|
398
|
+
{ name: 'startTime', required: false, description: 'Window start, epoch seconds (default: 24h ago)' },
|
|
399
|
+
{ name: 'endTime', required: false, description: 'Window end, epoch seconds (default: now)' },
|
|
400
|
+
],
|
|
401
|
+
fetch: (c, a) => c.readResource({ pathTemplate: '/sites/{siteId}/dashboard/top-device-memory-usage', siteId: a.siteId, query: resolveUsageWindowSec(a.params) }),
|
|
402
|
+
},
|
|
403
|
+
// ---- Firmware ----------------------------------------------------------
|
|
404
|
+
{
|
|
405
|
+
path: '/firmware',
|
|
406
|
+
kind: 'leaf',
|
|
407
|
+
permission: Q,
|
|
408
|
+
estimatedSize: 'small',
|
|
409
|
+
description: 'Latest available firmware info for a device. Requires deviceMac (find via /devices).',
|
|
410
|
+
params: [{ name: 'deviceMac', required: true, description: 'Device MAC address' }],
|
|
411
|
+
fetch: (c, a) => c.readResource({
|
|
412
|
+
pathTemplate: '/sites/{siteId}/devices/{deviceMac}/latest-firmware-info',
|
|
413
|
+
siteId: a.siteId,
|
|
414
|
+
pathParams: { deviceMac: a.params?.deviceMac ?? '' },
|
|
415
|
+
}),
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
path: '/firmware/critical',
|
|
419
|
+
kind: 'leaf',
|
|
420
|
+
permission: Q,
|
|
421
|
+
estimatedSize: 'small',
|
|
422
|
+
description: 'Controller-wide overview of critical firmware upgrades (not site-scoped).',
|
|
423
|
+
fetch: (c) => c.readResource({ pathTemplate: '/upgrade/overview/critical', siteScoped: false }),
|
|
424
|
+
},
|
|
425
|
+
// ---- Security (IDS/IPS) — ADMIN only -----------------------------------
|
|
426
|
+
{
|
|
427
|
+
path: '/security',
|
|
428
|
+
kind: 'container',
|
|
429
|
+
permission: A,
|
|
430
|
+
description: 'Security: IDS/IPS threat-management log. ADMIN only.',
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
path: '/security/threats',
|
|
434
|
+
kind: 'collection',
|
|
435
|
+
permission: A,
|
|
436
|
+
paginated: true,
|
|
437
|
+
defaultPageSize: 10,
|
|
438
|
+
estimatedSize: 'large',
|
|
439
|
+
description: 'IDS/IPS threat-management log (paginated, ADMIN). REQUIRES a time window: params.startTime and params.endTime ' +
|
|
440
|
+
'(epoch SECONDS, e.g. 1682000000). Optional params: archived ("true"/"false", default false), severity ' +
|
|
441
|
+
'(0=Critical,1=Major,2=Concerning,3=Minor), sortTime ("asc"/"desc"), searchKey (fuzzy text), siteList ' +
|
|
442
|
+
'(comma-separated site IDs; default all sites).',
|
|
443
|
+
params: [
|
|
444
|
+
{ name: 'startTime', required: true, description: 'Window start, epoch seconds (e.g. 1682000000)' },
|
|
445
|
+
{ name: 'endTime', required: true, description: 'Window end, epoch seconds (e.g. 1682003600)' },
|
|
446
|
+
{ name: 'archived', required: false, description: '"true" or "false" (default false)' },
|
|
447
|
+
{ name: 'severity', required: false, description: '0=Critical, 1=Major, 2=Concerning, 3=Minor' },
|
|
448
|
+
{ name: 'sortTime', required: false, description: 'Sort by time: "asc" or "desc"' },
|
|
449
|
+
{ name: 'searchKey', required: false, description: 'Fuzzy search on description/classification' },
|
|
450
|
+
{ name: 'siteList', required: false, description: 'Comma-separated site IDs (default: all sites)' },
|
|
451
|
+
],
|
|
452
|
+
fetch: (c, a) => c.getThreatList({
|
|
453
|
+
siteList: a.params?.siteList,
|
|
454
|
+
archived: a.params?.archived === 'true',
|
|
455
|
+
page: a.page ?? 1,
|
|
456
|
+
pageSize: a.pageSize ?? 10,
|
|
457
|
+
startTime: Number(a.params?.startTime),
|
|
458
|
+
endTime: Number(a.params?.endTime),
|
|
459
|
+
severity: a.params?.severity !== undefined ? Number(a.params.severity) : undefined,
|
|
460
|
+
sortTime: a.params?.sortTime === 'asc' ? 'asc' : a.params?.sortTime === 'desc' ? 'desc' : undefined,
|
|
461
|
+
searchKey: a.params?.searchKey,
|
|
462
|
+
}),
|
|
463
|
+
},
|
|
464
|
+
];
|
|
465
|
+
const byPath = new Map(OMADA_RESOURCES.map((n) => [n.path, n]));
|
|
466
|
+
/** Normalize a user-supplied path: leading slash, no trailing slash, '/' for root. */
|
|
467
|
+
export function normalizePath(path) {
|
|
468
|
+
if (!path || path === '/') {
|
|
469
|
+
return '/';
|
|
470
|
+
}
|
|
471
|
+
let p = path.trim();
|
|
472
|
+
if (!p.startsWith('/')) {
|
|
473
|
+
p = `/${p}`;
|
|
474
|
+
}
|
|
475
|
+
if (p.length > 1 && p.endsWith('/')) {
|
|
476
|
+
p = p.slice(0, -1);
|
|
477
|
+
}
|
|
478
|
+
return p;
|
|
479
|
+
}
|
|
480
|
+
/** The immediate parent path, or null for the root. */
|
|
481
|
+
function parentPath(path) {
|
|
482
|
+
if (path === '/') {
|
|
483
|
+
return null;
|
|
484
|
+
}
|
|
485
|
+
const idx = path.lastIndexOf('/');
|
|
486
|
+
return idx <= 0 ? '/' : path.slice(0, idx);
|
|
487
|
+
}
|
|
488
|
+
export function getResourceNode(path) {
|
|
489
|
+
return byPath.get(normalizePath(path));
|
|
490
|
+
}
|
|
491
|
+
/** Direct children (one segment deeper) of the given path. */
|
|
492
|
+
export function childrenOf(path) {
|
|
493
|
+
const norm = normalizePath(path);
|
|
494
|
+
return OMADA_RESOURCES.filter((n) => parentPath(n.path) === norm);
|
|
495
|
+
}
|
|
496
|
+
//# sourceMappingURL=namespace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../../src/tools/omada/namespace.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/docs/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,66 @@
|
|
|
1
|
+
### 1.3.4
|
|
2
|
+
**Feature — Omada resource-graph tool registration (`MCP_TOOL_REGISTRATION_MODE`).**
|
|
3
|
+
Implements the previously-designed-but-unbuilt registration-mode switch as a *resource
|
|
4
|
+
graph* for the Omada plugin. `MCP_TOOL_REGISTRATION_MODE=graph` registers two discovery
|
|
5
|
+
tools — `omada_browse` (navigate a permission-filtered tree of resource **types**, never
|
|
6
|
+
instances) and `omada_read` (generic, per-path-RBAC data fetch with single-page
|
|
7
|
+
pagination) — plus the 5 typed write/action tools, in place of the ~21 individual read
|
|
8
|
+
getters. `eager` (default) is unchanged. A single `OmadaClient.readResource()` primitive
|
|
9
|
+
(path-template driven) backs newly-exposed endpoints (gateway WAN/health, AP speed-test,
|
|
10
|
+
rogue-AP/WIDS, event/alert logs, dashboard CPU/memory, firmware info + controller-wide
|
|
11
|
+
critical-firmware) with no per-endpoint client code. `graph` mode is now a **complete
|
|
12
|
+
superset** of `eager` reads: the ADMIN-gated IDS/IPS threat-management log is exposed at
|
|
13
|
+
`/security/threats`, with its mandatory epoch time-window enforced via required
|
|
14
|
+
`params.startTime`/`params.endTime` (epoch seconds) validated before any controller call —
|
|
15
|
+
the first node to require a higher permission bit (ADMIN) than QUERY, demonstrating the
|
|
16
|
+
per-path RBAC. New manifest (`namespace.ts`) + tools (`graph.ts`); `getCallerPermissions()`
|
|
17
|
+
extracted in `tools/common.ts` and reused for per-path checks. Suite grew by 47 unit tests
|
|
18
|
+
(namespace + graph + config parsing).
|
|
19
|
+
|
|
20
|
+
**Fix — `OMADA_SITE_ID` is validated against the live controller at startup.** The Omada
|
|
21
|
+
controller's site list is now treated as the source of truth; `OMADA_SITE_ID` is only a
|
|
22
|
+
selector against it. At boot (reusing the existing `listSites()` connection test) a
|
|
23
|
+
configured `OMADA_SITE_ID` that is **not** present on the controller — e.g. a site id that
|
|
24
|
+
drifted after a controller migration, the same way `OMADA_OMADAC_ID` does — now disables the
|
|
25
|
+
**Omada plugin** with a clear, actionable error that names the bad value and lists the valid
|
|
26
|
+
sites, instead of silently scoping every site-scoped read to a dead site and surfacing later
|
|
27
|
+
as a confusing "user does not have permissions to access this site" error. The failure is
|
|
28
|
+
scoped to the Omada plugin only — Home Assistant and Local AI keep working (graceful
|
|
29
|
+
degradation preserved). Default-site auto-resolution for site-scoped reads is otherwise
|
|
30
|
+
unchanged: callers still need not pass `siteId` when a valid default is configured. New pure
|
|
31
|
+
`checkConfiguredSite()` helper + 4 unit tests.
|
|
32
|
+
|
|
33
|
+
**Fix — graph reads that require query parameters now send them (events/alerts, dashboard
|
|
34
|
+
CPU/memory, rogue-AP/WIDS, pending devices).** Seven graph nodes were authored from endpoint
|
|
35
|
+
paths alone and never sent the query parameters the controller requires, so every call
|
|
36
|
+
returned a bare framework `400 Bad Request` (rejected before reaching the Omada handler — no
|
|
37
|
+
`errorCode`/`msg` envelope). Verified against the live controller's own OpenAPI spec and
|
|
38
|
+
fixed:
|
|
39
|
+
- `/events` and `/events/alerts` now send the mandatory `filters.timeStart`/`filters.timeEnd`
|
|
40
|
+
window (epoch **milliseconds**). The window is optional to the caller and **defaults to the
|
|
41
|
+
last 7 days**, so a bare `omada_read('/events')` works; override via `params.startTime` /
|
|
42
|
+
`params.endTime`, with optional `params.module` (and `params.resolved` for alerts).
|
|
43
|
+
- `/dashboard/cpu` and `/dashboard/memory` now send the mandatory `start`/`end` window
|
|
44
|
+
(epoch **seconds**), defaulting to the **last 24 h**; override via `params.startTime` /
|
|
45
|
+
`params.endTime`.
|
|
46
|
+
- `/wifi/rogue`, `/wifi/wids`, and `/devices/pending` are now declared `paginated` so they
|
|
47
|
+
forward `page`/`pageSize` (all three are paginated list endpoints). `/wifi/wids` is
|
|
48
|
+
documented as Omada **Pro-only** — on a standard controller it returns a clear "Pro only"
|
|
49
|
+
message rather than data.
|
|
50
|
+
Two pure, unit-tested window helpers (`resolveLogWindowMs`, `resolveUsageWindowSec`) back the
|
|
51
|
+
defaults. Also surfaces the controller's own `errorCode`/`msg` in `RequestHandler`'s thrown
|
|
52
|
+
HTTP-error message (when present) so a rejected request explains itself instead of collapsing
|
|
53
|
+
to `"400 "` — internal hostnames/headers are still kept out of the message. Suite grew by 10
|
|
54
|
+
unit tests (window helpers + fixed-node wiring).
|
|
55
|
+
|
|
56
|
+
### 1.3.1
|
|
57
|
+
**Patch — RBAC role-name case-insensitivity.** Follow-up to the v1.3.0 fail-closed
|
|
58
|
+
permission change. `getUserPermissions` now resolves both the per-user `role` and the
|
|
59
|
+
`defaultRole` fall-back case-insensitively: a lowercase `"operator"` / `"admin"` in
|
|
60
|
+
`MCP_PERMISSIONS_CONFIG` (a common real-world spelling) maps to the correct mask instead
|
|
61
|
+
of silently collapsing to an empty (no-permission) mask. Unknown role names still fail
|
|
62
|
+
closed to `NONE`. Regression tests added under `tests/permissions/`.
|
|
63
|
+
|
|
1
64
|
### 1.3.0
|
|
2
65
|
**Security hardening release.** A full OWASP-aligned audit (API Top 10 2023 + Top 10 2021)
|
|
3
66
|
drove fixes across access control, authentication, injection, transport, configuration,
|
package/openapi.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"openapi": "3.1.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "Home Assistant MCP Wrapper",
|
|
5
|
-
"version": "1.3.
|
|
5
|
+
"version": "1.3.4",
|
|
6
6
|
"description": "REST endpoints that wrap MCP tools for Home Assistant integration. Raw JSON-RPC passthrough available at POST / for n8n compatibility."
|
|
7
7
|
},
|
|
8
8
|
"servers": [
|