Skip to main content
Glama
kzmp

aos8-mcp-server-iap

by kzmp

aos8-mcp-server-IAP

A read-only MCP server for Aruba Instant APs (Instant AOS-8). It exposes the Instant AP monitoring REST API as MCP tools and guided prompts, so an AI assistant can answer questions about a swarm without being able to change it.

It follows the architecture of teze3808/aos8-mcp-server, which targets AOS-8 controllers. The Instant AP API is a different API, so this is a separate implementation rather than a fork.

Overview

Once configured, an assistant can answer questions like:

  • "Which APs in the swarm are reporting high channel utilization?"

  • "Which SSIDs are still open?"

  • "Which AP is the client at 00:11:22:33:44:55 connected to?"

  • "Do all members of the swarm share the same config checksum?"

Operational Scope

  • Implemented: read-only show commands through /rest/show-cmd, bounded by a policy allowlist.

  • Implemented: deterministic analyzers that produce findings before an AI summarizes them.

  • Not implemented: any POST write. No Action API, no Configuration API, no os-upgrade, no ap-reboot.

  • Planned for v0.2: plan-only configuration previews that build and validate a payload without sending it.

Instant AP vs AOS-8 controller

AOS-8 controller

Instant AP (this server)

Login

POST /v1/api/login, cookie + X-CSRF-Token

POST /rest/login JSON, returns sid

Auth per request

cookie + CSRF header

sid in the query string

Monitoring

GET /v1/configuration/showcommand, JSON tables

GET /rest/show-cmd, raw CLI text

Config read

GET /v1/configuration/object/<name>

not available; only show commands

Errors

HTTP status codes

HTTP 200 with Status-code 0–8 in the body

Availability

any managed node

master or standalone AP only

APIs Used

POST /rest/login
POST /rest/logout
GET  /rest/show-cmd?iap_ip_addr=<ipv4>&cmd=<show command>&sid=<sid>

Tools

Inventory and stateiap_test_connection, iap_get_version, iap_get_summary, iap_get_access_points, iap_get_clients, iap_get_networks, iap_get_network_detail, iap_get_ap_stats, iap_get_client_status, iap_get_wired_port_settings, iap_get_port_status, iap_get_ap_env, iap_get_bootup_log

Analysisiap_get_health_summary, iap_analyze_wlan_security

Escape hatch and introspectioniap_show_command (allowlisted only), iap_list_targets

Every tool accepts an optional iap_ip_addr. Omit it to use the master or standalone AP; pass a member AP's IPv4 address to read that member through the master.

Every tool also accepts an optional cluster_name, which picks the Instant AP cluster/swarm to talk to (see Multiple clusters below). Omit it when only one cluster is configured; it is required when more than one is.

iap_get_access_points, iap_get_clients, and iap_get_networks page their results (limit, default 50; offset; include_extra). A production swarm is large — 227 APs serialize to roughly 220 KB — so each response reports total, returned, offset, and next_offset alongside the page.

Guided Prompts

iap_health_overview, iap_troubleshoot_client, iap_wlan_security_review, iap_swarm_review, iap_safe_show_command

Setup

1. Enable the REST API on the Instant AP

The REST API is disabled by default and is served only by the master (Virtual Controller) or a standalone AP:

(Instant AP)(config)# allow-rest-api
(Instant AP)(config)# end
(Instant AP)# commit apply

2. Configure this server

uv sync
cp .env.example .env
IAP_BASE_URL=https://192.0.2.10:4343
IAP_USERNAME=admin
IAP_PASSWORD=your-password
IAP_VERIFY_SSL=true

Do not commit .env.

/rest/show-cmd requires an IPv4 iap_ip_addr. When IAP_BASE_URL uses a DNS name, set IAP_DEFAULT_IAP_IP_ADDR to the master AP's IPv4 address; otherwise the server reports the problem at the first call instead of failing on the AP.

