Omada MCP
Reads and changes a TP-Link Omada SDN controller's sites, devices, clients, VLANs, firewall and Wi-Fi
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
Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.
It needs OMADA_BASE_URL, OMADA_OMADAC_ID, OMADA_CLIENT_ID, OMADA_CLIENT_SECRET. Replace each <NAME> with your value.
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-specclaude 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'{
"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>"
}
}
}
}{
"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>"
}
}
}
}{
"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>"
}
}
}
}[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 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'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. |
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).
| Runtime | Node.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.
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.
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.
omada_statusomada_sitesomada_devicesomada_clientsomada_ssidsomada_search_apiomada_describe_apiomada_callomada_ui_call