5,414,324 AI resources indexedWorking toward the world’s largest AI resource index.

PDF

Set Up UniFi Network MCP Server

Configure the UniFi Network MCP server for Claude Code, Codex, or OpenClaw — set controller host, credentials, and permissions

Installable skillMITBy sirkirbyUpdated Oct 30, 2026
INTENDED FORClaude CodeCodexInstall in a listed agent.

instructions.md

---
name: unifi-network-setup-4864d8c12977
description: Configure the UniFi Network MCP server for a supported MCP client — set controller host, credentials, and permissions. Also use when the unifi-network server failed to start or its tools are missing, especially right after a plugin update, because in Claude Code the plugin no longer reads settings an earlier version saved in the project's .claude/settings.local.json, and this skill migrates them
allowed-tools: Read, Bash, AskUserQuestion
---

# Set Up UniFi Network MCP Server

Walk the user through configuring their UniFi Network controller connection. Ask one question at a time and wait for the answer before continuing.

## Interaction Rules

Use the client target that matches the current agent runtime:
- Claude Code: `claude`
- Codex: `codex`
- OpenClaw: `openclaw`

If the runtime is unclear, ask which client to configure. For questions, use the platform's blocking question tool when available (`AskUserQuestion` in Claude Code, `request_user_input` in Codex). If no blocking question tool is available, ask in chat with numbered options and wait for the user's reply.

This skill may come from a complete UniFi plugin or a standalone `npx skills`
install. Before using a helper script, verify that the plugin's `scripts/`
directory exists. If it does not, do not guess a relative path: follow the
[canonical agent installation guide](https://github.com/sirkirby/unifi-mcp/blob/main/docs/agent-install.md)
for the client's native MCP registration path. That guide covers OpenCode,
Antigravity, Devin Desktop, Cursor, and other manual clients. A standalone
skill install does not install or register the MCP server by itself.

On macOS and Linux, resolve setup scripts relative to this skill file:
- `../../scripts/check-prereqs.sh`
- `../../scripts/set-env.sh`

When the host exposes a plugin-root variable such as `CLAUDE_PLUGIN_ROOT`, using `$CLAUDE_PLUGIN_ROOT/scripts/...` is also valid. Do not assume the current shell directory is the plugin root.

On Windows, use `../../scripts/set-env.ps1 -Target <claude|codex|openclaw>`
for every target. Use the matching PowerShell prerequisite checker. Both helpers
require uv/uvx and the selected client's CLI (`claude`, `codex` or `openclaw`). A working
Python 3.11+ on PATH is used first; otherwise uv supplies managed Python
(with a possible first-run download). No separate Python installation is needed.
Do not substitute direct client registration commands, which can expose env
values in process arguments.

## Step 0: Check Prerequisites

Before asking for credentials, run the prereq checker for the current OS.

On macOS/Linux:

```bash
bash <path-to-plugin>/scripts/check-prereqs.sh --target <claude|codex|openclaw> "unifi-network"
```

On Windows PowerShell:

```powershell
powershell -ExecutionPolicy Bypass -File <path-to-plugin>/scripts/check-prereqs.ps1 -Target <claude|codex|openclaw> -PluginName "unifi-network"
```

If the script exits non-zero, stop and report the error. Do not proceed to credentials.

## Step 1: Controller Host

Ask: "What is your UniFi controller's IP address or hostname?" Example: `192.168.1.1`.

## Step 2: Credentials

Ask which authentication path the user needs:
- API key only for supported device, client, network, and WLAN inventory plus
  API-key-only Integration API lookups
- Local username and password for legacy and session-backed tool families
- Both for the widest tool coverage and independently usable API-key reads if
  the session fails

Ask for the local username when session authentication is selected. Never ask the
user to send a password or API key in chat, and never place a raw secret in a tool
call or command argument. Ask for exactly one indirect provider per secret:
`UNIFI_NETWORK_PASSWORD_FILE=<absolute-path>` or
`UNIFI_NETWORK_PASSWORD_COMMAND=<absolute argv>`, and
`UNIFI_NETWORK_API_KEY_FILE=<absolute-path>` or
`UNIFI_NETWORK_API_KEY_COMMAND=<absolute argv>`. A command provider can call a
Keychain, `pass`, or 1Password helper; it is not run through a shell and must not
prompt. If no indirect provider already exists, explain how to create one outside
the chat transcript or use a client-native masked secret UI, then wait. In Claude
Code that UI is the plugin's options dialog (`/plugin`, then `unifi-network`, then
Configure options): its password and API key fields are masked and stored in
the system keychain.

