Skip to content

0xEkho/NETGEAR-AV-MCP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

NETGEAR M4250/M4300/M4350 MCP Server

Production-ready MCP Server for NETGEAR M4250, M4300, and M4350 Series Network Switches

A Model Context Protocol (MCP) server that provides AI assistants with secure, structured access to NETGEAR M4250/M4300/M4350 network infrastructure. Execute commands, retrieve device information, diagnose issues, and manage PoEβ€”all through a standardized interface.

License: Unlicense Python 3.11+ MCP Compatible Docker


✨ Features

Core Capabilities

  • πŸ”§ 10 Production-Ready Tools - Device facts, interface monitoring, PoE management, VLAN/routing/STP audits, LLDP discovery, configuration backup
  • ⚑ Automatic Pager Handling - Seamless navigation through long CLI outputs with --More-- prompts
  • πŸ“Š Structured Data - Parsed, typed responses optimized for AI consumption with flat data structures
  • 🎯 Read-Only by Design - Safe operations by default with configurable write capability

Security (v2.0)

  • πŸ” Bearer Token Authentication - API token required for all protected endpoints
  • 🚦 Rate Limiting - Configurable requests/minute and burst protection
  • 🌐 IP Subnet Filtering - Allowlist/denylist by CIDR notation
  • πŸ”‘ Multi-Tier Credentials - Global β†’ Zone-based β†’ Device-specific β†’ Fallback
  • πŸ“ Auto-Incrementing known_hosts - SSH host keys managed automatically
  • πŸ›‘οΈ Command Policy Enforcement - Allow/deny patterns with output redaction

Deployment

  • 🐳 Docker Ready - Production-grade containerization with health checks
  • πŸ“‹ LLM-Optimized Output - Structured responses designed for AI consumption
  • πŸ”Œ Full MCP Compliance - Protocol-compliant with tool discovery

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         LLM / AI Client                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                  β”‚
                                  β”‚ HTTP + Bearer Token
                                  β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     NETGEAR AV MCP Server                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Security   β”‚  β”‚   Rate      β”‚  β”‚     IP Filter           β”‚  β”‚
β”‚  β”‚  (Bearer)   β”‚β†’ β”‚   Limiter   β”‚β†’ β”‚   (Subnet Allow/Deny)   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                           β”‚                                      β”‚
β”‚                           β–Ό                                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚                   Credential Manager                     β”‚    β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚    β”‚
β”‚  β”‚  β”‚Deviceβ”‚β†’ β”‚  Global  β”‚β†’ β”‚ Zone-Based β”‚β†’ β”‚ Fallback β”‚   β”‚    β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                           β”‚                                      β”‚
β”‚                           β–Ό                                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚                    SSH Runner                            β”‚    β”‚
β”‚  β”‚  β€’ Auto-add known_hosts  β€’ Command policy enforcement    β”‚    β”‚
β”‚  β”‚  β€’ Output redaction      β€’ Pager handling                β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                  β”‚
                                  β”‚ SSH
                                  β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              NETGEAR M4250/M4350 Switches                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”‚
β”‚  β”‚ 192.168.1.10  β”‚  β”‚ 192.168.1.11  β”‚  β”‚ 192.168.2.x   β”‚  ...        β”‚
β”‚  β”‚  Zone 9     β”‚  β”‚  Zone 9     β”‚  β”‚  Zone 10    β”‚              β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🌐 OpenWebUI Integration

This server is fully compatible with OpenWebUI via OpenAPI or MCP Streamable HTTP.

Option 1: OpenAPI Integration (Recommended)

  1. Open βš™οΈ Admin Settings β†’ External Tools
  2. Click + (Add Server)
  3. Configure:
    • Type: OpenAPI
    • URL: http://your-server:8083/openapi.json
    • Auth: Bearer
    • Key: Your API token (same as NETGEAR_API_TOKEN)
  4. Save and restart if prompted

Option 2: MCP Streamable HTTP

  1. Open βš™οΈ Admin Settings β†’ External Tools
  2. Click + (Add Server)
  3. Configure:
    • Type: MCP (Streamable HTTP)
    • URL: http://your-server:8083/mcp
    • Auth: Bearer
    • Key: Your API token
  4. Save and restart if prompted

Example Configuration (OpenAPI)

Setting Value
Type OpenAPI
URL http://localhost:8083/openapi.json
Auth Bearer
Key your-secure-api-token

Exposed Tools

OpenWebUI will discover these 10 tools:

Tool Description
netgear.cli.readonly Execute read-only CLI commands
netgear.device.facts Get device info (model, version, uptime)
netgear.interface.status Get interface status
netgear.vlan.audit Audit VLAN configuration
netgear.port.info Get detailed port information
netgear.poe.status Get PoE status and power consumption
netgear.spanning.tree Get STP status
netgear.config.backup Backup running configuration
netgear.routing.info Get routing table
netgear.lldp.neighbors Discover LLDP neighbors

