npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bacnh85/pi-unifi

v0.2.0

Published

UniFi Network (UniFi OS) tools for the pi coding agent and a standard MCP server (mcp-unifi) — official UniFi Network Integration API.

Readme

unifi-agents

CI npm License: MIT

Let AI agents operate your UniFi Network controller — safely and conversationally. Ships two entry points in one package:

  • a pi coding agent extension (pi-unifi), and
  • a standard MCP server (mcp-unifi) that works with any MCP client: Claude Desktop, Cursor, Claude Code, pi, …

Both use the official UniFi Network Integration API (key-based, UniFi OS 10.x) — no scraping, no legacy credentials.

  • 49 tools — 18 read, 31 write
  • Resolve by name — unifi_device device="office-ap", not just UUIDs; MAC and IP work too
  • Controller filter DSL — filter=name.like('office*') on every list tool
  • Read-only mode — hide all write tools with one environment variable
  • Zero-config site — single-site controllers are auto-detected

Requirements

| Requirement | Notes | |---|---| | UniFi controller | UniFi OS (UDM/UDR/UNVR/UCG/Cloud Gateway or UniFi OS Server) with Network application 10.x; Integration API available since 10.6 | | API key | Create in the controller UI: Settings → Integrations → API Keys (10.7+) or Settings → Control Plane → Integrations. Use a read-only key unless you intend to allow changes | | Network access | The client machine must reach the controller (LAN/VPN). A locally-created key does not work against api.ui.com cloud URLs — see Cloud/remote consoles | | Node.js | ≥ 20 (for the MCP server / npx usage) | | pi | Only for the extension entry point |

Quick start

MCP clients (Claude Desktop, Cursor, Claude Code, pi, …)

Claude Desktop / Cursor — add to the MCP config (claude_desktop_config.json / mcp.json):

{
  "mcpServers": {
    "unifi": {
      "command": "npx",
      "args": ["-y", "@bacnh85/pi-unifi"],
      "env": {
        "UOS_API_KEY": "your-integration-api-key",
        "UOS_BASE_URL": "https://192.168.1.1"
      }
    }
  }
}

Self-signed certificates are tolerated by default (controllers ship them). To enforce validation set "UOS_TLS_STRICT": "true".

pi (any directory):

pi mcp add unifi \
  --env UOS_API_KEY=your-integration-api-key \
  --env UOS_BASE_URL=https://192.168.1.1 \
  -- npx -y @bacnh85/pi-unifi

Claude Code:

claude mcp add unifi \
  --env UOS_API_KEY=your-integration-api-key \
  --env UOS_BASE_URL=https://192.168.1.1 \
  -- npx -y @bacnh85/pi-unifi

pi extension (in-process, zero prompt tokens)

pi install npm:@bacnh85/pi-unifi

Then just ask: "what's on my unifi network?" — tools are discovered on demand via tool_search (deferred exposure), so they cost no prompt tokens until needed. /unifi prints instant status. If a session runs without tool_search (e.g. --tools overrides), add "defaultTools": ["+tool_search"] to pi settings.

Run the server directly

# one-off, no install
UOS_API_KEY=... UOS_BASE_URL=https://192.168.1.1 npx -y @bacnh85/pi-unifi

# or install it
npm install -g @bacnh85/pi-unifi
mcp-unifi   # serves MCP over stdio

Configuration

All variables are optional except the first two. A small built-in parser also reads .env.local / .env from the working directory (no dotenv dependency) — see .env.example.

| Variable | Required | Default | Meaning | |---|---|---|---| | UOS_API_KEY | yes | — | Integration API key | | UOS_BASE_URL | yes | — | UniFi OS host, e.g. https://192.168.1.1 (port included if non-standard) | | UOS_API_PATH | no | /proxy/network/integration | Path prefix before /v1. UniFi OS consoles keep the default; standalone Network installs set /integration | | UOS_SITE_ID | no | auto | Pin a site; otherwise the single site is auto-detected (multi-site requires this) | | UOS_READ_ONLY | no | false | true registers read tools only — write tools disappear from the tool list entirely | | UOS_TLS_STRICT | no | false | true enforces TLS certificate validation |

Cloud / remote consoles

A locally-created Integration API key does not work against api.ui.com cloud URLs. For remote-hosted deployments create a UI cloud API key (account.ui.com) and set:

UOS_BASE_URL=https://api.ui.com/v1/connector/consoles/<consoleId>
UOS_API_PATH=/proxy/network/integration

Tools