All three servers apply the same precedence: non-empty `UNIFI_<PRODUCT>_*`
values override shared `UNIFI_*` values; empty values count as unset. This applies
to host, username and credentials even where bundled YAML defaults name different
variables. Shared providers are fallback only. Multiple non-empty spellings
(plain, `_FILE`, `_COMMAND`) at the selected level refuse startup.

The setup helper switches providers atomically: selecting one spelling removes
its saved siblings at the same level while preserving unrelated settings. To
remove an authentication path, pipe a JSON patch setting all three saved
spellings to `null` (for example `UNIFI_NETWORK_PASSWORD`,
`UNIFI_NETWORK_PASSWORD_FILE`, `UNIFI_NETWORK_PASSWORD_COMMAND`). Remove or
override shared fallback settings deliberately too; deleting product settings
alone can reactivate shared credentials. Inherited environment providers must
also be corrected in the launcher. Never delete a working provider in a separate
preparatory write.

Claude Code 2.1.296 and earlier are the exception for a raw password or API
key held in the system keychain: they cannot clear one through `claude plugin
configure` or the options dialog. Setup therefore refuses, with nothing changed, any change that
would clear it, such as selecting a `_FILE` or `_COMMAND` provider for that
credential or a null deletion. The message names the variable and the choices:
keep the saved secret, or run `claude plugin uninstall` and `claude plugin
install` with the plugin id it names (usually `unifi-network@unifi-plugins`),
then rerun setup with the provider and the options the message lists.
Uninstalling clears every option of the plugin, so offer it to the user and
never run it without their consent.

On a newer or unrecognized Claude Code release, setup clears a keychain
secret only in a run that changes that one credential: send its patch alone,
then other settings in a second run. Setup refuses a combined patch with
nothing changed. It saves and verifies the new options first, then clears the
secret. If Claude Code keeps the secret, setup removes the credential's
providers so only the secret remains, and refuses with the same choices. If a
step of a provider switch fails or is interrupted, the credential still has a
saved value: rerun setup with the same settings to finish the switch. Until
then the server refuses to start if two spellings of the credential are set.
A deletion has no replacement: if its step fails, setup reports that whether
the secret was cleared is unknown.

Before changing or skipping API-key setup, remove obsolete
`UNIFI_NETWORK_API_KEY`, `UNIFI_NETWORK_API_KEY_FILE`, and
`UNIFI_NETWORK_API_KEY_COMMAND` spellings with null deletions in the same patch;
keep only the selected replacement, or delete all three when deselecting it. In
Claude Code, a keychain-held `UNIFI_NETWORK_API_KEY` cannot be removed this way;
see above.

### Optional API Key

Explain that UniFi API-key support is limited to inventory reads and explicit
Integration API tools; legacy mutations and full details may still require a local
username and password provider. If selected, configure only an API-key file or
command provider, never the raw key.

## Step 3: Optional Settings

Ask whether to use defaults or customize:
- Defaults: port `443`, site `default`, SSL verification `false`, lazy tool loading
- Customize: ask for port (`UNIFI_NETWORK_PORT`), site (`UNIFI_NETWORK_SITE`), SSL
  verification (`UNIFI_NETWORK_VERIFY_SSL`), and tool registration mode (`UNIFI_TOOL_REGISTRATION_MODE`: `lazy`, `eager` or
  `meta_only`; the Claude Code option is `registration_mode`)

