MCP server for UniFi UI API integration, providing tools to list and manage UniFi hosts, sites, devices, ISP metrics, and SD-WAN configurations
The server has 9 well-structured tools with consistent naming (verb_noun pattern), clear descriptions (150-300 chars), and explicit Zod schemas. All tools are READ_ONLY and properly documented. However, output schemas are not formally documented, responses are returned as plain JSON strings without structure definition. Parameter descriptions are thorough and include format hints (e.g., RFC3339 timestamps, enum constraints). Error handling is basic (catches exceptions, returns error text) but does not provide recovery guidance. Tool definitions are explicitly visible in src/mcp.ts with proper registration via server.tool(). Schemas are complete for all inputs with type constraints and descriptions. Main gaps: (1) output schema documentation, (2) limited error guidance, (3) no tool annotations (readOnlyHint, etc.), (4) passphrase parameter appears in every tool (could use server-level auth instead).
Get detailed information about a specific UniFi host by its ID
Get ISP performance metrics (latency, bandwidth, uptime, packet loss) for all sites. Use "5m" for 5-minute intervals or "1h" for hourly intervals.
Get detailed SD-WAN configuration including hub/spoke topology, tunnel settings, and routing
Get live status of an SD-WAN configuration including tunnel connectivity, WAN status, and errors
List UniFi devices (APs, switches, gateways) managed by hosts where you are owner or super admin
List all UniFi hosts (consoles/controllers) accessible to your account
Output schemas not documented. All tools return plain JSON strings (content: [{type: 'text', text: JSON.stringify(result)}]) without formal output schema definitions. LLMs cannot plan downstream tool calls or extract specific fields without knowing response structure.
Passphrase parameter repeated in every tool signature. Authentication should be handled server-side (via env var UI_API_KEY or request-level auth) rather than exposing it as a per-tool parameter. This avoids passphrase appearing in tool call logs/traces.
Inferred effective spec: 2026-07-28+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 62 | 2026-07-28+ | v2 |
| 2026-03-09 | C | 65 | - | v1 |
List all SD-WAN configurations
List all UniFi sites with metadata, device statistics, and ISP information
Query ISP metrics for specific sites by hostId and siteId. Use "5m" for 5-minute intervals or "1h" for hourly intervals.
Error handling is minimal. Errors are caught generically and returned as plain text (ERROR_RESULT) without categorization (retryable/user-fixable/fatal) or recovery guidance. Example: 'Error: 404 Not Found' tells the LLM nothing about whether to retry or ask the user.
Tool annotations missing. No readOnlyHint, destructiveHint, or idempotentHint set on tool definitions. All 9 tools are READ_ONLY but this is not declared via tool annotations, forcing LLMs to infer safety from descriptions.
Pagination parameters (pageSize, nextToken) are optional strings without type hints or bounds. LLMs may pass invalid values like 'pageSize: "abc"' or '1000'. Should constrain with z.string().regex() for pageSize or use z.number() with min/max.