s2-netbox-mcp
Click on "Deploy 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., "@s2-netbox-mcpsearch for a person named Jane Doe and show their access levels"
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.
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).
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:
LoginLogoutGetAPIVersionGetPersonSearchPersonDataGetCardAccessDetailsGetCardFormatsGetAccessLevel(s)GetAccessLevelGroup(s)GetPortalsGetReader(s)GetOutputsGetTimeSpec(s)GetTimeSpecGroup(s)GetHoliday(s)GetPortalGroup(s)GetReaderGroup(s)GetAccessLevelNamesGetPartitionsGetUDFListsGetUDFListItemsGetElevatorsGetFloorsPingAppGetEventHistoryListEventsGetAccessHistory
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
Related MCP server: UniFi Network MCP Server
Setup
Two ways to get the server:
Option A — npm (no clone needed):
npm install -g s2-netbox-mcpThis 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:
npm install
npm run buildEither 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.
cp .env.example .env
# edit .envStart 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):
npm startEnvironment variables
Variable | Required | Default | Description |
| Yes | — | Base URL of the NetBox controller's web interface, e.g. |
| Yes | — | NBAPI session-login username. |
| Yes | — | NBAPI session-login password. Never logged, never written to any tracked file. |
| No |
| Set to |
| No |
| The NBAPI path appended to |
| No |
| Set to |
| No |
| Set to |
| No | tracks | Request path used only for |
| No |
| The holiday groups reserved for the managed unlock window, in |
| No |
| Name prefix of every object the managed unlock window creates: the portal group ( |
| No |
| The single holiday group reserved for the managed daily recurring unlock window — see Scheduled daily unlock windows below. Must be a single integer in |
| No |
| Name prefix of every object the managed daily unlock window creates: the portal group ( |
| No | — | The |
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=trueregisters 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 toolsset_portals_state,schedule_unlock_window, andcancel_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 withoutNETBOX_ENABLE_DESTRUCTIVEbecause those objects are server-owned; they never delete anything else.NETBOX_ENABLE_DESTRUCTIVE=true, set in addition toNETBOX_ENABLE_WRITES, registers the 11 destructive tools (each description isDESTRUCTIVE:-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_personrefuses a call withDELETED="TRUE"orPERSONPURGE="TRUE", andmodify_udf_list_itemsrefuses a call where any list item hasDELETE="1"— both nameNETBOX_ENABLE_DESTRUCTIVEin the error and send nothing to the controller.Every write tool's description starts with
WRITE:(orDESTRUCTIVE:for the 11 above), and every successful write's result text contains the literalSUCCESSfollowed 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
READERKEYorREADERGROUPKEY, 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's env block.
Controller prerequisites
Before this server can talk to your controller, on the NetBox web UI go to Configuration → Site Settings → Network Controller → Data Integration and confirm all three of these are checked:
Enable V2
Use Authentication
Use login username/password for authentication (requires setup privilege)
The NBAPI user account also needs a role with NBAPI read access (see the
NBAPI doc's "Setting Up User Roles for the API" section) — a login that
succeeds but can't read the resources this server queries will surface as
FAIL or APIERROR responses per tool call. If you set
NETBOX_ENABLE_WRITES, that role needs Read-Write API privilege instead
(Configuration → Site Settings → User Roles → API Privilege) — Read-Only
suffices only for the read tools.
Troubleshooting
"Login succeeds but every other command returns
APIERROR 5." This is the live-observed symptom of the Use login username/password for authentication (requires setup privilege) checkbox being unticked, which puts the controller in MAC-authentication mode instead of session-login mode (MAC auth is out of scope for this server — see the spec).Loginstill returnsSUCCESSwith a session ID, but every subsequent command — includingLogout— fails withAPIERROR 5. Fix: tick that checkbox on the Data Integration tab. This server's client detects this exact pattern (a successful re-login followed by anotherAPIERROR 5) and surfaces a tool error naming the checkbox directly."HTTP 410 Gone." The configured
NETBOX_API_PATHis not served by this controller. NetBox 6.x serves the NBAPI at/nbws/goforms/nbapi(the default this server uses); the 2020 doc's/goforms/nbapipath is deregistered on 6.x and returns 410 for every request. If you're on a pre-6.x controller, setNETBOX_API_PATH=/goforms/nbapiexplicitly; if you're on 6.x and still see this, double-checkNETBOX_API_PATHisn't set to something else by mistake.
Registering with Claude Code
Add this to your Claude Code MCP server configuration (e.g. via
claude mcp add-json s2-netbox-mcp '<json>', or directly in your
.mcp.json / claude_desktop_config.json-style config file under
mcpServers):
{
"mcpServers": {
"s2-netbox-mcp": {
"command": "node",
"args": ["/absolute/path/to/s2-netbox-mcp/dist/index.js"],
"env": {
"NETBOX_BASE_URL": "https://netbox.example.internal",
"NETBOX_USERNAME": "svc-account",
"NETBOX_PASSWORD": "REPLACE_ME",
"NETBOX_ALLOW_INSECURE_TLS": "false"
}
}
}
}Replace the args path with the actual absolute path to dist/index.js on
your machine, and replace the env values with your real controller details
(or omit env entirely and rely on a .env file next to the project if you
prefer — either works, since src/index.ts loads .env via dotenv before
reading process.env). Run npm run build first so dist/index.js exists.
Tools exposed
Read tools (always registered)
Tool | Wraps NBAPI command | Required params |
|
| — |
|
|
|
|
| — (all filters optional) |
|
|
|
|
| — |
|
|
|
|
| — (optional |
|
|
|
|
| — (optional |
|
| — (optional |
|
| — (optional |
|
|
|
|
| — (optional |
|
| — (optional |
|
|
|
|
| — (optional |
|
| — |
|
| — (optional |
|
|
|
|
| — (optional |
|
|
|
|
| — (optional |
|
|
|
|
| — (optional |
|
|
|
|
| — (optional |
|
|
|
|
| — (optional |
|
| — |
|
| — |
|
|
|
|
| — (optional |
|
| — (optional |
|
| — |
|
| — |
|
| — |
There is deliberately no get_portal (singular) tool — no such NBAPI command
exists; only GetPortals (plural) does. get_card_access_details and
get_access_history identify a card by ENCODEDNUM/CARDFORMAT (and
get_access_history optionally by HOTSTAMP), not by PERSONID — neither
command has a PERSONID parameter.
Every read tool except find_portals returns a thin JSON pass-through of
that NBAPI command's response fields — no reshaping. Each tool's input
schema declares exactly the documented PARAMS fields for its command — no
invented, renamed, or passthrough fields. All NBAPI parameter names above
are copied verbatim from the NBAPI Command Reference (see
specs/archive/s2-netbox-mcp-write.md and the archived specs/archive/s2-netbox-mcp.md)
— none are invented or guessed.
Seven tools are composites — they combine several NBAPI commands and reshape
the result instead of passing one command through: find_portals,
get_unlock_window, and get_daily_unlock_window (read-only, always
registered), and set_portals_state, schedule_unlock_window,
cancel_unlock_window, schedule_daily_unlock_window, and
cancel_daily_unlock_window (write, registered only with
NETBOX_ENABLE_WRITES). Every composite reads list commands fully
paginated (following NEXTKEY until -1) and issues only commands from the
closed allowlist. set_portals_state locks, unlocks (Extended Unlock until
locked again), or momentarily unlocks many portals in one call — the given
portalKeys or every portal — issuing one command per portal sequentially and
never stopping on a single failure; its result partitions the portals into
succeeded, alreadyInState (the controller's "Portal state not changed"),
and failed, and is an error only when failed is non-empty. The five
unlock-window tools are described under Scheduled unlock windows and
Scheduled daily unlock windows below.
find_portals is for finding a door when you only know
where it is. Portal names are site codes (01OF05A), and the only
human-readable location text on the controller is each reader's DESCRIPTION.
GetPortals doesn't return it, and neither command takes a filter. So
find_portals reads every page of GetPortals and GetReaders, joins them by
READERKEY, and returns the portals where every term of query appears
(case-insensitive) in the portal name, a reader name, or a reader description.
For example, "maintenance office" matches a reader described as
BREAKROOM TO MAINTENANCE OFFICE. Each match includes its readers' names and
descriptions. The result also lists portalsWithoutDescriptions: portals none
of whose readers has a description, which can only be found by name. It issues
no commands beyond those two.
Write tools and Destructive tools
write (needs only NETBOX_ENABLE_WRITES) and destructive (needs
NETBOX_ENABLE_WRITES and NETBOX_ENABLE_DESTRUCTIVE). Every write
tool's input schema declares exactly the documented PARAMS fields for its
command, matching required/optional as documented — see the "Write access"
section above for the gating rules and the shared SUCCESS/WRITE:/
DESTRUCTIVE: conventions.
Tool | Wraps NBAPI command | Required params | Tier |
|
|
| write |
|
|
| write |
|
|
| write |
|
|
| write |
|
|
| write |
|
|
| write |
|
|
| write |
|
|
| write |
|
|
| write |
|
|
| write |
|
|
| destructive |
|
|
| destructive |
|
|
| write |
|
|
| write |
|
|
| destructive |
|
|
| write |
|
|
| write |
|
|
| destructive |
|
|
| write |
|
|
| write |
|
|
| destructive |
|
|
| write |
|
|
| write |
|
|
| destructive |
|
|
| write |
|
|
| write |
|
|
| destructive |
|
|
| write |
|
|
| write |
|
|
| destructive |
|
|
| write |
|
|
| write |
|
|
| destructive |
|
|
| write |
|
|
| write |
|
|
| write |
|
|
| destructive |
|
|
| write |
|
|
| write |
|
|
| destructive |
|
|
| write |
|
|
| write |
|
|
| write |
|
|
| write |
|
|
| write |
|
|
| write |
|
|
| write |
|
| — | write |
|
|
| write |
|
| — | write |
modify_portal_group and modify_reader_group always replace the group's
membership with the PORTALKEYS/READERKEYS you send — on this controller
(6.2.0, verified live) an omitted or unparsed list empties the group instead
of leaving it unchanged, so both tools require the complete membership.
trigger_event is unverified live on 6.x; NETBOX_EVENT_API_PATH is
available to override the request path if your controller serves the Event
API separately from the main NBAPI path (see the environment variable table
above).
switch_partition changes the partition for every later call made by this
server process, not just the caller's own next request — the NBAPI session
is cached and reused, and SwitchPartition has no per-call scope.
Person / credential tools and Active Directory
If this NetBox instance syncs person/access-level data from Active
Directory, any write this server makes to a synced field is silently
overwritten on the next AD sync — add_person and modify_person both
carry this caution in their tool descriptions. Separately, modify_person's
ACCESSLEVELS has two syntaxes: a plain list of access-level name strings
replaces the person's entire set of access levels, while a list of
{ ACCESSLEVELNAME, DELETE?, ACTDATE?, EXPDATE?, AUTOREMOVE? } blocks is
additive (adds/removes individual levels without touching the rest). Mixing
the two syntaxes in one call is rejected client-side before any command is
sent.
Scheduled unlock windows
"Unlock these doors from start to end" is one call —
schedule_unlock_window — and the controller itself enforces the
schedule: no process has to stay alive to relock the doors, so the MCP host
can go away the moment the call returns.
How it works (the same objects an operator creates by hand). The window is
realised as a Holiday covering the dates, a Time Spec with no weekdays
and only one holiday group ticked, and a Portal Group whose Unlock Time
Spec is that time spec's group. A time spec with no weekdays and holiday
group G ticked is active only on dates covered by a holiday in group G, so
the portals unlock exactly on the window's dates and clock range. A window
that spans midnight is split into up to three segments — first (start time →
23:59 on the start date), middle (00:00 → 23:59 on every date strictly
between, if any) and last (00:00 → end time on the end date) — each with its
own holiday + time spec pair.
Managed objects and the single-window model. Everything the tool creates
is named with NETBOX_UNLOCK_NAME_PREFIX (default MCP Unlock Window): the
portal group is named exactly <prefix>, the time spec group <prefix> time specs (never <prefix> — group names are unique across group types on this
controller, so a portal group and a time spec group cannot share a name), and
the per-segment holidays and time specs <prefix> first, <prefix> middle,
<prefix> last. Names are the identity. There is one managed window at a
time: scheduling a new one rewrites those same objects (modifying what
exists, adding what is missing, deleting leftover segments from the previous
window), and calling it twice with the same arguments is idempotent (only
Modify/Get commands, same keys). The composite tools never modify or delete
any object whose name is not exactly one of those; a user-created object
that happens to carry one of those names is treated as managed. The apply
order is fixed — resolve portals, managed time spec group, per-segment
holiday + time spec, group membership, delete leftovers, managed portal group
— and every step is read back and compared to the plan before the tool
reports verified: true; any mismatch is a tool error describing the field.
If any apply step fails, the tool rolls back by deleting every managed
holiday and time spec written so far (mirroring cancel_unlock_window's
cleanup) before returning the error, so no partial window is left active;
the error text names the failed step, the controller's message, and what the
rollback removed.
Reserved holiday groups. NetBox has exactly eight holiday groups (1–8),
shared by every time spec on the controller. NETBOX_UNLOCK_HOLIDAY_GROUPS
(default 8,7,6) reserves one group per segment kind (first, middle,
last, in that order). Reserve groups nothing else on the controller uses.
With fewer than three groups configured, only windows needing that many
segments can be scheduled (one group = same-day windows only); the tool never
doubles up a group, because two segments sharing one would each unlock on the
other's dates.
The side-effect check and acknowledgeSideEffects. A holiday in group
G suppresses, on its dates, every time spec that does not tick G — an
access level whose time spec ticks only groups 1–3, say, would lose access
during a window that uses group 8. Before writing anything,
schedule_unlock_window reads every time spec and holiday and reports
suppressedTimeSpecs (time specs other than Never and its own that lack a
group the plan uses) and overlappingHolidays (non-managed holidays whose
dates intersect the window — reported, never touched). If any time spec would
be suppressed, the call is refused with nothing written unless
acknowledgeSideEffects=true. dryRun=true returns the plan and the report
without writing anything, whether or not you acknowledged. The built-in
Always time spec ticks all eight groups and is never affected.
Cancelling. cancel_unlock_window first, if the managed portal group
exists, points it at the built-in Never time spec group (re-sending its
current portals); then, regardless of whether that portal group exists,
deletes the managed holidays and empties the managed time spec group and
deletes the managed time specs. The last two are best-effort: if the
controller refuses them, the tool still succeeds and lists what was left
under leftBehind, because once the portal group (if any) is on Never and
no managed holiday exists, nothing can unlock. The managed portal group and
time spec group are kept (pointing at Never / empty) and reused by the next
window. The tool reports there was nothing to cancel only when no managed
object of any kind — portal group, time spec group, holiday, or time spec —
exists.
get_unlock_window (always registered, read-only) shows the current managed
state — the portal group and whether it points at the managed time spec
group, that group's members (read from GetTimeSpecGroups, because
GetTimeSpecGroup returns FAIL/NOT FOUND on the verified 6.2.0
controller), the managed time specs and holidays — plus the window derived
from them and activeNow on the host clock.
Limits and caveats.
A window must end in the future and be at most 31 days long. Holidays are capped at 30 per partition, so a window whose segments would push past that is refused.
portalKeysare keys only (useget_portalsorfind_portalsto map names); an unknown key is refused before anything is written.End of day on the NBAPI is
23:59(the built-inAlwaysuses it), andENDTIMEis inclusive through the end of that minute, so there is no midnight gap between segments of a multi-day window. A window's door relocks up to 59 seconds after the statedendminute (observed live: a window ending08:27relocked at08:27:59controller time). Anendof00:00means "up to 23:59 of the previous day".Times are the controller's local time. The MCP host is assumed to share the controller's timezone; the host clock is used only to reject windows that have already elapsed and to compute
activeNow.The physical unlock is not observable through the NBAPI: no read command exposes portal state, and
GetEventHistorycarries no Unlock/Relock activity. The tool verifies its work by reading the configuration objects back and comparing them to the plan; confirm the door itself on Monitor → Portal Status or in person.set_portals_stateis the immediate alternative: itsUNLOCKis an Extended Unlock that lasts untilLOCK, with nothing scheduling the relock.
Session handling, retry-on-expired-session, and error mapping are all automatic and match the NBAPI documentation:
The first tool call triggers
Login; the session ID is cached and reused for every later call in the same server run.If a call fails with
APIERROR 5(auth failure / expired session), the client transparently re-logs-in once and retries the original command.An
<APIERROR>response surfaces as a tool error like"5: There was an authentication failure."A
<CODE>FAIL</CODE>response surfaces as a tool error including the controller'sERRMSGtext verbatim.A
<CODE>NOT FOUND</CODE>response (e.g. an unknownPERSONID) is returned as a normal, non-error result stating "not found" — it is not thrown as an exception.SIGINT/SIGTERMtriggerLogoutfor any active session before the process exits.
Scheduled daily unlock windows
The companion to Scheduled unlock windows above: "unlock these doors from
dailyStartTime to dailyEndTime, every day from startDate through
endDate" — a single partial-day window that recurs daily across a date
range, which schedule_unlock_window cannot express (it models one
continuous span, so a multi-day request there keeps doors unlocked overnight
on the days strictly between the first and last). schedule_daily_unlock_window
relocks the doors every night outside the daily window.
How it works (reusing the same mechanism). This reuses the exact
holiday + time spec + portal group mechanism described above: a Holiday
spanning the whole date range, a Time Spec with no weekdays and
only the one reserved daily holiday group ticked, and a Portal Group whose
Unlock Time Spec is that time spec's group. Because a time spec with no
weekdays and holiday group G ticked is active during its
STARTTIME-ENDTIME on every date covered by a holiday in group G,
one holiday (covering every date in the range) paired with one partial-day
time spec already expresses "the same time-of-day window, every day in the
range" — no first/middle/last segment-splitting is ever needed, unlike
the continuous feature, whose planner has to split a multi-day span into up
to three segments precisely because a middle day needs a full 00:00-23:59
grant. This feature's plan is always exactly one segment.
Environment variables and collision safety. NETBOX_DAILY_UNLOCK_HOLIDAY_GROUP
(default 5) is the single holiday group this feature reserves, and
NETBOX_DAILY_UNLOCK_NAME_PREFIX (default MCP Daily Unlock Window) names
its managed objects — see the environment variable table above for both.
NETBOX_DAILY_UNLOCK_HOLIDAY_GROUP is validated at startup to never be a
member of NETBOX_UNLOCK_HOLIDAY_GROUPS, so this feature and the
continuous one always use disjoint holiday groups, and — because each
feature's managed portal group and time spec group are named after its own
prefix — disjoint managed-object names as well. Consequently the two
features can be active at the same time: a daily window and a continuous
window may both be scheduled and unlocking doors concurrently, with no
shared NBAPI object between them. This also means schedule_daily_unlock_window's
side-effect check does not special-case a currently-active continuous
window — if its dates happen to overlap the daily plan's dates, it is
reported like any other foreign time spec/holiday, which is the correct,
general behaviour rather than a special case.
Managed objects and the single-daily-window model. Everything this
tool creates is named with NETBOX_DAILY_UNLOCK_NAME_PREFIX: the portal
group is named exactly <prefix>, the time spec group <prefix> time specs
(never <prefix> — group names are unique across group types on this
controller, same as the continuous feature), and the one holiday and one
time spec <prefix> schedule (same name, different object tables — no
collision). Names are the identity. There is one managed daily window at a
time: scheduling a new one rewrites those same objects (modifying what
exists, adding what is missing), and calling it twice with the same
arguments is idempotent (only Modify/Get commands, same keys). The tools
never modify or delete any object whose name is not exactly one of those; a
user-created object that happens to carry one of those names is treated as
managed. The apply order is fixed — resolve portals, managed time spec
group, managed holiday, managed time spec, group membership, managed portal
group — and every step is read back and compared to the plan before the
tool reports verified: true; any mismatch is a tool error describing the
field. If any apply step fails, the tool rolls back by deleting the managed
holiday and time spec written so far (mirroring cancel_daily_unlock_window's
cleanup) before returning the error, so no partial window is left active;
the error text names the failed step, the controller's message, and what
the rollback removed.
The side-effect check and acknowledgeSideEffects. Exactly as for the
continuous feature: a holiday in the reserved daily group suppresses, on its
dates, every time spec that does not tick that group. Before writing
anything, schedule_daily_unlock_window reads every time spec and holiday
and reports suppressedTimeSpecs (time specs other than Never and its own
that lack the reserved daily group) and overlappingHolidays (non-managed
holidays whose dates intersect the window — reported, never touched). If any
time spec would be suppressed, the call is refused with nothing written
unless acknowledgeSideEffects=true. dryRun=true returns the plan and the
report without writing anything, whether or not you acknowledged.
Cancelling. cancel_daily_unlock_window first, if the managed
portal group exists, points it at the built-in Never time spec group
(re-sending its current portals); then, regardless of whether that portal
group exists, deletes the managed holiday if it exists, and empties the
managed time spec group and deletes the managed time spec if either exists.
The last two are best-effort: if the controller refuses them, the tool still
succeeds and lists what was left under leftBehind, because once the portal
group (if any) is on Never and no managed holiday exists, nothing can
unlock. The managed portal group and time spec group are kept (pointing at
Never / empty) and reused by the next daily window. The tool reports there
was nothing to cancel only when no managed object of any kind — portal
group, time spec group, holiday, or time spec — exists.
get_daily_unlock_window (always registered, read-only) shows the current
managed state — the portal group and whether it points at the managed time
spec group, that group's members, the one managed time spec and holiday
(singular, not arrays — this feature never has more than one of each) —
plus the window derived from them and activeNow on the host clock.
Limits and caveats.
A window must end in the future and span at most 31 days (
endDate - startDate). Holidays are capped at 30 per partition, so a window whose one holiday would push past that is refused.portalKeysare keys only (useget_portals/find_portalsto map names); an unknown key is refused before anything is written.An overnight-crossing daily window is not supported:
dailyEndTimemust be strictly later thandailyStartTime(same-day time-of-day only). A request like "10 PM to 5 AM, every night" is rejected — a future extension could express this as two segments, but it is out of scope here.There is no per-weekday selectivity: the whole
[startDate, endDate]range unlocks every day at the given time-of-day (no "weekdays only" filtering).Dates are
YYYY-MM-DDand times areHH:MM, both controller-local; the same midnight-relock and host/controller-clock-assumption caveats as the continuous feature above apply here too.The physical unlock is not observable through the NBAPI — confirm the door on Monitor → Portal Status or in person, exactly as above.
Testing
npm testRuns the full unit test suite against a hand-rolled, in-memory HTTP stub — no network access and no live controller are required or contacted.
Live smoke test (optional)
npm run test:liveThis calls all read tools except get_unlock_window/get_daily_unlock_window
(34 of the 36 — see Tools exposed below) against a real, configured controller and
prints a PASS/FAIL line per tool plus a summary, exiting non-zero if
anything failed. It only runs if NETBOX_BASE_URL, NETBOX_USERNAME, and
NETBOX_PASSWORD are all set (loaded from .env if present); otherwise it
prints one line saying live testing was skipped and exits 0. It never prints
the value of NETBOX_PASSWORD, under any circumstance, and it never issues
a write/control command regardless of NETBOX_ENABLE_WRITES. npm test
never runs this script and never requires .env to exist.
Live write smoke test (optional, opt-in twice)
npm run test:live:write # CRUD round-trips only
npm run test:live:write -- --go # ... plus the real 2-minute unlock window
npm run test:live:write -- --go --start 14:30 # pin the unlock time (1-60 min ahead)PowerShell: on at least one PowerShell/npm combination this silently drops flags passed after
--(npm printsnpm warn Unknown cli config "--go"and the flag never reaches the script — observed live, 2026-09-15). If--godoesn't trigger phase (c), call the script directly instead:npx tsx scripts/live-check-write.ts --go.
This skips with one line and exit 0 — making no network call — unless
NETBOX_BASE_URL, NETBOX_USERNAME, NETBOX_PASSWORD,
NETBOX_ENABLE_WRITES=true and NETBOX_LIVE_TEST_PORTALKEY are all set.
Most of the round-trips below issue deletes/removes directly against the
controller (independent of the MCP server's own NETBOX_ENABLE_DESTRUCTIVE
gating, which this script bypasses by calling the NBAPI client directly), so
set NETBOX_ENABLE_DESTRUCTIVE=true before running it.
Otherwise it round-trips add → get → modify → get → delete for a time spec, a
time spec group, a holiday, a reader group, and a portal group under the
distinct prefix MCP livecheck (the portal group's unlock time spec group is
Never and the holiday is in 2099, so nothing can unlock), asserting each
read-back. It then round-trips a person (AddPerson → GetPerson →
ModifyPerson → GetPerson) plus a credential on that person (AddCredential
→ GetPerson with WANTCREDENTIALID → ModifyCredential with DISABLED=1
→ read-back → RemoveCredential → read-back) → RemovePerson, accepting
either NOT FOUND or DELETED=TRUE on the final GetPerson (never sends
PERSONPURGE); an access level (AddAccessLevel with TIMESPECGROUPKEY
Never → GetAccessLevel → ModifyAccessLevel → read-back →
DeleteAccessLevel → read-back gone) plus an access level group built from a
second temporary access level (AddAccessLevelGroup → GetAccessLevelGroup
→ ModifyAccessLevelGroup → read-back → DeleteAccessLevelGroup, tolerating
the same FAIL/ERRMSG="NOT FOUND" quirk documented for GetTimeSpecGroup
against an empty collection); a threat level plus a threat level group
(AddThreatLevel → AddThreatLevelGroup → ModifyThreatLevel →
ModifyThreatLevelGroup → RemoveThreatLevelGroup → RemoveThreatLevel,
proven gone by a second RemoveThreatLevel failing — there is no
GetThreatLevel, and SetThreatLevel is never called); InsertActivity
with a timestamped USERACTIVITY record; a UDF list item round-trip via
ModifyUDFListItems (or a recorded SKIPPED pass if no UDF list is
configured); and GetPartitions → SwitchPartition back to the session's
own partition (AddPartition is never called). It cleans up any
MCP livecheck leftovers — including persons, access levels/groups, and
threat levels/groups — from an aborted run, both before and after the round
trips.
It then estimates the controller's clock from the newest GetAccessHistory
record and refuses to run the door phase — regardless of --go — when that
estimate disagrees with the host clock by more than 2 minutes; window times
passed to schedule_unlock_window are always controller-local, not host-local.
With --go — pass it only after notifying the user (push notification
plus a chat message giving the exact unlock and relock clock times) and
receiving a go-ahead, because they observe the door — it prints a
HEADS-UP line, schedules a real 2-minute unlock of the designated portal
through the real schedule_unlock_window executor (unlock at now + 2 min and
relock at now + 4 min, or at --start HH:MM), prints OBSERVE: portal ... should unlock at HH:MM and relock at HH:MM — confirm on Monitor → Portal Status, polls get_unlock_window every 30 s until one minute after relock,
then calls cancel_unlock_window and asserts the managed portal group is on
Never with no managed holiday, time spec, or time spec group member left
(leftBehind is tolerated but reported). It refuses that phase if a managed
window already exists (so it never replaces a real one); apart from the
supervised single actions below, it never touches outputs, TriggerEvent, or
portal lock/unlock actions, never prints the password, exits non-zero on any
failed assertion (still cancelling the window first), and npm test never
runs it.
Supervised single actions
npm run test:live:write -- --action unlock_portal
npm run test:live:write -- --action set_threat_level --value High--action <name> [--value <v>] runs exactly one write against the
designated portal (or its strike output) instead of the full flow above —
skipping phases (b), (b2), and (c) entirely. It still requires
NETBOX_ENABLE_WRITES=true and the credential variables (same skip line as
above), but not NETBOX_ENABLE_DESTRUCTIVE, since no deletes happen. It
refuses to run — exit 2, no network call — if --action is combined with
--go, if the action name is unknown, or if set_threat_level's required
--value is missing. It prints the exact command and params sent (never
credentials), the controller's CODE/DETAILS or ERRMSG, and an
OBSERVE: ... line describing what to check at the door or on Monitor; a
FAIL with ERRMSG "Portal state not changed" is reported as
PASS-with-note rather than a failure. Exits 0 on success or already-in-state,
1 otherwise, and unknown/invalid arguments exit 2.
Every action is reversible:
Action | Effect | Reverse |
|
|
|
|
| — |
|
| — |
|
|
|
|
|
|
|
| — |
| the real |
|
|
| — |
|
| — |
|
|
|
|
|
|
|
| — |
activate_output/deactivate_output resolve the strike output by finding
the GetOutputs entry whose NAME starts with the designated portal's
NAME (e.g. portal "02OF01A" → output "02OF01A EL"), failing clearly if
none is found. AddPartition is never reachable through --action, same as
the rest of this script.
trigger_event_activate/trigger_event_deactivate require --value <EVENTNAME> — the name of a NetBox event that must already exist (events
cannot be created via the NBAPI; create it first in the NetBox UI). This is
the only live verification path for trigger_event — the full CRUD
flow above never calls TriggerEvent. Both actions go through the same
NetboxClient.call as every other command, so NETBOX_EVENT_API_PATH
routing still applies; the script prints which URL path it used.
Live write smoke test — daily unlock window (optional, opt-in twice)
npm run test:live:write:daily # CRUD round-trips only
npm run test:live:write:daily -- --go # ... plus the real 2-minute daily unlock windowPowerShell: see the same-named caveat under "Live write smoke test" above — if
--gois silently dropped, usenpx tsx scripts/live-check-write-daily.ts --goinstead (verified live, 2026-09-15, on portal02OF01A: unlock/relock confirmed in person, 16/16 steps PASS).
A sibling script to npm run test:live:write above, covering
schedule_daily_unlock_window/cancel_daily_unlock_window/
get_daily_unlock_window (kept as a separate npm script rather than
chained onto test:live:write so -- --go keeps reaching the script it is
meant for). It skips with one line and exit 0 — making no network call —
under the same gating as npm run test:live:write. Otherwise it round-trips
add → get → modify → get → delete for a time spec, a time spec group, a
holiday, and a portal group under the distinct prefix MCP livecheck daily
(the portal group's unlock time spec group is Never and the holiday is in
2099, so nothing can unlock), asserting each read-back, then runs the same
controller-clock-skew guard as test:live:write (refusing the door phase
above a 2-minute skew regardless of --go).
With --go — pass it only after notifying the user and receiving a
go-ahead, same as above — it prints a HEADS-UP line, schedules a real
2-minute daily unlock covering only today's date (dailyStartTime = now
2 min,
dailyEndTime= now + 4 min) on the designated portal through the realschedule_daily_unlock_windowexecutor, prints anOBSERVE: ...line, pollsget_daily_unlock_windowevery 30 s until one minute after relock, then callscancel_daily_unlock_windowand asserts the managed portal group is onNeverwith no managed holiday or time spec left (leftBehindis tolerated but reported). It refuses that phase if a managed daily window already exists, never touches persons, credentials, access levels, threat levels, outputs, events, partitions, or UDF lists, never prints the password, exits non-zero on any failed assertion (still cancelling the window first), andnpm testnever runs it.
Out of scope
Photo ID handling (
GetPictureand photo upload)StreamEvents/ the persistent/appdevent/nbapi/eventpush feedMAC-based authentication (session-login only)
The S2 Global API variant
The deprecated NBAPI commands (
EditPerson,EditThreatLevel,EditThreatLevelGroup,GetAccessDataLog,GetAccessCardDetails,LoginUserName,LoginUserPassword)Multiple concurrent managed unlock windows, per-window naming, or any persistence on the MCP host (there is one managed window; names are its identity)
Resolving portals by name in the composite tools (keys only —
get_portals/find_portalsmap names)Automatically deleting the managed portal group or time spec group on cancel (they stay, pointing at
Never/ empty, and are reused)Any scheduler on the host (Task Scheduler, in-process timers) — the controller is the only scheduler
Confirmation prompts inside the server — the MCP host's permission model and the environment gates are the controls
Any GUI/dashboard beyond the MCP tool surface
See specs/archive/s2-netbox-mcp-write.md for the full requirements the write-tool
surface was built against, and specs/archive/s2-netbox-mcp.md for the
original read-only v1 spec (archived — all its acceptance criteria passed,
including live verification).
Contributing
Bug reports, feature requests, and PRs are welcome — see CONTRIBUTING.md for the
workflow (issue first, branch naming, PR conventions) and the physical-safety note that
applies to any change touching write/destructive tools.
Security
Found a vulnerability? See SECURITY.md for how to report it privately and what the
physical-safety blast radius looks like at each configuration level.
Available Tools
36 toolscheck_connectionA
Confirms the server can authenticate to the configured S2 NetBox controller and returns the NBAPI version string (wraps GetAPIVersion). No parameters required.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of disclosing behavior. It clearly states that the tool performs an authentication check and returns a version string, and it names the wrapped API. This is transparent for a simple read/check operation, though it does not describe failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler, with the core purpose front-loaded. Every phrase adds useful information: what it confirms, what it returns, and the wrapped API method.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter connectivity check with no output schema, the description is complete: it states the action, the target system, the return value, and the underlying API. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is little to document. The description explicitly states 'No parameters required,' which reinforces the empty schema and removes any ambiguity for the agent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('confirms'), a specific resource ('server can authenticate to the configured S2 NetBox controller'), and a concrete outcome ('returns the NBAPI version string'). It also names the wrapped API method (GetAPIVersion), which clearly distinguishes it from the many get/list sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: to verify server authentication/connectivity to the S2 NetBox controller. It does not explicitly name alternatives or exclusions, but among siblings it is the only connection-checking tool, so the usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_portalsA
Finds portals (doors) by location or name. Portal names are site codes (e.g. 01OF05A), so this also searches each portal's reader names and reader descriptions (e.g. 'WORKSHOP TO MAINTENANCE OFFICE'). Case-insensitive; a portal matches when every whitespace-separated term appears in its name, a reader name, or a reader description. Reads every page of GetPortals and GetReaders and joins them by READERKEY. The result also lists portals with no reader description, which can only match by name.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Required. Search terms, e.g. "maintenance office", "electrical closet", or "01OF05". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden, and it does so thoroughly. It discloses case-insensitive matching, the all-terms-must-match rule, the fields searched, the full-page reads of GetPortals and GetReaders, the join key READERKEY, and the special case of portals with no reader description. This is far beyond what the minimal schema or annotations would provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence is functional: the first states what it finds, the second clarifies name semantics and examples, the third defines exact matching behavior, and the fourth explains the no-reader-description edge case. There is no filler or repetition of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (one required parameter), no annotations, and no output schema, the description provides enough detail for an agent to invoke it correctly and understand matching behavior. It does not describe the output shape or error cases, but those are less critical for a search-style tool when the matching and result inclusion behavior are already clearly specified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema already describes the single query parameter with examples, the description adds substantial meaning beyond it: whitespace-separated terms are treated as separate search terms, matching is case-insensitive, and every term must appear for a match. These semantic rules materially affect how an agent should construct a query, so the description earns credit above the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Finds' with a clearly defined resource, 'portals (doors)' and explains exactly what is searched: name, reader names, and reader descriptions. It effectively distinguishes this tool from sibling raw-listing tools like get_portals and get_readers by describing a joined, term-based search rather than a raw retrieval. The example site codes and human-readable names make the intent unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the main use case: searching for portals by location or name rather than listing all portals. However, it never explicitly says when to use this tool versus siblings like get_portals or get_readers, and it gives no exclusion criteria. The agent must infer the alternative from the sibling list and context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_access_historyA
Returns historical access (grant/deny) records for optional filters (wraps NBAPI GetAccessHistory). Identifies a person by ENCODEDNUM/HOTSTAMP, not PERSONID — GetAccessHistory has no PERSONID parameter.
| Name | Required | Description | Default |
|---|---|---|---|
| ORDER | No | Optional. Sort order for returned records. | |
| HOTSTAMP | No | Optional. Restrict results to this hot-stamp number. | |
| AFTERLOGID | No | Optional. Return records strictly after this LOGID. | |
| CARDFORMAT | No | Optional. Card format of ENCODEDNUM/HOTSTAMP. | |
| ENCODEDNUM | No | Optional. Restrict results to this encoded card number. | |
| MAXRECORDS | No | Optional. Maximum number of records to return. | |
| NEWESTDTTM | No | Optional. Newest date/time to include. | |
| OLDESTDTTM | No | Optional. Oldest date/time to include. | |
| STARTLOGID | No | Optional. Begin returning records at this LOGID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden of conveying behavior. It clearly signals a read-only operation ('Returns...records' in the first sentence), discloses that records are 'grant/deny' entries, and highlights a behavioral quirk: identification uses ENCODEDNUM/HOTSTAMP rather than PERSONID. It could add pagination or auth details, but the core behavior is transparent enough for safe invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler, and the most important behavior is front-loaded. The first sentence gives purpose and the second immediately clarifies the critical identifier limitation, earning its place without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a moderately complex tool with nine optional parameters and no output schema, the description is largely complete: it states the operation, the data kind, the filtering model, and the critical identification caveat. It leaves return-structure details unspecified, but the schema and the concise behavioral description give an agent enough to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all nine optional parameters. The description adds meaningful semantic context beyond the schema by explaining that ENCODEDNUM/HOTSTAMP are the identification keys used by the underlying NBAPI and that PERSONID is intentionally unsupported, which helps the agent reason about which parameters to supply.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Returns historical access (grant/expiry) records') and a clear resource subject to filters. It also differentiates from siblings by noting this tool identifies via ENCODEDNUM/HOTSTAMP and never PERSONID, which distinguishes it from other history-returning tools like get_event_history.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it — when you need historical access grant/deny records with optional filters. It gives one important exclusion (do not pass PERSONID; GetAccessHistory has no PERSONID parameter), but it does not name alternative sibling tools or explicitly state when a different tool should be chosen.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_access_levelA
Returns the details of a single access level for a given ACCESSLEVELKEY (wraps NBAPI GetAccessLevel).
| Name | Required | Description | Default |
|---|---|---|---|
| ACCESSLEVELKEY | Yes | Required. The unique ACCESSLEVELKEY of the access level to retrieve. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It only says the operation 'returns details'; it does not disclose error behavior, permissions, whether the key must be valid, or what the returned details look like.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence that states the operation, target, and required input in one line. There is no padding, and the key information is immediately visible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple single-key retrieval tool, the description plus full parameter schema is minimally sufficient for an agent to attempt a call. However, with no output schema and no annotations, the lack of return structure or error behavior leaves some uncertainty about what 'details' will be returned.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the ACCESSLEVELKEY parameter is already documented as required and unique. The tool description mostly restates the parameter name ('for a given ACCESSLEVELKEY') without adding meaningful semantic detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Returns') and the resource ('details of a single access level'), and names the required ACCESSLEVELKEY. The word 'single' also helps distinguish it from plural siblings like get_access_levels and get_access_level_names.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied: call this when you have an ACCESSLEVELKEY and need one access level's details. However, it gives no explicit guidance about when to prefer get_access_levels or get_access_level_group, leaving selection to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_access_level_groupA
Returns the details of a single access level group for a given ACCESSLEVELGROUPKEY (wraps NBAPI GetAccessLevelGroup).
| Name | Required | Description | Default |
|---|---|---|---|
| ACCESSLEVELGROUPKEY | Yes | Required. The unique ACCESSLEVELGROUPKEY of the access level group to retrieve. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral burden. 'Returns' and 'wraps NBAPI GetAccessLevelGroup' indicate a read operation and external API coupling, but there is no explicit statement about side effects, errors, permissions, or rate limits. Adequate for a simple read, but not comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence with no wasted words: function first, then key, then underlying API wrapper in a parenthetical. It is well-structured and easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-key lookup, the description and schema cover the basics. However, with no output schema and no annotation, the agent still doesn't know what 'details' includes or what happens for missing/invalid keys, leaving some uncertainty.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the schema already documents ACCESSLEVELGROUPKEY as the required unique key. The description only restates that the tool retrieves the group for that key, adding no extra format, constraints, or usage details beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action ('Returns the details') on a specific resource ('a single access level group') keyed by ACCESSLEVELGROUPKEY. The word 'single' helps differentiate it from plural siblings like get_access_level_groups, though it doesn't enumerate which details are returned.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this tool is for retrieving one group when you have a specific key, but it never names alternatives such as get_access_level_groups or states when not to use it. Usage context is present only by implication.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_access_level_groupsA
Lists access level groups configured on the NetBox system (wraps NBAPI GetAccessLevelGroups).
| Name | Required | Description | Default |
|---|---|---|---|
| STARTFROMKEY | No | Optional. Pagination cursor to continue listing from a previous call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that it lists groups and wraps an API, implying a read-only operation, but does not specify pagination behavior (though a pagination cursor parameter exists), rate limits, or whether the response is a list. It does not contradict annotations because none exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that states the purpose and the underlying wrapper, with no waste. The core purpose is front-loaded, and the parenthetical is a useful implementation note.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with one optional parameter and no output schema, the description covers the essential purpose and the pagination hint. However, it could mention that the result is a paginated list and how to use the cursor, but this is partially implied. Given the simplicity, this is adequate but not rich.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, STARTFROMKEY, is fully described in the schema as an optional pagination cursor. The description adds minimal value beyond that, only implying pagination via the parameter name. With 100% schema coverage, baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Lists') and resource ('access level groups configured on the NetBox system'), clearly indicating what the tool does. It also mentions it wraps an underlying API call. It does not explicitly differentiate from siblings like 'get_access_level_group' (singular) or 'get_access_levels' (plural), but the resource name is distinct enough.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies it is for listing all access level groups, which is a typical use case. There is no explicit guidance on when to use this versus alternatives like 'get_access_level_groups' (singular) or 'get_access_level_groups' (all groups), but the plural form and the phrase 'configured on the NetBox system' imply a system-wide listing. No exclusions or alternatives are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_access_level_namesB
Lists access level names configured on the NetBox system (wraps NBAPI GetAccessLevelNames).
| Name | Required | Description | Default |
|---|---|---|---|
| PARTITIONKEY | No | Optional. Per NBAPI GetAccessLevelNames — only "0" is documented as allowed. | |
| STARTFROMNAME | No | Optional. Pagination cursor (name) to continue listing from a previous call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. 'Lists' and 'wraps NBAPI GetAccessLevelNames' convey a read-only enumeration and tie the tool to a known API, but the description does not disclose return shape, pagination behavior, or any constraints beyond what the schema already documents.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that states the action, resource, and backend wrapper with no filler. It is appropriately sized for a simple list tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The combination of the description and the fully documented schema is sufficient to invoke the tool, but the definition is thin for tool selection: it does not explain how the returned names relate to the sibling access-level tools or what the output looks like. Given no output schema and no annotations, a bit more context would make it complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and both optional parameters (PARTITIONKEY, STARTFROMNAME) have meaningful descriptions, so the description does not need to repeat them. The tool description adds no additional parameter-level context, so the schema baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the operation ('Lists access level names') and the resource scope ('configured on the NetBox system'), and the wrapper reference adds endpoint precision. It does not explicitly differentiate itself from siblings like get_access_levels or get_access_level, though the word 'names' implies the distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance about when to call this tool versus get_access_levels, get_access_level, or get_access_level_group(s). The description only states what it does; it never provides conditions, exclusions, or alternative suggestions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_access_levelsA
Lists access levels configured on the NetBox system (wraps NBAPI GetAccessLevels).
| Name | Required | Description | Default |
|---|---|---|---|
| WANTKEY | No | Optional. Per NBAPI GetAccessLevels. | |
| STARTFROMKEY | No | Optional. Pagination cursor (key) to continue listing from a previous call. | |
| STARTFROMNAME | No | Optional. Pagination cursor (name) to continue listing from a previous call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral disclosure burden. 'Lists' implies a non-mutating read operation and the NetBox system scope is stated, but pagination behavior, effect of WANTKEY, and response shape are not described. This is minimally adequate for a simple list tool but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that front-loads the action, resource, and system context with no redundant wording. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity list tool with all parameters documented in the schema and no required inputs, the description is reasonably complete. The absence of an output schema and explicit pagination detail is a minor gap, but an agent can safely invoke and understand this read-only listing operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline baseline is 3 and the schema already explains all three optional parameters. The tool description itself adds no parameter-level meaning beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description uses a specific verb ('Lists') and resource ('access levels configured on the NetBox system'), and names the underlying API wrapper ('NBAPI GetAccessLevels'). This makes the plural list operation distinguishable from siblings like get_access_level or get_access_level_names.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description conveys a clear list operation but gives no explicit when-to-use guidance, exclusions, or alternatives. With many similar access-level siblings, an agent must infer selection from the resource name rather than being told how this tool differs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_card_access_detailsA
Returns card/credential access details for a given card (wraps NBAPI GetCardAccessDetails). Identifies the card by ENCODEDNUM + CARDFORMAT, not PERSONID — GetCardAccessDetails has no PERSONID parameter.
| Name | Required | Description | Default |
|---|---|---|---|
| CARDFORMAT | Yes | Required. The card format of ENCODEDNUM. | |
| ENCODEDNUM | Yes | Required. The encoded card number whose access details should be retrieved. | |
| MAXRECORDS | No | Optional. Maximum number of access records to return. | |
| OLDESTDTTM | No | Optional. Oldest date/time to include in the returned access records. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It discloses that this wraps NBAPI GetCardAccessDetails and clarifies the identification restriction, but it does not describe the returned detail structure, error behavior, or how MAXRECORDS and OLDESTDTTM affect results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The core purpose is front-loaded, and the critical identification constraint is stated immediately after, making the definition easy to parse and act on.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The parameter surface is well covered by the schema, but there is no output schema and the description does not explain what the returned access details actually contain or how optional record limiting works. For a straightforward getter this is adequate, but an agent must infer some response semantics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all four parameters with 100% coverage, so the baseline is 3. The description adds the useful contextual point that PERSONID is not a valid lookup path, but it does not add new meaning for MAXRECORDS or OLDESTDTTM beyond their schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a specific verb+resource pair: 'Returns card/credential access details for a given card.' It further distinguishes the tool from PERSONID-based access tools by explicitly stating that the card is identified by ENCODEDNUM + CARDFORMAT and that GetCardAccessDetails has no PERSONID parameter.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly establishes when to use this tool: when you have ENCODEDNUM and CARDFORMAT but not PERSONID for the lookup. It does not name an alternative tool for PERSONID-based access, so the routing guidance stops short of being fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_card_formatsB
Returns the card formats configured on the NetBox system (wraps NBAPI GetCardFormats). No parameters required.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It states 'Returns' which implies a read operation, but it does not explicitly declare it as read-only, safe, or free of side effects. It also does not disclose authentication requirements, error behavior, or any limitations. The mention of wrapping NBAPI GetCardFormats adds implementation detail but not behavioral transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences, front-loaded with the purpose and immediately noting the absence of parameters. Every word earns its place; there is no fluff or redundancy. The structure is efficient and easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no annotations, no output schema, and no parameters, the description is the only source of context. It fails to describe the return format, data shape, or potential failure modes. An agent calling this tool would know it returns card formats but not what the response looks like or how to interpret it. This is a significant gap for a tool that could return a list or object with various fields.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the schema confirms this with an empty properties object. The description explicitly says 'No parameters required', which is clear and sufficient. The baseline for 0 parameters is 4, and the description meets that baseline by reinforcing the absence of inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Returns' and the resource 'card formats configured on the NetBox system', which is specific and unambiguous. It also mentions the underlying NBAPI call, adding implementation context. However, it does not explicitly differentiate from the many sibling get_* tools, though the resource name itself is distinctive.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus the many sibling getters. It only states that no parameters are required, which is about invocation, not selection. There is no mention of alternatives, prerequisites, or scenarios where this tool is preferred or discouraged.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_daily_unlock_windowA
Reports the managed daily recurring unlock window, if any: the managed portal group "MCP Daily Unlock Window" (key, portals, its unlock time spec group and whether that is the managed time spec group "MCP Daily Unlock Window time specs"), that group and its members (read from paginated GetTimeSpecGroups), the one managed time spec and holiday, the window derived from them, and whether it is active right now on the host clock. Read-only: issues only Get commands. No parameters required.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It explicitly discloses that the tool issues only Get commands (read-only), reads from paginated GetTimeSpecGroups, derives a window, and checks whether it is active on the host clock. This goes beyond a simple 'reports the window' statement and gives useful behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, information-dense sentence that front-loads the main purpose and then lists the included details. It is somewhat long but every clause adds meaningful detail about scope, source, and read-only behavior, so it earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read-only reporting tool, the description is quite complete: it names the managed group, the source commands, the derived window, and the active-now check. It does not describe the output format, but with no output schema and a complex report, a bit more detail on the return shape would help; still, the core calling context is fully covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so the schema already fully defines the input surface. The description adds value by explaining what the tool reports and how it derives the result, which is more than the empty schema provides. Baseline 4 for zero params is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Reports') and a precise resource ('managed daily recurring unlock window'), and enumerates exactly what is included. It distinguishes itself from the sibling get_unlock_window by specifying the managed 'MCP Daily Unlock Window' group and the derived window, so an agent can tell them apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies this is a read-only reporting tool for the managed daily unlock window and notes it reads from paginated GetTimeSpecGroups. It does not explicitly name alternatives or when-not-to-use, but the detailed scope and read-only note give clear context for when to call it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_elevatorsA
Lists elevators configured on the NetBox system (wraps NBAPI GetElevators).
| Name | Required | Description | Default |
|---|---|---|---|
| STARTFROMKEY | No | Optional. Pagination cursor to continue listing from a previous call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It clearly signals a read-only listing operation ('Lists') and names the wrapped API, but it does not describe pagination behavior, output shape, or failure modes. This is adequate for a simple non-destructive list operation, but not detailed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that states the action and resource without filler. The parenthetical endpoint context is useful and non-redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with one optional pagination parameter and no output schema, the description plus schema are sufficient to call it correctly. It names the resource, the wrapped endpoint, and the only parameter; enumerating return fields would be helpful but is not necessary for invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides 100% coverage for the only parameter, STARTFROMKEY, with a clear description ('Optional. Pagination cursor to continue listing from a previous call.'). The tool description adds no parameter-specific meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Lists') and a specific resource ('elevators configured on the NetBox system'), and it identifies the wrapped endpoint ('NBAPI GetElevators'). This clearly distinguishes it from sibling get_* tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by naming the resource and action, so an agent can infer it is the tool for listing elevators. However, it gives no explicit guidance on when to use this tool versus alternatives such as get_readers or get_floors.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_event_historyB
Returns historical NetBox events for an optional event name/date range (wraps NBAPI GetEventHistory).
| Name | Required | Description | Default |
|---|---|---|---|
| ENDDTTM | No | Optional. End of the date/time range to query (NBAPI-documented format). | |
| NEXTKEY | No | Optional. Pagination continuation cursor from a previous call. | |
| EVENTNAME | No | Optional. Restrict results to this event name. | |
| STARTDTTM | No | Optional. Start of the date/time range to query (NBAPI-documented format). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It only states that it 'wraps NBAPI GetEventHistory' and returns historical events, but does not mention that it is a read-only operation, how pagination works (NEXTKEY), or what the response format is. This is minimal transparency for a tool that could have side effects or require specific handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that immediately states the tool's purpose and wraps the underlying API. It is efficient with no filler, front-loading the core action and optional filters. This is exemplary conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that there is no output schema and no annotations, the description should explain the return format, pagination behavior, and any limitations. It only vaguely states that it returns historical events, without describing the structure of the results, how NEXTKEY is used, or whether the operation is read-only. For a tool with four optional parameters and no other structured documentation, this is incomplete and leaves the agent guessing about expected output.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (all four parameters have descriptions in the schema). The description adds little beyond what the schema already provides, merely restating that event name and date range are optional. The NEXTKEY pagination parameter is not mentioned in the description, but the schema documents it. Thus, the description provides marginal additional value, warranting a baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool returns historical NetBox events and mentions the optional event name/date range filters. It also identifies the underlying API it wraps. While it distinguishes itself by focusing on historical events, it does not explicitly contrast with sibling tools like list_events, which might offer a different scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for retrieving historical event data by stating 'Returns historical NetBox events' and mentions optional filters. However, it does not provide explicit guidance on when to use this tool over alternatives (e.g., list_events) or any exclusions, leaving the agent to infer the appropriate context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_floorsA
Lists floors configured on the NetBox system (wraps NBAPI GetFloors).
| Name | Required | Description | Default |
|---|---|---|---|
| STARTFROMKEY | No | Optional. Pagination cursor to continue listing from a previous call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral burden. 'Lists' clearly signals a read-only operation, and 'wraps NBAPI GetFloors' gives implementation context. However, it does not mention pagination behavior, return format, or potential performance concerns, though the STARTFROMKEY parameter in the schema partially addresses pagination.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single focused sentence that front-loads the core action and resource. It contains no filler or redundant explanation, making it easy for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity list tool with one optional parameter and no output schema, the description plus the parameter schema is largely sufficient. It could mention pagination explicitly in the prose, but the schema already documents that behavior, so the main gap is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema fully describes the only parameter, STARTFROMKEY, as an optional pagination cursor, so the schema carries the semantic weight. The description adds no parameter-level detail, but with 100% schema coverage, the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Lists') with a clear resource ('floors') and scope ('configured on the NetBox system'), so an agent can understand the tool's function immediately. It doesn't explicitly distinguish from sibling tools, but no sibling tool appears to target floors, so the differentiation need is low.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool should be used when the agent needs to list floors, but it gives no explicit guidance about when to prefer this tool over alternatives or when not to use it. There are no exclusions or alternative tool references, but the purpose is straightforward enough that the usage is reasonably inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_holidayA
Returns the details of a single holiday for a given HOLIDAYKEY (wraps NBAPI GetHoliday).
| Name | Required | Description | Default |
|---|---|---|---|
| HOLIDAYKEY | Yes | Required. The unique HOLIDAYKEY of the holiday to retrieve. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It states the operation is a retrieval ('returns'), which implies a read, and notes it wraps NBAPI GetHoliday. However, it does not describe behavior for an invalid or missing HOLIDAYKEY or the response structure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence communicates the tool's purpose, scope, and key parameter without wasted words. The parenthetical wrapper note is short and adds context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter getter, the description is sufficient for an agent to select and invoke it correctly. The only gaps are the lack of an explicit not-found behavior and return format, but neither blocks correct use for the common case.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both the schema and description convey that HOLIDAYKEY is required and unique. The description adds no additional format, source, or usage detail beyond the schema, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb, resource, and selection criterion: 'returns the details of a single holiday' for a HOLIDAYKEY. This clearly distinguishes it from the sibling get_holidays, which presumably returns multiple holidays.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Makes clear this is the tool to use when you have a specific HOLIDAYKEY and need one holiday. It does not explicitly name get_holidays as the alternative for listing many holidays, so some inference is required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_holidaysA
Lists holiday keys configured on the NetBox system (wraps NBAPI GetHolidays). Returns a comma-separated key string, not a list of records — use get_holiday per key for details.
| Name | Required | Description | Default |
|---|---|---|---|
| STARTFROMKEY | No | Optional. Pagination cursor to continue listing from a previous call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full disclosure burden. It usefully reveals a non-obvious behavior: the result is a comma-separated key string rather than a list of record objects. It does not mention pagination behavior, error cases, or response formatting beyond the key string, but the most important gotcha is disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler. The core purpose is front-loaded, and the critical return-format caveat is stated immediately after. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-style tool with one optional parameter and no output schema, the description covers purpose, return format, and the path to richer detail via get_holiday. It could still clarify how STARTFROMKEY affects the returned string, but the schema covers that parameter. Nothing essential for invoking the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents STARTFROMKEY as an optional pagination cursor. The description adds no further parameter-level meaning beyond implying the tool returns keys; it neither clarifies cursor format nor explains continuation behavior. This matches the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Lists'), a specific resource ('holiday keys'), and the system ('NetBox'), and distinguishes itself from get_holiday by clarifying it only returns keys. The parenthetical 'wraps NBAPI GetHolidays' adds a useful API mapping without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly routes the agent to get_holiday for per-key details, which is a clear alternative. It does not elaborate on when not to use the tool or contrast with other list-type siblings, but the main selection condition (need keys vs details) is present and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_outputsB
Lists auxiliary outputs configured on the NetBox system (wraps NBAPI GetOutputs).
| Name | Required | Description | Default |
|---|---|---|---|
| STARTFROMKEY | No | Optional. Pagination cursor to continue listing from a previous call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are absent, so the description carries full responsibility for behavioral disclosure. It only says 'lists auxiliary outputs', which is a read operation, but does not mention safety implications (e.g., read-only nature, no side effects), pagination behavior beyond the parameter, or any potential errors. For a list operation, this is a minor gap, but given the lack of annotations, the description should have at least indicated it is non-destructive and returns a list. The reference to 'wraps NBAPI GetOutputs' adds some context but does not fully disclose behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that states the purpose and references the underlying API. It is appropriately sized and front-loaded with the core action. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one optional parameter, no output schema, no nested objects), the description plus the schema is nearly complete. However, the lack of any behavioral transparency (e.g., that the operation is read-only and returns a list of outputs) and absence of usage guidance leave minor gaps. With annotations absent, a bit more context would be expected, but for a simple list tool, the current state is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 100%, with the single parameter STARTFROMKEY fully described as a pagination cursor. The description does not add further meaning beyond that, so the baseline of 3 applies because the schema already provides sufficient semantics. The description's reference to 'auxiliary outputs' does not directly explain the parameter, but schema coverage meets the burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists auxiliary outputs on the NetBox system, a specific verb-resource combination. It also references the wrapped NBAPI endpoint, which helps identify the underlying operation. However, it does not explicitly differentiate from siblings beyond indicating 'auxiliary outputs' as a distinct resource, which is sufficient given the naming.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explicitly state when to use this tool versus alternatives, but the resource name 'auxiliary outputs' is specific enough that an agent can infer it is for that resource only. It does not mention any context like pagination handling, but the single parameter's schema covers that. No exclusions or alternatives are given, so it's adequate but not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_partitionsA
Lists partitions configured on the NetBox system (wraps NBAPI GetPartitions). No parameters required.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of behavioral disclosure. 'Lists' implies a read-only operation, and the wrapper reference adds context, but the description does not mention return format, pagination, error behavior, or access requirements. It is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that leads with the core action and resource, then adds the wrapper context and parameter note. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-argument list tool, the description is nearly complete: it states what is listed and that no parameters are needed. It does not describe the output shape, but the absence of an output schema and the low complexity make this a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so the baseline is 4. The description explicitly states 'No parameters required,' which reinforces the empty input schema even though the schema already communicates this.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Lists') and a clear resource ('partitions configured on the NetBox system'), and it also names the wrapped API ('NBAPI GetPartitions'). This makes the tool's purpose unambiguous and distinct from the sibling get_* tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage through its clear purpose, but it does not explicitly state when to use this tool versus alternatives or when not to use it. Mentioning that no parameters are required helps, but there is no explicit routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_personA
Returns the full person record for a given PERSONID (wraps NBAPI GetPerson).
| Name | Required | Description | Default |
|---|---|---|---|
| PERSONID | Yes | Required. The unique PERSONID of the person record to retrieve. | |
| ALLPARTITIONS | No | Optional. Per NBAPI GetPerson. | |
| WANTCREDENTIALID | No | Optional. Include CREDENTIALID values on returned access cards. | |
| ACCESSLEVELDETAILS | No | Optional. Include full access level details in the response. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
'Returns' makes the read-only nature reasonably clear, and 'wraps NBAPI GetPerson' adds a useful reference. However, with no annotations provided, the description carries the full behavioral burden and does not mention error behavior, authentication needs, or response format.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence with no filler; the core behavior and API wrapper are stated upfront. It earns its place entirely.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a get-by-ID tool with a complete parameter schema, this is adequate but minimal. It omits usage alternatives, return-shape expectations, and any edge cases, which matters more since there is no output schema and no annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters are already documented in the schema. The description adds little beyond naming PERSONID and calling the result 'full,' which is acceptable but not additive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Returns') and resource ('full person record') keyed by PERSONID, so an agent can tell this is a direct lookup tool. It does not explicitly differentiate it from sibling search_person_data, though the PERSONID-based lookup strongly implies it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The usage context is only implied: an agent would call this when it has a PERSONID and needs the full person record. It provides no explicit when-not guidance or comparison to alternatives like search_person_data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_portal_groupB
Returns the details of a single portal group for a given PORTALGROUPKEY (wraps NBAPI GetPortalGroup).
| Name | Required | Description | Default |
|---|---|---|---|
| PORTALGROUPKEY | Yes | Required. The unique PORTALGROUPKEY of the portal group to retrieve. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It states 'returns the details' but does not disclose whether this is a read-only operation, potential error conditions (e.g., invalid key), or what happens if the key does not exist. The parenthetical about wrapping NBAPI hints at an API call but adds no behavioral clarity. A simple getter still needs explicit assurance of non-mutation or side-effect-free behavior, which is absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that gets to the point. However, the parenthetical '(wraps NBAPI GetPortalGroup)' is an implementation detail that does not help the agent decide when to call the tool and may add noise. Removing it would improve conciseness, but the overall structure is efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description leaves the return structure undefined. Saying 'details' is vague; an agent cannot anticipate what fields will be returned (e.g., group name, members, permissions). For a getter, the description should at least hint at the typical content of a portal group or indicate it returns the full object. Given the simplicity of the tool, the description is inadequate for an agent to reason about downstream usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the parameter is fully documented in the schema. The description's phrase 'for a given PORTALGROUPKEY' adds no additional meaning beyond the schema's 'The unique PORTALGROUPKEY of the portal group to retrieve.' The description neither clarifies format, constraints, nor relationship to other parameters (there are none). Baseline 3 is appropriate when the schema already explains the parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'returns', the resource 'portal group', and the scope 'single' with a specific key. It differentiates from the plural sibling 'get_portal_groups' by emphasizing 'single' and 'given PORTALGROUPKEY'. The mention of wrapping NBAPI is implementation detail but does not obscure the purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives. The description does not mention conditions such as 'use this when you have a specific portal group key' or contrast with get_portal_groups or find_portals. The agent must infer from the name and the key requirement, which is insufficient for a tool set with many similar getters.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_portal_groupsA
Lists portal groups configured on the NetBox system (wraps NBAPI GetPortalGroups).
| Name | Required | Description | Default |
|---|---|---|---|
| STARTFROMKEY | No | Optional. Pagination cursor to continue listing from a previous call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavioral traits. It only states that it lists portal groups, but does not mention whether it is read-only, how pagination works (despite the STARTFROMKEY parameter), what the response structure is, or any error conditions. The cryptic 'wraps NBAPI GetPortalGroups' adds no behavioral clarity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that front-loads the purpose. There is no extraneous content, and it earns its place by stating exactly what the tool does.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description should convey what the response contains and any usage caveats. It says 'lists portal groups' which implies a list of portal group objects, but it does not mention the pagination mechanism or how to interpret the STARTFROMKEY parameter in practice. Given the simplicity of the tool (one optional param), this is minimally adequate but leaves some gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the single parameter STARTFROMKEY, and its description already explains it as a pagination cursor. The tool description adds no additional meaning beyond the schema, so a baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Lists') and the resource ('portal groups configured on the NetBox system'), and the plural form distinguishes it from the sibling tool get_portal_group (singular). The mention of wrapping NBAPI GetPortalGroups adds specificity without confusion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The purpose implies use when a list of portal groups is needed, but there is no explicit guidance on when to choose this over get_portal_group or other sibling tools like get_portals. No exclusions or alternative routing are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_portalsA
Lists portals (doors) configured on the NetBox system, each with its nested readers (wraps NBAPI GetPortals, paginated via STARTFROMKEY/NEXTKEY — there is no single-portal filter).
| Name | Required | Description | Default |
|---|---|---|---|
| STARTFROMKEY | No | Optional. Pagination cursor — the NEXTKEY from a previous call, to continue listing. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It discloses the underlying NBAPI call, pagination via STARTFROMKEY/NEXTKEY, nested-reader inclusion, and the absence of single-portal filtering. It does not mention auth, rate limits, or response fields, but the core behavior is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence conveys the resource, scope, nested structure, implementation wrapper, pagination mechanism, and a key limitation. There is no filler and the most important facts are front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple paginated list with no required parameters and no output schema, the description covers the scope, nested readers, pagination behavior, and the absence of a single-portal filter. Sibling tool names help fill the alternative-use context. Minor omissions like auth or exact return fields do not prevent correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, STARTFROMKEY, is already fully documented in the schema (100% coverage). The description reinforces that pagination uses STARTFROMKEY/NEXTKEY but adds little beyond the schema. Baseline 3 is appropriate since the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb-resource pair ('Lists portals configured on the NetBox system') and immediately adds distinguishing detail: each portal comes with nested readers, it wraps NBAPI GetPortals, and there is no single-portal filter. This clearly separates it from siblings like find_portals or get_portal_group.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly communicates that this is a paginated list operation and explicitly warns that there is no single-portal filter, so an agent knows not to use it to fetch a specific portal. It does not name an alternative tool directly, but the sibling list makes that inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_readerA
Returns the details of a single reader for a given READERKEY (wraps NBAPI GetReader).
| Name | Required | Description | Default |
|---|---|---|---|
| READERKEY | Yes | Required. The unique READERKEY of the reader to retrieve. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries the full behavioral disclosure burden. It does state the operation ('Returns the details') and identifies the underlying backend call ('wraps NBAPI GetReader'), which adds useful context, but it does not mention read-only behavior, error conditions, or output format.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single well-structured sentence that front-loads the core action, target, and required input. There is no superfluous text or repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple one-parameter getter, and the description combined with the schema provides enough information to invoke the tool correctly. However, since there is no output schema, the description could be slightly more explicit about what fields or object shape are contained in the returned 'details'.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameter READERKEY is already fully documented in the schema. The description repeats the parameter name but does not add any semantic detail beyond what the schema provides, keeping this at the baseline score of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the specific action ('Returns the details') and the target resource ('a single reader') with the required identifier READERKEY. The singular 'single reader' clearly distinguishes this from the sibling get_readers tool without needing to inspect schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the usage context: you call this when you have a READERKEY and need one reader's details. However, it does not explicitly state when to prefer it over get_readers or any other sibling, nor does it mention alternative tools for reader-related queries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_reader_groupB
Returns the details of a single reader group for a given READERGROUPKEY (wraps NBAPI GetReaderGroup).
| Name | Required | Description | Default |
|---|---|---|---|
| READERGROUPKEY | Yes | Required. The unique READERGROUPKEY of the reader group to retrieve. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It only says 'returns the details' without specifying the nature of the operation (likely read-only), potential error conditions, or what 'details' encompass. It does mention wrapping NBAPI GetReaderGroup, but that adds no behavioral clarity. The description is too thin to disclose meaningful behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence with no extraneous content. The key fact (returns a single reader group by key) is front-loaded, and the parenthetical implementation detail is supplementary without adding bulk.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a getter tool with no output schema and no annotations, the description leaves significant gaps: it does not define what 'details' are returned, does not indicate any error behavior, and does not clarify that the operation is read-only. Given the simple single-parameter interface, some of this is inferred, but the absence of return format and usage guidance makes it incomplete for an agent to call correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single parameter READERGROUPKEY, so the schema fully documents the parameter. The description merely restates 'given READERGROUPKEY' without adding format, constraints, or examples beyond what the schema provides, meeting the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns details of a single reader group for a given READERGROUPKEY, and explicitly uses 'single' to distinguish from the plural sibling get_reader_groups. The verb 'returns' and resource 'reader group' are specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'single' and 'given READERGROUPKEY', but the description does not explicitly state when to use this tool over alternatives like get_reader_groups or get_reader. No exclusions or conditions are provided, leaving selection to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_reader_groupsB
Lists reader groups configured on the NetBox system (wraps NBAPI GetReaderGroups).
| Name | Required | Description | Default |
|---|---|---|---|
| STARTFROMKEY | No | Optional. Pagination cursor to continue listing from a previous call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the behavioral disclosure burden. It only says 'Lists...' which implies read-only, but does not explicitly state safety, pagination behavior, permissions, or side effects. The pagination cursor is mentioned only in the schema, not the description, leaving the agent without important behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the main action. The parenthetical about wrapping NBAPI adds some implementation detail that may not be essential for an agent, but it does not bloat the description. Overall concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, no annotations, and only one optional parameter, the description still leaves gaps: it does not indicate what the response contains, whether pagination is required for large lists, or how this tool relates to the singular get_reader_group. The description is too minimal to be fully complete for an agent selecting and invoking the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: the sole parameter STARTFROMKEY has a clear description ('Optional. Pagination cursor to continue listing from a previous call.'). The tool description adds no additional semantic value beyond the schema, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Lists'), the resource ('reader groups'), and the system ('NetBox'). It distinguishes itself from sibling tools like get_reader_group (singular) by the plural form, and the parenthetical identifies the underlying API. This is a specific and unambiguous purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage through the plural 'reader groups' (listing all) but does not explicitly state when to use this instead of get_reader_group or related tools. No alternatives or exclusion criteria are mentioned, so the guidance is only implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_readersA
Lists readers configured on the NetBox system (wraps NBAPI GetReaders). There is no portal-id filter — use get_portals to see each reader nested under its portal.
| Name | Required | Description | Default |
|---|---|---|---|
| STARTFROMKEY | No | Optional. Pagination cursor to continue listing from a previous call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral burden. 'Lists' and the NBAPI wrapper make the read-only nature reasonably clear, and the 'no portal-id filter' constraint is useful. However, it does not describe pagination behavior or response format beyond what the schema already provides, so behavioral disclosure is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no wasted words. The core purpose is front-loaded, followed by the key limitation and the sibling alternative, making it highly scannable for an agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter, no-output-schema tool, the description covers what the tool does, its limitation, and the relevant alternative. The missing explicit statement about what the returned reader list contains is a minor gap, but the description is otherwise sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the only parameter, STARTFROMKEY, whose description already explains it as a pagination cursor. The tool description adds no parameter-level meaning beyond that, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Lists') and resource ('readers configured on the NetBox system'), making the purpose immediately clear. It also distinguishes itself from get_portals by explicitly noting the absence of a portal-id filter.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description directly tells the agent when to use this tool vs. an alternative: use get_readers for a flat reader list, and use get_portals to see readers nested under a portal. This is explicit routing with no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_time_specA
Returns the details of a single time spec for a given TIMESPECKEY (wraps NBAPI GetTimeSpec).
| Name | Required | Description | Default |
|---|---|---|---|
| TIMESPECKEY | Yes | Required. The unique TIMESPECKEY of the time spec to retrieve. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It states the tool 'returns' details, implying a read operation, but does not disclose error behavior, return format, or any side effects. For a simple get operation, this is minimal but not misleading; it lacks depth but does not contradict anything.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that front-loads the purpose and input. It contains zero fluff and efficiently conveys the tool's function and the required key. This is a model of conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter retrieval tool with no output schema and no annotations, the description is adequate. It tells what it does and the input. It does not describe the returned fields or error cases, but given the simplicity and the sibling context, this is sufficient for an agent to use it correctly. The only gap is the vague 'details' without specifics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameter TIMESPECKEY is already documented in the schema. The tool description adds no extra semantics, format, or examples beyond what the schema provides. This meets the baseline of 3 for schema-covered parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Returns', the resource 'details of a single time spec', and the input key TIMESPECKEY. It distinguishes itself from siblings like get_time_specs (plural) and get_time_spec_group(s) by indicating it operates on a single time spec. The wrapper reference adds credibility without confusion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The usage is implied: call when you have a TIMESPECKEY to retrieve its details. However, the description does not explicitly mention when not to use it or point to alternatives like get_time_specs for listing. It provides no exclusions or routing guidance, falling into the 'implied usage' category.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_time_spec_groupB
Returns the details of a single time spec group for a given TIMESPECGROUPKEY (wraps NBAPI GetTimeSpecGroup).
| Name | Required | Description | Default |
|---|---|---|---|
| TIMESPECGROUPKEY | Yes | Required. The unique TIMESPECGROUPKEY of the time spec group to retrieve. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full responsibility for behavioral disclosure. It only says 'returns the details' and wraps NBAPI GetTimeSpecGroup, but does not indicate whether the operation is read-only, what happens if the key is invalid, or the format of the returned details. This is a significant gap for a tool in a system with many similar retrieval tools.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no extraneous words. It states the action and the key input immediately, and the NBAPI reference adds context without bloating the text. This is ideal conciseness for a simple retrieval tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity (one parameter, no output schema) the description covers the basic call, but it lacks differentiation from the many similar sibling tools (e.g., get_time_spec_groups, get_time_specs) and does not mention error behavior or the contents of the returned details. It is adequate but not fully complete for an agent navigating a large toolset.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents the TIMESPECGROUPKEY parameter fully. The description merely restates that it uses the key without adding any new meaning, such as accepted formats or constraints. Baseline 3 is appropriate since the schema carries the semantic load.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns the details of a single time spec group for a given key, using a specific verb and resource. It does not explicitly differentiate from sibling tools like get_time_spec_groups (plural) or get_time_spec, but the word 'single' and the key parameter imply a distinct retrieval purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives. It only states the input requirement (TIMESPECGROUPKEY) but does not mention when to choose this over get_time_spec_groups for listing, or how it differs from get_time_spec. An agent must infer usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_time_spec_groupsA
Lists time spec groups configured on the NetBox system (wraps NBAPI GetTimeSpecGroups).
| Name | Required | Description | Default |
|---|---|---|---|
| STARTFROMKEY | No | Optional. Pagination cursor to continue listing from a previous call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses it wraps NBAPI GetTimeSpecGroups and states the list scope, but does not mention pagination behavior, result shape, or any side effects. With no annotations, the description carries some burden, but for a read-only list operation this is minimally adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one concise sentence with the key action front-loaded. The parenthetical wrapper context is relevant and does not add unnecessary clutter.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the low complexity, one optional parameter fully documented in the schema, and no output schema, the description covers the main invocation context. It does not explicitly elaborate on return format, but 'Lists' plus the parameter description is likely sufficient for correct use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 100% coverage with a clear description for STARTFROMKEY, so the description does not need to compensate. The description adds no parameter-level meaning beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Lists' with a clear resource 'time spec groups' and a scoping phrase 'configured on the NetBox system'. The plural form also distinguishes it from sibling get_time_spec_group, making the tool's purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance is provided and no alternatives are mentioned, even though siblings like get_time_spec_group and get_time_specs exist. The agent must infer the appropriate selection solely from the tool name and basic description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_time_specsA
Lists time specs configured on the NetBox system (wraps NBAPI GetTimeSpecs).
| Name | Required | Description | Default |
|---|---|---|---|
| STARTFROMKEY | No | Optional. Pagination cursor to continue listing from a previous call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries the behavioral burden. 'Lists' and 'wraps NBAPI GetTimeSpecs' imply a read-only retrieval operation, but the description does not explicitly state safety, permissions, pagination behavior, or what the response contains. It provides useful context but leaves notable behavioral details unspecified.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence communicates the resource, action, and underlying API wrapper with no filler. The essential information is front-loaded and every phrase earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple list operation with one optional, well-documented parameter, so it is not severely underserved. However, with no output schema and no annotation coverage, the description leaves return-value structure and the full pagination flow unspecified, making it adequate but not complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: the only parameter, STARTFROMKEY, is already documented as an optional pagination cursor. The description does not add any parameter-level meaning beyond this, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Lists') and a clear resource ('time specs configured on the NetBox system'), and the plural 'time specs' plus the mention of the system scope distinguishes it from singular/group sibling tools like get_time_spec and get_time_spec_group. It also anchors the behavior to a concrete NBAPI operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for listing all time specs configured in NetBox, so an agent can infer when to call it. However, it does not explicitly contrast it with sibling tools such as get_time_spec or get_time_spec_groups, nor does it state when to prefer one over the other.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_udf_list_itemsA
Returns the items of a single UDF list for a given UDFLISTKEY (wraps NBAPI GetUDFListItems).
| Name | Required | Description | Default |
|---|---|---|---|
| UDFLISTKEY | Yes | Required. The unique UDFLISTKEY of the UDF list to retrieve. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It does disclose that the call is a retrieval ('Returns') and that it wraps NBAPI GetUDFListItems, but it says nothing about error behavior, response shape, or whether any side effects exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with no filler, front-loading the core action and resource before the NBAPI wrapper reference. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read tool with a fully documented schema, the description is mostly sufficient to invoke it. However, with no output schema, it leaves the shape of the returned items unspecified, and it lacks usage or error context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents UDFLISTKEY as required and unique. The description merely restates the parameter without adding format, source, or additional semantic detail, so it stays at the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description uses a specific verb ('Returns'), resource ('items of a single UDF list'), and required key (UDFLISTKEY). The word 'single' and 'items' clearly differentiate it from the sibling get_udf_lists, which retrieves the lists themselves.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied: an agent can infer it should call this tool when it has a UDFLISTKEY and wants that list's items. However, it never explicitly states when to prefer this over get_udf_lists or any alternative, and it gives no exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_udf_listsB
Lists user-defined field (UDF) lists configured on the NetBox system (wraps NBAPI GetUDFLists). No parameters required.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It only states the action and that no parameters are required, but doesn't disclose return format, pagination, performance implications, or whether it's a read-only operation. For a list operation, an agent might need to know if the list is large or requires iteration, but the description offers no such context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one sentence, front-loaded with the action and resource, and includes a useful parenthetical about the underlying NBAPI wrapper. The extra note 'No parameters required' is redundant given the empty schema, but harmless. It's concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has zero parameters and no output schema, the description covers the essential input side. However, it doesn't describe what the return value looks like (e.g., a list of UDF list objects with IDs and names), which an agent might need to know for downstream processing. The sibling 'get_udf_list_items' hints at a hierarchy, but the description doesn't clarify the relationship or what fields are returned. Still, for a simple no-param list operation, it's mostly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the schema has no properties, so there's no parameter documentation needed. The description explicitly states 'No parameters required,' which is clear and accurate. With 0 parameters, the baseline is 4 as per the rubric, and the description meets it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it lists user-defined field (UDF) lists configured on the NetBox system, with a specific verb ('Lists') and resource ('UDF lists'). It distinguishes itself from the sibling 'get_udf_list_items' which likely lists the items within a UDF list, and other get_* tools. However, it doesn't explicitly differentiate itself from all siblings or mention the NBAPI wrapper context beyond a parenthetical.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no explicit guidance on when to use this tool versus alternatives. The context implies it's for retrieving UDF lists, and the sibling 'get_udf_list_items' suggests a related tool, but no direct comparison or conditions are stated. With many sibling tools, a brief 'use this to fetch all UDF lists; for individual items use get_udf_list_items' would be helpful.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_unlock_windowA
Reports the managed unlock window, if any: the managed portal group "MCP Unlock Window" (key, portals, its unlock time spec group and whether that is the managed time spec group "MCP Unlock Window time specs"), that group and its members (read from paginated GetTimeSpecGroups), the managed time specs and holidays, the window derived from them, and whether it is active right now on the host clock. Read-only: issues only Get commands. No parameters required.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and explicitly states 'Read-only: issues only Get commands' and 'No parameters required.' It also discloses that data is read from paginated GetTimeSpecGroups, making the safety and data-source behavior clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded in the first clause, and there is no outright waste. However, the remainder is a long, nested enumeration with multiple parentheticals that is dense and somewhat difficult to scan; splitting it into clearer clauses would improve readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless report tool with no output schema, the description is complete: it names the managed groups, the time specs and holidays, the derived window, the active status, and the read-only nature. An agent has enough information to invoke it correctly without further context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema is empty and there are zero parameters, so the baseline is 4. The description reinforces this with 'No parameters required,' confirming to the agent that no arguments are needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Reports') and a specific resource ('managed unlock window'), then precisely scopes it to the 'MCP Unlock Window' portal group, its time spec group, derived window, and active status. This is clearly differentiated from generic get_time_spec* siblings, even though get_daily_unlock_window is not explicitly named.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: to report the managed unlock window, its constituent groups/specs, and whether it is currently active. It does not explicitly name alternatives or state when not to use it, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_eventsA
Lists the event types/definitions known to the NetBox system (wraps NBAPI ListEvents). No parameters required.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions 'No parameters required' and that it wraps an API, but does not disclose the return format, pagination, potential errors, or whether it's read-only. For a simple list operation, this is minimal coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler. The purpose is front-loaded, the wrapper note adds context, and the parameter note is useful. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple no-parameter list tool, the description covers the essentials: what it lists and that no parameters are needed. However, it does not describe the response format (e.g., array of event definitions), and with no output schema, an agent might not know what to expect. This is a minor gap but not fatal for such a straightforward tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema is empty. The description explicitly states 'No parameters required', which confirms the parameter behavior. With 0 parameters, the baseline is 4, and the description adequately covers it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Lists' and the resource 'event types/definitions known to the NetBox system', and even names the underlying API wrapper (NBAPI ListEvents). This is unambiguous and distinguishes it from sibling tools like get_event_history, which deal with history rather than definitions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage (when you need to list event definitions) but does not explicitly state when not to use it or point to alternatives. Since there are siblings like get_event_history, the description could have clarified that this tool is for definitions, not history. However, the wording 'event types/definitions' is fairly clear, so it gets a mid score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ping_appB
Pings the NetBox NBAPI application to confirm it is responsive (wraps NBAPI PingApp). No parameters required.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states that it pings to confirm responsiveness, but does not disclose potential side effects, failure behavior, or what the response indicates. For a tool that likely only checks reachability, this is minimal but not contradictory.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with no wasted words. It states the action, target, purpose, and parameter status clearly and front-loads the core functionality.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, parameter-less health-check tool with no output schema, the description is sufficiently complete. It explains what the tool does and that no inputs are required. The only minor gap is not clarifying the return format or how to interpret the result, but this is not critical for a ping.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the description explicitly states 'No parameters required.' The schema coverage is 100% (since there are none), so the baseline for 0 parameters is 4, and the description appropriately confirms this.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Pings') and the target ('NetBox NBAPI application') with a purpose ('to confirm it is responsive'). It also references the wrapped NBAPI PingApp. However, it does not explicitly differentiate from the sibling 'check_connection', which likely serves a similar health-check role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives such as 'check_connection'. The description does not mention any conditions, prerequisites, or exclusions, leaving the agent to infer appropriate usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_person_dataC
Searches for person records matching the given criteria (wraps NBAPI SearchPersonData). Every documented SearchPersonData filter field is modeled explicitly; omit all filters to return every record.
| Name | Required | Description | Default |
|---|---|---|---|
| UDF1 | No | Optional. Search filter on user-defined field UDF1. | |
| UDF2 | No | Optional. Search filter on user-defined field UDF2. | |
| UDF3 | No | Optional. Search filter on user-defined field UDF3. | |
| UDF4 | No | Optional. Search filter on user-defined field UDF4. | |
| UDF5 | No | Optional. Search filter on user-defined field UDF5. | |
| UDF6 | No | Optional. Search filter on user-defined field UDF6. | |
| UDF7 | No | Optional. Search filter on user-defined field UDF7. | |
| UDF8 | No | Optional. Search filter on user-defined field UDF8. | |
| UDF9 | No | Optional. Search filter on user-defined field UDF9. | |
| UDF10 | No | Optional. Search filter on user-defined field UDF10. | |
| UDF11 | No | Optional. Search filter on user-defined field UDF11. | |
| UDF12 | No | Optional. Search filter on user-defined field UDF12. | |
| UDF13 | No | Optional. Search filter on user-defined field UDF13. | |
| UDF14 | No | Optional. Search filter on user-defined field UDF14. | |
| UDF15 | No | Optional. Search filter on user-defined field UDF15. | |
| UDF16 | No | Optional. Search filter on user-defined field UDF16. | |
| UDF17 | No | Optional. Search filter on user-defined field UDF17. | |
| UDF18 | No | Optional. Search filter on user-defined field UDF18. | |
| UDF19 | No | Optional. Search filter on user-defined field UDF19. | |
| UDF20 | No | Optional. Search filter on user-defined field UDF20. | |
| DELETED | No | Optional. Include/exclude deleted person records. | |
| HOTSTAMP | No | Optional. Match on a card hot-stamp number. | |
| LASTNAME | No | Optional. Match on the person's last name. | |
| PERSONID | No | Optional. Match on a specific PERSONID. | |
| FIRSTNAME | No | Optional. Match on the person's first name. | |
| MIDDLENAME | No | Optional. Match on the person's middle name. | |
| ACCESSLEVEL | No | Optional. Match persons assigned this access level. | |
| ALLPARTITIONS | No | Optional. Search across all partitions. | |
| NEWESTLASTMOD | No | Optional. Only include records last modified on/before this date/time. | |
| OLDESTLASTMOD | No | Optional. Only include records last modified on/after this date/time. | |
| RAWCARDNUMBER | No | Optional. Match on a raw (unformatted) card number. | |
| WILDCARDSEARCH | No | Optional. Treat text filters as wildcard patterns. | |
| CASEINSENSITIVE | No | Optional. Perform a case-insensitive match. | |
| WANTCREDENTIALID | No | Optional. Include CREDENTIALID values on returned access cards. | |
| ACCESSLEVELDETAILS | No | Optional. Include full access level details in the response. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions wrapping NBAPI SearchPersonData and the omit-all-filters behavior, but does not disclose return format, pagination, result size limits, or deleted-record default handling, which are important for a search tool with no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with the core purpose front-loaded. The second sentence adds a useful operational note without waste, though it could be considered slightly redundant with the schema's optionality.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 35-parameter search tool with no output schema and no annotations, the description is adequate but thin. It confirms the filter surface and the empty-criteria behavior but does not describe the response shape, which the agent must infer. It is minimally viable but not rich.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with all 35 parameters already described in the input schema. The description adds nothing beyond stating that every filter field is modeled explicitly, which merely restates the schema rather than enriching parameter meaning. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (searches) and resource (person records), and clarifies the search-by-criteria semantics. However, it does not differentiate itself from the sibling get_person, which is a direct single-record fetch — an agent must infer the distinction between search and direct retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides only the operational note that omitting all filters returns every record. It gives no explicit guidance on when to use this tool versus get_person or other sibling read tools, and names no alternatives or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
36 tool updates
v0.2.3- First observed
check_connection - First observed
find_portals - First observed
get_access_history - First observed
get_access_level - First observed
get_access_level_group - First observed
get_access_level_groups - First observed
get_access_level_names - First observed
get_access_levels - First observed
get_card_access_details - First observed
get_card_formats - First observed
get_daily_unlock_window - First observed
get_elevators - First observed
get_event_history - First observed
get_floors - First observed
get_holiday - First observed
get_holidays - First observed
get_outputs - First observed
get_partitions - First observed
get_person - First observed
get_portal_group - First observed
get_portal_groups - First observed
get_portals - First observed
get_reader - First observed
get_reader_group - First observed
get_reader_groups - First observed
get_readers - First observed
get_time_spec - First observed
get_time_spec_group - First observed
get_time_spec_groups - First observed
get_time_specs - First observed
get_udf_list_items - First observed
get_udf_lists - First observed
get_unlock_window - First observed
list_events - First observed
ping_app - First observed
search_person_data
TDQS
Scored across 36 tools
Each tool targets a distinct entity or operation (e.g., get_person vs search_person_data, get_portals vs find_portals, get_unlock_window vs get_daily_unlock_window). Descriptions clarify any potential overlap, such as get_readers vs get_portals. No two tools appear to serve the same purpose.
The dominant pattern is get_<entity> for singular and get_<entity>s for plural, with a few exceptions like list_events, check_connection, ping_app, find_portals, and search_person_data. These deviations are minor and do not create confusion, but they break the otherwise uniform get_ convention.
With 36 tools, the server exceeds the typical well-scoped range (3-15) by a wide margin. While the breadth of NetBox entities justifies many getters, the count feels heavy and could overwhelm an agent; a leaner surface with combined or parameterized tools would be more coherent.
The server provides comprehensive read-only coverage of NetBox entities: persons, time specs, groups, holidays, portals, readers, access levels, card formats, events, history, and more. Minor gaps exist (e.g., no single-portal getter, no individual event/access record retrieval), but the core read surface is complete for the apparent purpose.
Maintenance
Related MCP Connectors
An MCP server that provides an API to LLMs to manage their JumpCloud resources.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
Scans remote MCP servers for protocol, security, and TLS issues; exposes scan tools via MCP.
Related MCP Servers
AlicenseAqualityCmaintenanceRead-only MCP server for NetBox that enables LLMs to query NetBox objects (devices, IPAM, etc.) and change logs through natural language, with field filtering for token optimization.4228Apache 2.0- AlicenseNot gradedqualityDmaintenanceExposes the UniFi Network Integration API as MCP tools, dynamically loaded from JSON manifests, with read-only mode by default.MIT
- AlicenseBqualityCmaintenanceExposes N-able N-central REST API as MCP tools for managing devices, organizations, users, and more, with support for read-only, write, and full write modes.825MIT
- AlicenseAqualityAmaintenanceProvides MCP tools for governed multi-vendor network device operations, including configuration management (backup, diff, merge, replace, rollback) and read-only queries (facts, interfaces, BGP, LLDP, ARP) via NAPALM, with optional NetBox source-of-truth integration.33MIT