MCP server for LenelS2 NetBox via the NBAPI (persons, access levels, portals, event history)
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
git clone https://github.com/J-MaFf/s2-netbox-mcp{
"mcpServers": {
"s2-netbox-mcp": {
"command": "node",
"args": ["/path/to/s2-netbox-mcp/dist/index.js"]
}
}
}MCP Servers overview
# s2-netbox-mcp
A local MCP server that exposes LenelS2 S2 NetBox NBAPI operations —
persons/credentials, access levels, portals/readers/outputs, time specs,
holidays, portal/reader groups, threat levels, events/activity, and
partitions/UDF lists — as MCP tools usable from any MCP-compatible client
(Claude, Gemini/Antigravity, etc.).
> **Not** the open-source netboxlabs.com "NetBox" DCIM/IPAM tool. This targets
> LenelS2's **S2 NetBox** physical access-control appliance and its NBAPI
> (`Web-Based API for S2 NetBox and S2 Global`, LenelS2 doc #API-UG-14).
> [!WARNING]
> **This connects to a real physical security system.** With the wrong
> configuration, an AI agent using this server could unlock doors or modify
> access-control data on a live building. It is **read-only by default** —
> writes and destructive operations (lock/unlock, add/modify/delete) each
> require their own explicit opt-in environment variable (see **Write
> access** below) — but you are responsible for what you enable and which
> MCP client/model you point at it. See `SECURITY.md` before deploying
> anything beyond read-only against a production controller.
**Read-only by default.** With no write-related environment variables set,
this server registers only query/read NBAPI commands:
- `Login`
- `Logout`
- `GetAPIVersion`
- `GetPerson`
- `SearchPersonData`
- `GetCardAccessDetails`
- `GetCardFormats`
- `GetAccessLevel(s)`
- `GetAccessLevelGroup(s)`
- `GetPortals`
- `GetReader(s)`
- `GetOutputs`
- `GetTimeSpec(s)`
- `GetTimeSpecGroup(s)`
- `GetHoliday(s)`
- `GetPortalGroup(s)`
- `GetReaderGroup(s)`
- `GetAccessLevelNames`
- `GetPartitions`
- `GetUDFLists`
- `GetUDFListItems`
- `GetElevators`
- `GetFloors`
- `PingApp`
- `GetEventHistory`
- `ListEvents`
- `GetAccessHistory`
By default, this server registers only the query/read commands listed above.
It does not register any write, delete, or control operations against the
controller until you explicitly opt in via the environment variables in
**Write access** below. Among the read-only tools, two are composites,
`find_portals` and `get_unlock_window`, which issue only read commands. Note
there is no `GetPortal` (singular) command; only `GetPortals` (plural,
paginated, no single-portal filter) exists on the real NBAPI.
## Requirements
- Node.js >= 18.17 (tested on Node 24)
- An S2 NetBox controller reachable from wherever this server runs, with the
NBAPI enabled and configured for **session-login authentication** (not MAC
authentication — see the spec for why that's out of scope for v1)
- A NetBox operator account with API access and read permission on the
resources you want to query
## Setup
Two ways to get the server:
**Option A — npm (no clone needed):**
```bash
npm install -g s2-netbox-mcp
```
This installs the `s2-netbox-mcp` binary; point your MCP client's `command` at
`s2-netbox-mcp` directly (no `node dist/index.js` needed).
**Option B — clone and build:**
```bash
npm install
npm run build
```
Either way, copy `.env.example` to `.env` and fill in real values (or provide the same
variables directly in your shell / in the Claude Code MCP server config's
`env` block — see below). **Never commit `.env`** — it's already gitignored.
```bash
cp .env.example .env
# edit .env
```
Start the server directly to sanity-check it boots (it just waits on stdio
for an MCP client — Ctrl+C to stop; this also sends `Logout` if a session was
opened):
```bash
npm start
```
## Environment variables
| Variable | Required | Default | Description |
| ------------------------------ | -------- | ------- | --------------------------------------------------------------------------------------------------- |
| `NETBOX_BASE_URL` | Yes | — | Base URL of the NetBox controller's web interface, e.g. `https://netbox.example.internal`. No trailing slash or path — the client appends `NETBOX_API_PATH` itself. |
| `NETBOX_USERNAME` | Yes | — | NBAPI session-login username. |
| `NETBOX_PASSWORD` | Yes | — | NBAPI session-login password. Never logged, never written to any tracked file. |
| `NETBOX_ALLOW_INSECURE_TLS` | No | `false` | Set to `true`/`1`/`yes` to accept a self-signed/on-prem TLS certificate. **Explicit opt-in only** — any other value (including unset) keeps normal certificate verification. |
| `NETBOX_API_PATH` | No | `/nbws/goforms/nbapi` | The NBAPI path appended to `NETBOX_BASE_URL`. The default is the verified path on NetBox 6.x controllers. Only set this to override the default — e.g. to the legacy, pre-6.x path `/goforms/nbapi`, which returns **HTTP 410 Gone** on 6.x controllers (see Controller prerequisites below). A value without a leading `/` has one added automatically. |
| `NETBOX_ENABLE_WRITES` | No | `false` | Set to `true`/`1`/`yes` to register the write tools (see **Write access** below). Unset (or any other value) leaves the server strictly read-only. |
| `NETBOX_ENABLE_DESTRUCTIVE` | No | `false` | Set to `true`/`1`/`yes`, **together with** `NETBOX_ENABLE_WRITES`, to additionally register the 11 destructive tools (see **Write access** below). |
| `NETBOX_EVENT_API_PATH` | No | tracks `NETBOX_API_PATH` | Request path used only for `trigger_event`. Unset/empty tracks whatever `NETBOX_API_PATH` resolves to; a non-empty override is used verbatim (leading `/` added if missing) — e.g. the doc's pre-6.x Event API path `/appd/nbapi`, if your controller serves it separately. |
| `NETBOX_UNLOCK_HOLIDAY_GROUPS` | No | `8,7,6` | The holiday groups reserved for the managed unlock window, in `first,middle,last` segment order — see **Scheduled unlock windows** below. Must be 1-3 distinct integers in `1..8`, comma-separated; reserve groups nothing else on the controller uses. |
| `NETBOX_UNLOCK_NAME_PREFIX` | No | `MCP Unlock Window` | Name prefix of every object the managed unlock window creates: the portal group (`<prefix>`), the time spec group (`<prefix> time specs`), and the per-segment holidays/time specs (`<prefix> first/middle/last`). 1-40 characters so the longest name (`<prefix> time specs`) fits the 64-character NAME limit. |
| `NETBOX_DAILY_UNLOCK_HOLIDAY_GROUP` | No | `5` | The single holiday group reserved for the managed **daily recurring** unlock window — see **Scheduled daily unlock windows** below. Must be a single integer in `1..8`, and must not be a member of `NETBOX_UNLOCK_HOLIDAY_GROUPS` (the two features' reserved groups can never collide). |
| `NETBOX_DAILY_UNLOCK_NAME_PREFIX` | No | `MCP Daily Unlock Window` | Name prefix of every object the managed daily unlock window creates: the portal group (`<prefix>`), the time spec group (`<prefix> time specs`), and the one holiday/time spec (`<prefix> schedule`). 1-40 characters so the longest name fits the 64-character NAME limit. |
| `NETBOX_LIVE_TEST_PORTALKEY` | No | — | The `PORTALKEY` of the one door you designate safe to physically unlock during `npm run test:live:write`/`npm run test:live:write:daily`. Read only by those scripts, never by the server itself. |
If any of the three required variables is missing, the server prints a single
actionable line to stderr and exits with a non-zero status — it never prints
a stack trace on startup misconfiguration.
## Write access
Write/control tools exist in this server but are **not registered** unless
you explicitly opt in:
- **`NETBOX_ENABLE_WRITES=true`** registers the write tools listed in the
"Write tools" table below — the 45 pass-through tools (creating, modifying,
locking/unlocking, activating, and triggering) plus the three composite
write tools `set_portals_state`, `schedule_unlock_window`, and
`cancel_unlock_window`. Left unset (the default), the server's tool
surface is exactly the read tools below — byte-for-byte the same read-only
posture as before this variable existed.
- The two unlock-window composites delete **only** the holidays and time
specs they themselves own (named `<prefix> first|middle|last` — see
**Scheduled unlock windows**), and do so without `NETBOX_ENABLE_DESTRUCTIVE`
because those objects are server-owned; they never delete anything else.
- **`NETBOX_ENABLE_DESTRUCTIVE=true`**, set **in addition to**
`NETBOX_ENABLE_WRITES`, registers the 11 **destructive** tools (each
description is `DESTRUCTIVE:`-prefixed): `delete_access_level`,
`delete_access_level_group`, `delete_holiday`, `delete_portal_group`,
`delete_reader_group`, `delete_time_spec`, `delete_time_spec_group`,
`remove_credential`, `remove_person`, `remove_threat_level`,
`remove_threat_level_group`. Two ordinarily non-destructive write tools
also independently refuse one specific destructive-shaped call when this
flag is off, regardless of whether the tool itself is registered:
`modify_person` refuses a call with `DELETED="TRUE"` or
`PERSONPURGE="TRUE"`, and `modify_udf_list_items` refuses a call where any
list item has `DELETE="1"` — both name `NETBOX_ENABLE_DESTRUCTIVE` in the
error and send nothing to the controller.
- Every write tool's description starts with `WRITE:` (or `DESTRUCTIVE:` for
the 11 above), and every successful write's result text contains the
literal `SUCCESS` followed by the controller's response data as pretty
JSON (which may be `{}` when the command returns no data), so you can
always tell a write actually happened.
- Client-side guards (e.g. "give either `READERKEY` or `READERGROUPKEY`, not
both") reject malformed calls with a tool error **before** any NBAPI
command is issued — no partial or guessed request ever reaches the
controller.
Set these the same way as the other variables — in `.env` (see
`.env.example`) or your MCP server config'sWhat people ask about s2-netbox-mcp
What is J-MaFf/s2-netbox-mcp?
+
J-MaFf/s2-netbox-mcp is mcp servers for the Claude AI ecosystem. MCP server for LenelS2 NetBox via the NBAPI (persons, access levels, portals, event history) It has 0 GitHub stars and its last recorded update is dated 2026-09-16.
How do I install s2-netbox-mcp?
+
You can install s2-netbox-mcp by cloning the repository (https://github.com/J-MaFf/s2-netbox-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is J-MaFf/s2-netbox-mcp safe to use?
+
Our security agent has analyzed J-MaFf/s2-netbox-mcp and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.
Who maintains J-MaFf/s2-netbox-mcp?
+
J-MaFf/s2-netbox-mcp is maintained by J-MaFf. The last recorded GitHub activity is dated 2026-09-16, with 1 open issues.
Are there alternatives to s2-netbox-mcp?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy s2-netbox-mcp to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/j-maff-s2-netbox-mcp)<a href="https://claudewave.com/repo/j-maff-s2-netbox-mcp"><img src="https://claudewave.com/api/badge/j-maff-s2-netbox-mcp" alt="Featured on ClaudeWave: J-MaFf/s2-netbox-mcp" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ
The fastest path to AI-powered full stack observability, even for lean teams.