## Step 4: Permission Configuration

Ask whether to enable write permissions. For Codex and OpenClaw, offer:
- Read-only for now
- Enable common write permissions: firewall, port forwards, QoS, traffic routes, VPN clients
- Enable all write permissions except delete operations
- Custom categories

For Claude Code, the plugin's options hold only the server-level gates. Offer:
read-only (the default), allow updates, allow creates and updates, or allow
creates, updates and deletes. Set `UNIFI_POLICY_NETWORK_CREATE`,
`UNIFI_POLICY_NETWORK_UPDATE` and `UNIFI_POLICY_NETWORK_DELETE` to `true` or `false`,
and keep `UNIFI_NETWORK_TOOL_PERMISSION_MODE=confirm` so every mutation is previewed
first. Per-category overrides (`UNIFI_POLICY_NETWORK_<CATEGORY>_<ACTION>`) are not
available for Claude Code and setup refuses them. A user who wants only some
categories writable can allow the action server-wide and decline the previews
they do not want, or keep the action off.

For Codex and OpenClaw, before writing policy values, inspect a sanitized list of the selected client's
existing `unifi-network` MCP environment variable names (for Codex and OpenClaw, the key names in
`~/.config/unifi-mcp/network.env`).
Remove every existing category-specific
`UNIFI_POLICY_NETWORK_<CATEGORY>_<ACTION>` entry by including null deletions
in the same JSON patch, because those entries take precedence over server-level
defaults. Preserve unrelated variables. Set
`UNIFI_NETWORK_TOOL_PERMISSION_MODE=confirm`, then add back only the
category/action overrides the user selected.

For read-only setup, explicitly configure:

```text
UNIFI_POLICY_NETWORK_CREATE=false
UNIFI_POLICY_NETWORK_UPDATE=false
UNIFI_POLICY_NETWORK_DELETE=false
```

For requested writes on Codex or OpenClaw, keep those server-level defaults and
add only the selected category/action overrides using the existing
`UNIFI_POLICY_NETWORK_<CATEGORY>_<ACTION>=true` format.

## Step 5: Write Configuration

On macOS/Linux, run the target-aware setup script with only values the user provided or selected:

```bash
bash <path-to-plugin>/scripts/set-env.sh --target <claude|codex|openclaw> \
  UNIFI_NETWORK_HOST=<host> \
  UNIFI_NETWORK_USERNAME=<username> \
  'UNIFI_NETWORK_PASSWORD_FILE=<absolute-path>' \
  UNIFI_NETWORK_TOOL_PERMISSION_MODE=confirm \
  UNIFI_POLICY_NETWORK_CREATE=false \
  UNIFI_POLICY_NETWORK_UPDATE=false \
  UNIFI_POLICY_NETWORK_DELETE=false
```

Add optional values and policy variables to the same command. Per-category
overrides apply to Codex and OpenClaw only, for example:

```bash
bash <path-to-plugin>/scripts/set-env.sh --target <codex|openclaw> \
  UNIFI_NETWORK_HOST=<host> \
  UNIFI_NETWORK_USERNAME=<username> \
  'UNIFI_NETWORK_PASSWORD_COMMAND=<absolute-argv>' \
  'UNIFI_NETWORK_API_KEY_FILE=<absolute-path>' \
  UNIFI_NETWORK_TOOL_PERMISSION_MODE=confirm \
  UNIFI_POLICY_NETWORK_CREATE=false \
  UNIFI_POLICY_NETWORK_UPDATE=false \
  UNIFI_POLICY_NETWORK_DELETE=false \
  UNIFI_POLICY_NETWORK_FIREWALL_POLICIES_UPDATE=true
```

The script handles the client-specific write:
- Claude: validates every value, then saves the plugin's Claude Code options
  with `claude plugin configure --values-stdin` (values on stdin): non-secret
  options in user `settings.json` (`pluginConfigs`), a raw password or API key
  in the system keychain. The options apply in every project
