Skip to main content
Glama
README.md
# vyos-mcp

An MCP server for managing [VyOS](https://vyos.io) appliances over their HTTP API. It exposes
tools for the config verbs (show / set / delete), the config lifecycle (commit-confirm / revert /
save), operational `show` commands and log retrieval/search, plus two guided "skill" prompts for
traffic analysis and interactive troubleshooting.

Transport is **streamable HTTP only**.

## How it works

VyOS exposes a REST API where every call is a POST of a multipart form with a `data` JSON op
descriptor and a per-appliance `key`. This server wraps that API behind well-described MCP tools,
selecting the target appliance by name from a YAML inventory.

API reference: <https://docs.vyos.io/en/latest/automation/vyos-api.html>

### Commit model (important)

VyOS's `/configure` endpoint **commits immediately** — there is no separate commit step. To get a
safe, revertible edit:

1. `set_config` / `delete_config` with `confirm_minutes` > 0 — applies a **commit-confirm**; the
   change auto-reverts after that many minutes unless confirmed.
2. Verify with `show_config` / `run_show`.
3. `confirm_commit` — keep the change.
4. `save_config` — persist to boot config.

`revert_config` reloads the last saved config (`/config/config.boot`), discarding unsaved running
changes.

## Tools

| Tool | Purpose |
|---|---|
| `list_appliances` | List managed appliances (no keys) |
| `show_config` | Read config (`showConfig` / `exists` / `returnValue` / `returnValues`) |
| `list_options` | List the configured child nodes under a path (explore the tree to build set/delete paths) |
| `set_config` | Apply `set` commands (single or batch), optional commit-confirm |
| `delete_config` | Apply `delete` commands (single or batch), optional commit-confirm |
| `confirm_commit` | Finalize a pending commit-confirm |
| `revert_config` | Reload the last saved config |
| `save_config` | Persist running config to boot |
| `run_show` | Run an operational `show` command |
| `get_logs` | Retrieve / regex-search system logs with tail |
| `command_help` | Look up the bundled VyOS command schema at a path (help, value formats, allowed values, constraints, child options) |
| `search_commands` | Search the bundled command schema by keyword to find where a feature lives |

## Command schema (offline "help" for the model)

The VyOS HTTP API has no command-completion endpoint, so `list_options` can only show what is
*currently configured*. To give the model the full command tree — what *can* be set or run, with
help text, value formats, allowed values and constraints — this server bundles a compiled schema
generated from VyOS's own XML interface/op-mode definitions.

- **`command_help`** — at a path, returns the node's help plus its child options (config tree via
  `mode: configure`, or the `show`/operational tree via `mode: operational`). This is how the model
  discovers the exact tokens for a `set_config` / `run_show` call.
- **`search_commands`** — keyword search across the tree ("where does NAT live?").

Bundled versions (last 3 stable releases) live in `data/` and are selected per appliance via the
optional `version` field (`1.3`, `1.4`, `1.5`; defaults to newest). Both tools also accept an
explicit `version`.

Regenerate the bundled schemas (e.g. when a new VyOS release ships) with:

```bash
npm run build:schema   # downloads the pinned branches and rewrites data/vyos-*.json
```

Edit the `VERSIONS` list in `scripts/build-schema.mjs` to change which releases are bundled.

> The schema is a pinned snapshot. If an appliance runs a version not bundled, set its `version` to
> the closest bundled one; dynamic completions (values generated on the box) are shown as hints
> rather than concrete value lists.

## Prompts (skills)

- `traffic_analysis(appliance, interface?, focus?)`
- `troubleshoot(appliance, symptom)` — interactive; asks you to run tests and correlates results.

## Setup

```bash
npm install
npm run build
```

### Enable the API on each VyOS appliance

```
set service https api keys id mcp key '<PLAINTEXT-KEY>'
set service https api
commit ; save
```

### Configure the inventory

Copy the example and edit it:

```bash
cp appliances.example.yaml appliances.yaml
```

```yaml
appliances:
  - name: edge-fw
    host: 10.0.0.1
    port: 443            # default 443
    verify_ssl: false    # default true; opt out per appliance for self-signed certs
    api_key: ${EDGE_FW_KEY}   # literal, or ${ENV_VAR} reference
    description: "Branch edge firewall"
```

API keys may be `${ENV_VAR}` references so secrets stay out of the file. Referenced vars must be
set when the server starts. The config path defaults to `./appliances.yaml`; override with
`VYOS_MCP_CONFIG`.

> **TLS:** `verify_ssl` defaults to **`true`** (secure by default). Because VyOS ships a
> self-signed certificate, verification will fail until you install a properly-issued certificate
> or add the appliance CA to the host trust store. You can set `verify_ssl: false` per appliance to
> skip verification, but that exposes the connection to man-in-the-middle attacks — only do so on a
> trusted network.

### Run

```bash
export EDGE_FW_KEY=...     # any env vars referenced by appliances.yaml
npm start                  # or: npm run dev
```

Server listens on `http://localhost:3000/mcp` (`PORT`, `VYOS_MCP_PATH` configurable). Health check
at `GET /health`.

> The MCP endpoint itself is unauthenticated. Bind it to localhost or a trusted network, or front
> it with a reverse proxy that adds auth.

## Connect from Claude Code

```bash
claude mcp add --transport http vyos http://localhost:3000/mcp
```

## Smoke test with the MCP Inspector

```bash
# List tools
npx @modelcontextprotocol/inspector --cli http://localhost:3000/mcp \
  --transport http --method tools/list

# List appliances
npx @modelcontextprotocol/inspector --cli http://localhost:3000/mcp \
  --transport http --method tools/call --tool-name list_appliances

# Read config
npx @modelcontextprotocol/inspector --cli http://localhost:3000/mcp \
  --transport http --method tools/call --tool-name show_config \
  --tool-arg appliance=edge-fw --tool-arg 'path=["interfaces"]'

# List prompts
npx @modelcontextprotocol/inspector --cli http://localhost:3000/mcp \
  --transport http --method prompts/list
```

## Not included

The VyOS `/generate`, `/reset`, `/renew`, `/reboot`, `/poweroff`, `/image` and `/traceroute`
endpoints are not wrapped yet — they follow the same pattern in `src/tools.ts` if you need them.