| Tool | Type | What it does | |---|---|---| | unifi_status | read | Application version, sites; validates API key + connectivity | | unifi_devices | read | List devices (gateways, switches, APs); supports the filter DSL | | unifi_device | read | One device by id / MAC / name | | unifi_device_stats | read | Live stats: CPU, memory, load, throughput, per-port/radio | | unifi_clients | read | Connected clients (wired, wireless, VPN, guest) | | unifi_client | read | One client by id / MAC / IP / name | | unifi_networks | read | Networks/VLANs | | unifi_wifis | read | WiFi broadcasts (SSIDs) + security configuration | | unifi_vouchers | read | Hotspot vouchers | | unifi_firewall_zones | read | Zone-based firewall zones (list or one zone by id) | | unifi_firewall_policies | read | Zone-based firewall policies (list or one policy by id) | | unifi_pending_devices | read | Devices awaiting adoption (controller-wide) | | unifi_network_references | read | Resources referencing a network (pre-delete check) | | unifi_acl_rules | read | Switch ACL rules (list or one by id) | | unifi_dns_policies | read | Local DNS records (list or one by id) | | unifi_traffic_lists | read | Traffic matching lists (list or one by id) | | unifi_radius_profiles | read | RADIUS profiles (read-only; manage profiles in the UniFi UI) | | unifi_get | read | Generic GET for any /v1/... endpoint without a dedicated tool | | unifi_device_action | write | RESTART (reboot) — the API-documented device action | | unifi_port_action | write | Switch-port action: PoE POWER_CYCLE | | unifi_client_action | write | AUTHORIZE/UNAUTHORIZE guest access (with optional time/data/rate limits) | | unifi_device_adopt / unifi_device_delete | write | Adopt a pending device / unadopt (factory-reset) an adopted one | | unifi_create_voucher / unifi_voucher_delete | write | Generate hotspot vouchers; delete one or all matching a filter | | unifi_network_create / unifi_network_update / unifi_network_delete | write | Manage networks/VLANs | | unifi_wifi_create / unifi_wifi_update / unifi_wifi_delete | write | Create (open/WPA2-Personal/WPA2-Enterprise), update or remove SSIDs | | unifi_wifi_create_enterprise | write | Create a WPA2-Enterprise (802.1X) SSID (verified shape) | | unifi_firewall_zone_create / unifi_firewall_zone_update / unifi_firewall_zone_delete | write | Manage custom firewall zones | | unifi_firewall_policy_create / unifi_firewall_policy_update / unifi_firewall_policy_delete / unifi_firewall_policies_reorder | write | Manage zone-based firewall policies and their evaluation order | | unifi_acl_rule_create / unifi_acl_rule_update / unifi_acl_rule_delete / unifi_acl_rules_reorder | write | Manage switch ACL rules and their order | | unifi_dns_policy_create / unifi_dns_policy_update / unifi_dns_policy_delete | write | Manage local DNS records | | unifi_traffic_list_create / unifi_traffic_list_update / unifi_traffic_list_delete | write | Manage traffic matching lists (port/IP sets) |

All list tools accept the controller's filter syntax, passed through verbatim: filter=name.eq('web-server'), and(enabled.eq(true), name.isNotNull()), not(name.like('guest*')), type.in('uap','usw'). Wildcards use *; timestamps are ISO-8601.

Example prompts

  • "What's on my UniFi network?" → version, sites, devices, clients
  • "Which access points have clients on the guest SSID?"
  • "Show CPU and memory for the USW switch" → unifi_device_stats
  • "Reboot the UAP in the office" → unifi_device_action RESTART
  • "Cut guest access for the device with MAC aa:bb:cc:dd:ee:ff" → unifi_client_action UNAUTHORIZE_GUEST_ACCESS
  • "Create a voucher: 8 hours, 10 uses, named 'guests-weekend'"
  • "Set up a local DNS record: nas.local → 192.168.1.50"
  • "Block the cameras VLAN from reaching the office zone with a firewall policy"
  • "Add a VLAN 30 'iot' network and put the 'Cameras' SSID on it"

Security

  • Use a read-only API key (created the same way; the UI offers the choice) — the controller rejects writes regardless of tool availability.
  • UOS_READ_ONLY=true additionally hides every write tool from the tool list, so the model never sees them.
  • Destructive tools are annotated with MCP destructiveHint, which most clients surface as confirmation prompts.
  • API keys stay in your client's config (or .env.local) and are only sent to your controller. The server talks to nothing else.

Troubleshooting

| Symptom | Likely cause / fix | |---|---| | Missing UOS_API_KEY on startup | Env var not set — check the env block in your client config; remember some clients need a restart after editing it | | UniFi API 401 | Key revoked or wrong — recreate in Settings → Integrations | | UniFi API 404 on every call | Wrong UOS_API_PATH: standalone Network installs need /integration, UniFi OS keeps the default | | Connection refused / timeout | The client machine can't reach the controller — VPN or LAN required; npx runs on your machine, not in the cloud | | Multiple sites found | Set UOS_SITE_ID (get ids from unifi_status) | | TLS errors with UOS_TLS_STRICT=true | Controller uses a self-signed cert — leave strict mode off, or install a trusted cert | | Tools visible but calls fail with 400 Zone Based Firewall is not configured | ZBF isn't enabled on the controller; firewall tools need it |

Development

git clone ssh://[email protected]/bacnh85/unifi-agents.git
cd unifi-agents
npm install
npm run build      # tsc → dist/ (+ pi extension copied next to it)
npm run smoke      # unit + live-controller assertions (live part needs UOS_* env or .env.local)
npm start          # run the MCP server over stdio

Verify in pi without installing: pi -e ./src/extension.ts

CI & releases

Every push/PR runs build + smoke (unit checks; live-controller checks self-skip on GitHub-hosted runners — a home controller is unreachable from Actions). Pushes to main publish to npm as @bacnh85/pi-unifi automatically when the version isn't published yet, using the NPM_TOKEN secret. To release: bump version in package.json, push to main.

Notes

  • API endpoints are called verbatim (/v1/...) behind the configured prefix — verified against UniFi Network 10.6.106 on UniFi OS Server.
  • RADIUS profiles and wired 802.1X port profiles are read-only via the Integration API on 10.6.x (create them in the UniFi UI); unifi_wifi_create_enterprise covers WPA2-Enterprise SSIDs.
  • Switch port profiles are not exposed by the Integration API as of Network 10.6.106 (verified against the official OpenAPI spec — switch ports offer only the POWER_CYCLE action, no profile get/set endpoints). This is a controller-API limitation, not a tool gap: port profiles must be managed in the UniFi UI. The legacy "classic" API (/proxy/network/api/s/<site>/rest/portconf) does support them but requires an admin cookie login and is deliberately out of scope for this project.

License

MIT