IAP_VERIFY_SSL=true verifies that the AP presents a certificate trusted by the local machine or by IAP_CA_BUNDLE. Instant APs commonly ship a self-signed certificate; set IAP_VERIFY_SSL=false only for a temporary lab connection.

Multiple clusters

To reach more than one Instant AP cluster/swarm from one running server, set IAP_CLUSTERS instead of IAP_BASE_URL/IAP_USERNAME/IAP_PASSWORD — a JSON array of cluster objects, each with its own name, base_url, username, password, and (optionally) verify_ssl, ca_bundle, default_iap_ip_addr, allowed_iap_ips. Call iap_list_targets to see every configured cluster, then pass that cluster's name as cluster_name on subsequent tool calls. Credentials for every cluster live in the same local .env file as today, under the same trust model — do not commit it.

IAP_CLUSTERS=[
  {"name": "site-a", "base_url": "https://192.0.2.10:4343", "username": "admin",
   "password": "change-me-a", "allowed_iap_ips": []},
  {"name": "site-b", "base_url": "https://192.0.2.20:4343", "username": "admin",
   "password": "change-me-b", "default_iap_ip_addr": "192.0.2.20", "allowed_iap_ips": []}
]

With one cluster configured, cluster_name may be omitted on every tool call. With more than one, omitting it raises a clear error rather than guessing which cluster to use.

3. Verify

uv run iap-mcp-check

Run Locally

uv run iap-mcp-server

With the MCP inspector:

uv run mcp dev src/aruba_iap_mcp/server.py

MCP Client Configuration

Claude Code

claude mcp add iap --env IAP_BASE_URL=https://192.0.2.10:4343 --env IAP_USERNAME=admin --env IAP_PASSWORD=your-password -- uv --directory /path/to/aos8-mcp-server-IAP run iap-mcp-server

Claude Desktop, Codex, VS Code

{
  "mcpServers": {
    "iap": {
      "command": "uv",
      "args": ["--directory", "/path/to/aos8-mcp-server-IAP", "run", "iap-mcp-server"],
      "env": {
        "IAP_BASE_URL": "https://192.0.2.10:4343",
        "IAP_USERNAME": "admin",
        "IAP_PASSWORD": "your-password"
      }
    }
  }
}

For multiple clusters, set IAP_CLUSTERS in the project's .env file (see Multiple clusters) instead of passing it through --env or the env block above — the server reads .env from its working directory at startup, so the client config only needs command/args/--directory, no env overrides required.

Notes

  • show running-config is blocked by default. It is a supported command, but its output contains WPA passphrases, RADIUS secrets, and SNMP communities. IAP_ALLOW_RUNNING_CONFIG=true opts in; redaction still applies.

  • The Instant AP answers HTTP 200 even for failures, so the Status-code in the body is the real result. Codes 2–8 are caller or device-state problems and are never retried. Only transport errors, HTTP 429, and HTTP 5xx are retried with exponential backoff.

  • CLI output parsing is header-driven and degrades to raw text. A response with _meta.parsed = false means the table shape was not recognized, not that the call failed.

  • Openness is judged from Key Management, not Authentication Method. On a real swarm every PSK network reports Authentication Method: None, so reading that field as "open" produces false criticals.

  • Parsers and field mapping were validated against a live Instant AOS-8.12.0.1 swarm (227 APs, 407 clients, 6 networks); every column that release emits maps to a model field. Older releases may emit different columns — unmapped ones are preserved under extra (include_extra=true) rather than dropped. See RUNBOOK.md.

  • This project targets a trusted, single-user, local stdio deployment.

Compatibility

Component

Status

Python

3.11, 3.12, 3.13

Instant AOS-8

verified on 8.12.0.1; 8.5.0.0+ expected (REST API introduced there)

Transport

local stdio

Remote / multi-user MCP

not supported

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kzmp/aos8-mcp-server-iap'

If you have feedback or need assistance with the MCP directory API, please join our Discord server