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.
- π§ 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
- π 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
- π³ 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
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 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 β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
This server is fully compatible with OpenWebUI via OpenAPI or MCP Streamable HTTP.
- Open βοΈ Admin Settings β External Tools
- Click + (Add Server)
- Configure:
- Type: OpenAPI
- URL:
http://your-server:8083/openapi.json - Auth: Bearer
- Key: Your API token (same as
NETGEAR_API_TOKEN)
- Save and restart if prompted
- Open βοΈ Admin Settings β External Tools
- Click + (Add Server)
- Configure:
- Type: MCP (Streamable HTTP)
- URL:
http://your-server:8083/mcp - Auth: Bearer
- Key: Your API token
- Save and restart if prompted
| Setting | Value |
|---|---|
| Type | OpenAPI |
| URL | http://localhost:8083/openapi.json |
| Auth | Bearer |
| Key | your-secure-api-token |
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 |
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- Python 3.11+
- SSH access to NETGEAR switches
- Docker (optional, for containerized deployment)
# 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"# 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/healthzAll 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"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: 20Restrict access by IP subnet:
security:
ip_filter:
enabled: true
mode: allowlist # or "denylist"
subnets:
- "10.0.0.0/8"
- "192.168.0.0/16"Credentials are resolved in this order:
- Device-specific - Exact host match
- Global - Primary credentials (e.g., LDAP user - auth handled externally)
- Zone-based - By IP subnet (10.X.0.0/16 β Zone X) - local fallback
- 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| 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 |
| 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 |
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"}
}'{
"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"
}
}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
| 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
- Examples - Detailed usage examples for each tool
- Deployment Guide - Docker and production deployment
- Configuration Reference - Full configuration options
Contributions are welcome! Please feel free to submit issues and pull requests.
This project is released under the Unlicense - public domain.
- β 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
- Initial release with 10 tools
- SSH execution with pager handling
- Command policy enforcement