Skip to main content
Glama
README.md
# omada-mcp

An **MCP server for TP-Link Omada controllers**, so an AI assistant (Claude Code,
or any MCP client) can read and tune your WiFi network directly.

It is **spec-driven**: instead of hand-writing a tool per endpoint, it indexes the
Omada Open API (~1,650 operations) and gives the model three tools to search it,
inspect one operation, and call it. That means the whole API surface is reachable
through nine tools.

**It is read-only until you say otherwise.** Every non-GET request is refused
unless you explicitly unlock writes, and even then a mutation returns a dry-run
preview until it is confirmed.

Built while fixing roaming on a real 3-AP home network. **Full write-up with
screenshots and measurements: [article/](article/)** — what was actually wrong,
what the numbers looked like before and after, and the two things the AI got
wrong that measurement caught.

---

## What it can do

Ask things like:

- "What is connected to my WiFi right now, and how strong is each device?"
- "Are any of my APs on the same channel?"
- "Is fast roaming actually configured correctly?"
- "Why does my phone stay on the far access point?"
- "Show me the SSID settings" / "turn on the minimum RSSI threshold at -75"

## Tools

| Tool | |
|---|---|
| `omada_status` | controller info, token health, write-mode, API index, site list |
| `omada_sites` / `omada_devices` / `omada_clients` / `omada_ssids` | typed reads |
| `omada_search_api` | search the Omada Open API spec |
| `omada_describe_api` | parameters + request/response schema for one operation |
| `omada_call` | invoke any Open API endpoint (write-guarded) |
| `omada_ui_call` | legacy `/api/v2` web-session API, for settings Open API does not expose |

## Safety model

Three independent gates on any write:

1. `OMADA_ALLOW_WRITES` unset or `0` → every non-GET is refused.
2. Unlocked but no `confirm: true` → returns a **dry-run preview** of the exact
   method, URL and JSON body. Nothing is sent.
3. A **deny-list** blocks the irreversible regardless of the other two: factory
   reset, controller restore, firmware upgrade, device/site deletion, MSP mode,
   and edits to the Open API app itself.

The server reads its own `.env`, so credentials never enter your MCP client
config.

## Setup

**1. Create an Open API app on the controller**

Controller UI → **Settings → Platform Integration → Open API → Add New App**
→ *Client Mode* → give it an admin role and all site privileges → save.
Copy the **Client ID** and **Client Secret** (the secret is shown only once).

Find your `omadacId`:

```bash
curl -sk https://<controller-ip>/api/info
```

**2. Install**

```bash
git clone https://github.com/<you>/omada-mcp.git && cd omada-mcp
npm ci && npm run build
cp .env.example .env && chmod 600 .env   # fill in the values
npm run smoke                            # verifies both transports
npm run fetch-spec                       # builds the API index
```

**3. Register with your MCP client**

```bash
claude mcp add --scope user omada -- node "$PWD/dist/index.js"
```

## About the API index

The server first tries to download the OpenAPI document from your controller.
**Hardware controllers (OC200/OC300) on 5.15.x do not serve one** —
`/openapi/v3/api-docs` returns 404 even with a valid token. In that case it falls
back to a pinned export of the same document, taken from a controller that does
serve it (vendored from [realtydev/omada-mcp](https://github.com/realtydev/omada-mcp),
MIT).

Treat the index as a **map, not the territory**: it may list endpoints your
firmware does not have. The live controller is always the authority. Re-run
`npm run fetch-spec` after a firmware upgrade.

## Shell scripts (work without any MCP client)

```bash
scripts/omada-status.sh      # reachability, token, sites, device/client counts
scripts/omada-token.sh       # print an access token
scripts/omada-api.sh /sites  # authenticated GET
scripts/omada-snapshot.sh <dir>   # full read-only config snapshot (for rollback)
scripts/omada-roamwatch.sh   # live: prints a line each time a client changes AP
scripts/omada-survey.sh -m <MAC> "Kitchen" "Bedroom"   # guided walk survey
```

`omada-roamwatch.sh` and `omada-survey.sh` are the ones worth knowing about: they
turn "my WiFi feels bad in that room" into numbers.

## Skill for Claude Code

`skill/SKILL.md` is a reusable skill capturing the hard-won bits: Omada API
gotchas, enum decoders, the difference between configured and on-air settings,
and a tested method for measuring roaming. Copy it to
`~/.claude/skills/omada-network/` and adapt the placeholders to your own site.

## Requirements

Node 22+. Tested against Omada Controller **5.15.24.21** (OC200) with EAP225,
EAP625-Outdoor and EAP683 access points.

## License

MIT

TDQS

A3.7/5.0

Scored across 9 tools

Disambiguation4/5

Each tool has a clearly separated role: status, sites, devices, clients, and SSIDs are distinct resource views, while search_api, describe_api, call, and ui_call form a staged API workflow. There is minor overlap between omada_status (which also lists sites) and omada_sites, and between omada_call and omada_ui_call, but the descriptions make the boundaries explicit enough.

Naming Consistency3/5

The omada_ prefix and snake_case are consistent, but the pattern is mixed: status/sites/devices/clients/ssids are noun-only names, while search_api/describe_api/call/ui_call are verb-oriented. This is readable and not chaotic, yet it does not follow a uniform verb_noun convention.

Tool Count5/5

Nine tools is well-scoped: five high-level read/resource tools cover the common Omada surfaces, and four API/UI tools provide discovery, documentation lookup, and safe execution. Each tool earns its place without the set feeling bloated or thin.

Completeness5/5

The high-level tools cover the main query needs, while omada_search_api, omada_describe_api, omada_call, and omada_ui_call fill essentially any gap in the controller's exposed API or UI-facing session API. The dry-run/confirm write flow also prevents dead ends for mutating operations.

Maintenance

ActivityMaintained
ResponsivenessNo issues