Skip to content

Configuration

Variable Default Description
ACS_URL http://localhost:7557 GenieACS NBI endpoint (without trailing /)
ACS_USER (empty) GenieACS NBI basic-auth username
ACS_PASS (empty) GenieACS NBI basic-auth password
TRANSPORT (empty = HTTP) Set to stdio for stdio transport
DEVICE_LIMIT 500 Max devices returned by genieacs://devices/list
MCP_LISTEN_ADDR 127.0.0.1:8080 HTTP listen address (only used when TRANSPORT is not stdio)
MCP_AUTH_TOKEN (empty) Bearer token for HTTP transport auth. Required when MCP_LISTEN_ADDR is non-loopback
MCP_ALLOWED_HOSTS (empty) Comma-separated extra Host header values to accept (e.g. a reverse-proxy domain). Loopback names on the listen port are always allowed
MCP_ALLOWED_ORIGINS (empty) Comma-separated extra browser Origin values to accept (e.g. https://my-ai-app.com). A value that is not a plain scheme://host[:port] origin stops the server at startup
GENIEACS_READ_ONLY false true (or 1, yes, on) serves only the tools that never change a device or the ACS: search_devices and get_parameter. The resources are always served
GENIEACS_TOOLS (empty = all) Comma-separated tool names to serve, e.g. search_devices,get_parameter,reboot_device. An unknown name stops the server at startup and the error lists the known ones. With GENIEACS_READ_ONLY a tool must pass both
ACS_TIMEOUT 30 Seconds to wait for one GenieACS NBI request before the call fails
ACS_MAX_RESPONSE_BYTES 4194304 (4 MiB) Largest NBI response the server reads. A bigger one fails with a message to narrow the query or projection instead of filling memory

Security — HTTP transport. The HTTP transport validates the Host and Origin headers on every request to prevent DNS rebinding from a malicious web page reaching a local listener. Requests with an untrusted Host, or a present-but-untrusted Origin, are rejected with 403. Loopback access works with no configuration; if you expose the server through a reverse proxy or a hostname, add that name to MCP_ALLOWED_HOSTS (and MCP_ALLOWED_ORIGINS for browser clients). The stdio transport is unaffected and remains the recommended mode for local MCP clients.

Every HTTP request also passes Go's cross-origin protection, which turns away a browser request whose Sec-Fetch-Site says it came from another site. When MCP_AUTH_TOKEN is set the request needs the header Authorization: Bearer <token>; the scheme word is matched case-insensitively and the token in constant time, and anything else gets 401 with WWW-Authenticate: Bearer. A request body larger than 4 MiB is refused.

Ten of the twelve tools act on a device or change the ACS. Each tool says so in its annotations (readOnlyHint, destructiveHint, idempotentHint), so a client can ask before the ones that act. To take the acting tools away altogether, set GENIEACS_READ_ONLY=true, or list the tools you want in GENIEACS_TOOLS. A tool left out is never registered, so the client never sees it.

The server speaks MCP 2026-07-28 and the earlier versions 2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05. A new client finds it with server/discover, an older one with initialize; both work over stdio and over HTTP. The HTTP transport is stateless and issues no Mcp-Session-Id.

Put them in a .env file (from .env.example) or set them in the environment.

A value that is nothing but an unexpanded placeholder, such as ${ACS_PASS}, counts as unset. Some MCP clients write that placeholder when an optional field is left blank; the server ignores it rather than send it to GenieACS as a password or accept it as the HTTP auth token.

Client configuration

Over stdio, which the npm package always uses, a client that reads an mcpServers block starts the server itself:

{
  "mcpServers": {
    "genieacs": {
      "command": "npx",
      "args": ["-y", "genieacs-mcp"],
      "env": { "ACS_URL": "http://localhost:7557" }
    }
  }
}

Add ACS_USER and ACS_PASS only if you put basic auth in front of the NBI; GenieACS itself ships the NBI without authentication, and the admin / admin login of the web UI is not an NBI credential.

Over HTTP, for a server you already run (the Docker image, or the binary without TRANSPORT=stdio), a client that supports remote servers connects to the /mcp endpoint. Drop headers if you did not set MCP_AUTH_TOKEN:

{
  "mcpServers": {
    "genieacs": {
      "url": "http://localhost:8080/mcp",
      "headers": { "Authorization": "Bearer <MCP_AUTH_TOKEN>" }
    }
  }
}