Docker with OpenWebUI

If OpenWebUI runs in Docker and this MCP server is on the host:

# Use host.docker.internal instead of localhost
http://host.docker.internal:8083/mcp

πŸš€ Quick Start

Prerequisites

  • Python 3.11+
  • SSH access to NETGEAR switches
  • Docker (optional, for containerized deployment)

Local Execution

# 1. Clone and setup
git clone https://github.com/0xEkho/NETGEAR-AV-MCP.git
cd NETGEAR-AV-MCP
python3 -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate

# 2. Install dependencies
pip install -e .

# 3. Configure
cp config.example.yaml config.yaml
# Edit config.yaml with your settings

# 4. Set credentials (minimum required)
export NETGEAR_API_TOKEN="your-secure-api-token"
export NETGEAR_USER="admin"
export NETGEAR_PASSWORD="your_password"

# 5. Start server
uvicorn netgear_av_server.main:app --host 0.0.0.0 --port 8083

# 6. Test
curl http://localhost:8083/netgear/healthz

# 7. Test authenticated endpoint
curl -X POST http://localhost:8083/v1/netgear/tools/list \
  -H "Authorization: Bearer your-secure-api-token" \
  -H "Content-Type: application/json"

Docker Deployment (Recommended)

# 1. Clone repository
git clone https://github.com/0xEkho/NETGEAR-AV-MCP.git
cd NETGEAR-AV-MCP

# 2. Create .env file
cat > .env << EOF
NETGEAR_API_TOKEN=your-secure-api-token
NETGEAR_USER=admin
NETGEAR_PASSWORD=your_password
LOG_LEVEL=INFO
EOF

# 3. Configure (optional)
cp config.example.yaml config.yaml
# Edit config.yaml for zone-based credentials, etc.

# 4. Deploy
cd deploy
docker-compose up -d

# 5. Verify
docker-compose logs -f
curl http://localhost:8083/netgear/healthz

πŸ” Security Configuration

Bearer Token Authentication

All protected endpoints require a Bearer token:

# Set your API token
export NETGEAR_API_TOKEN="your-secure-random-token"

# Use in requests
curl -X POST http://localhost:8083/v1/netgear/tools/list \
  -H "Authorization: Bearer your-secure-random-token" \
  -H "Content-Type: application/json"

Rate Limiting

Default configuration (can be changed in config.yaml):

  • 60 requests/minute per IP address
  • 20 burst requests in 10-second window
security:
  rate_limit:
    enabled: true
    requests_per_minute: 60
    burst_size: 20

IP Subnet Filtering

Restrict access by IP subnet:

security:
  ip_filter:
    enabled: true
    mode: allowlist  # or "denylist"
    subnets:
      - "10.0.0.0/8"
      - "192.168.0.0/16"

Credential Management

Credentials are resolved in this order:

  1. Device-specific - Exact host match
  2. Global - Primary credentials (e.g., LDAP user - auth handled externally)
  3. Zone-based - By IP subnet (10.X.0.0/16 β†’ Zone X) - local fallback
  4. Fallback - Default credentials
credentials:
  # Global credentials (primary - e.g., LDAP user, auth handled externally)
  global_creds:
    username_env: NETGEAR_GLOBAL_USER
    password_env: NETGEAR_GLOBAL_PASSWORD
  
  # Zone-based local credentials (fallback per subnet)
  zones:
    - zone_id: 9
      subnet: "10.9.0.0/16"
      username_env: ZONE9_USER
      password_env: ZONE9_PASSWORD
  
  # Device-specific (highest priority)
  devices:
    - host: "192.168.1.10"
      username_env: SWITCH_CORE_USER
      password_env: SWITCH_CORE_PASSWORD
  
  # Ultimate fallback
  fallback_username_env: NETGEAR_USER
  fallback_password_env: NETGEAR_PASSWORD

πŸ› οΈ Available Tools

Tool Description
netgear.cli.readonly Execute read-only CLI commands with policy enforcement
netgear.device.facts Get device info (model, serial, firmware, uptime)
netgear.interface.status Monitor interface status and traffic counters
netgear.vlan.audit Audit VLAN configuration with port-level details
netgear.port.info Get detailed port statistics
netgear.poe.status Check PoE status and power consumption
netgear.spanning.tree View Spanning Tree Protocol information
netgear.config.backup Backup running configuration
netgear.routing.info Get routing table information
netgear.lldp.neighbors Discover LLDP neighbors

πŸ“‘ API Endpoints

