Symptoms: Connection timeout, refused, or "cannot reach host" errors.
Check:
- Verify the controller is reachable:
curl -k https://<UNIFI_HOST>:<UNIFI_PORT> - Confirm
UNIFI_HOSTandUNIFI_PORTare correct - If using Docker, ensure the container can reach the controller (use
--network hostor the correct Docker network) - Check firewall rules between the MCP server and the controller
Symptoms: 401 Unauthorized, "invalid credentials" errors.
Check:
- Verify
UNIFI_USERNAMEandUNIFI_PASSWORDare correct - Ensure the account is a local admin (not a Ubiquiti SSO account)
- Try logging into the Protect web UI with the same credentials
- The
uiprotectlibrary requires local authentication -- cloud-only accounts will not work
Symptoms: Tools return errors mentioning uiprotect or ProtectApiError.
Check:
- Ensure the controller is running UniFi OS with Protect application installed
- Verify the Protect application is running (not stopped or updating)
- Check that the user account has access to the Protect application
- Ensure the NVR firmware is reasonably current (uiprotect targets recent firmware versions)
Symptoms: SSL: CERTIFICATE_VERIFY_FAILED or similar errors.
Fix: Set UNIFI_VERIFY_SSL=false (most UniFi controllers use self-signed certificates).
export UNIFI_VERIFY_SSL=falseThis is the default, so this error typically only occurs if you explicitly set it to true.
Cause: The tool's permission is disabled. All Protect mutation tools are disabled by default.
Fix:
- Check permissions.md for the relevant category
- Enable via environment variable:
export UNIFI_PERMISSIONS_<CATEGORY>_<ACTION>=true
- Restart the server
Example: If protect_update_camera_settings is missing:
export UNIFI_PERMISSIONS_CAMERAS_UPDATE=trueCause: In lazy/meta_only mode, protect_tool_index shows all tools (from the static manifest), but disabled tools return permission errors when called.
Fix: Same as above -- enable the permission and restart.
Check:
- Verify the server started successfully (check stderr logs)
- Confirm your MCP client is connected
- Try
UNIFI_TOOL_REGISTRATION_MODE=eagerto load all tools immediately - Check if
UNIFI_ENABLED_CATEGORIESorUNIFI_ENABLED_TOOLSis set and limiting the tools
Symptoms: protect_recent_events returns empty results; protect://events/stream resource is empty.
Check:
- Verify
PROTECT_WEBSOCKET_ENABLED=true(default) - Check server logs for websocket connection errors
- Ensure the NVR has cameras generating events (try triggering motion manually)
- Use
protect_list_eventsto verify events exist on the NVR (REST API works independently)
Cause: Buffer overflow or TTL expiration.
Fix:
- Increase
PROTECT_EVENT_BUFFER_SIZE(default 100) for high-traffic environments - Increase
PROTECT_EVENT_BUFFER_TTL(default 300 seconds) if you poll less frequently - Poll more frequently (every 2-5 seconds) to process events before they expire
Cause: Minimum confidence filter is too high.
Fix: Lower PROTECT_SMART_DETECTION_MIN_CONFIDENCE (default 50):
export PROTECT_SMART_DETECTION_MIN_CONFIDENCE=25Or pass min_confidence parameter directly to protect_list_smart_detections or protect_recent_events.
Check:
- Verify the camera is connected and online (
protect_list_cameras) - Ensure the camera supports snapshots (most do, but some may be in a degraded state)
- Try fetching via the tool (
protect_get_snapshot) withinclude_image=true - Check server logs for specific error messages
Check:
- Verify
UNIFI_MCP_HTTP_ENABLED=trueis set - If not running as PID 1 (non-container), set
UNIFI_MCP_HTTP_FORCE=true - Check that port 3001 is not already in use (or change
UNIFI_MCP_PORT)
Check:
- Ensure
-iflag is set (stdin must be open for stdio transport) - Check logs:
docker logs <container> - Verify all required env vars are set (
UNIFI_HOST,UNIFI_USERNAME,UNIFI_PASSWORD)
Fix options:
- Use
--network hostto share the host network stack - Or ensure the Docker network can route to the NVR IP
- Verify the NVR IP is not a localhost address (use the actual network IP)
Cause: Usually a build issue.
Fix: Pull the latest image:
docker pull ghcr.io/sirkirby/unifi-protect-mcp:latestEnable verbose logging to diagnose issues:
export UNIFI_MCP_LOG_LEVEL=DEBUG
export UNIFI_MCP_DIAGNOSTICS=trueThis outputs detailed information about:
- Protect connection and authentication
- WebSocket connection state
- Permission decisions
- Tool registration
- API requests and responses (redacted)
- Tool call timing
All logs go to stderr (stdout is reserved for MCP JSON-RPC in stdio mode).