Omada MCP
Reads and changes a TP-Link Omada SDN controller's sites, devices, clients, VLANs, firewall and Wi-Fi
Query and lightly manage a TP-Link Omada network controller: sites, devices, clients, Wi-Fi and firewall
By João Miguel Tabosa Vaz Marques Silva (individual) TypeScript Local · stdio DevOps and monitoring
18 popularity score ★ 29
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_CLIENT_ID, OMADA_CLIENT_SECRET, OMADA_OMADAC_ID. Replace each <NAME> with your value.
claude mcp add tp-link-omada -e OMADA_BASE_URL=<OMADA_BASE_URL> -e OMADA_CLIENT_ID=<OMADA_CLIENT_ID> -e OMADA_CLIENT_SECRET=<OMADA_CLIENT_SECRET> -e OMADA_OMADAC_ID=<OMADA_OMADAC_ID> -- docker run -i --rm -e OMADA_BASE_URL -e OMADA_CLIENT_ID -e OMADA_CLIENT_SECRET -e OMADA_OMADAC_ID jmtvms/tplink-omada-mcp:latest{
"mcpServers": {
"tp-link-omada": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"OMADA_BASE_URL",
"-e",
"OMADA_CLIENT_ID",
"-e",
"OMADA_CLIENT_SECRET",
"-e",
"OMADA_OMADAC_ID",
"jmtvms/tplink-omada-mcp:latest"
],
"env": {
"OMADA_BASE_URL": "<OMADA_BASE_URL>",
"OMADA_CLIENT_ID": "<OMADA_CLIENT_ID>",
"OMADA_CLIENT_SECRET": "<OMADA_CLIENT_SECRET>",
"OMADA_OMADAC_ID": "<OMADA_OMADAC_ID>"
}
}
}
}{
"mcpServers": {
"tp-link-omada": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"OMADA_BASE_URL",
"-e",
"OMADA_CLIENT_ID",
"-e",
"OMADA_CLIENT_SECRET",
"-e",
"OMADA_OMADAC_ID",
"jmtvms/tplink-omada-mcp:latest"
],
"env": {
"OMADA_BASE_URL": "<OMADA_BASE_URL>",
"OMADA_CLIENT_ID": "<OMADA_CLIENT_ID>",
"OMADA_CLIENT_SECRET": "<OMADA_CLIENT_SECRET>",
"OMADA_OMADAC_ID": "<OMADA_OMADAC_ID>"
}
}
}
}{
"servers": {
"tp-link-omada": {
"type": "stdio",
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"OMADA_BASE_URL",
"-e",
"OMADA_CLIENT_ID",
"-e",
"OMADA_CLIENT_SECRET",
"-e",
"OMADA_OMADAC_ID",
"jmtvms/tplink-omada-mcp:latest"
],
"env": {
"OMADA_BASE_URL": "<OMADA_BASE_URL>",
"OMADA_CLIENT_ID": "<OMADA_CLIENT_ID>",
"OMADA_CLIENT_SECRET": "<OMADA_CLIENT_SECRET>",
"OMADA_OMADAC_ID": "<OMADA_OMADAC_ID>"
}
}
}
}[mcp_servers.tp-link-omada]
command = "docker"
args = ["run", "-i", "--rm", "-e", "OMADA_BASE_URL", "-e", "OMADA_CLIENT_ID", "-e", "OMADA_CLIENT_SECRET", "-e", "OMADA_OMADAC_ID", "jmtvms/tplink-omada-mcp:latest"]
[mcp_servers.tp-link-omada.env]
OMADA_BASE_URL = "<OMADA_BASE_URL>"
OMADA_CLIENT_ID = "<OMADA_CLIENT_ID>"
OMADA_CLIENT_SECRET = "<OMADA_CLIENT_SECRET>"
OMADA_OMADAC_ID = "<OMADA_OMADAC_ID>"gemini mcp add --scope user -e OMADA_BASE_URL=<OMADA_BASE_URL> -e OMADA_CLIENT_ID=<OMADA_CLIENT_ID> -e OMADA_CLIENT_SECRET=<OMADA_CLIENT_SECRET> -e OMADA_OMADAC_ID=<OMADA_OMADAC_ID> tp-link-omada docker -- run -i --rm -e OMADA_BASE_URL -e OMADA_CLIENT_ID -e OMADA_CLIENT_SECRET -e OMADA_OMADAC_ID jmtvms/tplink-omada-mcp:latestOpens 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_CLIENT_ID, OMADA_CLIENT_SECRET, OMADA_OMADAC_ID. Replace each <NAME> with your value.
git clone https://github.com/migueltvms/tplink-omada-mcp.git
cd tplink-omada-mcp
npm install
npm run buildclaude mcp add tp-link-omada -e OMADA_BASE_URL=<OMADA_BASE_URL> -e OMADA_CLIENT_ID=<OMADA_CLIENT_ID> -e OMADA_CLIENT_SECRET=<OMADA_CLIENT_SECRET> -e OMADA_OMADAC_ID=<OMADA_OMADAC_ID> -- node '<ABSOLUTE_PATH_TO_CLONE>/dist/index.js'{
"mcpServers": {
"tp-link-omada": {
"command": "node",
"args": [
"<ABSOLUTE_PATH_TO_CLONE>/dist/index.js"
],
"env": {
"OMADA_BASE_URL": "<OMADA_BASE_URL>",
"OMADA_CLIENT_ID": "<OMADA_CLIENT_ID>",
"OMADA_CLIENT_SECRET": "<OMADA_CLIENT_SECRET>",
"OMADA_OMADAC_ID": "<OMADA_OMADAC_ID>"
}
}
}
}{
"mcpServers": {
"tp-link-omada": {
"command": "node",
"args": [
"<ABSOLUTE_PATH_TO_CLONE>/dist/index.js"
],
"env": {
"OMADA_BASE_URL": "<OMADA_BASE_URL>",
"OMADA_CLIENT_ID": "<OMADA_CLIENT_ID>",
"OMADA_CLIENT_SECRET": "<OMADA_CLIENT_SECRET>",
"OMADA_OMADAC_ID": "<OMADA_OMADAC_ID>"
}
}
}
}{
"servers": {
"tp-link-omada": {
"type": "stdio",
"command": "node",
"args": [
"<ABSOLUTE_PATH_TO_CLONE>/dist/index.js"
],
"env": {
"OMADA_BASE_URL": "<OMADA_BASE_URL>",
"OMADA_CLIENT_ID": "<OMADA_CLIENT_ID>",
"OMADA_CLIENT_SECRET": "<OMADA_CLIENT_SECRET>",
"OMADA_OMADAC_ID": "<OMADA_OMADAC_ID>"
}
}
}
}[mcp_servers.tp-link-omada]
command = "node"
args = ["<ABSOLUTE_PATH_TO_CLONE>/dist/index.js"]
[mcp_servers.tp-link-omada.env]
OMADA_BASE_URL = "<OMADA_BASE_URL>"
OMADA_CLIENT_ID = "<OMADA_CLIENT_ID>"
OMADA_CLIENT_SECRET = "<OMADA_CLIENT_SECRET>"
OMADA_OMADAC_ID = "<OMADA_OMADAC_ID>"gemini mcp add --scope user -e OMADA_BASE_URL=<OMADA_BASE_URL> -e OMADA_CLIENT_ID=<OMADA_CLIENT_ID> -e OMADA_CLIENT_SECRET=<OMADA_CLIENT_SECRET> -e OMADA_OMADAC_ID=<OMADA_OMADAC_ID> tp-link-omada node -- '<ABSOLUTE_PATH_TO_CLONE>/dist/index.js'OMADA_BASE_URL |
Required: Address of the Omada controller, e.g. https://omada-controller.local. |
|---|---|
OMADA_CLIENT_ID |
Required: Open API client ID from the controller's Platform Integration page. |
OMADA_CLIENT_SECRET |
Required: Secret paired with the client ID. |
OMADA_OMADAC_ID |
Required: ID (omadacId) of the controller to target. |
OMADA_SITE_ID |
Optional: Default site; without it each call must pass a siteId. |
OMADA_STRICT_SSL |
Optional: TLS certificate checking, true by default; set false for a self-signed controller. |
OMADA_TOOL_CATEGORIES |
Optional: Categories to load with :r, :w or :rw; default dashboard:r,client-insights:r,clients:r,devices-all:r. |
OMADA_TIMEOUT |
Optional: Request timeout in milliseconds, 30000 by default. |
MCP_SERVER_USE_HTTP |
Optional: Set true to serve Streamable HTTP instead of stdio. |
MCP_HTTP_BIND_ADDR |
Optional: HTTP bind address, 127.0.0.1 by default. |
MCP_HTTP_PORT |
Optional: HTTP port, 3000 by default. |
MCP_SERVER_LOG_LEVEL |
Optional: debug, info (default), warn or error. |
In a container, a setting goes in with -e NAME=value after docker run.
This server connects to a self-hosted or hardware TP-Link Omada controller through the controller's Open API and turns its endpoints into MCP tools. An assistant can list sites, look up access points, switches and gateways, check WAN and LAN status, read wireless, routing, firewall, VPN and logging settings, and see which clients are connected and how much traffic they use.
Nearly every tool only reads. The three that change anything all belong to the clients category: setting a custom bandwidth limit on one client, applying a saved rate-limit profile to it, or removing its limit. Tools are switched on by category through OMADA_TOOL_CATEGORIES, each with a read, write or read-write suffix. Out of the box only dashboard, client-insights, clients and all device categories load, and all of them read-only, so the write tools stay off until a user asks for them.
The tool registry in src/tools/index.ts at release v0.15.0 holds 319 tools, while the README's tables list 248; tools such as getClientDetail are registered but missing from those tables. The code's log-level setting accepts debug, info, warn and error only: the README also offers silent, which src/config.ts rejects at startup. The server runs over stdio by default or as a Streamable HTTP endpoint. In HTTP mode the code lets the client ID, secret and controller ID come from request headers instead of the environment. Its maker states that since March 2026 all of its code has been written by AI agents, with people approving the changes.
| Runtime | DockerorNode.js 24+ |
|---|
A TP-Link Omada controller (tested with versions 5.x and 6.x) that the machine can reach, plus an Open API client ID and secret created under the controller's Platform Integration settings and the controller's omadacId. To run it you need Docker for the published image, or Node.js 24+ to build from source.
Write support covers client bandwidth limits only; categories such as insights, network-sim-lte, account-sso, the hotspot ones, site-templates, voip, olt and msp are reserved, have no tools yet, and are skipped with a startup warning. The README's opening mention of a generic tool for calling any Omada endpoint matches no tool in the v0.15.0 registry. getClient and getDevice are deprecated and filter full lists in-process. Without OMADA_SITE_ID every call must pass a siteId. Strict TLS checking is on by default, so a controller with a self-signed certificate needs OMADA_STRICT_SSL=false. Integration tests against a real controller are planned but not yet in place.
It suits network administrators who run an Omada controller and want an assistant to answer questions about devices, clients, Wi-Fi, WAN health, firewall rules and logs without clicking through the controller UI. The default read-only setup fits auditing and troubleshooting. Anyone who wants an assistant to change SSIDs, VLANs, firewall rules or reboot devices will find only client rate limits on offer. It is a community project, not from TP-Link, and it needs Open API credentials with access to the controller, so someone who cannot create those, or who manages TP-Link gear without an Omada controller, should look elsewhere.
listSitesgetSiteDetailgetSiteCapacitylistClientsgetClientDetailgetClientlistMostActiveClientslistClientsActivitylistClientsPastConnectionssetClientRateLimitsetClientRateLimitProfiledisableClientRateLimitlistDevicesgetDevicesearchDeviceslistDevicesStatslistPendingDevicesgetSwitchDetailgetSwitchStackDetailgetGatewayDetailgetGatewayWanStatusgetGatewayLanStatusgetGatewayPortsgetApDetailgetApRadiosgetFirmwareInfogetCableTestLogsgetRFScanResultgetSpeedTestResultsgetUpgradeLogsgetDashboardOverviewgetDashboardWifiSummarygetDashboardTrafficActivitiesgetGlobalDashboardOverviewgetSsidListgetSsidDetaillistAllSsidsgetWlanGroupListgetInternetgetWanHealthDetailgetWanUsageStatsgetLanNetworkListlistPortForwardingRuleslistStaticRouteslistPolicyRoutesgetFirewallSettinglistEapAclslistOsgAclsgetUrlFilterRulesgetThreatListgetRogueApsgetVpnSettingslistSiteToSiteVpnsgetVpnTunnelStatslistSiteEventslistSiteAlertslistSiteAuditLogslistGlobalEventsgetBackupFileListgetAllLocalUsers