MCP Galaxy / Directory / Arista CloudVision
Network Assurance Read-Only Docker / Podman

Arista CloudVision

Query an Arista CloudVision instance (CVaaS or on-prem CVP) through the modern state-based Resource APIs. Stdio over Docker or Podman.

Runtime
Docker / Podman
Transport
stdio
API
CloudVision Resource APIs
Overview

What This Server Does

Arista CloudVision exposes a curated set of GET-only tools that wrap Arista CloudVision's state-based Resource APIs. There is one shared HTTP helper, it only issues GETs, and no POST, PUT, PATCH, or DELETE code path exists anywhere in server.py.

The server is pinned to a single CloudVision cluster at startup via CVP_HOST, no tool accepts a host parameter, so your AI client (Claude, Gemini, Codex …) can't pivot to a different instance the token might also reach. Path segments are hard-coded per tool; free-form values like device IDs, MAC addresses, and label names are regex-allowlisted before they reach a query parameter.

Ships as both a Docker and a Podman container, pick whichever runtime you already run.

Try Asking

What to Ask, in Plain English

A handful of real questions you can put to your AI client once this server is wired in. The model figures out which tools to call, you describe the outcome.

  • "Which switches reach end-of-support this year, and which have known CVE exposure on top of that?"
  • "What change controls ran this week, who approved them, and which ones touched core devices?"
  • "Are any devices out of image compliance or config compliance right now?"
  • "Find the endpoint with MAC aa:bb:cc:dd:ee:ff and tell me which port it's connected to."
  • "Show critical events from the last hour and group them by device."
  • "Who changed what in CloudVision in the last 24 hours?"
Capabilities

27 Read-Only Tools Across the Resource APIs

A
Inventory
Device inventory (hostname, FQDN, model, EOS version, MAC, streaming status); one-device lookup by serial.
B
Tags
Tag definitions, tag-to-element assignments, all tags on a single device, tag.v2 surface.
C
Events & Alerts
Time-windowed events with severity / type / device filters, one event by key, alerts with severity filter.
D
Configlets
Configlet inventory, one configlet by id (including body), and the configlet → device/container assignment map.
E
Change Controls, Workspaces, Studios
Change controls with task tree and approval state, workspace build/submit state, studios per workspace.
F
Compliance & Lifecycle
Running vs. designed config diffs, per-device image compliance, hardware/software EoL/EoS, bug & CVE exposure.
G
Operations & Audit
Connectivity-monitor probe stats, endpoint location by MAC/IP, license assignments, audit log, service-account state.

Every list tool takes max_results (hard ceiling 50) and verbose (full records instead of projected summaries). Time-windowed tools take since_seconds. Oversized responses come back as a truncation envelope with a hint on how to narrow the query, so a single tool call never blows the context window. A visible attempt_write_operation stub sits in the catalog as model-visible proof of the read-only contract, it performs no I/O and refuses.

Installation

Build & Configure

Two supported runtimes, pick the one you already run. The docker/ and podman/ backends ship byte-identical server.py; only the container file and how credentials reach it differ. Expand your runtime below.

New to the Docker MCP Gateway? The Docker pane below uses a catalog → registry → gateway flow with three bind-mounts. If any of that terminology is unfamiliar, skim Docker MCP Gateway under Good to Know first, it walks through the architecture these steps build on. The Podman pane runs the container directly and doesn't depend on the gateway.
Step 0, Generate a service-account token (out of band)

In the CloudVision UI under Settings → Access Control → Service Accounts (CVaaS) or Settings → Service Accounts (on-prem), create a dedicated account (e.g. mcp-readonly) bound to the most restrictive read-only role available, network-operator, not network-admin. Generate a token with a finite expiry, copy it once, and treat it like a password. Don't paste it into chat with your AI client.

Read-only is not the same as harmless. Audit logs reveal who changed what; configlets and config diffs can contain SNMP communities, RADIUS/TACACS server addresses, and ACL structure. Scope the role accordingly.
Docker Docker Desktop · MCP Gateway
Step 1, Get the project files

Clone the repository. The Docker backend lives in docker/ and ships a custom-catalog.yaml alongside the Dockerfile.

Clone
$ git clone https://github.com/rosarion97/cloudvision-readonly-mcp-server-public.git
$ cd cloudvision-readonly-mcp-server-public/docker
Step 2, Build the image

The image tag must match the image: field in custom-catalog.yaml (cloudvision-readonly-mcp:latest).

Build
$ docker build -t cloudvision-readonly-mcp:latest .
Step 3, Provide secrets

Two required values, CVP_HOST and CVP_TOKEN; three optional ones for tuning (CVP_PORT defaults to 443, set 8443 for many on-prem clusters; CVP_VERIFY_SSL defaults to true; CVP_MAX_RESPONSE_BYTES defaults to 120000).

Option A, Docker MCP secret store (recommended). Each value lives in Docker Desktop's encrypted store; the gateway injects them as env vars at launch and they never appear in your client's config file. With Option A, continue through Steps 4–7.

