Skip to main content
ClaudeWave

MCP server for Cisco Catalyst SD-WAN Manager (vManage). Read-only by default: fabric inventory, device health, control connections, BFD/OMP state, alarms, tunnel path quality, templates and policies as MCP tools for Claude and other AI assistants.

MCP ServersOfficial Registry0 stars0 forksPythonMITUpdated today
Install in Claude Code / Claude Desktop
Method: UVX (Python) · cisco-sdwan-mcp
Claude Code CLI
claude mcp add cisco-sdwan-mcp -- uvx cisco-sdwan-mcp
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "cisco-sdwan-mcp": {
      "command": "uvx",
      "args": ["cisco-sdwan-mcp"],
      "env": {
        "SDWAN_VMANAGE_URL": "<sdwan_vmanage_url>",
        "SDWAN_USERNAME": "<sdwan_username>",
        "SDWAN_PASSWORD": "<sdwan_password>"
      }
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Detected environment variables
SDWAN_VMANAGE_URLSDWAN_USERNAMESDWAN_PASSWORD
Use cases

MCP Servers overview

# Cisco SD-WAN MCP Server

<!-- mcp-name: io.github.pcDamasceno/cisco-sdwan-mcp -->

[![PyPI](https://img.shields.io/pypi/v/cisco-sdwan-mcp)](https://pypi.org/project/cisco-sdwan-mcp/)
[![Python](https://img.shields.io/pypi/pyversions/cisco-sdwan-mcp)](https://pypi.org/project/cisco-sdwan-mcp/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-cisco--sdwan--mcp-6E56CF)](https://registry.modelcontextprotocol.io/v0/servers?search=cisco-sdwan-mcp)

`cisco-sdwan-mcp` is an [MCP](https://modelcontextprotocol.io) server for
**Cisco Catalyst SD-WAN Manager (vManage)**, built with
[FastMCP](https://github.com/jlowin/fastmcp).

It gives an LLM client a working view of your SD-WAN fabric — inventory,
device health, control and data plane state, alarms, path quality, templates
and policies — so you can ask "why is the Frankfurt branch down?" and get an
answer backed by real controller data instead of a guess.

**Read-only by default.** The configuration-changing tools are not registered
unless you explicitly enable them, and even then every call requires a human to
approve it.

---

## Contents

- [What you get](#what-you-get)
- [Quickstart](#quickstart)
- [Configuration](#configuration)
- [Write protection](#write-protection)
- [Tool reference](#tool-reference)
- [Prompts](#prompts)
- [Resources](#resources)
- [Connecting an MCP client](#connecting-an-mcp-client)
- [Transports](#transports-http-vs-stdio)
- [Authenticating MCP clients](#authenticating-mcp-clients)
- [Docker](#docker)
- [Deploying](#deploying)
- [Adding your own tools](#adding-your-own-tools)
- [Testing](#testing)
- [Troubleshooting](#troubleshooting)
- [Project structure](#project-structure)

---

## What you get

| Area | Tools |
|---|---|
| **Inventory** | `list_devices`, `get_device`, `get_fabric_summary`, `list_inventory` |
| **Device health** | `check_device_health`, `get_system_status`, `get_control_connections`, `get_bfd_sessions`, `get_omp_peers`, `get_interfaces` |
| **Alarms & events** | `get_alarm_summary`, `list_alarms`, `list_events` |
| **Path quality** | `find_degraded_tunnels`, `get_tunnel_statistics`, `get_interface_statistics` |
| **Templates & policy** | `list_device_templates`, `get_device_template`, `list_feature_templates`, `list_policies`, `get_template_input_variables` |
| **Configuration** *(opt-in)* | `attach_device_template`, `activate_vsmart_policy`, `get_task_status` |

Plus four workflow [prompts](#prompts) and three [resources](#resources).

Three design decisions are worth knowing up front, because they shape every
tool:

- **Responses are projected, not dumped.** A vManage device record carries 60+
  fields; a 200-device fabric would bury a model's context. Each tool returns
  the fields that answer the question and accepts `detailed=true` when you want
  everything.
- **Counts always accompany results.** Every list reports `count` (what
  matched) alongside `returned` (what you got), so "3 devices are down" is
  never confused with "3 devices are down in the first 100 I looked at".
- **Failures come back as answers.** A wrong password, an unreachable
  controller or an unknown hostname returns a readable message — often with the
  valid options — rather than raising. The model can then correct itself or
  tell you exactly what to fix.

---

## Quickstart

### Prerequisites

- Python 3.11+
- [uv](https://docs.astral.sh/uv/) (recommended) **or** pip
- A reachable Cisco Catalyst SD-WAN Manager (vManage) and an account on it

> **Make a dedicated vManage account.** Give it a read-only role to start.
> The account's privileges are the real security boundary — see
> [Write protection](#write-protection).

### Install

From PyPI, if you only want to run it:

```bash
uvx cisco-sdwan-mcp        # no install, run it straight
pip install cisco-sdwan-mcp
```

From a checkout, if you want to change it:

```bash
git clone https://github.com/pcDamasceno/cisco-sdwan-mcp.git
cd cisco-sdwan-mcp

# with uv (recommended)
uv sync --extra dev

# with pip
pip install -e ".[dev]"
```

### Configure

```bash
cp .env.example .env
```

The three settings you must fill in:

```bash
SDWAN_VMANAGE_URL=https://vmanage.example.com:8443
SDWAN_USERNAME=automation-readonly
SDWAN_PASSWORD=...
```

The server reads `.env` from the repository root at startup — set
`SDWAN_ENV_FILE` to load a different file. Variables already present in the
environment (compose `env_file`, Kubernetes secrets) are never overwritten by
it, and the startup log names the file it used.

### Run

```bash
uv run python -m cisco_sdwan_mcp.server        # or: python -m cisco_sdwan_mcp.server
```

The server starts over **HTTP** on `0.0.0.0:8000`. The MCP endpoint is at
`http://localhost:8000/mcp`, a health probe at `http://localhost:8000/healthz`,
and this README at `http://localhost:8000/`.

Startup logs confirm what it will talk to before any client connects:

```
INFO  cisco_sdwan_mcp.server: vManage controller: vmanage.example.com:8443 (user automation-readonly, TLS verify: True)
INFO  cisco_sdwan_mcp.server: Write tools: disabled (read-only)
```

### First call

Point an MCP client at it (see [Connecting an MCP client](#connecting-an-mcp-client))
and ask for `get_fabric_summary`. It is one round trip and exercises
authentication, TLS and reachability at once:

```json
{
  "total_devices": 42,
  "by_type": {"vedge": 38, "vsmart": 2, "vbond": 1, "vmanage": 1},
  "by_reachability": {"reachable": 40, "unreachable": 2},
  "unreachable_count": 2,
  "unreachable_devices": [{"host-name": "BR2-EDGE1", "system-ip": "10.0.0.12", "site-id": "1002"}]
}
```

---

## Configuration

Everything is environment-driven; `.env.example` is the annotated reference.

### vManage connection

| Variable | Default | Description |
|---|---|---|
| `SDWAN_VMANAGE_URL` | — | Controller URL, e.g. `https://vmanage.example.com:8443`. **Required** (or use `SDWAN_VMANAGE_HOST`) |
| `SDWAN_VMANAGE_HOST` | — | Hostname instead of a full URL |
| `SDWAN_VMANAGE_PORT` | `443` | Port, when using `SDWAN_VMANAGE_HOST` |
| `SDWAN_USERNAME` | — | vManage username. **Required** |
| `SDWAN_PASSWORD` | — | vManage password. **Required** |
| `SDWAN_VERIFY_SSL` | `true` | TLS certificate verification |
| `SDWAN_CA_BUNDLE` | — | Path to a CA bundle — the right answer for a private CA |
| `SDWAN_TIMEOUT` | `60` | Seconds to wait for vManage |
| `SDWAN_PAGE_SIZE` | `100` | Default cap on records per tool call |
| `SDWAN_ENABLE_WRITES` | `false` | Register the configuration tools — see below |

### Server

| Variable | Default | Description |
|---|---|---|
| `MCP_SERVER_NAME` | `cisco-sdwan-mcp` | Name advertised to MCP clients |
| `MCP_TRANSPORT` | `http` | `http` or `stdio` |
| `MCP_HOST` | `0.0.0.0` | Bind address (HTTP only) |
| `MCP_PORT` | `8000` | Bind port (HTTP only) |
| `MCP_AUTH` | `none` | How MCP *clients* authenticate to this server |
| `LOG_LEVEL` | `INFO` | Python log level |

> `SDWAN_USERNAME`/`SDWAN_PASSWORD` authenticate **this server to vManage**.
> `MCP_AUTH` governs how **clients authenticate to this server**. They are
> unrelated, and you generally want both.

### TLS

vManage very often presents a self-signed or private-CA certificate. In
descending order of preference:

1. Point `SDWAN_CA_BUNDLE` at the controller's CA — verification stays on.
2. Add the CA to `certificates/`, which the Docker build installs into the
   container trust store automatically.
3. Only as a last resort, on a lab you control, set `SDWAN_VERIFY_SSL=false`.
   The server logs a warning naming the host each time it does this, because
   it means anything on the path can read the credentials.

---

## Write protection

The tools that change configuration are gated twice.

**Gate 1 — registration.** With `SDWAN_ENABLE_WRITES` unset or `false`, the
module holding them is never imported. They do not appear in the tool list, so
a model cannot call them by mistake, misinterpretation or prompt injection.
The server is read-only by construction, not by policy.

**Gate 2 — confirmation.** With writes enabled, each call still asks the user
through MCP elicitation, naming the template or policy and the devices
affected, before anything reaches vManage. Clients that do not implement
elicitation cannot silently proceed — the call is refused unless the caller
passes `confirm=true`, which puts the decision in a human's hands either way.

```bash
SDWAN_ENABLE_WRITES=true uv run python -m cisco_sdwan_mcp.server
```

```
WARNING cisco_sdwan_mcp.tools: SDWAN_ENABLE_WRITES=true — configuration-changing tools are registered.
                   Each one still requires explicit user confirmation before it runs.
```

> **The vManage account is the real boundary.** `SDWAN_ENABLE_WRITES` controls
> which tools exist in *this* server; it does nothing about what the account
> can do through any other path. If a change must be impossible, use a
> read-only vManage role — do not rely on this flag alone.

vManage applies configuration asynchronously: a write returns a `task_id`,
meaning *accepted*, not *applied*. Poll `get_task_status(task_id)` until it
reports done.

The intended flow for a template push, with a review step in the middle:

```
list_device_templates          → find the template
get_device_template            → see what it configures and who has it
get_template_input_variables   → the exact per-device values (read-only preview)
check_device_health            → never push to an already-broken device
attach_device_template         → asks for approval, returns a task_id
get_task_status                → confirm it actually landed
```

---

## Tool reference

Every tool takes `limit` (cap on records) and most take `detailed` (return all
vManage fields instead of the summary set).

### Inventory

| Tool | What it answers |
|---|---|
| `get_fabric_summary()` | Device counts by type, reachability and version, plus every unreachable device. **Start here** for open questions
ai-agentscatalyst-sdwanciscoclaudefastmcpmcpmcp-servermodel-context-protocolnetopsnetwork-automationpythonsd-wansdwanvmanage

What people ask about cisco-sdwan-mcp

What is pcDamasceno/cisco-sdwan-mcp?

+

pcDamasceno/cisco-sdwan-mcp is mcp servers for the Claude AI ecosystem. MCP server for Cisco Catalyst SD-WAN Manager (vManage). Read-only by default: fabric inventory, device health, control connections, BFD/OMP state, alarms, tunnel path quality, templates and policies as MCP tools for Claude and other AI assistants. It has 0 GitHub stars and was last updated today.

How do I install cisco-sdwan-mcp?

+

You can install cisco-sdwan-mcp by cloning the repository (https://github.com/pcDamasceno/cisco-sdwan-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is pcDamasceno/cisco-sdwan-mcp safe to use?

+

pcDamasceno/cisco-sdwan-mcp has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.

Who maintains pcDamasceno/cisco-sdwan-mcp?

+

pcDamasceno/cisco-sdwan-mcp is maintained by pcDamasceno. The last recorded GitHub activity is from today, with 0 open issues.

Are there alternatives to cisco-sdwan-mcp?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy cisco-sdwan-mcp to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: pcDamasceno/cisco-sdwan-mcp
[![Featured on ClaudeWave](https://claudewave.com/api/badge/pcdamasceno-cisco-sdwan-mcp)](https://claudewave.com/repo/pcdamasceno-cisco-sdwan-mcp)
<a href="https://claudewave.com/repo/pcdamasceno-cisco-sdwan-mcp"><img src="https://claudewave.com/api/badge/pcdamasceno-cisco-sdwan-mcp" alt="Featured on ClaudeWave: pcDamasceno/cisco-sdwan-mcp" width="320" height="64" /></a>

More MCP Servers

cisco-sdwan-mcp alternatives