TP-Link Omada MCP server

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

Connect your client

Local (container)

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_CLIENT_ID, OMADA_CLIENT_SECRET, OMADA_OMADAC_ID. Replace each <NAME> with your value.

Claude CodeTerminal
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
Claude Desktopclaude_desktop_config.json
{
  "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>"
      }
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "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>"
      }
    }
  }
}
VS Code.vscode/mcp.json
{
  "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>"
      }
    }
  }
}
Codex~/.codex/config.toml
[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 CLITerminal
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:latest
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_CLIENT_ID, OMADA_CLIENT_SECRET, OMADA_OMADAC_ID. Replace each <NAME> with your value.

FirstTerminal
git clone https://github.com/migueltvms/tplink-omada-mcp.git
cd tplink-omada-mcp
npm install
npm run build
Claude CodeTerminal
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> -- node '<ABSOLUTE_PATH_TO_CLONE>/dist/index.js'
Claude Desktopclaude_desktop_config.json
{
  "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>"
      }
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "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>"
      }
    }
  }
}
VS Code.vscode/mcp.json
{
  "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>"
      }
    }
  }
}
Codex~/.codex/config.toml
[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 CLITerminal
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'

Settings 12

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.

What it does

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.

What it needs

RuntimeDockerorNode.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.

Limits

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.

Who it suits

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.

Tools 60 of 319

listSites
List every site on the controller.
getSiteDetail
Show a site's name, region, timezone and settings.
getSiteCapacity
Show a site's maximum device and client counts.
listClients
List clients currently connected to a site.
getClientDetail
Show details for one client by MAC address.
getClient
Deprecated: find one client by filtering the site's client list.
listMostActiveClients
Rank clients by traffic used.
listClientsActivity
Show client activity statistics over time.
listClientsPastConnections
Show earlier connections made by clients.
setClientRateLimit
Set custom download and upload limits on one client (write).
setClientRateLimitProfile
Apply a saved rate-limit profile to one client (write).
disableClientRateLimit
Remove bandwidth limiting from one client (write).
listDevices
List provisioned devices at a site.
getDevice
Deprecated: find one device by filtering the site's device list.
searchDevices
Search devices across every site the account can see.
listDevicesStats
Page through statistics for adopted devices.
listPendingDevices
List devices waiting to be adopted.
getSwitchDetail
Show configuration and status of one switch.
getSwitchStackDetail
Show configuration and status of a switch stack.
getGatewayDetail
Show configuration and status of one gateway.
getGatewayWanStatus
Show a gateway's WAN port status.
getGatewayLanStatus
Show a gateway's LAN port status.
getGatewayPorts
List a gateway's ports.
getApDetail
Show configuration and status of one access point.
getApRadios
Show an access point's radio state.
getFirmwareInfo
Show the newest firmware available for a device.
getCableTestLogs
Read cable test logs from a switch.
getRFScanResult
Read an access point's RF scan results.
getSpeedTestResults
Read speed test results.
getUpgradeLogs
Read firmware upgrade logs.
getDashboardOverview
Summarise a site's dashboard.
getDashboardWifiSummary
Summarise Wi-Fi state on the dashboard.
getDashboardTrafficActivities
Show recent traffic activity on the dashboard.
getGlobalDashboardOverview
Summarise the dashboard across all sites.
getSsidList
List the SSIDs in a WLAN group.
getSsidDetail
Show one SSID's settings.
listAllSsids
List SSIDs across the site.
getWlanGroupList
List WLAN groups.
getInternet
Read the site's internet (WAN) setup.
getWanHealthDetail
Show WAN health details.
getWanUsageStats
Show WAN usage statistics.
getLanNetworkList
List LAN networks.
listPortForwardingRules
List port forwarding rules.
listStaticRoutes
List static routes.
listPolicyRoutes
List policy routes.
getFirewallSetting
Read firewall settings.
listEapAcls
List access point ACL rules.
listOsgAcls
List gateway ACL rules.
getUrlFilterRules
List URL filtering rules.
getThreatList
List detected threats.
getRogueAps
List rogue access points found by WIDS.
getVpnSettings
Read VPN settings.
listSiteToSiteVpns
List site-to-site VPNs.
getVpnTunnelStats
Show VPN tunnel statistics.
listSiteEvents
List a site's events.
listSiteAlerts
List a site's alerts.
listSiteAuditLogs
List a site's audit log entries.
listGlobalEvents
List controller-wide events.
getBackupFileList
List controller backup files.
getAllLocalUsers
List the controller's local user accounts.

Similar servers