Option A, MCP Toolkit secret
$ docker mcp secret set CVP_HOST="www.arista.io"
$ docker mcp secret set CVP_TOKEN="<your-token-here>"
$ docker mcp secret set CVP_PORT="443"          # 8443 for many on-prem clusters
$ docker mcp secret set CVP_VERIFY_SSL="true"
$ docker mcp secret list   # values are masked
Option B writes your token to disk in clear text. Use it only for local testing, chmod 600 .env, never commit it. This path skips the gateway: skip Steps 4–6, point your client straight at docker run --env-file (below), then jump to Step 7.
Option B, .env file (fallback)
$ cp .env.example .env
$ chmod 600 .env   # then set CVP_HOST and CVP_TOKEN
claude_desktop_config.json (Option B)
{
  "mcpServers": {
    "cloudvision-readonly": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "--env-file", "/absolute/path/to/docker/.env",
        "cloudvision-readonly-mcp:latest"
      ]
    }
  }
}
Step 4, Install the custom catalog

Steps 4–6 are the Option A (secret store) path. Used Option B? Skip to Step 7.

Catalog
$ mkdir -p ~/.docker/mcp/catalogs
$ cp custom-catalog.yaml ~/.docker/mcp/catalogs/custom.yaml

Already have a custom.yaml from another MCP Galaxy server? Merge the cloudvision-readonly: entry into your existing file under the single registry: key, don't overwrite it.

Step 5, Enable the server in the registry

Add the entry under the single top-level registry: key in ~/.docker/mcp/registry.yaml. Don't overwrite the file if it already exists.

~/.docker/mcp/registry.yaml
registry:
  cloudvision-readonly:
    catalog: custom
    enabled: true
Step 6, Point Claude Desktop at the gateway

Add the gateway block to claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json). The gateway spawns the CloudVision image on demand, reads your catalog and registry, and resolves your CVP_* secrets at request time. Replace <your-username> with your macOS username (run whoami to check):

claude_desktop_config.json, gateway block
{
  "mcpServers": {
    "mcp-toolkit-gateway": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-v", "/var/run/docker.sock:/var/run/docker.sock",
        "-v", "/Users/<your-username>/.docker/mcp:/mcp",
        "-v", "/Users/<your-username>/Library/Caches/docker-secrets-engine/engine.sock:/root/.cache/docker-secrets-engine/engine.sock",
        "docker/mcp-gateway:latest",
        "--catalog=/mcp/catalogs/custom.yaml",
        "--registry=/mcp/registry.yaml",
        "--transport=stdio"
      ]
    }
  }
}

All three bind-mounts are required: the Docker socket lets the gateway spawn the server container; ~/.docker/mcp is where it reads your catalog and registry; the docker-secrets-engine socket is the resolver Docker Desktop exposes for the secret store, without it your CVP_* values resolve to empty strings and the server never starts. On Linux Docker Desktop the path is ~/.docker/desktop/secrets-engine/engine.sock; find it with find ~ -name engine.sock.

Works the same for other clients. Claude Code takes the same args via claude mcp add -s user mcp-toolkit-gateway -- docker run …; Codex reads the same shape from ~/.codex/config.toml as [mcp_servers.mcp-toolkit-gateway]. Any MCP-capable client, Google's Gemini included, reads an mcpServers block from its own settings file; only the location changes, the entry is identical.

Then quit and reopen the client. claude_desktop_config.json never contains CVP_TOKEN, the gateway resolves it from Docker's secret store at request time. As a shortcut, docker mcp client connect claude-desktop (or MCP Toolkit → Clients in Docker Desktop) writes a similar block automatically; the explicit JSON above survives Docker Desktop updates that may rewrite the auto-managed entry.

Step 7, Verify
Verify
$ docker mcp server list   # cloudvision-readonly → enabled
$ docker mcp tools list

Or run the image directly, it logs a startup line to stderr and waits silently on stdin (correct for an MCP stdio server). Press Ctrl+C to exit; a missing required env var fails fast on stderr.

Smoke test (Option B)
$ docker run --rm -i --env-file /absolute/path/to/.env cloudvision-readonly-mcp:latest
Podman Rootless · stdio
Step 1, Get the project files

Clone the repository. The Podman backend lives in podman/.

Clone
$ git clone https://github.com/rosarion97/cloudvision-readonly-mcp-server-public.git
$ cd cloudvision-readonly-mcp-server-public/podman
Step 2, Build the image

On macOS / Windows, start a Podman machine first (podman machine init && podman machine start); Linux runs natively. Podman 4.4+ is required for the --secret type=env flag below.

Build
$ podman build -t cloudvision-readonly-mcp:latest -f Containerfile .
Step 3, Provide credentials