- Codex: validates every value, then atomically writes the settings file
  `~/.config/unifi-mcp/network.env` (`%USERPROFILE%\.config\unifi-mcp\network.env`
  on Windows), readable by the user only. The plugin's own server reads it through
  `UNIFI_SETTINGS_FILE`; setup writes no `config.toml` entry. Env never enters argv
- OpenClaw: writes the same settings file as Codex,
  `~/.config/unifi-mcp/network.env`, readable by the user only. The plugin's own
  server reads it through `UNIFI_SETTINGS_FILE`; setup writes no `openclaw.json`
  entry

For raw values or null deletions, use JSON stdin: `set-env.sh --target <target>
--input-json` or `set-env.ps1 -Target <target> -InputJson`. Have the user supply
this JSON locally from a private file or a masked input UI; never put raw secrets
in chat, a tool call, command arguments, or a shell history entry. Provider
references in the examples are non-secret paths or helper argv, never embedded
passwords or API keys. Setup checks that provider files are readable and non-empty
and provider executables exist; it does not read secrets, execute providers, or
contact the controller. Provider output and controller authentication are checked
only when the server starts.

### Codex upgrades

The plugin's own MCP server is the one Codex runs, and it reads the settings
file setup wrote, so a plugin upgrade upgrades the server with nothing to rerun.
Codex installs an upgrade in the background as a session starts; the next
session runs the new server.

Setup before plugin 1.0.0 saved a `[mcp_servers.unifi-network]` entry in Codex's
`config.toml` instead. That entry takes precedence over the plugin's server and
keeps an old server version. Step 0 then prints a notice naming the entry and
`--refresh`. Relay it and, once the user agrees, run refresh from this skill's
plugin root, then restart Codex:

```bash
bash <plugin-root>/scripts/set-env.sh --target codex --refresh
```

On Windows: `& <plugin-root>/scripts/set-env.ps1 -Target codex -Refresh`.
Refresh needs no credential input. It moves the entry's `UNIFI_` settings,
provider references included, into the settings file, removes the entry from
`config.toml` after saving a private backup beside it, and names any other entry
settings it did not move. Ordinary setup does the same when it finds the entry.
It is needed once. If a settings file already exists and holds different
settings, refresh changes nothing and says which to remove.

Setup edits only that entry's tables in `config.toml`, so every other setting and
comment stays as written. If the file lays out its MCP servers in a form setup
cannot edit in place (dotted or inline `mcp_servers` keys), setup lets Codex
remove the entry, which drops the comments inside every `[mcp_servers.*]`
table, and says so in its output.

### OpenClaw upgrades

OpenClaw runs the plugin's own MCP server, which reads the settings file setup
wrote, so `openclaw plugins update` upgrades the server with nothing to rerun.
A running Gateway applies the update at the next agent turn.

Setup before plugin 1.0.0 saved an `mcp.servers.unifi-network` entry in
`openclaw.json` instead. That entry replaces the plugin's server and keeps an
old server version. Step 0 then prints a notice naming the entry and
`--refresh`. Relay it and, once the user agrees, run refresh from this skill's
plugin root:

```bash
bash <plugin-root>/scripts/set-env.sh --target openclaw --refresh
```

On Windows: `& <plugin-root>/scripts/set-env.ps1 -Target openclaw -Refresh`.
Refresh needs no credential input. It moves the entry's `UNIFI_` settings,
provider references included, into the settings file, saves a private backup of
`openclaw.json` beside it, then removes the entry with `openclaw mcp unset` and
names any other entry settings it did not move. Ordinary setup does the same
when it finds the entry. It is needed once. If a settings file already exists
and holds different settings, refresh changes nothing and says which to remove.

### Claude Code projects set up by an earlier plugin version

Earlier versions saved Claude Code settings in the project's
`.claude/settings.local.json`. This version no longer reads them; setup, the
prerequisite check and a session-start notice name the leftover variables. From
that project, run:

