Releases: ZenixSolutions/netbox-mcp-server
Release list
v0.2.0
Added
-
NetBox deprecation warnings, surfaced through
netbox_describe
(src/schema/deprecations.ts). NetBox emits no machine-readable deprecation
signal — noDeprecationorSunsetheader, nodeprecated: trueanywhere
in the OpenAPI document, for any deprecated model. Verified against 4.6.8. A
client cannot detect any of it at runtime, which is why this one table is
hand-maintained while the rest of the layer is derived.It is advisory only. Nothing is blocked, nothing is refused, and there is
no switch to turn it into a gate. Write access remains the NetBox token's
write_enabledflag and object permissions, enforced by NetBox where no tool
argument can reach them.Covered:
dcim.inventoryitem,dcim.inventoryitemroleand
dcim.inventoryitemtemplate(deprecated 4.3, #19004, still full CRUD in
4.6.8 — and note that 5.0 appears only in the tracking issue: the release
notes and all three model docs say "a future NetBox release", so the note
says that too);dcim.interface.mac_addressand
virtualization.interface.mac_address;ipam.vlan.site(deprecated 4.4,
no removal version announced at all);dcim.module.local_context_data
(removed in a patch release, 4.6.3);dcim.frontport.rear_portand
rear_port_position(removed 4.5 forPortMapping); writes to
dcim.cabletermination(405 since 4.5); and v1 API tokens.Deprecations appear on read operations as well as writes — a caller
enumerating inventory items in order to migrate off them should be told why. -
The modular-hardware modelling doctrine, and a deprecations reference, in the
netbox-modelingskill. Modules generate interfaces; interfaces never hold
modules; cables terminate only on interfaces, so the module install precedes
the cable. Covers the{module}/{module}/N/eth/{module}/Npatterns —
including that{module}substitutes the module bay'sposition, not its
name, which is the difference betweeneth/1/1and an interface named
after nothing — nested bays (4.6, #19796), and the distinction between a
breakout optic (a module with several interface templates) and a breakout
cable (dcim.cablewith aprofile, 26 values in 4.6.8 against 4 in the
model doc, so take the enum fromnetbox_describe).The skill now forbids creating inventory items and models the same
hardware as modules in module bays, with module type profiles for parts that
have no components — 4.6 shipsFan,Power Supply,Hard Disk,CPU,
GPUandMemoryprofiles by default. Reading existing inventory items
stays allowed, because migrating off them requires enumerating them first.
Where NetBox has no replacement —discovered, per-instance roles, the
componentgeneric FK for a transceiver in a fixed port, and a spare part on
a shelf — the skill stops and asks rather than inventing an answer. -
Distribution as a plugin:
.claude-plugin/marketplace.jsonand
.claude-plugin/plugin.jsonbundle the skill and the MCP server together, and
docs/installing-the-skill.mdgives per-surface steps for Claude, ChatGPT
desktop (~/.codex/config.toml, skills in~/.agents/skills/) and Grok Build
(~/.grok/config.toml, which also reads Claude Code config unmodified).
npm run build:skillnow emits a flattened single-file Markdown render
alongside the.skillarchive, for surfaces that take an uploaded document
rather than a skill directory.What updates and what does not is stated plainly rather than implied: Claude
plugins check at session start, third-party marketplaces default to
auto-update off, and nothing else updates at all. ChatGPT Scheduled Tasks
and Grok Automations can report that a document changed but cannot write back
to stored skills or instructions, so a weekly alarm is possible and a weekly
refresh is not. -
tests/unit/tool-schema-contract.test.ts, which asserts whattools/list
actually publishes rather than what the Zod shapes say. The input schema is
the contract, and this repository does not generate it — the SDK converts our
Zod shapes and Zod decides what the JSON Schema says, so the contract can
change without a line here changing.It already has. Bumping Zod 3.25.76 → 4.4.3 (#40) drops
additionalProperties: falsefrom all five tool schemas: 7 occurrences
become 2. Every test passed and all six CI checks were green. Zod still strips
unknown keys at runtime, so it is not an injection path — but a host that
validates a call against the advertised schema before dispatching would begin
accepting arguments the previous schema refused, and nothing would report it.The test also pins the properties that are meant to be structural: that
neither execution tool exposes apath,url,endpointoruriargument,
and that the read/write annotation split is accurate rather than conservative
— ChatGPT desktop'swritesapproval mode gates on exactly those hints.
Confirmed to fail under 4.4.3 and pass under 3.25.76.
Fixed
-
A removal note asserted behaviour the connected instance refuted. It read
"It worked on earlier releases, so an instance older than 4.6.3 still accepts
it" fordcim.module.local_context_data— and a contract run against a live
NetBox 4.6.0 found the field absent from that instance's own derived write
schema. NetBox's release note calls it "unused", so it was very likely never
writable through the API at all. The table knew a version number and inferred
behaviour from it.A removal is now read against the instance rather than asserted from the
table: absent explains why the field is missing, present says the instance
predates the release so the field works now and breaks on upgrade, and with no
field list to check the note states the removal and stops. Same discipline as
the rest of this layer — the connected instance is the evidence. -
netbox_readcould sendbrief=false, which turns brief mode ON. NetBox
tests the raw query string for truthiness —request.GET.get('brief')— and
'false'and'0'are truthy Python strings, so absence is the only "off".
A model asking for complete objects wrote the obvious{ brief: false }and
received the compact form: a well-formed object with most of its fields
missing, HTTP 200, and nothing in the response saying it had been truncated.
A caller could then report a field as absent from NetBox and be wrong.This is the same failure shape as the misspelled filter the live contract run
found — the request succeeds and the answer is not what was asked for — and it
is caught the same way, before the request leaves the process.briefis now
translated rather than forwarded: falsey values drop the parameter, truthy
ones send the canonicaltrue. Real boolean filters such asenabled=false
are untouched. The underlying behaviour is a source-level reading of 4.6.8 and
is not documented, so the tests pin our translation rather than NetBox's
parsing. -
netbox_describe'sstructuredContentomitted the newdeprecationsarray,
so a client reading the structured channel rather than the rendered Markdown
would have seen none of it. -
Eight claims in the
netbox-modelingskill that a 4.6.8 audit refuted,
including "a front port requires the rear port it maps to" (rear_portwas
removed in 4.5), the asset-intake instruction to model SFPs and cables as
inventory item types, and "if this skill andnetbox_describedisagree,
netbox_describeis right" — still true about what the API accepts, false
about what you should write, since the schema cannot signal deprecation.