Skip to main content
Glama

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_devices takes 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_parameter and 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=true serves only the two reading tools and the resources; GENIEACS_TOOLS=search_devices,reboot_device serves 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 Host and Origin against 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:7557

Then 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

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

GPL-3.0-or-later

Available Tools

12 tools
connection_requestWake device (connection request)A
Idempotent

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 taskA
DestructiveIdempotent

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 deviceA
Destructive

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 parametersA
Read-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 presetA
DestructiveIdempotent

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 scriptA
DestructiveIdempotent

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 deviceA
Destructive

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 deviceA
Idempotent

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 taskA
Idempotent

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 devicesA
Read-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 parametersA
DestructiveIdempotent

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 tagA
DestructiveIdempotent

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

    A4.5/5.0

    Scored across 12 tools

    Disambiguation5/5

    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.

    Naming Consistency4/5

    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.

    Tool Count5/5

    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.

    Completeness4/5

    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

    ActivityActive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      Not graded
      maintenance
      A 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
      -
    • A
      license
      Not graded
      quality
      C
      maintenance
      Provider-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