genieacs-mcp
genieacs-mcp lets an MCP client inspect and manage GenieACS/TR-069 CPE devices through 12 tools and 7 resources.
Search devices using MongoDB-style filters, projections, sorting, and paging.
Read cached TR-069 parameters and browse device, task, fault, preset, provision, and file resources.
Refresh parameter values from a device without changing it.
Set writable parameters, reboot devices, push firmware or files, and send connection requests.
Add or remove device tags, and create/replace/delete presets and provision scripts.
Delete queued tasks or retry faulted tasks.
Run in read-only mode or restrict the server to selected tools, over stdio or HTTP.
genieacs-mcp is an MCP server for GenieACS, the open-source TR-069 ACS that manages routers, ONTs and other CPE devices. Add it to Claude Desktop, Cursor or any other MCP client and ask in plain words: which devices stopped informing last night, what firmware serial 000003 runs, reboot the ones tagged pilot. The assistant reads and acts through your GenieACS NBI with 7 resources and 12 tools; one Go binary, no database of its own.
Features
Find devices the way you would ask a colleague: by tag, model, firmware, last inform, or any TR-069 parameter (
search_devicestakes a MongoDB-style filter).Read a device's full parameter tree, its tasks and its faults, plus the presets, provisions and files on the ACS, as resources (
genieacs://device/{id},genieacs://devices/list, ...).Reboot a device, push firmware to it, refresh or set a parameter, or wake it with a connection request, from a chat.
Tag devices, create or delete presets and provisions, and delete or retry tasks, so the assistant can fix what it finds.
Every tool description says what it does, its limits and an example, so clients pick the right one without a prompt from you.
Read versus act:
search_devices,get_parameterand the seven resources only read; the other ten tools queue a task on a device or change the ACS, and each tool's hints say which, so your client can ask before the ones that act.Read-only mode:
GENIEACS_READ_ONLY=trueserves only the two reading tools and the resources;GENIEACS_TOOLS=search_devices,reboot_deviceserves only the tools you name.Speaks MCP 2026-07-28 and every earlier version back to 2024-11-05, so new and old clients both connect, over stdio or stateless HTTP.
Safe on a laptop: the HTTP transport listens on loopback only unless you set an address and a bearer token, and checks
HostandOriginagainst DNS rebinding.One static Go binary for Linux, macOS and Windows on amd64 and arm64, also as an npm package (
npx genieacs-mcp) and a Docker image.
Related MCP server: router-mcp
Quick start
You need a GenieACS whose NBI (port 7557) this machine can reach; without one, the family's demo stack gives you an ACS with a simulated router in about a minute:
curl -fsSLO https://raw.githubusercontent.com/GeiserX/genieacs-container/main/docker-compose.yml
docker compose --profile testing up -d # GenieACS + MongoDB + one simulated CPE, NBI on localhost:7557Then add the server to a client that reads an mcpServers block (Claude Desktop, Cursor, Claude Code; in VS Code the .vscode/mcp.json key is servers):
{
"mcpServers": {
"genieacs": {
"command": "npx",
"args": ["-y", "genieacs-mcp"],
"env": { "ACS_URL": "http://localhost:7557" }
}
}
}The same server in other clients:
# Claude Code
claude mcp add --transport stdio --env ACS_URL=http://localhost:7557 genieacs -- npx -y genieacs-mcp
# Docker, over stdio (any client that starts a command)
docker run -i --rm -e ACS_URL=http://host.docker.internal:7557 drumsergio/genieacs-mcp:v0.4.0// VS Code, .vscode/mcp.json
{ "servers": { "genieacs": { "type": "stdio", "command": "npx", "args": ["-y", "genieacs-mcp"], "env": { "ACS_URL": "http://localhost:7557" } } } }# Codex, ~/.codex/config.toml
[mcp_servers.genieacs]
command = "npx"
args = ["-y", "genieacs-mcp"]
env = { ACS_URL = "http://localhost:7557" }It worked when you ask "which devices does the ACS know about?" and the assistant answers with device ids such as 202BC1-BM632w-000000 (the demo stack) or your own. Docker, the HTTP transport and a local build are in Getting started.
Documentation
The full documentation is at geiserx.github.io/genieacs-mcp.
Getting started: npm, Docker Compose, local build, and what the first exchange looks like
Configuration: every environment variable, the HTTP transport's security model, client config for stdio and HTTP
Usage: the 7 resources and 12 tools with their arguments, which ones act on devices, example prompts
Development: tests, trying the server with MCP Inspector, contributing
Related projects: the GenieACS family, other MCP servers, where this server is listed
Related projects
Listed in the official MCP Registry as io.github.GeiserX/genieacs-mcp. Part of the GenieACS family: genieacs-container (the ACS itself, Docker and Helm, with this server as a compose profile), genieacs-sim-container, genieacs-ansible, genieacs-ha, genieacs-services, and n8n-nodes-genieacs (archived).
License
Available Tools
12 toolsconnection_requestWake device (connection request)AIdempotent
Send a TR-069 connection request so a CPE device contacts GenieACS now instead of at its next periodic inform. Use it to run tasks that are already queued, or to apply a preset change without waiting. It queues nothing itself. Succeeds when the device answered; fails with ACS error 504 when the device is unreachable (offline, or behind NAT without STUN). Example: connection_request(device_id="202BC1-BM632w-000001").
Inputs: device_id (required).
delete_taskDelete queued taskADestructiveIdempotent
Remove a task from the GenieACS queue before the device runs it, for example a firmware download or reboot queued by mistake, or a faulted task you do not want retried. GenieACS already deletes a task once the device has run it, so every task you can see in genieacs://tasks/{device_id} is either waiting or faulted. Fails with ACS error 503 while the device is in a session with GenieACS; try again a few seconds later. Use retry_task instead to run a faulted task again. Example: delete_task(task_id="67abc123def4560012345678").
Inputs: task_id (required).
download_firmwarePush firmware or file to deviceADestructive
Tell a CPE device to download and apply a file stored on GenieACS: a firmware image, a configuration file or another file the device accepts. A wrong image can leave a device unusable, so check the file's metadata (genieacs://file/{name}: OUI, product class, version) against the device first. GenieACS queues a download task and sends a connection request at once; the transfer itself can take minutes after the tool returns. Check genieacs://tasks/{device_id} and genieacs://faults/{device_id} afterwards. Example: download_firmware(device_id="202BC1-BM632w-000001", file_id="firmware-v2.0.bin").
Inputs: file_id (required), device_id (required), filename. Returns: task, status, message, task_id, +1 more
get_parameterRead cached device parametersARead-onlyIdempotent
Read TR-069 parameter values GenieACS has cached for a device, without contacting the device: firmware version, serial number, uptime, WiFi SSID, IP addresses and so on. Values are what the device reported at its last inform or refresh, with a timestamp each; call refresh_parameter first when you need a value from the device now. Give one path or a comma-separated list; an object path such as "Device.WiFi" returns every cached leaf under it. Returns found=false for an unknown device id, and lists paths with no cached value under missing.
Inputs: device_id (required), parameter_path (required). Returns: found, missing, device_id, parameters
manage_presetCreate, replace or delete presetADestructiveIdempotent
Create, replace or delete a GenieACS preset. A preset is a fleet-wide rule: at their next inform, every device matching its precondition gets its configurations applied, so a broad precondition (or an empty one) reconfigures the whole fleet. Confirm the precondition and the devices it matches (search_devices with the same filter) before a put. action="put" creates or overwrites the preset with body; action="delete" removes it. body is a JSON object: weight (integer, higher wins), precondition (a MongoDB-style filter as a JSON string, e.g. "{"_tags":"office"}"), and configurations (an array of {type: "value" | "provision" | "add_object" | "delete_object", ...}). Example body: {"weight":0,"precondition":"{"_tags":"pilot"}","configurations":[{"type":"provision","name":"myScript"}]}. Read genieacs://presets/list first.
Inputs: name (required), action (required), body.
manage_provisionCreate, replace or delete provision scriptADestructiveIdempotent
Create, replace or delete a GenieACS provision script. A provision is JavaScript that GenieACS runs during the inform session of every device a preset applies it to, so replacing one changes how those devices are configured. Scripts use the GenieACS sandbox API (declare, commit, clear, ext, log); ext() calls extension scripts that run on the ACS host with full privileges, so treat a provision as code running on your ACS. action="put" uploads or overwrites the script (raw JavaScript, not JSON; GenieACS answers 400 on a syntax error); action="delete" removes it. Presets reference provisions by name. Read genieacs://provisions/list first. Example script: log("Device " + DeviceID.ID + " informed");
Inputs: name (required), action (required), script.
reboot_deviceReboot deviceADestructive
Reboot a CPE device through GenieACS. Use it when a device needs a restart, for example after a configuration change or to recover an unresponsive device. The device drops its service while it restarts. GenieACS queues the task and sends a connection request at once: status "done" means the device ran it in that session, "queued" means it runs at the device's next inform. A reboot does not confirm the device came back; read Device.DeviceInfo.UpTime (or InternetGatewayDevice.DeviceInfo.UpTime) with refresh_parameter afterwards. Example: reboot_device(device_id="202BC1-BM632w-000001").
Inputs: device_id (required). Returns: task, status, message, task_id, +1 more
refresh_parameterRefresh parameter from deviceAIdempotent
Ask a CPE device for the current value of a TR-069 parameter, or of every parameter under an object path, and store it in GenieACS. Use it when get_parameter's cached value may be stale. It changes nothing on the device. GenieACS queues a getParameterValues task and sends a connection request at once: status "done" means the fresh value is already stored, so read it with get_parameter; "queued" means it arrives at the device's next inform. Example: refresh_parameter(device_id="202BC1-BM632w-000001", parameter="Device.DeviceInfo.SoftwareVersion").
Inputs: device_id (required), parameter (required). Returns: task, status, message, task_id, +1 more
retry_taskRetry faulted taskAIdempotent
Run a faulted task again: GenieACS clears the task's fault, and the device runs the task at its next session. Read genieacs://faults/{device_id} first to see why it failed; retrying a task whose cause is unchanged faults again. A task that has not faulted is left as it is. Example: retry_task(task_id="67abc123def4560012345678").
Inputs: task_id (required).
search_devicesSearch devicesARead-onlyIdempotent
Find CPE devices in GenieACS with a MongoDB-style filter: by tag, manufacturer, model, firmware version, last inform time or any TR-069 parameter. It only reads. Examples: {"_tags":"office"}; {"InternetGatewayDevice.DeviceInfo.Manufacturer":"Huawei"} (GenieACS adds ._value to parameter paths); {"_lastInform":{"$lt":"2026-01-01T00:00:00Z"}} for devices silent since that date; {"_id":{"$regex":"^202BC1-"}}. Query operators such as $eq, $ne, $gt, $lt, $in, $nin, $exists, $regex, $and and $or work; $where, $function, $accumulator and $expr are refused, and a $regex pattern may be at most 256 characters. By default each device comes back as a summary (id, last inform, tags, manufacturer, product class, serial); ask for other fields with projection. Results come in pages of limit (default 50, at most 200); page with skip.
Inputs: query (required), skip, sort, limit, +1 more. Returns: more, skip, count, limit, +1 more
set_parameterSet device parametersADestructiveIdempotent
Write one or more TR-069 parameter values on a CPE device, overwriting the current values: WiFi SSID or key, periodic inform interval, management server URL, or any writable parameter. A wrong value can cut the device off (a wrong WAN or ACS URL setting, for example). parameter_values is a JSON array of [path, value] or [path, value, xsdType] tuples; xsd types include xsd:string, xsd:boolean, xsd:unsignedInt, xsd:int and xsd:dateTime, and GenieACS infers the type when it is omitted. Example: [["InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.SSID","Lab-2","xsd:string"]]. GenieACS queues the task and sends a connection request at once: status "done" means the device applied it, "queued" means it runs at the next inform. A read-only or unknown parameter makes the device fault the task; see genieacs://faults/{device_id}. Read the current value with get_parameter first.
Inputs: device_id (required), parameter_values (required). Returns: task, status, message, task_id, +1 more
tag_deviceAdd or remove device tagADestructiveIdempotent
Add a tag to a CPE device or remove one. Tags group devices: presets match on them (precondition {"tags":"office"}) and search_devices finds by them. Adding or removing a tag can therefore make a preset apply to the device, or stop applying, at its next inform. Tags are case-sensitive. Use letters, digits, "-" and "": GenieACS rejects a tag with other characters (a "." for example) with a 404. Fails with ACS error 404 when the device id does not exist. Example: tag_device(device_id="202BC1-BM632w-000001", tag="office", action="add").
Inputs: tag (required), action (required), device_id (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 12 tools
Each tool targets a distinct resource+action, and subtle pairs are explicitly separated: get_parameter (cached) vs refresh_parameter (fresh from device), delete_task vs retry_task, manage_preset vs manage_provision. Several tools queue tasks, but their purposes (reboot, download firmware, set/refresh parameters) are clearly different, and connection_request is explicitly documented as queueing nothing.
Eleven of twelve tools follow a clean verb_noun snake_case pattern (get_parameter, set_parameter, delete_task, reboot_device, tag_device, search_devices, etc.). The outlier is connection_request, which drops the leading verb; manage_preset/manage_provision also fold create/update/delete into an action parameter rather than separate names, a minor inconsistency.
Twelve tools is well within the ideal range and each earns its place: device discovery, parameter read/write/refresh, task lifecycle, firmware, presets, provisions, tagging, and connection requests. Nothing feels redundant or missing for the apparent ACS-management scope.
The surface covers the core TR-069 lifecycle: discover/tag devices, read/write/refresh parameters, reboot, download firmware, manage tasks (delete/retry), and CRUD presets/provisions. Minor gaps remain—no tool to list or upload the files that download_firmware references, and no dedicated task/fault listing tool (deferred to resource URIs), which agents can partly work around.
Maintenance
Related MCP Connectors
Go MCP server for GitLab: 2 dynamic tools reach 1000+ REST/GraphQL actions. Free/CE, no paid tier.
An MCP server that provides an API to LLMs to manage their JumpCloud resources.
MCP server for OnceAsk, the AI-native current-address layer for people and agents.
Host any HTTP API as a standard MCP server; auto-distribute to 12+ mainstream agent platforms.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceA high-performance Go-based MCP server that provides a microservice architecture for orchestrating diverse tools through gRPC and HTTP/REST APIs. Enables seamless integration of language-agnostic tools including ML capabilities, web search, calculations, and human interaction for intelligent agent workflows.2-
- AlicenseAqualityDmaintenanceMCP server for monitoring and controlling WiFi routers (OpenWrt) via SSH, enabling device listing, status checks, WiFi configuration, rebooting, and more.717 npmMIT
- AlicenseNot gradedqualityCmaintenanceProvider-agnostic MCP server for managing heterogeneous infrastructure (SSH, Proxmox VE, Virtualizor, Hetzner Cloud, Cloudflare) via a JSON inventory, exposing tools for VM/container management, DNS, firewalls, and SSH operations.MIT
- AlicenseBqualityBmaintenanceCommunity-maintained downstream MCP server for bounded AsusWRT and AsusWRT-Merlin administration over SSH.68MIT