Two required values (CVP_HOST, CVP_TOKEN) plus optional tuning (CVP_PORT, CVP_VERIFY_SSL, CVP_MAX_RESPONSE_BYTES). Option 1 keeps them in Podman's encrypted secret store and is recommended; Option 2 writes a plaintext .env.

Option 1, podman secret (recommended)
$ printf '%s' 'www.arista.io'     | podman secret create CVP_HOST -
$ printf '%s' '<your-token-here>' | podman secret create CVP_TOKEN -
$ printf '%s' '443'               | podman secret create CVP_PORT -
$ printf '%s' 'true'              | podman secret create CVP_VERIFY_SSL -
$ podman secret ls   # confirm; values not shown

printf '%s' (no \n) avoids a trailing newline in the secret value, a stray newline in CVP_HOST produces "Could not connect" errors that are tedious to debug.

Option 2 writes your token to disk in clear text. Use it only for local testing or on Podman older than 4.4, chmod 600 .env, never commit it (it's gitignored).
Option 2, .env file (fallback)
$ cp .env.example .env
$ chmod 600 .env   # then set CVP_HOST and CVP_TOKEN
Step 4, Configure your AI client

Add the entry matching your Step 3 choice. Option 1 injects each secret with --secret NAME,type=env; Option 2 reads them from your .env.

claude_desktop_config.json, Option 1 (secret store)
{
  "mcpServers": {
    "cloudvision-readonly": {
      "command": "podman",
      "args": [
        "run", "-i", "--rm",
        "--secret", "CVP_HOST,type=env",
        "--secret", "CVP_TOKEN,type=env",
        "--secret", "CVP_PORT,type=env",
        "--secret", "CVP_VERIFY_SSL,type=env",
        "cloudvision-readonly-mcp:latest"
      ]
    }
  }
}
claude_desktop_config.json, Option 2 (.env)
{
  "mcpServers": {
    "cloudvision-readonly": {
      "command": "podman",
      "args": [
        "run", "-i", "--rm",
        "--env-file", "/absolute/path/to/podman/.env",
        "cloudvision-readonly-mcp:latest"
      ]
    }
  }
}
Works the same for other assistants. Any MCP-capable client reads an mcpServers block from its own settings.json, Google's Gemini included. Drop this same entry into that client's settings.json and the CloudVision tools appear there too. Only the file's name and location change; the server entry is identical.

If podman isn't on Claude Desktop's PATH (common on macOS, where GUI apps don't inherit your shell's PATH), use the absolute path to the binary, usually /opt/homebrew/bin/podman (Apple Silicon Homebrew) or /usr/local/bin/podman (Intel Homebrew).

Step 5, Verify

Run the image manually, it starts and waits on stdin. Press Ctrl+C to exit; a missing required env var fails fast on stderr.

Smoke test
$ podman run --rm -i \
    --secret CVP_HOST,type=env \
    --secret CVP_TOKEN,type=env \
    --secret CVP_PORT,type=env \
    --secret CVP_VERIFY_SSL,type=env \
    cloudvision-readonly-mcp:latest

One container serves one CloudVision cluster, run a second container with its own credentials to serve another. --rm cleans up the container after each session.

Configuration

Five Variables

  • CVP_HOST, required. CloudVision hostname only, no scheme or path. CVaaS uses something like www.arista.io or a regional cluster; on-prem CVP uses the cluster's DNS name. Pins this instance to one cluster.
  • CVP_TOKEN, required. Service-account bearer token (Step 0). Generate it once in the CloudVision UI; the server never mints tokens itself.
  • CVP_PORT, optional. HTTPS port; 443 for CVaaS, often 8443 for on-prem CVP clusters.
  • CVP_VERIFY_SSL, optional. Defaults to true. Set false only for self-signed lab certs, and only if you accept the risk.
  • CVP_MAX_RESPONSE_BYTES, optional. Caps the JSON size of any one tool response. Default 120000 (~30k tokens). Oversize responses come back as a truncation envelope with a hint on how to narrow.
Requirements

Before You Start

  • Docker Engine 24+ / Docker Desktop 4.27+ (MCP Toolkit for the secret-store path), or Podman 4.4+ on $PATH. Pick one; the step-by-step for each is above.
  • Arista CloudVision, CVaaS, or on-prem CVP 2021.2.0+ with the Resource APIs enabled. The legacy /cvpservice/*.do REST surface is never used.
  • A CloudVision service account with a read-only role (e.g. network-operator) and a generated access token with a finite expiry.
  • An MCP-capable client, Claude Desktop, Claude Code, Gemini CLI, Codex, or any client speaking MCP over stdio.
License & Policy

Read-Only by Construction

Provided as-is for integrating Arista CloudVision with MCP clients. Use at your own risk. Not affiliated with or endorsed by Arista Networks. Every data query is an HTTPS GET through one shared helper; no POST, PUT, PATCH, or DELETE code path exists, and no read-write *Config resource is ever addressed. Read-only is not the same as harmless, audit logs, configlets, and running configs can contain sensitive operational data. Scope the service-account role accordingly.