Install
$ agentstack add mcp-migueltvms-tplink-omada-mcp ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
TP-Link Omada MCP server
> ## 🤖 AI-Developed Repository > > Since March 2, 2026, this repository contains no human-written code. > > All planning, development, and code review is performed by AI agents. Humans remain in the loop for direction, decisions, and final approval — but every line of code, every test, every commit, and every PR is the work of AI. > > This is not an experiment. This is how it works now. Know more
A Model Context Protocol (MCP) server implemented in TypeScript that exposes the TP-Link Omada controller APIs to AI copilots and automation workflows. The server authenticates against a controller, lists sites, devices, and connected clients, and offers a generic tool to invoke arbitrary Omada API endpoints.
> Compatibility: Tested with Omada Controller versions 5.x and 6.x
Quick Start
Using with Claude Desktop (stdio)
- Pull the Docker image (or build it locally with
npm run docker:build):
``bash docker pull jmtvms/tplink-omada-mcp:latest ``
- Add the MCP server to Claude Desktop configuration. Edit your Claude Desktop config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
- Add the following configuration:
``json { "mcpServers": { "tplink-omada": { "command": "docker", "args": [ "run", "-i", "--rm", "-e", "OMADA_BASE_URL=https://your-omada-controller.local", "-e", "OMADA_CLIENT_ID=your-client-id", "-e", "OMADA_CLIENT_SECRET=your-client-secret", "-e", "OMADA_OMADAC_ID=your-omadac-id", "-e", "OMADA_SITE_ID=your-site-id", "-e", "OMADA_STRICT_SSL=false", "jmtvms/tplink-omada-mcp:latest" ] } } } ``
Replace the environment variable values with your actual Omada controller credentials.
- Restart Claude Desktop to load the new MCP server configuration.
- Verify the connection by asking Claude to list your Omada sites or devices.
Using Docker Containers
CLI/stdio Container
docker run -it --rm \
--env-file .env \
jmtvms/tplink-omada-mcp:latest
HTTP Server Container
docker run -d \
--env-file .env \
-e MCP_SERVER_USE_HTTP=true \
-e MCP_HTTP_BIND_ADDR=0.0.0.0 \
-p 3000:3000 \
jmtvms/tplink-omada-mcp:latest
The HTTP server will be available at http://localhost:3000/mcp.
Features
- OAuth client-credentials authentication with automatic token refresh
- Tools for retrieving sites, network devices, and connected clients
- Generic Omada API invoker for advanced automation scenarios
- Environment-driven configuration
- Per-tag Omada OpenAPI references stored under
docs/openapi - Ready-to-use devcontainer with a companion Omada controller service
Getting started
Prerequisites
- Docker (for running pre-built containers) or Node.js 24+ (for local development)
- Access to a TP-Link Omada controller (for example using the
mbentley/omada-controllerDocker image)
Configuration
The MCP server reads its configuration from environment variables. See .env.example for a complete reference.
Tool Category Filtering
| Variable | Required | Default | Description | | ------------------------- | -------- | ------------------------------------------------------------ | ---------------------------------------------------- | | OMADA_TOOL_CATEGORIES | No | dashboard:r,client-insights:r,clients:r,devices-all:r | Comma-separated categories to enable at startup | Each token is [:]. Permission suffixes:
| Suffix | Effect | | ------ | -------------------- | | :r | Read tools only | | :w | Write tools only | | :rw | Read and write tools | | (none) | Same as :rw |
Category Reference
Categories marked with * are reserved for upcoming phases and have no tool implementations yet. Specifying them will produce a startup warning and they will be skipped. Write tools are currently limited to the clients category.
| Group | Categories | | ----------------------- | ----------------------------------------------------------------------------- | | Dashboard & Insights | dashboard, client-insights, insights | | Clients | clients | | Devices | devices-general, devices-ap, devices-switch, devices-gateway | | Wireless | wireless-ssid, wireless-radio, wireless-auth | | Network | network-wan, network-sim-lte, network-lan, network-routing, network-nat, network-services | | Firewall & Security | firewall-acl, firewall-traffic, firewall-ids, security-threat, security-wids | | VPN | vpn | | Profiles & Schedules | profiles, schedules, auth-profiles | | Logs | logs | | Controller & Org | controller, sites, maintenance, account-users, account-sso, account-cloud | | Hotspot | hotspot-portal, hotspot-vouchers, hotspot-users | | Niche | site-templates, voip, olt, msp |
Group aliases expand to all categories in their group:
| Alias | Expands to | | -------------- | --------------------------------------------------------------------------------------------- | | all | Every category | | devices-all | devices-general, devices-ap, devices-switch, devices-gateway | | wireless-all | wireless-ssid, wireless-radio, wireless-auth | | network-all | network-wan, network-lan, network-routing, network-nat, network-services | | firewall-all | firewall-acl, firewall-traffic, firewall-ids | | security-all | security-threat, security-wids |
Examples:
# Read-only access to everything
OMADA_TOOL_CATEGORIES=all:r
# Default safe subset (read only)
OMADA_TOOL_CATEGORIES=dashboard:r,client-insights:r,clients:r,devices-all:r
# Full access including write operations
OMADA_TOOL_CATEGORIES=all:rw
# Network read + client write operations
OMADA_TOOL_CATEGORIES=network-all:r,clients:rw
Omada Client Configuration
| Variable | Required | Default | Description | | --------------------- | -------- | ------- | --------------------------------------------------------------------------- | | OMADA_BASE_URL | Yes | - | Base URL of the Omada controller (e.g., https://omada-controller.local) | | OMADA_CLIENT_ID | Yes | - | OAuth client ID generated under Omada Platform Integration | | OMADA_CLIENT_SECRET | Yes | - | OAuth client secret associated with the client ID | | OMADA_OMADAC_ID | Yes | - | Omada controller ID (omadacId) to target | | OMADA_SITE_ID | No | - | Optional default site ID; if omitted, each MCP call must pass a siteId | | OMADA_STRICT_SSL | No | true | Enforce strict SSL certificate validation (set to false for self-signed) | | OMADA_TIMEOUT | No | 30000 | HTTP request timeout in milliseconds |
MCP Generic Server Configuration
| Variable | Required | Default | Description | | ------------------------ | -------- | ------- | --------------------------------------------------------------------------- | | MCP_SERVER_LOG_LEVEL | No | info | Logging verbosity (debug, info, warn, error, silent) | | MCP_SERVER_LOG_FORMAT | No | plain | Log output format (plain, json, or gcp-json) | | MCP_SERVER_USE_HTTP | No | false | Start HTTP server instead of stdio | > Session IDs and authentication: When OMADA_CLIENT_ID, OMADA_CLIENT_SECRET, and OMADA_OMADAC_ID are provided (the default client-credentials mode), the server runs statelessly and treats the Mcp-Session-Id header as optional. A future OAuth-based user authentication mode will require this header again.
MCP Server HTTP Configuration
These variables are only used when MCP_SERVER_USE_HTTP=true:
| Variable | Required | Default | Description | | ------------------------------ | -------- | ------------------------------- | --------------------------------------------------------------------------- | | MCP_HTTP_PORT | No | 3000 | Port for the HTTP server | | MCP_HTTP_BIND_ADDR | No | 127.0.0.1 | Bind address (IPv4/IPv6). Use atapter IP address to expose to the network. | | MCP_HTTP_PATH | No | /mcp | Base path for MCP endpoints | | MCP_HTTP_ENABLE_HEALTHCHECK | No | true | Enable a healthcheck endpoint | | MCP_HTTP_HEALTHCHECK_PATH | No | /healthz | Path for the healthcheck endpoint | | MCP_HTTP_ALLOW_CORS | No | true | Enable CORS for the HTTP server | | MCP_HTTP_ALLOWED_ORIGINS | No | 127.0.0.1, localhost | Comma-separated list of allowed origins. Use * to allow all (dev only) | | MCP_HTTP_NGROK_ENABLED | No | false | Use ngrok to expose the HTTP server publicly | | MCP_HTTP_NGROK_AUTH_TOKEN | No | - | Ngrok auth token (required if MCP_HTTP_NGROK_ENABLED=true) | Create a .env file (ignored by git) or export the variables before launching the server.
Development
npm run dev
The dev mode keeps the TypeScript server running with live reload support via tsx.
Building
npm run build
Linting
npm run check
Testing
Unit tests
npm test # run all unit tests
npm run test:watch # watch mode
npm run test:coverage # with coverage report
Coverage thresholds:
| Level | Metric | Threshold | |-------|--------|-----------| | Per-file | Lines, Statements, Functions | 90% | | Global | Branches | 70% |
Integration tests (Docker)
> Not implemented yet — this section documents the planned integration test strategy tracked in #57 and #58.
Integration tests will run against a real Omada Software Controller in a Docker container. They are not planned to run on every PR — they serve as a milestone release gate and a test harness for write tools.
Planned layout:
test/docker/(compose + snapshot/seed tooling)tests/integration/npm run test:integration
> ⚠️ Phase 2 write tools must only be tested against the Docker controller — never against a production controller.
Running the MCP server
npm start
The MCP server communicates over standard input and output. Integrate it with MCP-compatible clients by referencing the npm start command and providing the required environment variables.
Docker image
A container image is provided for running the MCP server:
npm run docker:build # Build the Docker image (tag: jmtvms/tplink-omada-mcp:latest)
npm run docker:run # Launch the container with your .env file
npm run docker:push # Push the image to Docker Hub
You can also pull the pre-built image directly from Docker Hub:
docker pull jmtvms/tplink-omada-mcp:latest
The same image supports both stdio and HTTP transports - configure the desired mode using environment variables (e.g., set MCP_SERVER_USE_HTTP=true for HTTP mode).
Debugging with MCP Inspector
Use the MCP Inspector to interactively test tools, resources, and prompts without leaving your browser. The inspector automatically adapts to your .env configuration:
npm run inspector— Launches the inspector based on your.envsettings:- If
MCP_SERVER_USE_HTTP=false(or unset): Runs the server in stdio mode withtsx src/index.tsfor live reload debugging - If
MCP_SERVER_USE_HTTP=true: Connects to an already-running HTTP server at the configured port/transport (start the server first withnpm run dev)
npm run inspector:build— Compiles the project first, then launches the inspector against the production build (dist/index.js) to verify release parity. Also adapts to stdio or HTTP mode based on.env.
Requirements: The inspector requires a .env file at the repository root. It will load both .env and .env.local (if present) to determine the server mode, port, transport, and path.
The MCP Inspector tool automatically binds to localhost and generates a session token for authentication (printed to the console and auto-filled in the browser URL).
Transport Protocols
The MCP server uses the Streamable HTTP transport, which implements the MCP protocol version 2025-03-26.
export MCP_SERVER_USE_HTTP=true
npm run dev
Features:
- Single endpoint for all operations (GET, POST, DELETE)
- Server-Sent Events for streaming responses
- Built-in session management with cryptographic session IDs (the server currently operates statelessly when using client credentials)
The endpoint defaults to /mcp and handles:
GET /mcp- Establish SSE stream and initialize sessionPOST /mcp- Send JSON-RPC messagesDELETE /mcp- Terminate session
Security Considerations
DNS rebinding protection is enabled by default:
- Origin Validation: The server validates the
Originheader on all incoming connections. Configure allowed origins withMCP_HTTP_ALLOWED_ORIGINS(default:127.0.0.1, localhost). Use*to allow all origins (development only, not recommended for production). - Network Binding: The server binds to
127.0.0.1by default, restricting access to localhost only. SetMCP_HTTP_BIND_ADDR=0.0.0.0to expose the server to your network (not recommended for production without additional security measures).
For more information on the MCP protocol and transports, see the Model Context Protocol documentation.
HTTP transport usage
Start the HTTP transport with:
# Start with HTTP enabled
export MCP_SERVER_USE_HTTP=true
npm run dev # live reload during development
npm run start # run the compiled output
By default, the server listens on 127.0.0.1:3000 and exposes the MCP endpoint at /mcp with a health check on /healthz. Configure the bind address, port, and path using the optional MCP_HTTP_* environment variables documented in .env.example. The npm run docker:run:http helper wraps the HTTP image and publishes the port automatically.
Using ngrok
To share the local server with remote tooling, you can use ngrok to expose the HTTP server publicly.
Option 1: Built-in ngrok support (recommended)
Set the following environment variables:
export MCP_HTTP_NGROK_ENABLED=true
export MCP_HTTP_NGROK_AUTH_TOKEN=your
…
## Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [MiguelTVMS](https://github.com/MiguelTVMS)
- **Source:** [MiguelTVMS/tplink-omada-mcp](https://github.com/MiguelTVMS/tplink-omada-mcp)
- **License:** MIT
- **Homepage:** https://hub.docker.com/r/jmtvms/tplink-omada-mcp
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.