OPNsense MCP Server
Provides tools for managing OPNsense firewall, including firewall rules, VLANs, NAT, DHCP, routing, VPN, DNS, and plugins like os-acme-client and os-haproxy via its REST API.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@OPNsense MCP Serverblock tiktok.com on the guest network"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
OPNsense MCP Server
Let an MCP-capable agent inspect and, when explicitly enabled, change an OPNsense firewall from plain-language requests.
This is a Model Context Protocol (MCP) server that exposes the OPNsense REST API to an AI agent — Claude, GPT, a local Hermes model, or any MCP-capable client. Requests such as "block tiktok.com on the guest network", "open port 443 to the web server", or "show me every device on VLAN 20" are mapped to the exposed tools, subject to the deployment's OPNsense privileges and server guardrails.
Its defining trait is a small, curated tool surface backed by generic, registry-driven verbs.
The committed registry catalogues 96 CRUD resources, while an opt-in escape hatch
(ENABLE_RAW_API_TOOL=true) can call an endpoint supplied by the client. This is broad
reachability, not proof that every controller on every OPNsense version has been discovered or
semantically verified.
Design goals: maximize safe API reachability; use opt-in, clearly-labeled SSH only for the few operations OPNsense exposes no REST API for (e.g. interface assignment) — always backed up first; redact secrets; offer strict pre-change backups; and distinguish deterministic tests from manual VM evidence and unattested agentic results.
Table of contents
Related MCP server: io.github.abl030/pfsense-mcp
Features
Broad API reach through a compact surface. A live-harvested registry of 96 CRUD resources across 55 controllers is driven by generic verbs (
opn_list/get/create/update/delete/toggle,opn_describe,opn_service,opn_settings_get/set), with an opt-inopn_api_callescape hatch (ENABLE_RAW_API_TOOL=true) for arbitrary caller-supplied API paths outside the typed registry. The server does not enforce endpoint review, so the hatch stays hidden by default and every call through it takes a mandatory pre-change backup.Self-describing.
opn_describereads the connected resource's field template live from the firewall. This is version-sensitive evidence for that known resource, not independent discovery of every controller;opn_createforwards fields accepted by that template.API-first. VLANs, firewall rules, NAT, DHCP (Kea), routing, VPN and DNS primarily use REST. Selected config-only gaps use fixed, parameterized SSH operations when explicitly enabled.
Native auto-backup. Optionally snapshot the full config before classified mutations. Snapshots stay server-side (checksum-verified,
0600); the tools return metadata and guidance, never the raw XML.Plugin-aware.
os-acme-clientandos-haproxyare covered; tools degrade gracefully to{available:false}when a plugin or version-specific module isn't installed.Defense in depth. Logs apply pattern-based secret redaction, TLS verification defaults on, and ignore rules cover common credential, backup and audit filenames. Sensitive files still require private storage outside the checkout.
Local MCP interoperability.
stdiois the recommended deployment. SSE/Streamable HTTP exists but has no built-in authentication or TLS; it now binds to loopback only (non-loopback hosts and wildcard CORS refuse startup) and still requires an authenticated TLS proxy for any remote use.
How it works
Most MCP servers expose one tool per endpoint, which buries the model under hundreds of tools. This one inverts that: a resource registry (catalogued by introspecting a live firewall) describes what each OPNsense resource is, and a few generic verbs know how to talk to any of them. The typical flow an agent follows:
opn_list_resources → discover the ~96 resource keys
opn_describe {resource:"firewall_alias"} → read its observed live field template
opn_create {resource:"firewall_alias", fields:{name:"web", type:"host", content:"10.0.0.9"}}Anything outside the CRUD registry — diagnostics, action endpoints, single-form settings — may be reached
through opn_settings_get/set, opn_service, and the opt-in opn_api_call escape hatch. The result:
the model sees a compact surface without a one-tool-per-endpoint catalogue. Full detail and limits in
docs/api-coverage-matrix.md.
Requirements
Node.js 22.13+ and npm (the release-gated toolchain)
An OPNsense firewall reachable over HTTPS; the local harness targets 26.1.6 by default and 25.7 explicitly
An API key/secret — OPNsense → System → Access → Users → (user) → API keys. A dedicated least-privilege key is required for a production deployment.
Support matrix
Area | Position |
Runtime | Node.js 22.13+; Node 22 is exercised by public CI. |
Package manager | npm + |
OPNsense | v26.1.6 is the default VM target; v25.7 is an explicit compatibility target. Fresh VM evidence is required for a release claim. |
VM host | macOS or Linux after QEMU/Python prerequisites; Windows VM automation is unsupported. |
Transport | Local |
SSH | Off by default; privileged and subject to the host-key limitation in docs/ssh-features.md. |
Containers/dashboard | Present but not part of the release-gated production profile. |
Benchmark | Structural offline validation exists; no full agentic result is attested for HEAD. |
Installation
git clone <your-repo-url> OPNSenseMCP
cd OPNSenseMCP
npm ci --ignore-scripts
npm run build # tsc -> dist/ and copy fixed SSH PHP assetsTry it locally first (no real firewall)
Before pointing the server at a real firewall, use a disposable local OPNsense VM. Provisioning is one command only after host prerequisites are installed; it downloads an image and plugins from external mirrors and is not a byte-for-byte bootstrap of a clean machine.
1) Provision one local OPNsense VM (macOS or Linux; x86 emulated under QEMU):
npm run vm:doctor # checks QEMU, qemu-img, curl, bzip2 and Python
npm run vm:provision # v26 only by default; mints a lab key and installs required pluginsThis brings up one throwaway firewall:
Version | Web GUI / API | Default login |
OPNsense 26.1.6 |
|
|
The cert is self-signed (accept the browser warning). The default root/opnsense password is fine
only for the loopback-isolated lab image and must never be copied to a real installation. Stop it with
npm run vm:stop. To exercise v25 explicitly, stop v26, run
INSTANCES=v25 npm run vm:provision, then use the :25 test/Inspector commands.
The managed provisioner assigns a dedicated WAN for downloads and then disables pf by default for
management-path stability (DISABLE_PF=0 skips that step on a fresh overlay). It therefore tests
configuration management, not live packet filtering or NAT enforcement.
2) Open the MCP Inspector against a VM — the official web UI for poking an MCP server by hand:
npm run inspect:26 # OPNsense 26.1.6 (use inspect:25 only with the explicit v25 VM)This launches the dev server (tsx src/index.ts) under the
MCP Inspector and auto-loads that VM's API
key from ~/.opnsense-mcp-testvm/<v25|v26>/apikey.env — no manual env injection. Your browser opens
with the session token pre-filled; click Connect, then Tools → List Tools to see the active surface
and call any of them from a form. Since it's the dev server, edits under src/ are picked up when you
hit the Inspector's Restart button.
Safe first calls: test_connection → opn_list_resources → opn_describe {"resource":"firewall_alias"}
→ block_domain {"domain":"example.com"} then list_dns_blocklist then unblock_domain.
Inspect your own (non-production) firewall instead? Drop credentials into a .env and use the
generic script — same one-command flow:
cp .env.example .env
chmod 600 .env # fill in credentials without sharing or committing the file
npm run inspectThe dev server reads config from its environment, not from
.env;npm run inspectreads the file and passes each variable to the Inspector with-e KEY=valuearguments. Secret values may therefore be visible in the local process table, andnpxmay resolve/download the Inspector when it is not cached. This is a disposable-lab convenience, not a production credential path..gitignoreonly reduces accidental commits; keep the file owner-only and do not use this helper for a sensitive firewall.
Configuration
The server reads its config from environment variables — supplied by your MCP client (the env
block in its config) or exported in your shell (the runtime configure tool stays hidden unless
ENABLE_CONFIGURE_TOOL=true). The server
itself does not auto-load a .env file; the local dev/Inspector flow
(npm run inspect) reads .env and forwards it for you. See
.env.example for the full list.
# Required
OPNSENSE_HOST=https://your-opnsense:port
OPNSENSE_API_KEY=your-api-key
OPNSENSE_API_SECRET=your-api-secret
OPNSENSE_VERIFY_SSL=true # verification is ON unless set to false
# Start with diagnostics only
READ_ONLY=true
# Native auto-backup for an intentionally writable deployment
AUTO_BACKUP=true # snapshot before classified firewall mutations
BACKUP_PATH=/var/lib/opnsense-mcp/backups
AUTO_BACKUP_KEEP=50 # prune to N most recent
AUTO_BACKUP_STRICT=true # refuse a mutation when its pre-change backup fails
# ALLOWED_RESOURCES=firewall_alias,unbound_host_override
# AUDIT_LOG=/var/log/opnsense-mcp/audit.jsonl
# Transport (optional)
MCP_TRANSPORT=stdio # recommended default; no listening socket
# HTTP mode is unauthenticated: it binds to loopback only (anything else refuses to start) and
# still needs an authenticated TLS proxy in front for any remote client.
# MCP_SSE_PORT=3000 MCP_SSE_HOST=127.0.0.1
# MCP_ALLOWED_ORIGINS=https://approved-client.example # exact origins; wildcard is fatal
# Logging (optional)
LOG_LEVEL=INFO # ERROR | WARN | INFO | DEBUG; known secret keys/patterns are redactedThe server starts and lists its tools even without credentials, but every tool call fails until
OPNSENSE_HOST / OPNSENSE_API_KEY / OPNSENSE_API_SECRET are set. (Runtime credential setup via
the configure tool is hidden unless ENABLE_CONFIGURE_TOOL=true; environment variables are the
default path.)
Var | Default | Purpose |
| — | Firewall base URL, |
| — | API credentials |
|
| TLS verification (set |
|
| Recommended local transport; HTTP mode requires external security controls |
|
| HTTP bind address; only loopback values are accepted — anything else refuses startup |
| unset (deny) | Exact-origin allow-list for browser clients; wildcard or malformed values are fatal |
| loopback names |
|
| unset | Deprecated alias for a single allowed origin; |
|
| When |
| unset | Optional comma-separated mutation boundary for registry resource keys; unscoped mutations are refused while set |
|
| Snapshot before classified firewall mutations |
|
| Refuse the mutation if its required pre-change snapshot fails; |
|
| Sensitive snapshot location ( |
| unset | Sensitive redacted JSONL observer; write failure is non-blocking |
|
| When |
|
| Expose the |
|
| Expose the runtime |
|
| Additionally required for |
|
| Expose the experimental |
|
| Log verbosity; known secret keys/patterns are redacted, but logs remain sensitive |
Quickstart — connect your AI
MCP is client-agnostic. The examples below cover representative hosts; verify the current client syntax and approval behavior before relying on it. The two transports are:
stdio (default) — the host launches the server as a subprocess. Recommended for production.
SSE / Streamable-HTTP (
MCP_TRANSPORT=sse) — the server listens on a port; clients connect over HTTP at/mcpor/sse, with/healthfor liveness. It has no built-in client authentication or TLS. The listener now enforces loopback binding, an exact-origin allow-list andHost-header validation, and refuses to start on unsafe configuration — but a remote deployment still requires an authenticated, TLS-terminating proxy in front.
Claude Desktop
Add the server to claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"opnsense": {
"command": "node",
"args": ["/absolute/path/to/OPNSenseMCP/dist/index.js"],
"env": {
"OPNSENSE_HOST": "https://your-opnsense:port",
"OPNSENSE_API_KEY": "your-key",
"OPNSENSE_API_SECRET": "your-secret",
"OPNSENSE_VERIFY_SSL": "true",
"READ_ONLY": "true"
}
}
}
}Restart Claude Desktop; the firewall tools appear in the client. Enable scoped writes only after the diagnostics-only deployment is verified.
Claude Code
claude mcp add opnsense -- node /absolute/path/to/OPNSenseMCP/dist/index.jsSupply OPNSENSE_HOST, credentials, OPNSENSE_VERIFY_SSL=true and READ_ONLY=true through the
client's protected environment/configuration mechanism rather than putting secret values in shell
history or process arguments. Run /mcp to confirm the server is connected.
OpenAI / GPT
OpenAI supports MCP two ways.
A) Agents SDK (local, stdio) — best for running a GPT agent on your own machine next to the firewall:
import asyncio, os
from agents import Agent, Runner
from agents.mcp import MCPServerStdio
async def main():
async with MCPServerStdio(
name="opnsense",
params={
"command": "node",
"args": ["/absolute/path/to/OPNSenseMCP/dist/index.js"],
"env": {
"OPNSENSE_HOST": "https://your-opnsense:port",
"OPNSENSE_API_KEY": os.environ["OPNSENSE_API_KEY"],
"OPNSENSE_API_SECRET": os.environ["OPNSENSE_API_SECRET"],
"OPNSENSE_VERIFY_SSL": "true",
"READ_ONLY": "true",
},
},
) as opnsense:
agent = Agent(
name="NetAdmin",
model="gpt-5",
instructions="You manage an OPNsense firewall via the connected tools.",
mcp_servers=[opnsense],
)
result = await Runner.run(agent, "Report the current OPNsense system settings.")
print(result.final_output)
asyncio.run(main())B) Responses API (remote
MCP) — not a direct deployment path for this repository today. A hosted client needs a reachable
HTTPS MCP URL, while this server's HTTP transport has no built-in client authentication or TLS. Do
not expose it or place a raw tunnel in front of it. Only use this option after adding an authenticated,
TLS-terminating gateway, strict network controls and an explicit data-handling review. Keep approval
required for sensitive tool calls; do not set a global require_approval: "never" policy for a
firewall. For local use, prefer option A over stdio.
Hermes & local models
Hermes Agent (Nous Research) ships a native MCP client and
runs open Hermes models locally (via Ollama / llama.cpp / LM Studio). Add this server to
~/.hermes/config.yaml:
mcp_servers:
opnsense:
command: "node"
args: ["/absolute/path/to/OPNSenseMCP/dist/index.js"]
env:
OPNSENSE_HOST: "https://your-opnsense:port"
OPNSENSE_API_KEY: "your-key"
OPNSENSE_API_SECRET: "your-secret"
OPNSENSE_VERIFY_SSL: "true"
READ_ONLY: "true"The same applies to any agent stack driving an open model (Hermes, Llama, Qwen, …) with MCP support. Keep client configuration owner-only because it contains credentials. Remote HTTP is subject to the same external authentication, TLS and network-control requirements described above.
Any other MCP client
Cursor, Continue, Cline, Windsurf, Zed, and most other hosts use the same canonical stdio spec — drop this block into the client's MCP config:
{
"mcpServers": {
"opnsense": {
"command": "node",
"args": ["/absolute/path/to/OPNSenseMCP/dist/index.js"],
"env": {
"OPNSENSE_HOST": "https://your-opnsense:port",
"OPNSENSE_API_KEY": "…",
"OPNSENSE_API_SECRET": "…",
"OPNSENSE_VERIFY_SSL": "true",
"READ_ONLY": "true"
}
}
}
}A stdio-only client must not be bridged to an unauthenticated HTTP instance. Use local stdio, or a
separately reviewed authenticated gateway.
Usage — talk to your firewall
Once connected, you drive everything in natural language; the agent picks the right tools. Examples:
The mutating examples require an intentionally writable, least-privilege deployment with the relevant
ALLOWED_RESOURCES; they are refused by the recommended initial READ_ONLY=true configuration.
You say | What happens |
"Block tiktok.com and instagram.com on the network." |
|
"Create a firewall alias |
|
"Open TCP 443 from any to the web server, then show me all WAN rules." |
|
"Add VLAN 20 on igb0 for IoT." |
|
"What devices are on the guest VLAN?" |
|
"Set up a Kea DHCPv4 subnet on the LAN." |
|
"Restart the Unbound service." |
|
"Back up the config before you change anything." |
|
To see the live tool list yourself: node tests/smoke/list-tools.mjs.
Tools
The catalogued API surface is reached through generic, registry-driven verbs plus a curated set
of ergonomic built-ins. Generic verbs each take a resource key from the registry (e.g. firewall_alias,
kea_dhcpv4_subnet, haproxy_server, ipsec_connection):
Tool | Purpose |
| Discover the ~96 resource keys (optionally by category). Start here. |
| Read an observed field template from OPNsense. Types are simplified, options may be capped, and required/cross-field constraints are not inferred. |
| List a resource's entries / get one by UUID. |
| Mutate and apply; use scoped resources and strict auto-backup in production. |
| Construct a conventional single-form settings path for a caller-supplied module/controller. |
| Construct a conventional service path for a caller-supplied module and action. |
| Last-resort arbitrary GET/POST under |
Curated built-ins (ergonomic shortcuts): test_connection, configure (opt-in via
ENABLE_CONFIGURE_TOOL=true); backups
(create_backup / list_backups / get_backup / restore_backup / delete_backup); DNS blocking
(block_domain / unblock_domain / block_multiple_domains / list_dns_blocklist); firewall rules
(list_firewall_rules / create_firewall_rule / delete_firewall_rule / find_firewall_rules);
VLANs (list_vlans / create_vlan / delete_vlan); discovery (list_arp_entries /
interface_list_overview / list_dhcp_leases / find_devices_on_vlan / find_device_by_name /
get_interfaces); routing_diagnostics, system_get_settings.
Shell tools (cli_* / ssh_*) are hidden unless ENABLE_SHELL_TOOLS=true. See
docs/tool-descriptions.md for how the descriptions are written and tested.
Native auto-backup
With AUTO_BACKUP=true, the server attempts to snapshot the full config before classified firewall
mutations. Set AUTO_BACKUP_STRICT=true so a snapshot failure refuses the mutation:
Snapshots persist under
BACKUP_PATHas<id>.xml(the config) +<id>.json(metadata: timestamp, sha256, the triggering tool, auto flag). The directory is forced to0700, files to0600, and reads are checksum-verified.get_backupreturns snapshot metadata only — the config XML never crosses the MCP boundary (includeContentis refused).Restore caveat: OPNsense exposes no REST API to push back a full config (restore is a GUI/console action).
restore_backupis honest about this — it returns metadata and guidance so the agent re-applies settings via the granular tools, or a human retrieves the saved XML fromBACKUP_PATHand uploads it in the web UI (System → Configuration → Backups).
The XML is a complete, sensitive firewall configuration and may include hashes, certificates, private network details and service configuration. Store it in a private absolute path outside the checkout with appropriate ACLs/encryption/retention. Keeping it server-side is deliberate: it stays out of the MCP client/model data boundary.
SSH-backed features
A few OPNsense operations have no REST API — notably assigning an interface and giving it an IP. When enabled, the server performs these over SSH, but only as an explicit, clearly-labeled, backed-up opt-in (separate from the discouraged free-text shell tools):
ENABLE_SSH_FEATURES=true # off by default
OPNSENSE_SSH_HOST=your-opnsense
OPNSENSE_SSH_USERNAME=root # privileged boundary; use only when the REST gap justifies it
OPNSENSE_SSH_KEY_PATH=/absolute/path/to/a/private/keyThe opt-in surface includes interface_assign, interface_unassign,
interface_set_ipv4, interface_toggle, system_set_general (System > General — hostname/domain/
timezone/DNS), system_set_ntp (NTP servers), interface_set_pppoe (add a PPPoE/DSL link),
interface_set_wireless (add a wireless clone), and restore_backup_ssh (real full restore — pushes
a saved config.xml back and reboots; additionally requires ENABLE_RESTORE_TOOLS=true). They:
are labeled for AI and human: a
⚠️ Uses SSH…description, MCPdestructiveHintannotations, and a⚠️ What this didblock in every result;drive OPNsense's own config framework — no
sed, no free-text into commands (params are staged as a JSON file the fixed PHP reads) — then apply the tool-specific consequence: scoped interface reload, service reconfiguration, config-only write, or an explicitly labeled restore reboot;always snapshot the config first, fail-closed — the change is refused if the backup fails.
Flow: create_vlan (REST) → interface_assign {device:"vlan0.20", ipv4:"192.168.20.1/24"} (SSH) →
DHCP/DNS/firewall rules over REST. Full detail + the extension recipe:
docs/ssh-features.md.
Testing
Deterministic tests drive the real built server over stdio. Never test against a production
firewall.
npm test # complete offline CI suite, including security and harness regressions
npm run test:mock # E2E against a deterministic in-process OPNsense mock
npm run test:backup # the auto-backup feature against the mockAgainst real OPNsense VMs (macOS/Linux, x86 emulated; run the prerequisite check first):
npm run vm:doctor # checks qemu-system, qemu-img, curl, bzip2 and python3 before writing files
npm run vm:provision # boot/provision v26 only; use INSTANCES=v25 after stopping v26
npm run test:vm # v26 only (use test:vm:25 explicitly for v25)
npm run vm:stop # stop allDefault release archives are SHA-256 pinned. Supplying another V26_VERSION/V25_VERSION also
requires an independently verified OPNSENSE_IMAGE_SHA256.
For interactive, by-hand exploration, use the MCP Inspector against a VM — see
Try it locally first (npm run inspect:26).
There is also an agentic test (npm run test:agentic): a real AI agent is given hint-free,
natural-language tasks and must pick the right tools from their descriptions alone, after which the
harness reads selected state back through a separate MCP connection. Its acceptance criterion covers
eligible advertised tool names, but there is no attested full result for HEAD. The REST readback shares
the server implementation; it is a common-implementation regression check, not an independent
semantic oracle. Full guide: docs/testing.md.
Security
Secret redaction in the logger (auth headers, API key/secret, passwords) — unit-tested.
SSL verification on by default (
OPNSENSE_VERIFY_SSLmust be explicitlyfalseto disable).API-first; SSH is opt-in & labeled. Most coverage is pure REST. SSH is used only for the few config-only operations (e.g. interface assignment), behind
ENABLE_SSH_FEATURES, clearly labeled to AI + human, and backed up before every SSH mutation (fail-closed) — see docs/ssh-features.md. The free-textcli_*/ssh_*tools remain a separate, discouraged thing behindENABLE_SHELL_TOOLS.Least privilege: use a dedicated least-privilege API key, and enable strict auto-backup for writes.
Closed tool classification. Every declared tool carries an explicit security policy (effect, backup, audit, resource scope); an unclassified name fails closed at listing and at dispatch, so a cached or forged tool name cannot bypass the active surface.
Privileged tools are opt-in.
opn_api_call(ENABLE_RAW_API_TOOL),configure(ENABLE_CONFIGURE_TOOL),restore_backup_ssh(ENABLE_RESTORE_TOOLS) andiac_*(IAC_ENABLED) are hidden and refused by default.Hardened network transport. SSE/Streamable HTTP binds loopback only, denies browser origins by default, validates
Hostheaders against a loopback allow-list, rejects wildcard CORS and ambiguous/oversized requests, and exits non-zero on unsafe configuration.Production guardrails: start with
READ_ONLY=true; for writes combineALLOWED_RESOURCES,AUTO_BACKUP=true,AUTO_BACKUP_STRICT=trueandAUDIT_LOG(optionallyAUDIT_LOG_STRICT=trueto gate mutations on the audit pre-write) as described in docs/production.md.Sensitive files:
.gitignoreis only a last line of defense. Keep credentials, backup XML, audit logs and traces outside the checkout with private permissions and retention controls. Backup snapshots never cross the MCP boundary; they are stored0700/0600and read back checksum-verified.Known gaps: the HTTP transport has no built-in auth/TLS (loopback enforcement is not authentication); optional SSH host-key verification is permissive; audit write failures are non-blocking unless
AUDIT_LOG_STRICT=true; containers/dashboard are not release-gated.
See SECURITY.md for private reporting and docs/production.md for the threat model. GitHub Private Vulnerability Reporting must be enabled before publication.
Architecture
src/index.ts is the live server: one OPNSenseMCPServer class, lazy-initialized from env, exposing
a ListTools array and a CallTool dispatch. The API client (src/api/client.ts)
encodes OPNsense quirks (GET sends no Content-Type; errors arrive as HTTP 200 + result:'failed';
the bootgrid search pattern). The coverage engine is the registry
(src/tools/registry.ts + auto-generated registry.data.ts) plus the generic
verbs (src/tools/generic-tools.ts) over a single CRUD contract
(src/resources/generic/crud.ts). Curated built-ins use per-domain
resource managers under src/resources/. Transports (stdio / SSE) live in
src/transports/. Full map: CLAUDE.md.
Roadmap
Authentication for the SSE / Streamable-HTTP transport.
SSH host-key pinning and a documented rotation flow.
Reproducible, hardened container and dashboard build paths before claiming support.
Continue long-tail controller coverage as OPNsense adds APIs (re-run
npm run gen:registry).Finish migrating legacy tests to a single runner; prune unused dependencies.
Historical design/backlog documents under docs/superpowers/ are non-normative; current guarantees
live in CLAUDE.md, docs/production.md and the tests.
Contributing
Contributions are welcome. Please read CONTRIBUTING.md and run npm test (and,
when touching the API client or registry, npm run test:vm) before opening a PR. To add coverage for
a new resource, regenerate the registry — see docs/adding-api-modules.md.
Documentation
CLAUDE.md — authoritative architecture, config, and known gaps
docs/HANDOVER.md — start here if you're taking over the project
docs/api-coverage-matrix.md — what's covered, what isn't
docs/adding-api-modules.md — how to add a module (the recipe)
docs/testing.md — complete testing guide (all layers, the VM fleet, agentic gate)
docs/tool-descriptions.md — tool-description quality + the agentic gate
docs/ground-truth-eval.md — DeepEval ground-truth eval (CSV dataset, metrics, how to run)
docs/ssh-features.md — SSH-backed features (interface assignment): safety model + recipe
docs/production.md — threat model, support matrix and staged deployment
docs/release.md — source-release checklist and authority boundaries
SECURITY.md — vulnerability reporting and security limits
CHANGELOG.md — history
License & acknowledgements
MIT — see LICENSE. This project originated as a fork of vespo92/OPNSenseMCP and preserves its MIT copyright notice; this repository was republished from a clean snapshot, so the pre-fork commit history lives upstream. Built on the Model Context Protocol for OPNsense, and usable from Claude, OpenAI, Hermes, and any other MCP-compatible client.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/gabrielion/OPNSenseMCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server