Skip to content

MCP Servers for scandora.net

Overview

Model Context Protocol (MCP) servers allow AI assistants like Claude to interact with infrastructure services via their APIs. The scandora.net project uses three MCP servers:

  1. OPNsense MCP - Gateway management and network diagnostics
  2. Grafana MCP - Monitoring queries and dashboard exploration
  3. GitHub MCP - Issue tracking and project board management

These complement (but don't replace) Ansible IaC — they're best for interactive querying, exploratory debugging, and validating that Ansible-managed config took effect.

Use cases alongside Ansible:

  • Query live state during Ansible role development (DHCP leases, firewall rules, DNS overrides, metrics)
  • Verify Ansible changes applied correctly without opening web UIs
  • Debug network issues interactively (ARP tables, routing, interface status, alerts)
  • Security auditing of running configuration
  • Explore monitoring data and create queries for dashboards

Available Servers (as of February 2026)

1. vespo92/OPNSenseMCP — "IaC Proxy"

  • Repository: https://github.com/vespo92/OPNSenseMCP
  • Language: TypeScript (Node.js 18+ or Bun)
  • Transport: stdio
  • License: MIT
  • Stars: 64
  • npm: opnsense-mcp-server
  • Last activity: February 2026 (most active)

Tools (~35): Firewall rules, NAT (including SSH-based XML manipulation), ARP, routing diagnostics, VLANs, backups, service restarts, raw CLI execution.

Unique features:

  • SSH-based NAT management (direct config.xml manipulation beyond the API)
  • Auto-repair tools: nat_fix_dmz, routing_fix_all
  • system_execute_command for arbitrary CLI access
  • Docker deployment option
  • IaC-oriented design philosophy

Auth: API key/secret + optional SSH credentials via .env or environment variables.

Best for: Hands-on firewall operations, NAT troubleshooting, interactive debugging sessions.

2. Pixelworlds/opnsense-mcp-server — "Modular Full API"

Tools (88 modules → 2000+ methods): Entire OPNsense API surface — 752 core methods + 1,271 plugin methods across 24 core + 64 plugin modules.

Architecture: One tool per module (e.g., firewall_manage) with a method parameter. This keeps tool count manageable for the AI while covering everything.

Core modules: core_manage, interfaces_manage, firewall_manage, unbound_manage, dhcpv4_manage, openvpn_manage, ipsec_manage, wireguard_manage, firmware_manage, diagnostics_manage

Plugin modules (64): Nginx, HAProxy, Caddy, BIND, Let's Encrypt, and more.

Auth: API key/secret only (no SSH).

Best for: Comprehensive API coverage, querying any subsystem, development/exploration.

3. floriangrousset/opnsense-mcp-server — "Python + Security Auditing"

Tools: Firewall rules, aliases, DHCP leases, VPN monitoring, system health, service control, config backups, and security auditing.

Unique features:

  • Automated security auditing (identifies outdated firmware, overly permissive rules)
  • Only Python implementation (easier to extend in Python ecosystems)
  • AGPL license (copyleft — modifications must be open-sourced)

Auth: API key/secret.

Best for: Security-conscious environments, Python ecosystems, periodic audit checks.

4. bshandley/homelab-mcp — "Multi-Service Homelab"

OPNsense scope: Read-only monitoring + service restart only. No rule management.

Multi-service: Docker containers, OPNsense, TrueNAS, Proxmox, Home Assistant.

Unique features:

  • 4 graduated capability levels: L1 (read-only) → L2 (start/stop) → L3 (read configs) → L4 (full management)
  • Remote HTTP transport with OAuth (shared service, not just local stdio)

Best for: Homelab dashboarding, multi-service monitoring. Not suitable for OPNsense IaC work.

Comparison Matrix

Feature vespo92 Pixelworlds floriangrousset bshandley
Language TypeScript TypeScript Python TypeScript
API methods ~35 focused 2000+ comprehensive Moderate Minimal
Firewall CRUD Yes Yes Yes No (read-only)
DHCP management No Yes Yes (leases) No
DNS/Unbound No Yes Unknown No
NAT management Yes (SSH+API) Yes (API) Unknown No
Security audit No No Yes No
SSH access Yes No No No
Multi-service No No No Yes
Remote transport No No No Yes (OAuth)
Activity Very active Stale (7mo) Moderate Active
License MIT MIT AGPL 3.0 Unknown

Scandora.net Setup

All three MCP servers use automatic credential loading via wrapper scripts. No manual environment setup required!

OPNsense MCP

We use vespo92/OPNSenseMCP (v0.9.4, 111 tools).

Installation:

# One-time global install
npm install -g opnsense-mcp-server

# Required patch for nested KVM dev VM (firmware/info endpoint hangs):
# Edit /opt/homebrew/lib/node_modules/opnsense-mcp-server/dist/api/client.js
# In testConnection(), replace:
#   const result = await this.get('/core/firmware/info');
# With:
#   const result = await this.get('/diagnostics/interface/getInterfaceNames');
# This is only needed for the dev VM; production OPNsense responds normally.

Grafana MCP

We use @leval/mcp-grafana - a comprehensive TypeScript implementation with 43+ tools.

Installation: Automatic via npx (no global install needed)

Features:

  • Dashboard queries and management
  • Datasource exploration
  • Alert rule inspection
  • Incident management
  • Logs and metrics queries
  • Service account integration

GitHub MCP

We use github/github-mcp-server — the official GitHub MCP server for repository, issue, PR, and Projects management.

Installation: Automatic via Docker (pulled on first run)

Features:

  • Issues: Create, update, search, assign, label issues
  • Pull Requests: Create, review, merge PRs
  • Projects: View and update GitHub Projects v2 boards (kanban items, status)
  • Repositories: Browse files, check CI/CD run status

Toolsets enabled: repos,issues,pull_requests,projects

Target: https://github.com/users/scandora/projects/1 (scandora.net infrastructure project)

Unified Configuration

.mcp.json (project root, committed to git — no secrets):

{
  "mcpServers": {
    "opnsense": {
      "type": "stdio",
      "command": "/Users/joe/src/scandora.net/scripts/opnsense-mcp-wrapper.sh",
      "env": {
        "OPNSENSE_TARGET": "${OPNSENSE_TARGET:-dev}"
      }
    },
    "grafana": {
      "type": "stdio",
      "command": "/Users/joe/src/scandora.net/scripts/grafana-mcp-wrapper.sh",
      "env": {
        "GRAFANA_TARGET": "${GRAFANA_TARGET:-dumbo}"
      }
    },
    "github": {
      "type": "stdio",
      "command": "/Users/joe/src/scandora.net/scripts/github-mcp-wrapper.sh"
    },
    "gitlab": {
      "type": "stdio",
      "command": "/Users/joe/src/scandora.net/scripts/gitlab-mcp-wrapper.sh"
    }
  }
}

How it works:

  1. Each MCP server has a wrapper script that automatically loads credentials from 1Password
  2. Wrappers check for 1Password CLI authentication and validate connectivity
  3. Environment variables select which target to connect to (dev/owl/blue for OPNsense, dumbo for Grafana)
  4. Credentials are loaded on-demand when Claude Code starts

Usage:

Just start Claude Code from the project directory:

cd ~/src/scandora.net
claude

Default targets:

  • OPNsense: dev (opnsense-dev via localhost:8443)
  • Grafana: dumbo (http://192.168.194.131:3000)
  • GitHub: github.com — scandora/scandora.net repo + projects/1

To connect to different targets:

# Connect to Owl production gateway
OPNSENSE_TARGET=owl claude

# Connect to Blue production gateway
OPNSENSE_TARGET=blue claude

# Shell aliases (add to ~/.bashrc or ~/.zshrc):
alias claude-dev='cd ~/src/scandora.net && claude'
alias claude-owl='cd ~/src/scandora.net && OPNSENSE_TARGET=owl claude'
alias claude-blue='cd ~/src/scandora.net && OPNSENSE_TARGET=blue claude'

1Password Items

OPNsense MCP:

Item Vault Fields Target
OPNsense API - Dev Private api key, api secret opnsense-dev (GCE/KVM, via SSH tunnel)
OPNsense API - Owl Private api key, api secret owl.scandora.net (via ZeroTier)
OPNsense API - Blue Private api key, api secret blue.scandora.net (direct)

Grafana MCP:

Item Vault Fields Target
Monitoring - Grafana Admin scandora.net api key dumbo (http://192.168.194.131:3000)

GitHub MCP:

Item Vault Fields Target
github_pat_mcp_claude scandora-automation credential (PAT) github.com

Creating GitHub PAT:

  1. Visit: https://github.com/settings/tokens (classic) or Fine-grained tokens
  2. Create token with scopes: repo, project, read:org
  3. Store in 1Password:
op item create --category="API Credential" \
  --title="github_pat_mcp_claude" \
  --vault="scandora-automation" \
  --tags="scandora.net" \
  "credential[password]=ghp_YOUR_TOKEN_HERE"

Creating Grafana API Key:

  1. Log into Grafana at http://192.168.194.131:3000
  2. Go to: Administration → Service Accounts
  3. Click "Add service account"
  4. Display name: "Claude Code MCP"
  5. Role: Viewer (or Editor for write access)
  6. Click "Add service account token"
  7. Display name: "luna-workstation"
  8. Expiration: No expiration (or set as needed)
  9. Copy the generated token (starts with "glsa_...")
  10. Store in 1Password:
op item edit "Monitoring - Grafana Admin" \
  --vault "scandora.net" \
  "api key[password]"="glsa_YOUR_TOKEN_HERE"

Access Paths

OPNsense:

Claude Code ──stdio──> opnsense-mcp-wrapper.sh ──1Password──> OPNsense MCP ──HTTPS──> OPNsense API
                       (loads credentials)                                          (via tunnel/ZT)

For the dev VM, an SSH tunnel must be active:

ssh -f -N -L 8443:10.7.0.1:443 joe@<gce-external-ip>

For production (owl), use the ZeroTier IP: https://192.168.194.10.

Grafana:

Claude Code ──stdio──> grafana-mcp-wrapper.sh ──1Password──> Grafana MCP ──HTTP──> Grafana API
                       (loads api key)                                          (via ZeroTier)

Requires ZeroTier connectivity to reach dumbo at 192.168.194.131:3000.

GitHub:

Claude Code ──stdio──> github-mcp-wrapper.sh ──1Password──> Docker (github-mcp-server) ──REST API──> GitHub
                       (loads PAT)                                                              (github.com)

Requires internet connectivity and Docker running locally.

Prerequisites

General:

  • 1Password CLI (op) installed and authenticated: eval $(op signin)

OPNsense MCP:

  • For dev target: SSH tunnel to GCE active: ssh -f -N -L 8443:10.7.0.1:443 joe@<gce-ip>
  • For owl/blue targets: ZeroTier connectivity to 192.168.194.x network

Grafana MCP:

  • ZeroTier connectivity to reach dumbo (192.168.194.131)
  • Service account token stored in 1Password (see "Creating Grafana API Key" above)

GitHub MCP:

  • Internet connectivity to reach github.com
  • Docker installed and running (docker info should succeed)
  • PAT stored in 1Password (see "Creating GitHub PAT" above)

Known Issues

OPNsense - Dev VM firmware endpoint hang: The MCP server's testConnection() calls /api/core/firmware/info, which hangs indefinitely on nested KVM OPNsense (same issue that affects Ansible packages and monitoring tags). The workaround is to patch the globally installed client.js to use /diagnostics/interface/getInterfaceNames instead. This patch survives until the next npm update -g.

Grafana - Connection timeout: If the Grafana MCP fails to connect, verify:

  1. ZeroTier is connected: zerotier-cli listnetworks (should show status: OK)
  2. Dumbo is reachable: ping 192.168.194.131
  3. Grafana API responds: curl -H "Authorization: Bearer $GRAFANA_API_KEY" http://192.168.194.131:3000/api/health

GitHub - Authentication failures: If the GitHub MCP fails to authenticate:

  1. Verify PAT is valid and has repo + project + read:org scopes
  2. Test manually: curl -H "Authorization: token $(op item get github_pat_mcp_claude --vault scandora-automation --fields credential --reveal)" https://api.github.com/user
  3. Check 1Password item github_pat_mcp_claude has credential field with the PAT
  4. Ensure Docker is running: docker info

Important: MCP servers are for interactive querying and debugging. Production configuration changes should always flow through Ansible (run-opnsense.sh, run-monitoring.sh) to maintain IaC as the source of truth.

Troubleshooting

"Not signed in to 1Password"

# Sign in to 1Password
eval $(op signin)

# Verify
op account get

"Could not retrieve API key"

Verify 1Password items exist:

# List items
op item list --vault "scandora-automation" | grep -i opnsense
op item list --vault "scandora-automation" | grep -i grafana
op item list --vault "scandora-automation" | grep -i github

# Check specific items
op item get "dumbo_grafana_admin_password" --vault "scandora-automation"
op item get "github_pat_mcp_claude" --vault "scandora-automation"

Check MCP server logs

Claude Code logs show MCP server startup messages. Look for:

OPNsense MCP: Connecting to dev (https://localhost:8443)
Grafana MCP: Connecting to dumbo (http://192.168.194.131:3000)
GitHub MCP: Connected to github.com

Verify MCP servers in Claude Code

After starting Claude Code, run:

/doctor    # Should show 'opnsense', 'grafana', 'github', and 'gitlab' as Ready
/mcp       # Should show all four servers connected

References