# Alcatel AOS8 MCP

> Alcatel Lucent Enterprise - OmniSwitch AOS8 MCP

- **Type:** MCP server
- **Install:** `agentstack add mcp-0xekho-alcatel-aos8-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [0xEkho](https://agentstack.voostack.com/s/0xekho)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [0xEkho](https://github.com/0xEkho)
- **Source:** https://github.com/0xEkho/Alcatel-AOS8-MCP

## Install

```sh
agentstack add mcp-0xekho-alcatel-aos8-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# ALE OmniSwitch AOS8 — MCP Server 🔌

An **MCP (Model Context Protocol) server** that exposes Alcatel-Lucent Enterprise OmniSwitch AOS8 network devices as AI-native tools.
Connect any MCP-compatible LLM client (Claude Desktop, OpenWebUI, Cursor…) to your network infrastructure and query, monitor, or troubleshoot your OmniSwitch fleet through natural language.

> **Target audience**: Network engineers and IT administrators who want to interact with AOS8 switches using AI assistants without leaving their workflow.

---

## ✨ Features

- **Dual HTTP transport** — `streamable-http` (recommended) and `SSE`, switchable via a single environment variable
- **SSH connectivity** — connects to OmniSwitch devices over SSH using [asyncssh](https://asyncssh.readthedocs.io/)
- **Multi-switch support** — target any switch by IP; credentials resolved per subnet zone or global fallback
- **Structured JSON output** — every tool returns a consistent, machine-readable JSON payload
- **Security middleware** — Bearer token authentication and IP allowlist (CIDR), enforced at the ASGI layer without buffering streaming responses
- **OpenWebUI compatible** — works out of the box as an MCP Tool Server in OpenWebUI
- **57 AOS8 tools** — one tool per AOS8 show/config command (VLANs, interfaces, spanning-tree, routing, MAC table, LLDP, system info…)
- **Write-guard by design** — no MCP tool can modify a switch configuration without prior human approval; `aos_poe_restart` has been removed in favor of `aos_poe_reboot_request` (Teams approval workflow)

---

## 🔧 Available Tools

### Core & Device Info

| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_system` | `show system` | System info (hostname, uptime, location) |
| `aos_show_microcode` | `show microcode` | Firmware version and package info |
| `aos_show_chassis` | `show chassis` | Chassis hardware details (model, serial, MAC) |
| `aos_show_running_directory` | `show running-directory` | CMM mode and config sync status |
| `aos_show_cmm` | `show cmm` | CMM module details |
| `aos_config_backup` | `write terminal` | Retrieve full running configuration |

### Ports & Interfaces

| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_interfaces_status` | `show interfaces status` | All ports speed/duplex/autoneg status |
| `aos_show_interfaces_alias` | `show interfaces alias` | Port descriptions/aliases and link state |
| `aos_show_interfaces_counters_errors` | `show interfaces counters errors` | Error counters per port |
| `aos_show_interfaces_ddm` | `show interfaces ddm` | SFP/XFP optical transceiver diagnostics |
| `aos_show_interfaces_port` | `show interfaces port ` | Detailed single port stats and counters |
| `aos_show_interfaces_flood_rate` | `show interfaces flood-rate` | Broadcast/multicast/unicast flood rate limits |
| `aos_show_lldp_remote_system` | `show lldp remote-system` | All LLDP neighbors |
| `aos_show_lldp_port` | `show lldp port  remote-system` | LLDP neighbor on specific port |

### VLAN

| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_vlan` | `show vlan` | All VLANs (type, admin/oper status, name) |
| `aos_show_vlan_members` | `show vlan members` | VLAN port membership and forwarding status |

### Spanning Tree

| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_spantree` | `show spantree` | STP instances overview |
| `aos_show_spantree_cist` | `show spantree cist` | CIST details (root bridge, cost, topology) |

### Health & MAC Learning

| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_health` | `show health` | CPU and memory usage (current + averages) |
| `aos_show_temp` | `show temp` | Temperature sensors status |
| `aos_show_fan` | `show fan` | Fan status |
| `aos_show_mac_learning` | `show mac-learning` | Full MAC learning table |
| `aos_show_mac_learning_port` | `show mac-learning port ` | MAC table for a specific port |

### Routing & L3

| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_ip_routes` | `show ip routes` | IP routing table (up to 500 entries, truncated if larger) |
| `aos_show_ip_interface` | `show ip interface` | IP interfaces (name, address, mask, status) |
| `aos_show_ip_ospf` | `show ip ospf` | OSPF global parameters and statistics |
| `aos_show_ip_ospf_neighbor` | `show ip ospf neighbor` | OSPF neighbor adjacencies |
| `aos_show_vrf` | `show vrf` | Virtual Routing and Forwarding instances |
| `aos_show_arp` | `show arp` | ARP table entries |

### PoE (Power over Ethernet)

| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_lanpower_slot` | `show lanpower slot ` | PoE status per slot (power, status, class) |
| `aos_show_lanpower_slot_port` | `show lanpower slot  port` | Detailed PoE config per port |
| ~~`aos_poe_restart`~~ | ~~`lanpower port  admin-state disable/enable`~~ | 🚫 **Removed** — replaced by `aos_poe_reboot_request` (Teams approval required) |
| `aos_poe_reboot_request` | Teams workflow + SSH | ✅ **Approved write** — PoE reboot after human approval |

### Diagnostics

| Tool | Command | Description |
|------|---------|-------------|
| `aos_ping` | `ping  count ` | Ping from switch to destination |
| `aos_show_log_swlog` | `show log swlog` | System log (swlog) — may timeout on busy switches |

### LACP / Link Aggregation

| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_linkagg` | `show linkagg` | Link aggregation groups |
| `aos_show_linkagg_port` | `show linkagg port` | Link aggregation port membership |

### NTP

| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_ntp_status` | `show ntp client` | NTP synchronization status and server reference |
| `aos_show_ntp_keys` | `show ntp keys` | NTP authentication keys |

### DHCP Relay

| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_ip_dhcp_relay` | `show ip dhcp relay` | DHCP relay configuration |
| `aos_show_ip_dhcp_relay_statistics` | `show ip dhcp relay statistics` | DHCP relay counters |

### Virtual Chassis
| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_vc_topology` | `show virtual-chassis topology` | VC members, roles, and MAC addresses |
| `aos_show_vc_consistency` | `show virtual-chassis consistency` | VC consistency check (type, group, VLANs, license) |
| `aos_show_vc_vf_link` | `show virtual-chassis vf-link` | Virtual Fabric Link status |

### Cloud Agent (OmniVista)
| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_cloud_agent_status` | `show cloud-agent status` | Cloud agent state, VPN, OmniVista tenant, certificate status |

### SNMP
| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_snmp_station` | `show snmp station` | SNMP trap stations (IP, port, protocol, user) |
| `aos_show_snmp_community_map` | `show snmp community-map` | SNMP community strings mapping |
| `aos_show_snmp_security` | `show snmp security` | SNMP security configuration |

### sFlow
| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_sflow_agent` | `show sflow agent` | sFlow agent IP and version |
| `aos_show_sflow_sampler` | `show sflow sampler` | sFlow sampling configuration per port |
| `aos_show_sflow_poller` | `show sflow poller` | sFlow polling configuration |
| `aos_show_sflow_receiver` | `show sflow receiver` | sFlow collector (receiver) configuration |

### QoS
| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_qos_config` | `show qos config` | QoS global configuration |

### UNP (Universal Network Profile)
| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_unp_port` | `show unp port` | UNP port configuration (802.1X, MAC auth, classification) |
| `aos_show_unp_user` | `show unp user` | Authenticated UNP users |
| `aos_show_unp_profile` | `show unp profile` | UNP profile definitions |
| `aos_show_unp_statistics` | `show unp statistics` | UNP authentication statistics |

### Port Security
| Tool | Command | Description |
|------|---------|-------------|
| `aos_show_port_security` | `show port-security` | Global port security status |
| `aos_show_port_security_brief` | `show port-security brief` | Port security summary per port |
| `aos_show_port_security_port` | `show port-security port ` | Port security detail for a specific port |

---

## 🚀 Quick Start

**Prerequisites**: [Python 3.10+](https://www.python.org/downloads/) and [uv](https://docs.astral.sh/uv/getting-started/installation/)

```bash
# 1. Clone the repository
git clone https://github.com/rpoulard-alcatel/Alcatel-AOS8-MCP.git
cd Alcatel-AOS8-MCP

# 2. Install dependencies (virtualenv created automatically)
uv sync

# 3. Configure your environment
cp .env.example .env
#    → Edit .env: set AOS_GLOBAL_USERNAME, AOS_GLOBAL_PASSWORD, MCP_API_KEY, etc.

# 4. Start the MCP server
uv run mcp-server
```

The server starts on `http://0.0.0.0:8080` by default (Streamable HTTP transport).

### 🐳 Docker (Production)

> **Prerequisites**: [Docker](https://docs.docker.com/get-docker/) with the Compose plugin (`docker compose`)

```bash
# 1. Copy and configure environment variables
cp .env.example .env
#    → Edit .env: set AOS_GLOBAL_USERNAME, AOS_GLOBAL_PASSWORD, MCP_API_KEY, MCP_HOST=0.0.0.0

# 2. (Optional) Prepare known_hosts for strict SSH host key checking
touch ./known_hosts
#    → Populate it, then set SSH_STRICT_HOST_KEY=true in .env

# 3. Build and start the container
docker compose up -d

# 4. Follow live logs
docker compose logs -f
```

The MCP endpoint is available at `http://:${MCP_PORT:-8080}/mcp`.

> **Important**: set `MCP_HOST=0.0.0.0` in `.env` so uvicorn binds on all interfaces inside the container.

---

## ⚙️ Configuration

Copy `.env.example` to `.env` and adjust the values. **Never commit `.env` to version control.**

### MCP Server

| Variable | Default | Description |
|---|---|---|
| `MCP_SERVER_NAME` | `alcatel-aos8-mcp` | Display name shown in MCP clients |
| `MCP_TRANSPORT` | `streamable-http` | Transport mode: `streamable-http`, `sse`, or `stdio` |
| `MCP_HOST` | `0.0.0.0` | Bind address (HTTP transports only) |
| `MCP_PORT` | `8080` | Listening port (HTTP transports only) |

### Security

| Variable | Default | Description |
|---|---|---|
| `MCP_API_KEY` | *(empty)* | Bearer token required in `Authorization: Bearer `. Leave empty to disable. |
| `MCP_ALLOWED_IPS` | `127.0.0.1/32,10.0.0.0/8,192.168.0.0/16` | Comma-separated CIDR allowlist. Leave empty to allow all IPs. |

### SSH — Switch Credentials

| Variable | Default | Description |
|---|---|---|
| `AOS_GLOBAL_USERNAME` | — | Default SSH username for all switches |
| `AOS_GLOBAL_PASSWORD` | — | Default SSH password for all switches |
| `AOS_ZONE{X}_USERNAME` | *(empty)* | Override username for switches on `10.X.0.0/16` |
| `AOS_ZONE{X}_PASSWORD` | *(empty)* | Override password for switches on `10.X.0.0/16` |

> **Zone-based credentials**: set `AOS_ZONE1_USERNAME` / `AOS_ZONE1_PASSWORD` to use different credentials for all switches on `10.1.0.0/16`. Add as many zones as needed (X = second octet of the target subnet).

### SSH Settings

| Variable | Default | Description |
|---|---|---|
| `SSH_STRICT_HOST_KEY` | `false` | Set to `true` in production and populate `SSH_KNOWN_HOSTS_FILE` |
| `SSH_KNOWN_HOSTS_FILE` | `./known_hosts` | Path to known_hosts (used when strict host key is enabled) |
| `SSH_CONNECT_TIMEOUT` | `10` | Connection timeout in seconds |
| `SSH_COMMAND_TIMEOUT` | `30` | Command execution timeout in seconds |

### Logging

| Variable | Default | Description |
|---|---|---|
| `LOG_LEVEL` | `INFO` | Verbosity: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` |

---

## 📁 Project Structure

```
Alcatel-AOS8-MCP/
├── src/
│   └── mcp_server/
│       ├── server.py          # Entry point: FastMCP init, transport, security middleware
│       ├── tools/             # MCP tools — one file per AOS8 command category
│       ├── resources/         # MCP resources — read-only context (switch inventory, docs)
│       ├── prompts/           # MCP prompts — reusable templates for network tasks
│       └── ssh/
│           ├── client.py      # asyncssh wrapper — connects and runs AOS8 commands
│           └── auth.py        # Credential resolver (global → zone fallback)
├── tests/
│   ├── test_tools.py
│   ├── test_resources.py
│   ├── test_prompts.py
│   └── test_ssh.py
├── .env.example               # All variables with inline documentation
├── pyproject.toml             # Project metadata and dependencies
├── AGENTS.md                  # Copilot agent instructions
└── LICENSE
```

---

## 🔒 Security Policy — WRITE Operations

### Absolute rule

> **No MCP tool may execute a configuration command on a switch without prior human approval.**

AOS8 switches are critical network equipment. A misrouted WRITE command can cause a production outage. The MCP server enforces a **strict separation** between read and write operations:

- **READ tools** — query the switch (`show ...`). Can be called directly by the AI.
- **WRITE tools** — modify switch configuration. **May never** be executed without explicit approval from a human engineer.

---

### `aos_poe_restart` — intentionally removed

The `aos_poe_restart` tool (direct command `lanpower port  admin-state disable/enable`) has been **intentionally removed** from the codebase.

Its replacement is `aos_poe_reboot_request` (module `poe_approval.py`), which enforces a human-in-the-loop approval workflow via Teams before any command is executed on the switch. See [⚡ PoE Approval Workflow (Teams)](#-poe-approval-workflow-teams) for the full flow.

---

### Convention for future WRITE operations

Any developer wishing to add a WRITE tool **MUST** follow these three rules:

1. **Implement an approval workflow** (Teams, e-mail, or equivalent mechanism) — the AI must never trigger a network change on its own initiative.
2. **Use `write_guard()` as a safety net** — if the tool is called without a workflow (design error), `write_guard()` blocks execution and returns an LLM-readable error message without raising an exception.
3. **Mention `_write_guard` in the tool's docstring** to indicate it has been audited.

```python
# ✅ Compliant pattern — WRITE tool with write_guard fallback
from mcp_server.tools._write_guard import write_guard

@mcp.tool()
async def my_write_tool(host: str, port: str) -> str:
    """Perform a WRITE operation after human approval.

    This tool goes through the Teams approval workflow. _write_guard audited.

    Args:
        host: IP address of the target switch.
        port: Port to modify (e.g. "1/1/3").
    """
    # If this code is reached without a workflow → block immediately
    return write_guard("my_write_tool")
```

---

### `_write_guard.py` — architectural reference

The module `src/mcp_server/tools/_write_guard.py` is the **architectural reference point** for all WRITE operations:

- Its module docstring states the full contract (WRITE rule, implementation convention, compliant example).
- The function `write_guard(tool_name: str) -> str` **always** returns a `str` and **never** raises an exception — in accordance with MCP best practices (business errors are returned, not propagated).
- The returned message guides the LLM toward the correct approval workflow (`aos_poe_reboot_request`).

---

### Regression tests — `tests/test_write_guard.py`

The file `tests/test_write_guard.py` is an **automated safety net**. It will fail immediately if someone re-introduces an unapproved WRITE tool:

| Monitored scenario | Concerned test |
|---|---|
| `aos_poe_restart` re-introduced in `poe.py` | `test_aos_poe_restart_absent_from_poe_module` |
| `aos_poe_restart` present on a multi-module instance | `test_aos_poe_restart_absent_from_combined_instance` |
| `aos_poe_reboot_request` removed from `poe_approval.py` | `test_aos_poe_reboot_request_present_in_

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [0xEkho](https://github.com/0xEkho)
- **Source:** [0xEkho/Alcatel-AOS8-MCP](https://github.com/0xEkho/Alcatel-AOS8-MCP)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-0xekho-alcatel-aos8-mcp
- Seller: https://agentstack.voostack.com/s/0xekho
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
