omada-mcp

Reads and, once unlocked, changes settings on a self-hosted TP-Link Omada WiFi controller

By Kavith Lokuhewage (individual) TypeScript Local · stdio DevOps and monitoring

8 popularity score ★ 4

Connect your client

Local (from source)

Add in one click

Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.

Or add it by command or config

It needs OMADA_BASE_URL, OMADA_OMADAC_ID, OMADA_CLIENT_ID, OMADA_CLIENT_SECRET. Replace each <NAME> with your value.

FirstTerminal
git clone https://github.com/kaviththiranga/omada-mcp-server.git && cd omada-mcp-server
npm ci && npm run build
cp .env.example .env && chmod 600 .env
npm run fetch-spec
Claude CodeTerminal
claude mcp add omada -e OMADA_BASE_URL=<OMADA_BASE_URL> -e OMADA_OMADAC_ID=<OMADA_OMADAC_ID> -e OMADA_CLIENT_ID=<OMADA_CLIENT_ID> -e OMADA_CLIENT_SECRET=<OMADA_CLIENT_SECRET> -- node '<ABSOLUTE_PATH_TO_CLONE>/dist/index.js'
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "omada": {
      "command": "node",
      "args": [
        "<ABSOLUTE_PATH_TO_CLONE>/dist/index.js"
      ],
      "env": {
        "OMADA_BASE_URL": "<OMADA_BASE_URL>",
        "OMADA_OMADAC_ID": "<OMADA_OMADAC_ID>",
        "OMADA_CLIENT_ID": "<OMADA_CLIENT_ID>",
        "OMADA_CLIENT_SECRET": "<OMADA_CLIENT_SECRET>"
      }
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "omada": {
      "command": "node",
      "args": [
        "<ABSOLUTE_PATH_TO_CLONE>/dist/index.js"
      ],
      "env": {
        "OMADA_BASE_URL": "<OMADA_BASE_URL>",
        "OMADA_OMADAC_ID": "<OMADA_OMADAC_ID>",
        "OMADA_CLIENT_ID": "<OMADA_CLIENT_ID>",
        "OMADA_CLIENT_SECRET": "<OMADA_CLIENT_SECRET>"
      }
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "omada": {
      "type": "stdio",
      "command": "node",
      "args": [
        "<ABSOLUTE_PATH_TO_CLONE>/dist/index.js"
      ],
      "env": {
        "OMADA_BASE_URL": "<OMADA_BASE_URL>",
        "OMADA_OMADAC_ID": "<OMADA_OMADAC_ID>",
        "OMADA_CLIENT_ID": "<OMADA_CLIENT_ID>",
        "OMADA_CLIENT_SECRET": "<OMADA_CLIENT_SECRET>"
      }
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.omada]
command = "node"
args = ["<ABSOLUTE_PATH_TO_CLONE>/dist/index.js"]

[mcp_servers.omada.env]
OMADA_BASE_URL = "<OMADA_BASE_URL>"
OMADA_OMADAC_ID = "<OMADA_OMADAC_ID>"
OMADA_CLIENT_ID = "<OMADA_CLIENT_ID>"
OMADA_CLIENT_SECRET = "<OMADA_CLIENT_SECRET>"
Gemini CLITerminal
gemini mcp add --scope user -e OMADA_BASE_URL=<OMADA_BASE_URL> -e OMADA_OMADAC_ID=<OMADA_OMADAC_ID> -e OMADA_CLIENT_ID=<OMADA_CLIENT_ID> -e OMADA_CLIENT_SECRET=<OMADA_CLIENT_SECRET> omada node -- '<ABSOLUTE_PATH_TO_CLONE>/dist/index.js'

Settings 12

OMADA_BASE_URL Required: LAN address of the controller, e.g. https://192.168.1.10.
OMADA_OMADAC_ID Required: Controller id, as returned by GET <url>/api/info.
OMADA_CLIENT_ID Required: Client ID of the Open API app created on the controller.
OMADA_CLIENT_SECRET Required: Client Secret of that Open API app.
OMADA_ALLOW_WRITES Optional: Set to 1 to allow non-GET requests; 0 (read-only) by default.
OMADA_VERIFY_TLS Optional: Verify the controller's TLS certificate; false in the example for self-signed certificates.
OMADA_WEB_USER Optional: Controller local account user for the legacy web-session tool; blank disables it.
OMADA_WEB_PASS Optional: Password for that local account.
OMADA_DENY_PATTERNS Optional: Extra comma-separated regexes blocked even when writes are on.
OMADA_DENY_DEFAULTS Optional: Set 0 to drop the built-in deny-list; 1 by default.
OMADA_SITE_ID Optional: Default site to use.
OMADA_TIMEOUT_MS Optional: Request timeout in milliseconds; 20000 in the example.

What it does

omada-mcp connects an MCP client to a TP-Link Omada controller on your own network, so an assistant can look at access points, connected clients, SSIDs and sites, and adjust WiFi settings such as roaming thresholds. It was written by an individual while tuning roaming on a three-access-point home network; it is not a TP-Link product.

Rather than one tool per endpoint, it ships five typed read tools plus a small set of generic tools over an index of the Omada Open API (about 1,650 operations): one searches the index, one shows the parameters and schemas of a single operation, and one calls it. A ninth tool reaches the older /api/v2 web-session interface for settings the Open API does not cover, such as the minimum RSSI threshold; it only works when a controller local account is configured.

Writes go through three checks. With OMADA_ALLOW_WRITES unset or 0 (the default in .env.example) every non-GET request is refused. When unlocked, a call without confirm: true only returns a preview of the method, URL and body. A built-in deny-list blocks factory reset, restore, firmware upgrade, device or site deletion, MSP mode and edits to the Open API app; .env.example shows it can be switched off with OMADA_DENY_DEFAULTS=0 and extended with OMADA_DENY_PATTERNS, which the README does not mention. In the source, omada_search_api returns 25 matches by default (up to 100 with limit) and omada_clients pages 100 clients by default (up to 1000 with pageSize).

What it needs

RuntimeNode.js 22+

Node.js 22 or later, and git to clone and build it from source (it is not published to npm). A TP-Link Omada controller you administer, reachable from the machine running it, with an Open API app created in Client Mode with an admin role and all site privileges; you need its Client ID, Client Secret and the controller's omadacId. Tested by its author on Omada Controller 5.15.24.21 (OC200) with EAP225, EAP625-Outdoor and EAP683 access points.

Limits

Not on npm: the package is marked private, so it runs only from a local clone. The README's clone command uses a placeholder (<you>/omada-mcp.git); the repository is kaviththiranga/omada-mcp-server. Hardware controllers (OC200/OC300) on 5.15.x do not serve the OpenAPI document, so the server falls back to a bundled export that may list endpoints your firmware lacks; re-run npm run fetch-spec after a firmware upgrade. The legacy web-session tool needs OMADA_WEB_USER and OMADA_WEB_PASS and is disabled without them. stdio only; no hosted endpoint. Version 0.1.0.

Who it suits

Suits someone who runs their own Omada controller and wants an assistant to inspect clients, channels and roaming settings, with changes held behind an explicit unlock and a preview step. Reading needs only the Open API credentials; changing settings needs the write switch turned on deliberately. It is a small personal project tested on one controller model and firmware line, so people with other Omada hardware or firmware should expect gaps between the bundled API index and their controller. Not for cloud-managed Omada setups unless the controller address is reachable locally.

Tools 9

omada_status
Shows controller details, token state, whether writes are unlocked, API index state and the site list
omada_sites
Lists the sites on the controller
omada_devices
Lists access points, switches and gateways adopted on a site
omada_clients
Lists connected clients with signal details, paged (100 by default)
omada_ssids
Shows the configured wireless networks and their settings
omada_search_api
Searches the indexed Omada Open API operations by text, method or group
omada_describe_api
Gives the parameters and request and response schemas of one API operation
omada_call
Calls any Open API endpoint, subject to the read-only switch, preview step and deny-list
omada_ui_call
Calls the legacy /api/v2 web-session interface for settings the Open API lacks

Similar servers