Skip to main content
Glama
edutacara

network-mcp-server

by edutacara
README.md
# network-mcp-server

**MCP server for network operations** — lets AI assistants (Claude Code,
Claude Desktop, or any [Model Context Protocol](https://modelcontextprotocol.io)
client) talk to your Cisco/Juniper network through safe, well-defined tools.

> *"Is rtr-core-01 compliant?"* → the assistant calls `run_compliance_audit`,
> reads the findings and explains which rules failed — no copy-pasting
> configs into a chat.

Built on the official MCP Python SDK (FastMCP) with the domain logic from
[`python-netops-tools`](../python-netops-tools) — the same engine behind the
`netops` CLI and the [`network-api-portal`](../network-api-portal) REST API.

## Tools exposed

| Tool | Network access | What it does |
|------|----------------|--------------|
| `list_devices` | none | Devices from the YAML inventory (name, IP, platform) |
| `list_backups` | none | Saved config backups with timestamps |
| `get_device_config` | none | Content of a device's most recent backup |
| `run_compliance_audit` | none | Audits the latest backups against the YAML rules |
| `backup_device` | **SSH to device** | Pulls and saves the running config (the only write-path tool) |

The split is deliberate: four read-only tools the assistant can call freely,
and one clearly-documented tool that touches the network — MCP clients ask
for user approval per tool, so risky actions stay visible.

## Installation

```bash
python3 -m venv .venv && source .venv/bin/activate
pip install -e ../python-netops-tools   # domain logic (or its git URL)
pip install -e ".[dev]"
```

## Hooking it up to Claude Code

```bash
claude mcp add network-ops \
  --env NETMCP_INVENTORY=/path/to/devices.yml \
  --env NETMCP_RULES=/path/to/rules.yml \
  --env NETMCP_BACKUP_DIR=/path/to/backups \
  --env NETOPS_USER=admin \
  --env NETOPS_PASSWORD=your-password \
  -- /path/to/network-mcp-server/.venv/bin/network-mcp
```

Then just ask: *"list my network devices"*, *"run a compliance audit"*,
*"show me the config of mx-edge-01"*.

## Hooking it up to Claude Desktop

`claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "network-ops": {
      "command": "/path/to/network-mcp-server/.venv/bin/network-mcp",
      "env": {
        "NETMCP_INVENTORY": "/path/to/devices.yml",
        "NETMCP_RULES": "/path/to/rules.yml",
        "NETMCP_BACKUP_DIR": "/path/to/backups",
        "NETOPS_USER": "admin",
        "NETOPS_PASSWORD": "your-password"
      }
    }
  }
}
```

## Configuration

| Variable | Default | Purpose |
|----------|---------|---------|
| `NETMCP_INVENTORY` | `examples/devices.yml` | Device inventory |
| `NETMCP_RULES` | `examples/rules.yml` | Compliance rules |
| `NETMCP_BACKUP_DIR` | `backups` | Where configs are stored/read |
| `NETOPS_USER` / `NETOPS_PASSWORD` | — | SSH credentials (only needed by `backup_device`) |

## Design notes

- **Read-only by default**: every question-answering path works from saved
  backups; only `backup_device` opens an SSH session, and its docstring says
  so explicitly so both the model and the human approving the call know.
- **Prescriptive tool descriptions**: each docstring states *when* to call
  the tool, not just what it does — that's what drives correct tool
  selection by the model.
- **Thin server, reusable core**: `server.py` only declares tools;
  `operations.py` bridges to netops-tools and is fully unit-tested. CLI,
  REST API and MCP server all share one engine.

## Tests

```bash
pytest
```

Runs entirely offline (temporary inventories; the SSH path is exercised
with a monkeypatched backup function).

## License

MIT