Skip to main content
Glama
kzmp

aos8-mcp-server-iap

by kzmp
README.md
# 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`](https://github.com/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

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

## Tools

**Inventory and state** — `iap_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`

**Analysis** — `iap_get_health_summary`, `iap_analyze_wlan_security`

**Escape hatch and introspection** — `iap_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](#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:

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

### 2. Configure this server

```bash
uv sync
cp .env.example .env
```

```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.

```env
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

```bash
uv run iap-mcp-check
```

## Run Locally

```bash
uv run iap-mcp-server
```

With the MCP inspector:

```bash
uv run mcp dev src/aruba_iap_mcp/server.py
```

## MCP Client Configuration

### Claude Code

```bash
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

```json
{
  "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](#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](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 |

TDQS

B3.2/5.0

Scored across 17 tools

Disambiguation4/5

Each tool targets a distinct resource or aspect (version, summary, APs, clients, networks, ports, logs, security), with clear list/detail pairs. Minor overlap exists between iap_get_summary and iap_get_health_summary, and iap_show_command could be confused with structured getters, but descriptions make the boundaries reasonably clear.

Naming Consistency5/5

All tools share the iap_ prefix and follow a consistent verb_noun pattern: test_connection, get_version, show_command, analyze_wlan_security, list_targets. The naming is uniformly snake_case and predictable across both collection and single-resource operations.

Tool Count3/5

At 17 tools, the set is within the 16-25 range that feels heavy for a read-only monitoring/analysis surface. Each tool does have a distinct purpose, but the count is slightly more than necessary for the apparent scope.

Completeness5/5

The tool surface covers connectivity validation, version, swarm summary, AP inventory, clients, WLAN networks, port settings/status, logs, health summary, security analysis, and a raw show-command fallback. For a read-only Instant AP monitoring server, there are no obvious dead ends or missing operations.

Maintenance

ActivityMaintained
ResponsivenessSyncing