```bash
bash <plugin-root>/scripts/set-env.sh --target claude --migrate
```

On Windows: `& <plugin-root>/scripts/set-env.ps1 -Target claude -Migrate`. It
copies this plugin's settings into its options, then removes only this plugin's
keys from the project file atomically. Shared `UNIFI_*` keys are kept unless
every possible consumer is proven migrated; setup currently verifies only this
plugin's options. It names the retained shared keys and explains that other
consumers have not been verified as migrated. Output includes only variable
names, including what it moved and what has no Claude Code option (per-category
policy overrides). A missing provider file stops it with nothing changed, as
does a provider that would replace a password or API key held in the keychain.

Plugin options apply in every project. If options saved from another project
already hold a different host, username, port or site, `--migrate` refuses
and names those variables without values. Ask the user which settings every
project should use: rerun with `--replace` (`-Replace`) to make this project's
settings the options for every project, or remove this plugin's leftover
`UNIFI_NETWORK_*` keys from the project file to keep the saved options. A
session-start notice also fires in a project that still holds its own
`UNIFI_NETWORK_*` keys while options from another project are in use; offer the
same choice there. When the project's host, username, port and site equal the saved
options, the notice says nothing changes instead; offer to remove the leftover
keys, or to tidy up with `--migrate`, which also copies the project's other
settings, such as its credential source, into the options.

After the migration, in a session that was already open, run `/reload-plugins`
or start a new session. `/mcp reconnect` alone keeps the options the session
started with: it reports success, but the server stays in setup mode. Use
`/mcp reconnect plugin:unifi-network:unifi-network` only if `/mcp` shows the server as
failed. Once no UniFi plugin keys remain in the project file, the prerequisite
check names any shared `UNIFI_*` keys still there: Claude Code exports them into
every process in that project, so suggest removing them once nothing else needs
them.

### Recovery

On validation, dependency, registration, or write failure the previous file and
registration remain in place. Repair malformed configuration without discarding
unrelated settings, install the reported dependency, or correct the provider,
then rerun. `--dry-run` / `-DryRun` validates the patch without changing files and
omits values. OpenClaw setup reads `openclaw.json` as strict JSON; a JSON5
configuration is refused unchanged. After a forced termination,
remove adjacent `.setup-lock` and `.unifi-setup-*` staging directories only after
confirming no setup process is running. Staging files are private and may contain
credentials; delete them without displaying their contents. An interruption at
publication leaves either the old configuration or the complete new one.

## Step 6: Final Message

For Claude Code, tell the user:

"Saved as the unifi-network plugin's Claude Code options (a raw password or API key goes to the system keychain). In this session, run `/reload-plugins` (a new session also loads the options); `/mcp reconnect` alone keeps the options the session started with, so the server would stay in setup mode. Then run `/mcp` and check that `plugin:unifi-network:unifi-network` offers more than one tool: a server offering only its setup-status tool is still unconfigured. Use `/mcp reconnect plugin:unifi-network:unifi-network` only if `/mcp` shows the server as failed. Review or change the options with `/plugin`, then `unifi-network`, then Configure options."

For Codex, tell the user:

"Saved the settings for `unifi-network` to `~/.config/unifi-mcp/network.env`, readable by you only. The plugin's own server reads them and follows plugin upgrades on its own. Restart Codex so the server loads them."

For OpenClaw, tell the user:

"Saved the settings for `unifi-network` to `~/.config/unifi-mcp/network.env`, readable by you only. The plugin's own server reads them and follows plugin updates on its own. OpenClaw starts it with these settings in a new session or after `openclaw gateway restart`; a session that is already open keeps the unconfigured server until then."

Discuss this resource

Platform guidance

Imported from the listed AgentSkill.sh category. Complete supplied package files and notices are retained. Required external tools and credentials are not installed. No bundled code was executed during import. Individual agent task behavior has not been tested.