ames-unifi-mcp 1.0.3 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="icon.png" width="80" height="80" alt="UniFi">
|
|
2
|
+
<img src="assets/icon.png" width="80" height="80" alt="UniFi">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<h1 align="center">UniFi MCP Server</h1>
|
|
@@ -17,12 +17,14 @@
|
|
|
17
17
|
|
|
18
18
|
<p align="center">
|
|
19
19
|
<a href="https://www.npmjs.com/package/ames-unifi-mcp"><img src="https://img.shields.io/npm/v/ames-unifi-mcp?style=flat-square&color=f5a542" alt="npm"></a>
|
|
20
|
+
<a href="https://github.com/oliverames/ames-unifi-mcp/releases/tag/v1.0.6"><img src="https://img.shields.io/github/v/release/oliverames/ames-unifi-mcp?style=flat-square&color=f5a542&label=MCPB" alt="MCPB release"></a>
|
|
20
21
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-f5a542?style=flat-square" alt="License"></a>
|
|
21
22
|
<a href="https://www.buymeacoffee.com/oliverames"><img src="https://img.shields.io/badge/Buy_Me_a_Coffee-support-f5a542?style=flat-square&logo=buy-me-a-coffee&logoColor=white" alt="Buy Me a Coffee"></a>
|
|
22
23
|
</p>
|
|
23
24
|
|
|
24
25
|
<p align="center">
|
|
25
26
|
<a href="#quick-start">Quick Start</a> •
|
|
27
|
+
<a href="#install-with-mcpb">MCPB Download</a> •
|
|
26
28
|
<a href="#tool-coverage">Tool Coverage</a> •
|
|
27
29
|
<a href="#architecture">Architecture</a> •
|
|
28
30
|
<a href="#configuration">Configuration</a>
|
|
@@ -40,6 +42,14 @@ Every mutating operation passes through a **confirm gate** that returns a dry-ru
|
|
|
40
42
|
|
|
41
43
|
## Quick Start
|
|
42
44
|
|
|
45
|
+
### Install with MCPB
|
|
46
|
+
|
|
47
|
+
For Claude Desktop and other MCPB-compatible clients, download the local bundle from the [v1.0.6 release](https://github.com/oliverames/ames-unifi-mcp/releases/tag/v1.0.6):
|
|
48
|
+
|
|
49
|
+
[Download `ames-unifi-mcp-1.0.6.mcpb`](https://github.com/oliverames/ames-unifi-mcp/releases/download/v1.0.6/ames-unifi-mcp-1.0.6.mcpb)
|
|
50
|
+
|
|
51
|
+
The bundle includes the UniFi favicon, production runtime binaries for macOS and Linux, and setup prompts for host, authentication, site, SSL, tool mode, and permission profile.
|
|
52
|
+
|
|
43
53
|
Add to your MCP client configuration:
|
|
44
54
|
|
|
45
55
|
```json
|
|
@@ -126,7 +136,7 @@ If a tool isn't in the index, the controller firmware is too old to support it.
|
|
|
126
136
|
<tr>
|
|
127
137
|
<td width="50%" valign="top">
|
|
128
138
|
|
|
129
|
-
**Devices** —
|
|
139
|
+
**Devices** — 63 tools
|
|
130
140
|
```
|
|
131
141
|
device_list device_restart
|
|
132
142
|
device_get device_adopt
|
|
@@ -136,9 +146,12 @@ device_spectrum_scan device_rolling_upgrade_*
|
|
|
136
146
|
device_migrate device_port_action
|
|
137
147
|
device_list_v2 device_stats_latest
|
|
138
148
|
device_unadopt device_pending_list
|
|
149
|
+
system_device_tags system_tag_*
|
|
150
|
+
switching_stack_* switching_lag_*
|
|
151
|
+
switching_mclag_* cloud_device_list
|
|
139
152
|
```
|
|
140
153
|
|
|
141
|
-
**Clients** —
|
|
154
|
+
**Clients** — 16 tools
|
|
142
155
|
```
|
|
143
156
|
client_list_active client_block/unblock
|
|
144
157
|
client_get client_reconnect
|
|
@@ -147,112 +160,107 @@ client_rename client_update
|
|
|
147
160
|
client_list_v2 client_action
|
|
148
161
|
```
|
|
149
162
|
|
|
150
|
-
**Networks** —
|
|
163
|
+
**Networks** — 39 tools
|
|
151
164
|
```
|
|
152
|
-
network_list
|
|
153
|
-
network_get
|
|
154
|
-
network_delete
|
|
165
|
+
network_list network_create
|
|
166
|
+
network_get network_update
|
|
167
|
+
network_delete network_*_v2
|
|
168
|
+
system_network_references
|
|
169
|
+
system_radius_profiles_v2
|
|
170
|
+
dns_policy_* system_portprofile_*
|
|
155
171
|
```
|
|
156
172
|
|
|
157
|
-
**Wireless (WLAN + WiFi)** —
|
|
173
|
+
**Wireless (WLAN + WiFi)** — 14 tools
|
|
158
174
|
```
|
|
159
175
|
wlan_list wlan_create/update/delete
|
|
160
176
|
wlan_enable wlan_disable
|
|
161
177
|
wifi_broadcast_list/get/create/update/delete
|
|
162
178
|
```
|
|
163
179
|
|
|
164
|
-
**Firewall** —
|
|
180
|
+
**Firewall** — 30 tools
|
|
165
181
|
```
|
|
166
182
|
firewall_rule_* (legacy CRUD)
|
|
167
183
|
firewall_group_* (address/port groups)
|
|
168
184
|
firewall_zone_* (ZBF zones, 9.0+)
|
|
169
185
|
firewall_policy_* (ZBF policies + ordering)
|
|
186
|
+
acl_rule_* acl_rule_ordering_*
|
|
170
187
|
```
|
|
171
188
|
|
|
172
|
-
**
|
|
173
|
-
```
|
|
174
|
-
acl_rule_list/get/create/update/delete
|
|
175
|
-
acl_rule_ordering_get/set
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
**DNS Policies** — 5 tools
|
|
189
|
+
**QoS** — 10 tools
|
|
179
190
|
```
|
|
180
|
-
|
|
191
|
+
traffic_matching_list_* (10.0+)
|
|
181
192
|
```
|
|
182
193
|
|
|
183
|
-
**
|
|
194
|
+
**Routing** — 10 tools
|
|
184
195
|
```
|
|
185
196
|
traffic_rule_* (v2 API rules)
|
|
186
197
|
traffic_route_* (v2 API routes)
|
|
187
|
-
|
|
198
|
+
system_static_route_*
|
|
188
199
|
```
|
|
189
200
|
|
|
190
|
-
</td>
|
|
191
|
-
<td width="50%" valign="top">
|
|
192
|
-
|
|
193
201
|
**VPN** — 10 tools
|
|
194
202
|
```
|
|
195
203
|
vpn_server_list/get/create/update/delete
|
|
196
204
|
vpn_tunnel_list/get/create/update/delete
|
|
197
205
|
```
|
|
198
206
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
switching_stack_* (switch stacks)
|
|
202
|
-
switching_lag_* (link aggregation)
|
|
203
|
-
switching_mclag_* (MC-LAG domains)
|
|
204
|
-
```
|
|
207
|
+
</td>
|
|
208
|
+
<td width="50%" valign="top">
|
|
205
209
|
|
|
206
|
-
**Stats
|
|
210
|
+
**Stats** — 20 tools
|
|
207
211
|
```
|
|
208
212
|
stats_site_health stats_sysinfo
|
|
209
213
|
stats_dashboard stats_report
|
|
210
214
|
stats_speedtest_* stats_ips_events
|
|
211
215
|
stats_rogueap stats_spectrumscan
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**DPI** — 11 tools
|
|
219
|
+
```
|
|
212
220
|
stats_dpi_site stats_dpi_client
|
|
213
221
|
stats_dpi_apps stats_dpi_categories
|
|
222
|
+
misc_dpigroup_*
|
|
214
223
|
```
|
|
215
224
|
|
|
216
|
-
**Events
|
|
225
|
+
**Events** — 8 tools
|
|
217
226
|
```
|
|
218
227
|
event_list alarm_list
|
|
219
228
|
alarm_count alarm_archive
|
|
220
229
|
alarm_archive_all
|
|
221
230
|
```
|
|
222
231
|
|
|
223
|
-
**Hotspot
|
|
232
|
+
**Hotspot** — 27 tools
|
|
224
233
|
```
|
|
225
234
|
hotspot_authorize/unauthorize_guest
|
|
226
235
|
hotspot_create_voucher hotspot_extend
|
|
227
236
|
hotspot_voucher_*_v2 (Integration API)
|
|
228
237
|
hotspot_config hotspot_packages
|
|
238
|
+
misc_hotspotop_* hotspot_2_0_package_*
|
|
229
239
|
```
|
|
230
240
|
|
|
231
|
-
**System
|
|
241
|
+
**System** — 27 tools
|
|
232
242
|
```
|
|
233
243
|
system_reboot/poweroff system_settings
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
system_dhcpoption_* system_radiusprofile_*
|
|
238
|
-
system_tag_* system_led_toggle
|
|
244
|
+
system_firmware_* admin_site_*
|
|
245
|
+
admin_invite/revoke cloud_host_list/get
|
|
246
|
+
cloud_site_list cloud_sdwan_*
|
|
239
247
|
```
|
|
240
248
|
|
|
241
|
-
**
|
|
249
|
+
**Settings** — 19 tools
|
|
242
250
|
```
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
251
|
+
system_setting_* system_led_toggle
|
|
252
|
+
system_ips_update misc_scheduletask_*
|
|
253
|
+
misc_cnt_resource
|
|
246
254
|
```
|
|
247
255
|
|
|
248
|
-
**
|
|
256
|
+
**Backup** — 5 tools
|
|
249
257
|
```
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
258
|
+
system_backup_* backup_restore
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**PoE** — 1 tool
|
|
262
|
+
```
|
|
263
|
+
poe_power_cycle
|
|
256
264
|
```
|
|
257
265
|
|
|
258
266
|
</td>
|
|
@@ -276,7 +284,7 @@ The server covers all three UniFi API layers:
|
|
|
276
284
|
|
|
277
285
|
| Variable | Required | Default | Description |
|
|
278
286
|
|----------|----------|---------|-------------|
|
|
279
|
-
| `UNIFI_HOST` |
|
|
287
|
+
| `UNIFI_HOST` | * | — | Controller URL (`https://192.168.1.1`) |
|
|
280
288
|
| `UNIFI_API_KEY` | * | — | API key (preferred, requires 9.1.105+) |
|
|
281
289
|
| `UNIFI_USERNAME` | * | — | Username (if no API key) |
|
|
282
290
|
| `UNIFI_PASSWORD` | * | — | Password (if no API key) |
|
|
@@ -285,7 +293,18 @@ The server covers all three UniFi API layers:
|
|
|
285
293
|
| `UNIFI_TOOL_MODE` | No | `lazy` | `lazy` (3 meta-tools) or `eager` (all 310 tools) |
|
|
286
294
|
| `UNIFI_PERMISSION_PROFILE` | No | `standard` | `read-only`, `standard`, or `admin` |
|
|
287
295
|
|
|
288
|
-
<sub>*
|
|
296
|
+
<sub>* `UNIFI_HOST` plus either `UNIFI_API_KEY` or both `UNIFI_USERNAME` + `UNIFI_PASSWORD` are required for the server to actually call the controller. If they are absent, the server still starts and registers all tools (so the plugin appears installed), but every tool call returns a structured "credentials not configured" error pointing the user at the env vars or 1Password fallback. This lets the connector live in a clean "needs authentication" state instead of a hard startup error.</sub>
|
|
297
|
+
|
|
298
|
+
### 1Password fallback
|
|
299
|
+
|
|
300
|
+
If env vars are unset, the server falls back to 1Password CLI (`op read`) using these references:
|
|
301
|
+
|
|
302
|
+
- `op://Development/UniFi Controller/host`
|
|
303
|
+
- `op://Development/UniFi Controller/api_key`
|
|
304
|
+
- `op://Development/UniFi Controller/username`
|
|
305
|
+
- `op://Development/UniFi Controller/password`
|
|
306
|
+
|
|
307
|
+
Create a `UniFi Controller` item in your `Development` vault with those fields and the server will resolve credentials at startup with no env vars required. Resolution happens in `internal/config/config.go:opRead` and requires either an interactive `op` session or `OP_SERVICE_ACCOUNT_TOKEN` in the environment.
|
|
289
308
|
|
|
290
309
|
### Authentication Methods
|
|
291
310
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require("child_process");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const os = require("os");
|
|
6
|
+
|
|
7
|
+
const binaryName = "ames-unifi-mcp";
|
|
8
|
+
|
|
9
|
+
const platformMap = {
|
|
10
|
+
"darwin-arm64": `${binaryName}-darwin-arm64`,
|
|
11
|
+
"darwin-x64": `${binaryName}-darwin-amd64`,
|
|
12
|
+
"linux-arm64": `${binaryName}-linux-arm64`,
|
|
13
|
+
"linux-x64": `${binaryName}-linux-amd64`,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const key = `${os.platform()}-${os.arch()}`;
|
|
17
|
+
const platformBinary = platformMap[key];
|
|
18
|
+
|
|
19
|
+
if (!platformBinary) {
|
|
20
|
+
console.error(
|
|
21
|
+
`Unsupported platform: ${key}. Supported: ${Object.keys(platformMap).join(", ")}`
|
|
22
|
+
);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const binaryPath = path.join(__dirname, "..", "dist", platformBinary);
|
|
27
|
+
const child = spawn(binaryPath, process.argv.slice(2), {
|
|
28
|
+
stdio: "inherit",
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
child.on("error", (error) => {
|
|
32
|
+
console.error(`Failed to start ${binaryName}: ${error.message}`);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
child.on("exit", (code, signal) => {
|
|
37
|
+
if (signal) {
|
|
38
|
+
process.kill(process.pid, signal);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
process.exit(code ?? 0);
|
|
43
|
+
});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ames-unifi-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "UniFi Network MCP server — 310 tools for complete controller management via the Model Context Protocol",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
23
|
-
"url": "https://github.com/oliverames/ames-unifi-mcp.git"
|
|
23
|
+
"url": "git+https://github.com/oliverames/ames-unifi-mcp.git"
|
|
24
24
|
},
|
|
25
25
|
"homepage": "https://github.com/oliverames/ames-unifi-mcp#readme",
|
|
26
26
|
"bugs": {
|
|
@@ -30,15 +30,14 @@
|
|
|
30
30
|
"ames-unifi-mcp": "bin/ames-unifi-mcp"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
|
-
"
|
|
34
|
-
"
|
|
33
|
+
"bin/ames-unifi-mcp",
|
|
34
|
+
"dist/ames-unifi-mcp-darwin-arm64",
|
|
35
|
+
"dist/ames-unifi-mcp-darwin-amd64",
|
|
36
|
+
"dist/ames-unifi-mcp-linux-arm64",
|
|
37
|
+
"dist/ames-unifi-mcp-linux-amd64",
|
|
35
38
|
"README.md",
|
|
36
39
|
"LICENSE"
|
|
37
40
|
],
|
|
38
|
-
"scripts": {
|
|
39
|
-
"postinstall": "node install.js",
|
|
40
|
-
"postpublish": "$HOME/Developer/projects/ames-claude/bump-and-sync"
|
|
41
|
-
},
|
|
42
41
|
"os": [
|
|
43
42
|
"darwin",
|
|
44
43
|
"linux"
|
package/install.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// Postinstall script: copies the correct platform binary to bin/ames-unifi-mcp
|
|
4
|
-
|
|
5
|
-
const fs = require("fs");
|
|
6
|
-
const path = require("path");
|
|
7
|
-
const os = require("os");
|
|
8
|
-
|
|
9
|
-
const BINARY_NAME = "ames-unifi-mcp";
|
|
10
|
-
|
|
11
|
-
const PLATFORM_MAP = {
|
|
12
|
-
"darwin-arm64": `${BINARY_NAME}-darwin-arm64`,
|
|
13
|
-
"darwin-x64": `${BINARY_NAME}-darwin-amd64`,
|
|
14
|
-
"linux-arm64": `${BINARY_NAME}-linux-arm64`,
|
|
15
|
-
"linux-x64": `${BINARY_NAME}-linux-amd64`,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
function install() {
|
|
19
|
-
const platform = os.platform();
|
|
20
|
-
const arch = os.arch();
|
|
21
|
-
const key = `${platform}-${arch}`;
|
|
22
|
-
|
|
23
|
-
const binaryFile = PLATFORM_MAP[key];
|
|
24
|
-
if (!binaryFile) {
|
|
25
|
-
console.error(
|
|
26
|
-
`Unsupported platform: ${platform}-${arch}. ` +
|
|
27
|
-
`Supported: ${Object.keys(PLATFORM_MAP).join(", ")}`
|
|
28
|
-
);
|
|
29
|
-
process.exit(1);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const distDir = path.join(__dirname, "dist");
|
|
33
|
-
const binDir = path.join(__dirname, "bin");
|
|
34
|
-
const src = path.join(distDir, binaryFile);
|
|
35
|
-
const dest = path.join(binDir, BINARY_NAME);
|
|
36
|
-
|
|
37
|
-
if (!fs.existsSync(src)) {
|
|
38
|
-
console.error(`Binary not found: ${src}`);
|
|
39
|
-
console.error("Try rebuilding: make build-all");
|
|
40
|
-
process.exit(1);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Ensure bin/ exists
|
|
44
|
-
if (!fs.existsSync(binDir)) {
|
|
45
|
-
fs.mkdirSync(binDir, { recursive: true });
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Copy binary
|
|
49
|
-
fs.copyFileSync(src, dest);
|
|
50
|
-
|
|
51
|
-
// Make executable
|
|
52
|
-
fs.chmodSync(dest, 0o755);
|
|
53
|
-
|
|
54
|
-
console.log(`Installed ${BINARY_NAME} for ${platform}/${arch}`);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
install();
|