Endpoint Method Auth Description
/netgear/healthz GET No Health check
/mcp/metadata GET No MCP protocol metadata
/v1/netgear/tools/list POST Yes List available tools
/v1/netgear/tools/call POST Yes Execute a tool
/v1/netgear/status GET Yes Server status and stats
/v1/netgear/test-connection POST Yes Test SSH connectivity

Example: Execute Tool

curl -X POST http://localhost:8083/v1/netgear/tools/call \
  -H "Authorization: Bearer your-token" \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "netgear.device.facts",
    "args": {"host": "192.168.1.10"}
  }'

Example Response

{
  "status": "ok",
  "data": {
    "host": "192.168.1.10",
    "hostname": "SW-CORE-01",
    "model": "M4250-40G8XF-PoE+",
    "serial_number": "ABC123456789",
    "software_version": "14.0.1.6",
    "uptime": "15 days, 6 hours, 32 minutes",
    "credential_source": "zone",
    "zone_id": 9
  },
  "content": [
    {
      "type": "text",
      "text": "**Device Facts: 192.168.1.10**\n\n- **Hostname:** SW-CORE-01\n..."
    }
  ],
  "meta": {
    "tool": "netgear.device.facts",
    "client_ip": "10.0.0.1"
  }
}

πŸ“ Project Structure

NETGEAR-AV-MCP/
β”œβ”€β”€ netgear_av_server/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ main.py              # FastAPI application
β”‚   β”œβ”€β”€ api_models.py        # Pydantic request/response models
β”‚   β”œβ”€β”€ config.py            # Configuration management
β”‚   β”œβ”€β”€ security.py          # Auth, rate limiting, IP filter
β”‚   β”œβ”€β”€ credentials.py       # Global, zone, device credentials
β”‚   β”œβ”€β”€ known_hosts.py       # SSH known_hosts management
β”‚   β”œβ”€β”€ ssh_runner.py        # SSH command execution with enable mode
β”‚   β”œβ”€β”€ tools.py             # Tool definitions and handlers
β”‚   β”œβ”€β”€ parsers.py           # CLI output parsers (M4250/M4300/M4350)
β”‚   β”œβ”€β”€ llm_formatters.py    # LLM-friendly output formatting
β”‚   β”œβ”€β”€ command_mapping.py   # Model-adaptive command selection
β”‚   β”œβ”€β”€ vlan_parse.py        # VLAN-specific parsing
β”‚   └── inventory.py         # Device inventory
β”œβ”€β”€ deploy/
β”‚   β”œβ”€β”€ Dockerfile
β”‚   β”œβ”€β”€ docker-compose.yaml
β”‚   └── README.md
β”œβ”€β”€ examples/
β”‚   β”œβ”€β”€ 01_cli_readonly.md
β”‚   β”œβ”€β”€ 02_device_facts.md
β”‚   └── ...
β”œβ”€β”€ config.example.yaml      # Example configuration
β”œβ”€β”€ known_hosts              # SSH known hosts (auto-managed)
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ pyproject.toml
└── README.md

πŸ”§ Environment Variables

Variable Required Description
NETGEAR_API_TOKEN Yes* Bearer token for API authentication
NETGEAR_GLOBAL_USER No Global SSH username (primary)
NETGEAR_GLOBAL_PASSWORD No Global SSH password (primary)
NETGEAR_USER Yes Fallback SSH username
NETGEAR_PASSWORD Yes Fallback SSH password
NETGEAR_CONFIG_FILE No Path to config.yaml (default: ./config.yaml)
LOG_LEVEL No Logging level (default: INFO)
ZONE{N}_USER No Zone-specific username (e.g., ZONE9_USER)
ZONE{N}_PASSWORD No Zone-specific password

*Required unless security.bearer_token.enabled: false in config


πŸ“š Documentation


🀝 Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.


πŸ“„ License

This project is released under the Unlicense - public domain.


🏷️ Changelog

v1.1.0 (2026-01-10)

  • βœ… Added Bearer token authentication
  • βœ… Added rate limiting (60/min, 20 burst)
  • βœ… Added IP subnet filtering (allowlist/denylist)
  • βœ… Added multi-tier credential management (Global + Zones)
  • βœ… Added auto-incrementing known_hosts
  • βœ… Added M4300 series support with model-adaptive commands
  • βœ… Added enable/privileged mode handling for SSH
  • βœ… Enhanced pager handling (--More--, Press any key, etc.)
  • βœ… Added LLM-friendly formatters for all tools
  • βœ… Renamed endpoints with /netgear/ prefix
  • βœ… Improved output cleaning and normalization
  • βœ… Docker healthcheck updated

v1.0.0 (2025-12-28)

  • Initial release with 10 tools
  • SSH execution with pager handling
  • Command policy enforcement

About

NETGEAR AV Switch MCP

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published