Skip to main content
Glama
theonlytruebigmac

N-central MCP Server

N-central REST API MCP Server

A Model Context Protocol server for N-able N-central — exposing the N-central REST API as MCP tools, resources, and prompts for use with any MCP-compatible client.

Disclaimer: This is an unofficial, community-maintained MCP server. It is not an official N-able MCP server, and it is focused specifically on the N-central REST API surface.


Features at a Glance

  • Focused 12-tool default catalog for common read-only work, with opt-in operations, administration, psa, reporting, and deprecated compatibility toolsets

  • Three write modes: read-only (default), write, full — authority is intersected with selected toolsets, so visibility never grants writes by itself

  • Structured results with stable data and meta fields, readable text fallback, operation provenance, partial-error reporting, redaction, and bounded 256 KiB output

  • Bounded report workflows with safe auto-pagination; run_report supports JSON or CSV output

  • MCP Resources for live org-hierarchy context (ncentral://org-tree) and per-entity lookups via templated URIs

  • MCP Prompts for common audit and reporting workflows

  • Two transports: stdio (for Claude Desktop / local clients) and Streamable HTTP (for remote clients, MCP Inspector, etc.)

  • Single- or multi-tenant: self-host against one N-central (env credentials), or run one hosted server many users point at — each targeting their own N-central via per-request headers (NC_MULTI_TENANT=1), with strict per-request credential isolation. See the Setup & Client Guide

  • Production-grade auth: JWT exchange with auto-refresh, hash-based bearer-token auth for the HTTP endpoint, CORS allow-list, rate limiting, audit log

  • Operability: /healthz and /metrics (Prometheus text format) endpoints, structured audit logging, configurable retry/timeout/session caps


Related MCP server: nable-rmm-mcp

Quick Start

Prerequisites

  • Node.js ≥ 22.9 (uses the built-in --env-file-if-exists flag and fetch)

  • An N-central instance you can reach over HTTPS

  • A User-API JWT token generated in the N-central UI

1. Install dependencies

npm install

2. Get your N-central JWT token

In the N-central UI: Administration → User Management → Users → [user] → API Access → Generate JSON Web Token

Best practice: Use a dedicated API-only user with least-privilege roles. The API user password rotates every 90 days — regenerate the JWT proactively to avoid 500 errors.

3. Configure your environment

cp .env.example .env
# Edit .env — set NC_SERVER_URL and NC_JWT_TOKEN at minimum.

The most common variables (full list in .env.example):

Variable

Required when

Description

NC_SERVER_URL

single-tenant

Your N-central URL, e.g. https://ncentral.example.com. Not needed in multi-tenant mode

NC_JWT_TOKEN

single-tenant

User-API JWT from the N-central UI. Not needed in multi-tenant mode

NC_MULTI_TENANT

hosted mode

Set to 1 to require per-request X-NC-FQDN/X-NC-JWT headers (HTTP only). See Multi-Tenant Mode

NC_FQDN_ALLOWLIST

multi-tenant

Comma-separated host suffixes a client may target — SSRF guard (exact or DNS-suffix match)

NC_TOOLSETS

optional

Comma-separated catalogs; defaults to core. all selects every preferred v3 catalog. Valid names: all, core, operations, administration, psa, reporting, compatibility

NC_WRITE_MODE

optional

read-only | write | full (default read-only)

MCP_PORT

HTTP mode only

Setting this enables HTTP mode (omit for stdio)

MCP_API_KEY

HTTP mode

Bearer token clients must present. Generate with openssl rand -hex 32. Required unless MCP_ALLOW_UNAUTHENTICATED=1

MCP_BIND_ADDRESS

optional

Interface to bind. 127.0.0.1 (default) for localhost-only; 0.0.0.0 for Docker / LAN exposure

MCP_CORS_ORIGIN

browser clients

Comma-separated allow-list of origins

Connecting a client? See the Setup & Client Guide for copy-paste config for Claude Code, VS Code, Claude Desktop, and Cursor — in both single- and multi-tenant modes.

Toolsets and write modes

Omitting both settings advertises exactly the 12 core tools in read-only mode. Toolsets control relevance; write mode controls authority after the selected toolsets are combined.

Mode

Visible scopes

read-only (default)

read only

write

read and non-destructive write

full

read, write, and explicitly destructive

For example, NC_TOOLSETS=core,reporting remains read-only by default, while NC_TOOLSETS=operations NC_WRITE_MODE=full enables destructive operational workflows. All write/destructive tools are audit-logged. See MCP Toolsets for exact current membership and Migrating to 3.0 for all 87 legacy-name dispositions. NC_TOOLSETS=all expands to the five preferred v3 catalogs and intentionally excludes the legacy compatibility aliases; use NC_TOOLSETS=all,compatibility only while testing or migrating old names.

Upgrade from 2.x

  1. Keep the version 3 defaults (NC_TOOLSETS=core, NC_WRITE_MODE=read-only) for the twelve-tool task-oriented catalog.

  2. If an existing integration still needs supported 2.x names, stage it with NC_TOOLSETS=core,compatibility; add NC_WRITE_MODE=write or full only when that authority is deliberately required.

  3. Review Migrating to 3.0 for all 87 names. In particular, list_custom_psa_tickets is removed because the upstream route returns navigation links; use get_psa_ticket with a known identifier.

  4. Run node --test test/contract/mcp/compatibility.contract.test.js before switching production clients. This walkthrough is designed to take less than 15 minutes.

4. Start the server

The server runs in stdio mode by default and switches to HTTP mode when MCP_PORT is set.

Option A — stdio (Claude Desktop / local clients)

Use the npm script (loads .env if present):

npm start

Or wire it into Claude Desktop directly. Add to claude_desktop_config.json:

{
  "mcpServers": {
    "ncentral": {
      "command": "node",
      "args": ["--env-file-if-exists=/absolute/path/to/n-central-rest-api-mcp/.env", "/absolute/path/to/n-central-rest-api-mcp/index.js"],
      "env": {
        "NC_WRITE_MODE": "read-only"
      }
    }
  }
}

Option B — Streamable HTTP (remote clients, MCP Inspector)

Set an MCP_API_KEY, then use the HTTP script, which explicitly selects port 3100:

npm run start:http
# Listening at http://127.0.0.1:3100/mcp
# Health probe: http://127.0.0.1:3100/healthz
# Metrics:      http://127.0.0.1:3100/metrics

To use another port, start the server with MCP_PORT=<port> npm start. There is no HTTP port default in the runtime: an omitted MCP_PORT selects stdio.

Clients send Authorization: Bearer <MCP_API_KEY> on every request.

The Prometheus endpoint exposes bounded-label call counts plus cumulative tool duration, serialized response bytes, upstream-operation counts, and partial/truncated-result counters. Divide duration or byte totals by the matching call count to track average latency and response size without using tenant, organization, device, user, or request identifiers as labels.

Option C — Docker

cp .env.example .env
# Edit .env: NC_SERVER_URL, NC_JWT_TOKEN, MCP_API_KEY are required for the HTTP listener.
docker compose up -d

Compose maps 127.0.0.1:3100:3100 by default. To expose on the LAN, edit docker-compose.yml and ensure MCP_API_KEY is set.

Versioned images are also published to GitHub Container Registry:

docker pull ghcr.io/theonlytruebigmac/n-central-rest-api-mcp:<released-version>

Version 3.0.0 is currently an unreleased candidate; see Release Readiness for its exact scope and publication state.

5. Verify

# stdio mode — should print "Authenticated with N-central..." on first tool call.
# HTTP mode — should respond:
curl -s http://127.0.0.1:3100/healthz
# {"status":"ok","sessions":0}

Run deterministic and one-off credential-backed checks according to the Verification Policy. The live smoke command is explicitly opt-in, read-only, and emits no tenant response data. See Updating the OpenAPI Baseline before replacing the contract snapshot.

HTTP sessions, token/cache entries, and rate-limit buckets are process-local. Deploy one instance, or use reliable session affinity for the full MCP session; round-robin session traffic across replicas is unsupported in version 3. See Runtime Architecture.


Multi-Tenant (Hosted) Mode

By default the server is single-tenant: it reads one NC_SERVER_URL + NC_JWT_TOKEN from its environment. That's the right model for an MSP self-hosting it against a single N-central.

Set NC_MULTI_TENANT=1 to host one server that many users point at, each targeting a different N-central server with their own JWT — supplied per request via headers in their own MCP client config. (Intended for a centrally-hosted demo/eval box, not for routing third parties' production credentials through infrastructure you don't control.)

# Hosted server (HTTP only — stdio cannot carry per-request headers):
NC_MULTI_TENANT=1 \
MCP_PORT=3100 \
MCP_API_KEY="$(openssl rand -hex 32)" \
NC_FQDN_ALLOWLIST=ncentral.com,n-able.com \
node index.js

Each user's MCP client config sends, per request:

{
  "mcpServers": {
    "ncentral": {
      "type": "http",
      "url": "https://mcp.example.com/mcp",
      "headers": {
        "Authorization": "Bearer <MCP_API_KEY>",       // gates access to THIS server
        "X-NC-FQDN": "https://their-ncentral.example.com",
        "X-NC-JWT":  "<their N-central User-API JWT>"
      }
    }
  }
}

Isolation guarantees

  • One session = one tenant. Credentials are validated at session init (before the session exists); an invalid/missing header pair is rejected with 400. The tenant is then bound to the session for its lifetime — later header changes on the same session are ignored.

  • No shared credential state. Tokens are keyed per tenant and resolved per request via AsyncLocalStorage, so concurrent requests for different servers can never read each other's URL or token. The resource cache is tenant-scoped for the same reason.

  • Memory only, auto-evicted. Tokens and cache entries live in memory and are dropped when the last session for a tenant closes. Nothing is persisted; JWTs are never logged.

  • SSRF guard. NC_FQDN_ALLOWLIST restricts which N-central hosts a client may target (exact or DNS-suffix match). Leave it unset only behind trusted network boundaries — the server warns at startup if it's empty.

Scaling. The event loop handles many concurrent users on one process (the work is I/O-bound — waiting on N-central). If you outgrow one process, run replicas behind a load balancer with sticky routing by mcp-session-id — StreamableHTTP sessions live in process memory, so a session must return to the replica that created it.

Tip — multiple servers without hosting: a self-hoster who just needs to target several N-central servers from their own editor can skip multi-tenant mode entirely and define one stdio entry per server, each with its own env: { NC_SERVER_URL, NC_JWT_TOKEN }.


Tools

The default catalog is deliberately small. With no catalog configuration, clients discover these 12 read-only tools:

  1. get_server_status

  2. validate_session

  3. get_current_user

  4. search_organizations

  5. get_organization_context

  6. search_devices

  7. get_device_context

  8. list_active_issues

  9. list_device_scheduled_tasks

  10. get_scheduled_task_context

  11. run_report

  12. list_job_statuses

Optional catalogs contain 21 operations tools, 23 administration tools, 11 PSA tools, and 6 reporting tools. The deprecated compatibility catalog exposes 84 safely retained or adapted 2.x names. Counts are catalog memberships and are not additive when selected catalogs overlap. See the generated MCP Toolsets reference for exact names, descriptions, scopes, and configuration examples.

Both core inventory searches accept human names without requiring callers to construct endpoint-specific FIQL fields:

{ "organizationType": "customer", "name": "Acme", "nameMatch": "contains" }
{ "name": "Vienna Laptop", "nameMatch": "exact", "orgUnitId": 123 }

Name matching is case-insensitive and whitespace-normalized. It automatically scans bounded pages (at most 20 pages or 10,000 records), so pageNumber and pageSize cannot be combined with name. Advanced select, sort, parent, organization-unit, and device-filter inputs remain available as upstream pre-filters. Results include match mode, count, and retrieval bounds in meta.page.search.

Every successful tool result has the same shape:

{
  "data": {},
  "meta": {
    "operations": ["GET /api/..."],
    "partial": false,
    "errors": [],
    "page": null,
    "truncated": false
  }
}

The complete value is returned once as MCP structuredContent; text content is a compact summary with record count, page guidance, and partial/truncation state. Component failures can be reported as partial results; secrets and tenant URLs are redacted. Structured results are capped at 256 KiB.

Pagination and composition limits

List calls return one page unless all: true is supported. Automatic pagination is bounded to 20 pages and 10,000 records, with endpoint-specific page rules (including positive-only active-issue paging). Compositions use at most 10 upstream calls with concurrency capped at 5.

High-cardinality core/reporting tools use compact, bounded defaults:

  • get_organization_context returns compact organization, child, and custom-property projections; child/property components default to page 1 with 25 rows. Use their option objects and detailLevel: "full" when broader context is intentional.

  • search_devices returns compact discovery fields by default; request detailLevel: "full" only when complete device records are required.

  • get_current_user omits contact and postal-profile fields by default; request full detail only for workflows that need the broader profile.

  • list_active_issues defaults to 10 compact rows; use detailLevel: "full" explicitly for the complete upstream issue fields.

  • list_job_statuses defaults to 25 compact rows and supports local status, deviceId, jobId, since, pageNumber, and pageSize filtering/pagination. The upstream REST route itself remains unpaged, so these options reduce MCP context rather than upstream latency.

  • report_devices_bulk defaults to one compact 25-device page. Use all: true only for an explicit complete-inventory fan-out, detailLevel: "full" for raw data, and propertyNames to restrict a compact custom-property report to named properties.

  • report_all_users_by_service_org defaults to one compact 25-user page. Page through the deduped roster, or request all: true / detailLevel: "full" only when the broader result is necessary.

API coverage and limitations

Against the reviewed 104-operation OpenAPI snapshot, 92 operations are implemented, none remains partially implemented, and 12 have reviewed unsupported dispositions. The generated API Coverage report names every exposure decision, capability mapping, limitation, safe alternative, and test-evidence path. This project does not claim one public tool per REST operation or support for the 12 reviewed exclusions.


Resources

Resources provide live context to the client without requiring explicit tool calls. Hierarchical resources are cached for 60s by default — set NC_RESOURCE_CACHE_TTL_MS=0 to disable.

URI

Description

ncentral://org-tree

Bounded SO → Customer → Site hierarchy with IDs/names and partial/unlinked diagnostics

ncentral://status

Server health + version snapshot

ncentral://device/{deviceId}

Templated — full device record by ID

ncentral://customer/{customerId}

Templated — customer details by ID

ncentral://org-unit/{orgUnitId}

Templated — org unit details by ID


Prompts

Name

Description

full-customer-report

Comprehensive customer/site report with org custom properties

device-health-audit

Active issues and monitoring status across the environment

agent-deployment-status

Find sites with missing or low device counts

custom-property-audit

Audit custom property consistency across all customers


Resilience

Concern

Behavior

Rate limits (429)

Auto-retry with exponential backoff on all methods (up to 3 attempts)

Unauthorized (401)

Auto re-authenticates from JWT and replays the request on all methods

Token expiry

Access tokens (1hr) and refresh tokens (25hr) auto-refreshed; concurrent refreshes coalesced

Server errors (all 5xx)

Retried on GET/PUT/DELETE/HEAD (replay-safe), except PSA discovery/detail reads that fail fast because those routes can use 500 for missing integration/data. POST/PATCH fail fast to avoid duplicate writes

Request timeouts

30s on API calls, 15s on auth calls. Retried on idempotent methods only

Stale HTTP sessions

Cleaned up after 30 minutes of inactivity


Known API Quirks

  • Errors inside HTTP 200: Some N-central failures arrive as an error message field in an otherwise successful HTTP response. The client rejects that field case-insensitively instead of returning it as valid data. See N-able's known issues and limitations.

  • Probe assets: Return 404 — probes don't have asset records (expected behavior, skipped in bulk reports)

  • Active issues: deviceClassValue and deviceClassLabel are always null (known N-central API bug)

  • get_device by ID: lastLoggedInUser and stillLoggedIn may return null — use list_devices instead for these fields. (lastApplianceCheckinTime was also missing pre-v2025.3.1.9 — now fixed.)

  • Active issues at SO level: The /active-issues endpoint only supports customer/site org unit types, not service org

  • Scheduled task /details: does NOT accept DEVICE-level task IDs — only SYSTEM and CUSTOMER. Navigate via parentId if you have a device task ID.

  • Scheduled-task root: GET /api/scheduled-tasks is a link-discovery root, not a pageable global task list. Use a device's scheduled-task route to discover DEVICE-level IDs, then follow parentId when SYSTEM/CUSTOMER-level task information is required. N-able's endpoint reference and task FAQ agree with the OpenAPI/live response; the task overview's global-list wording is inconsistent.

  • create_direct_scheduled_task: Scripts must have Repository ID ≥ 2000 and "Enable API" toggled ON in the N-central UI. There's no API to enumerate scripts — find IDs in the Script/Software Repository UI. Extensive use accumulates DB rows that slow the UI's Task Execution page.

  • validate_psa_credential: only works with TigerPaw 3.0 — calls for other PSAs will fail.

  • Standard PSA collection shapes: Customer mappings, companies, contacts, and sites return { data: [...] } envelopes on live systems even though the reviewed OpenAPI responses reference singular PSA models. The MCP preserves the upstream envelope.

  • Standard PSA company discovery: Some systems return HTTP 500 when no integration is configured. list_psa_companies converts that ambiguous condition into an empty result with integrationStatus: "unavailable"; it does not claim the integration is definitively absent.

  • Per-endpoint concurrency limits: N-central enforces concurrency per-endpoint (range 1-50). /api/devices allows 5 concurrent; /api/devices/{id}/assets/lifecycle-info only 1. Bulk reports default to safe values; tune via the concurrency parameter.

  • PREVIEW endpoints: customer-scoped site listing/creation, customer/site registration tokens, and user-role listing/detail/creation are flagged PREVIEW by N-central. Every mapped tool warns during discovery because these contracts may change.

  • Credentialed POST tools: validate_psa_credential and the compatibility alias get_custom_psa_ticket_detail transmit plaintext credentials in request bodies — use them only over HTTPS. The credential-bearing authenticated server-information operation is intentionally not exposed.

  • select is a filter, not a projection: despite the name, the select query parameter on list endpoints is a FIQL/RSQL predicate that filters rows. It does NOT pick which fields come back. Valid: select=soId==50 (returns only that SO). Invalid: select=soId,soName (parse error). Not all fields are queryable — unsupported ones error with Field not found: X. Some operators (e.g. =gt=) throw NPEs on the server.

  • Device-create required fields: The reviewed OpenAPI snapshot contains one malformed generated entry in DeviceAddRequest.required. create_device deliberately enforces the five valid required fields (customerId, networkAddress, longName, supportedOs, and deviceClass) and ignores only that invalid schema artifact.


Troubleshooting

Symptom

Likely cause

Fix

500 errors on every API call

N-central API user password expired (rotates every 90 days)

Reset the password in N-central UI; regenerate the JWT; set a reminder for ~80 days

Repeated Got 401, re-authenticating... logs

N-central instance was rebooted (in-memory token state lost)

First 401 triggers re-auth; subsequent calls recover automatically. Noisy on restart but transient.

JWT works now but fails 5 minutes later

Token revocation propagation

After regenerating a JWT in N-central UI, allow up to 5 minutes for the old token's revocation to propagate

Server restart loses authentication state

Tokens are stored in-memory only

First API call after restart triggers fresh JWT exchange — no action needed

Can't reach the API on a custom port

N-central only serves the API on port 443

Use a reverse proxy or accept port 443

create_direct_scheduled_task errors with no script found

Repository ID < 2000 (bundled default) or "Enable API" toggle is OFF

Use a custom-uploaded script; toggle "Enable API" in the UI

Reaching pagination bounds on big environments

Automatic pagination caps at 20 pages or 10,000 records

Use a tighter filter via the select parameter, or call the tool with explicit pageNumber/pageSize

HTTP mode exits with "FATAL: MCP_PORT is set but MCP_API_KEY is not"

Safety check — HTTP mode requires an API key

Set MCP_API_KEY=$(openssl rand -hex 32) or MCP_ALLOW_UNAUTHENTICATED=1 for local dev

ERR_CONNECTION_REFUSED / can't reach /healthz//metrics from another machine

Server bound or published to localhost only

Set MCP_BIND_ADDRESS=0.0.0.0; in Docker publish 0.0.0.0:3100:3100 (not 127.0.0.1:3100:3100) and connect to the host's LAN IP, not localhost. If curl 127.0.0.1:3100/healthz works on the host but not remotely, it's the bind/publish scope

Client connects but queries the wrong N-central / X-NC-* headers ignored

Server not started with NC_MULTI_TENANT=1

In single-tenant mode the headers are ignored and env NC_SERVER_URL/NC_JWT_TOKEN are used. Start with NC_MULTI_TENANT=1 for header passthrough

400 at connect in multi-tenant mode

Missing/invalid X-NC-FQDN / X-NC-JWT

Send both; FQDN must be https:// and match NC_FQDN_ALLOWLIST if set

"FATAL: NC_MULTI_TENANT=1 requires HTTP mode"

Multi-tenant needs per-request headers, which stdio can't carry

Set MCP_PORT (run in HTTP mode)

For client-side setup issues, see the Setup & Client Guide.


Releases

Pushing a stable semantic-version tag starts .github/workflows/release.yml. The workflow requires the tag to exactly match the package, lockfile, and MCP server version, runs the release gates, builds Linux AMD64 and ARM64 images, publishes them to GHCR, and then creates the corresponding GitHub Release.

Version 3.0.0 metadata currently describes an unreleased candidate. Do not create its tag until the generated Release Readiness report is current, npm run release:check and the container smoke gate pass on the merged revision, and a maintainer explicitly approves publication.

After those conditions are satisfied for version 3.0.0:

git tag -a v3.0.0 -m "Release v3.0.0"
git push origin v3.0.0

The container receives immutable 3.0.0 and moving 3.0, 3, and latest tags. The GitHub Release includes the pushed image digest. A mismatched or non-stable tag fails before anything is published.


Spec-Driven Development

This repository is initialized with GitHub Spec Kit for three coding-agent integrations. All three agents share the specifications and plans under specs/ and the project-wide constitution under .specify/memory/constitution.md.

Agent

Project skills

How to start a workflow

Codex

.agents/skills/

Invoke $speckit-constitution, then $speckit-specify

Claude Code

.claude/skills/

Invoke /speckit-constitution, then /speckit-specify

GitHub Copilot

.github/skills/

In Agent mode, ask Copilot to use speckit-constitution or speckit-specify

Establish the constitution once. For each feature, use the shared workflow:

constitution (once) -> specify -> clarify (optional) -> plan -> tasks -> analyze (optional) -> implement -> converge

Codex is the default Spec Kit integration. To make another installed integration the default for shared templates and any extensions or presets, run specify integration use claude or specify integration use copilot. Return to Codex with specify integration use codex.

The Copilot integration requires Spec Kit's explicit multi-install override when it is installed alongside other agents. This repository has that supported setup recorded in .specify/integration.json; the three agent-specific skill directories do not overlap.


Project Structure

├── index.js                  # Entry point — transport selection (stdio / HTTP)
├── src/
│   ├── auth.js               # Per-tenant JWT → Access Token auth, auto-refresh logic
│   ├── client.js             # HTTP client with retry, timeout, and rate-limit handling
│   ├── config.js             # Shared bounded numeric environment parsing
│   ├── context.js            # Per-request tenant context (AsyncLocalStorage) — credential isolation
│   ├── http-runtime.js       # Streamable HTTP routing, rate limits, and session lifecycle
│   ├── logging.js            # Structured logger + audit log
│   ├── mcp-server.js         # Transport-independent MCP capability registration
│   ├── metrics.js            # Prometheus counters / gauges
│   ├── paginator.js          # Auto-pagination, bounded concurrency, CSV helpers
│   ├── prompts.js            # MCP Prompts definitions
│   ├── resources.js          # MCP Resources definitions
│   ├── server-utils.js       # JSON-schema → Zod, header parsing, safeCompare
│   ├── shared.js             # Shared pagination/format schema helpers
│   ├── tool-registry.js      # Write-mode gating + MCP tool annotations
│   ├── toolsets.js           # Deterministic catalog union + write-mode intersection
│   ├── capabilities/         # Bounded, task-oriented compositions used by core tools
│   ├── operations/           # Contract-shaped REST operation adapters
│   └── tools/
│       ├── core.js
│       ├── operations.js
│       ├── administration.js
│       ├── psa.js
│       ├── reporting.js
│       └── compatibility.js
├── scripts/
│   ├── check-critical-coverage.js # Aggregate and critical per-file coverage gate
│   ├── live-readonly-smoke.js     # Explicit credential-backed read-only verification
│   └── …                          # Generated-doc, evaluation, readiness, and version checks
├── test/
│   ├── auth-isolation.test.js  # Per-tenant token/credential isolation (forced interleave, 401 path)
│   ├── config.test.js          # Fail-fast numeric configuration contracts
│   ├── critical-coverage.test.js # Per-file coverage parser and enforcement
│   ├── isolation.test.js       # End-to-end session isolation, cache, boot matrix, SSRF guard
│   ├── mock-fetch.js           # Shared test helpers (not a test suite)
│   ├── repository-quality.test.js # Documentation, defaults, and repository hygiene
│   ├── server-runtime.test.js  # Focused MCP/HTTP runtime behavior
│   ├── helpers.test.js
│   ├── server-utils.test.js
│   └── utils.test.js
├── docs/
│   ├── API-COVERAGE.md          # Generated 104-operation implementation/evidence ledger
│   ├── ARCHITECTURE.md           # Runtime boundaries and supported deployment topology
│   ├── DEPENDENCY-REVIEW.md      # Combined dependency and superseded-PR disposition record
│   ├── MCP-EVALUATION.md         # Generated tool-selection quality report
│   ├── MCP-TOOLSETS.md          # Generated exact catalog membership and scopes
│   ├── MIGRATING-TO-3.0.md      # All 87 legacy-name dispositions
│   ├── OPENAPI-UPDATE.md         # Contract replacement and provenance procedure
│   ├── RELEASE-READINESS.md      # Generated version-3 scope and gate reconciliation
│   ├── SETUP-GUIDE.md           # Client setup how-to
│   └── VERIFICATION.md          # Deterministic and guarded live verification policy
├── .env.example
├── Dockerfile
└── docker-compose.yml

License

Released under the MIT License — see the LICENSE file for the full text.

Available Tools

12 tools
get_current_userA
Read-only

Return compact current-user identity and authorization context, or explicit full profile detail.

ParametersJSON Schema
NameRequiredDescriptionDefault
detailLevelNocompact (default) omits contact and postal profile fields.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
metaYes

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds the compact-versus-full behavioral distinction, which is useful, but it does not disclose error behavior, authentication requirements, or what 'authorization context' contains. No contradiction with annotations exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence states the core purpose and optional variation with no wasted words. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple one-optional-parameter, read-only tool with an output schema, annotations, and full parameter documentation. The description, combined with the schema and annotations, gives an agent everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: the detailLevel parameter is fully described with an enum and default. The description merely echoes the compact/full distinction without adding new semantic information, so it meets the baseline but does not exceed it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Return') and identifies a clear resource: the current user's identity and authorization context. It also signals an optional mode ('compact' vs 'explicit full profile detail'), which distinguishes it from the device-, server-, and organization-focused sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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 the current user's identity or authorization context is needed. It also implies the compact/full choice through the detailLevel parameter. However, it does not explicitly contrast it with related sibling tools like validate_session or get_organization_context, so it stops short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_device_contextA
Read-only

Load a device plus selected monitoring, asset, lifecycle, note, custom-property, and task context.

ParametersJSON Schema
NameRequiredDescriptionDefault
includeNoOptional components; details are always the primary component.
deviceIdYesDevice identifier.
noteOptionsNoPagination used only when notes are selected.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
metaYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, covering the safety profile. The description adds that context is 'selected' rather than exhaustive, but does not disclose pagination behavior, open-world response characteristics, or that 'details' is always included; these are left to the schema. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with no filler, front-loading the action and resource before the optional context list. Every element earns its place, and the structure is immediately scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a rich input schema, output schema, and read-only annotations, the minimal description is mostly adequate. However, for a context-aggregating tool with nested options and multiple siblings, a short usage pointer or completeness note would improve orientation; the current text omits 'details' and 'maintenanceWindows' from its enumeration.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%; deviceId, include, and noteOptions are already described with enums, ranges, and defaults. The description's list of context types roughly mirrors the include enum but omits details and maintenanceWindows, so it adds little semantic value beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Load'), names the resource ('a device'), and enumerates the context areas included (monitoring, asset, lifecycle, note, custom-property, task). This clearly differentiates it from sibling context loaders like get_organization_context and get_scheduled_task_context by naming the device resource.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this tool is for retrieving a device with selected context, but it never states when to prefer it over search_devices or get_organization_context, nor does it give exclusions. Usage context is inferable from the name and resource type, but no explicit when-to-use guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_organization_contextA
Read-only

Load compact organization details plus selected bounded children, limits, and custom-property context. Request full/all explicitly.

ParametersJSON Schema
NameRequiredDescriptionDefault
includeNoOptional components; details are always the primary component.
orgUnitIdYesOrganization unit identifier.
detailLevelNocompact (default) returns task-focused fields; full retains upstream records.
childrenOptionsNoPagination for children; defaults to page 1 with 25 rows.
propertyOptionsNoPagination for custom properties; defaults to page 1 with 25 rows.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
metaYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds behavioral nuance by noting the tool returns 'bounded' results and that full/all components must be explicitly requested. This complements the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that states the purpose and key behavioral requirement ('Request full/all explicitly') without any wasted words. It is appropriately concise for a tool whose schema carries detailed parameter information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with five parameters, nested objects, and an output schema, the description is terse but the schema fills in all parameter details. The description mentions the key components and the explicit request requirement, which is sufficient for an agent to understand the tool's scope. No critical information is missing given the schema and annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five parameters are documented in the schema itself. The description adds a high-level hint about requesting full/all, which relates to detailLevel and the 'all' flags, but it does not elaborate on individual parameter semantics beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear purpose: 'Load compact organization details plus selected bounded children, limits, and custom-property context.' It identifies the resource (organization) and the specific components (children, limits, custom properties) that can be included, distinguishing it from sibling tools like get_device_context or get_scheduled_task_context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when organization context is needed and hints at how to request full details ('Request full/all explicitly'), but it does not explicitly state when to use this tool over alternatives like search_organizations or get_current_user. There is no when-not-to-use guidance or mention of alternative tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_scheduled_task_contextA
Read-only

Load a scheduled-task definition and optionally its aggregate or per-device execution status.

ParametersJSON Schema
NameRequiredDescriptionDefault
taskIdYesScheduled-task identifier.
includeStatusNoInclude execution status.
detailedStatusNoUse per-device status; valid only for system/customer task IDs.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
metaYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, covering the safety profile. The description adds value by clarifying the distinction between aggregate and per-device execution status, which is not fully captured in the schema. This enhances behavioral understanding beyond the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that efficiently conveys the main purpose and the optional status feature without any waste. It is concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and a simple 3-parameter read-only tool, the description covers the essential behavior. It does not mention prerequisites like task existence, but these are implicit and the schema and annotations fill in the remaining gaps. The description is adequate for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds meaning by explicitly naming 'aggregate or per-device' status, which maps to includeStatus and detailedStatus respectively, and clarifies the relationship between these booleans beyond the schema's individual descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Load') and resource ('scheduled-task definition') and clearly distinguishes the tool's scope from siblings like list_device_scheduled_tasks, which lists tasks rather than loading a specific one. It also mentions the optional status retrieval, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when a specific scheduled task's definition or status is needed, but it does not explicitly contrast with sibling tools or state when not to use it. No alternatives or exclusions are mentioned, leaving the agent to infer from the name and context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_server_statusA
Read-only

Check N-central service health and API version, optionally including the server clock.

ParametersJSON Schema
NameRequiredDescriptionDefault
includeTimeNoInclude the N-central server time.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
metaYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds the optional includeTime behavior, which is useful. It doesn't mention response format or error cases, but the output schema likely covers return values.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One concise sentence with no wasted words. The main purpose is front-loaded, and the optional parameter is mentioned naturally.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only status tool with one optional parameter and an output schema, the description is nearly complete. It could explicitly state that no authentication is required or that it's safe to call, but the annotations already convey that.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 includeTime parameter. The description mentions 'optionally including the server clock,' which aligns with the parameter but doesn't add new meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Check') and resource ('N-central service health and API version'), and adds the optional server clock detail. This clearly distinguishes it from sibling tools like validate_session or get_current_user, which target different resources.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this is a health/status check tool, and the readOnlyHint annotation reinforces that it is safe to call. It doesn't explicitly name alternatives or when-not-to-use, but the context is clear enough for an agent to select it for health/version checks.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_active_issuesA
Read-only

List current active monitoring issues for a customer or site (service-org scope is unsupported), with bounded pagination and a compact default projection. Use detailLevel=full only when complete upstream records are required.

ParametersJSON Schema
NameRequiredDescriptionDefault
allNoFetch bounded pages, up to 20 pages or 10,000 records.
selectNoN-central FIQL/RSQL row filter.
sortByNoField used to sort results.
pageSizeNoPositive active-issue page size from 1-1000; defaults to 10 when omitted.
orgUnitIdYesOrganization unit identifier.
sortOrderNoSort direction.
pageNumberNoPage number, starting at 1.
detailLevelNocompact (default) removes the verbose _extra object; full returns complete issue records.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
metaYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only and non-destructive nature. The description adds meaningful behavioral context: bounded pagination, a compact default projection, and the service-org unsupported constraint, all of which are not inferable from annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler. The core purpose and scope are front-loaded, and the detailLevel guidance is placed where it matters most. Every clause carries signal.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a moderately complex 8-parameter tool with an output schema, the description conveys the essential non-obvious details: scope limitations, pagination bounds, default projection, and when to request full records. The output schema handles return-value specifics, so nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds value by explaining the trade-off between compact and full detailLevel and stating the default behavior. This gives the agent actionable selection guidance beyond the schema's enum descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource: 'List current active monitoring issues'. It also narrows scope to customer or site and explicitly excludes service-org scope, which clearly distinguishes it from sibling tools like list_job_statuses or search_devices.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context: active issues for a customer/site, service-org unsupported, and provides a decision rule for detailLevel ('use full only when complete upstream records are required'). It does not name alternative tools for comparison, but the scope constraints effectively guide when to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_device_scheduled_tasksA
Read-only

List scheduled tasks associated with one N-central device.

ParametersJSON Schema
NameRequiredDescriptionDefault
deviceIdYesDevice identifier.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
metaYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, so the safety profile is covered. The description is consistent with those annotations but adds little behavioral context beyond the per-device scoping; no additional side effects, pagination, or session requirements are disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single focused sentence that states the action, the object, and the scope with no wasted words. It is front-loaded and easy to parse, which is ideal for an agent selecting among many tools.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter read-only list operation, the description covers the essential usage context. The output schema is present, so return-value details do not need to be restated, and the annotations cover the read-only and non-destructive behavior. Nothing critical appears missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides 100% coverage for the single deviceId parameter, including a clear description. The description's mention of 'one N-central device' aligns with the parameter but does not add new semantic meaning beyond what the schema already documents, so the baseline score applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('list') and resource ('scheduled tasks') scoped to 'one N-central device', making the tool's purpose immediately clear. The wording also distinguishes it from sibling tools like list_active_issues and list_job_statuses by naming the resource and scope directly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

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 such as get_scheduled_task_context or list_job_statuses. It implies per-device usage, but does not state prerequisites, exclusions, or conditions that would route an agent to this tool instead of a sibling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_job_statusesA
Read-only

List asynchronous N-central job statuses with local filtering, bounded pagination, and a compact default projection.

ParametersJSON Schema
NameRequiredDescriptionDefault
jobIdNoOptional exact job identifier filter.
sinceNoKeep jobs scheduled or completed at or after this ISO 8601 timestamp.
statusNoOptional case-insensitive exact status filter.
deviceIdNoOptional exact device identifier filter.
pageSizeNoLocal result page size from 1-100; defaults to 25.
orgUnitIdYesOrganization unit identifier.
pageNumberNoLocal result page number; defaults to 1.
detailLevelNocompact (default) removes the unbounded _extra object; full retains complete rows.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
metaYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal a safe read operation via readOnlyHint and destructiveHint. The description adds meaningful behavioral detail beyond annotations: 'local filtering' indicates filters are applied after retrieval, 'bounded pagination' tells the agent results are limited and pageable, and 'compact default projection' explains the default output shape without requiring the agent to inspect the schema first.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, information-dense sentence with zero filler. The core action and resource are front-loaded, followed by three distinct behavioral characteristics that summarize the tool's personality. Every phrase earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-parameter read-only listing tool with a complete output schema and fully described parameters, the description covers the essential behavioral context: what is listed, how results are filtered, how pagination works, and what the default projection is. It could name the required orgUnitId explicitly, but the schema already requires it, so the agent can proceed confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds value by clarifying that filters are local and pagination is bounded, which helps an agent reason about how parameters like since, status, deviceId, pageSize, and pageNumber interact. It also reinforces that the default detailLevel is compact, aligning with the schema's default description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'List asynchronous N-central job statuses.' It also distinguishes this tool from siblings by adding behavioral qualifiers—'local filtering, bounded pagination, and a compact default projection'—so an agent can differentiate it from list_device_scheduled_tasks and other list/search tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for retrieving job statuses, and the resource scope is clear, but it does not explicitly state when to prefer this tool over alternatives or when not to use it. The sibling list does not include a directly competing 'list jobs' tool, so the lack of explicit exclusions is less harmful, but guidance is still only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_reportB
Read-only

Run one reviewed read-only report adapter; arbitrary REST methods or paths are not accepted.

ParametersJSON Schema
NameRequiredDescriptionDefault
allNoFetch bounded pages, up to 20 pages or 10,000 records.
formatNoRequested presentation format.
selectNoN-central FIQL/RSQL row filter.
sortByNoField used to sort results.
pageSizeNoPage size from 1-1000; -1 is used only on documented operations.
reportIdNoRequired for a completed patch-comparison report.
sortOrderNoSort direction.
viewScopeNoOptional device-filter view scope.
pageNumberNoPage number, starting at 1.
reportTypeYesReviewed report adapter.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
metaYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds the constraint that only reviewed adapters are accepted, which is useful context, but does not disclose other behaviors like output format or error handling. It does not contradict annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, focused sentence that front-loads the core purpose and includes a key limitation. No wasted words, and the structure is efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having an output schema and annotations, the tool has 10 parameters and two report types. The description gives no guidance on selecting reportType or understanding the tool's scope, leaving the agent to rely entirely on the schema. For this complexity, the description is too sparse to be fully self-sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all parameters are documented. The description does not add any parameter-specific meaning beyond the schema, which is acceptable given the baseline of 3 for full schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the tool runs a reviewed read-only report adapter, which is a specific verb and resource. It distinguishes itself from siblings by focusing on reports, but does not fully define what a report adapter is. The constraint about arbitrary REST methods adds clarity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use this tool versus alternatives. It mentions that arbitrary REST methods or paths are not accepted, but does not suggest what to use instead. The description lacks context on prerequisites or situations where this tool is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_devicesA
Read-only

Search the global or organization-scoped N-central device inventory by human name or bounded filters and pagination.

ParametersJSON Schema
NameRequiredDescriptionDefault
allNoFetch bounded pages, up to 20 pages or 10,000 records.
nameNoCase-insensitive human-name search. Automatically scans bounded pages; do not combine with pageNumber or pageSize.
selectNoN-central FIQL/RSQL row filter.
sortByNoField used to sort results.
filterIdNoOptional N-central device filter identifier.
pageSizeNoPage size from 1-1000; -1 is used only on documented operations.
nameMatchNoHuman-name matching mode; requires name.
orgUnitIdNoOptional organization unit scope.
sortOrderNoSort direction.
pageNumberNoPage number, starting at 1.
detailLevelNocompact (default) returns discovery fields; full returns complete device records.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
metaYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already establish the safety profile (readOnlyHint=true, destructiveHint=false), and the description adds useful behavioral context by noting 'bounded filters and pagination' rather than an unbounded search. It does not discuss result limits, case-insensitivity, or authentication, though the output schema and parameter descriptions cover some of that. This is adequate but not exceptional.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with no filler: the verb, scope, and search modes are front-loaded. 'global or organization-scoped' and 'bounded filters and pagination' pack meaningful constraints into a compact phrase, making the description easy to scan and act on.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 11 optional parameters, a fully documented schema, a rich output schema, and safety annotations, the description provides enough high-level orientation for an agent to select and invoke it correctly. It could have been slightly more explicit about name-vs-pagination mutual exclusivity and the orgUnitId scoping, but those details are already captured in the parameter descriptions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already documents all 11 parameters with constraints, enums, and descriptions. The tool description's mention of 'human name or bounded filters and pagination' maps loosely to the name, select, and pagination parameters but adds no semantic detail beyond what the schema provides. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb ('Search') and identifies the resource ('N-central device inventory'), then states scope ('global or organization-scoped') and the two main access modes ('human name or bounded filters and pagination'). This clearly separates it from sibling tools like search_organizations or get_device_context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'global or organization-scoped N-central device inventory' phrasing gives an agent clear context for when to use this tool: when locating devices by name or filters. It does not explicitly name alternatives or state exclusions, but the target use case is evident without needing to open the schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_organizationsA
Read-only

Find service organizations, customers, sites, or organization units by human name or bounded filtering and pagination. Customer-scoped site listing is PREVIEW and may change.

ParametersJSON Schema
NameRequiredDescriptionDefault
allNoFetch bounded pages, up to 20 pages or 10,000 records.
nameNoCase-insensitive human-name search. Automatically scans bounded pages; do not combine with pageNumber or pageSize.
selectNoN-central FIQL/RSQL row filter.
sortByNoField used to sort results.
pageSizeNoPage size from 1-1000; -1 is used only on documented operations.
parentIdNoService-org parent for customers or customer parent for sites.
nameMatchNoHuman-name matching mode; requires name.
sortOrderNoSort direction.
pageNumberNoPage number, starting at 1.
organizationTypeYesOrganization kind to search.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
metaYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the read-only safety profile is covered. The description adds useful behavioral context by noting bounded filtering/pagination and flagging that customer-scoped site listing is PREVIEW and may change. This goes beyond the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences with no filler. It front-loads the core purpose immediately and adds the preview caveat as a necessary second sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a rich output schema, full parameter documentation, and annotations covering safety, the description is largely sufficient. It covers entity types and search modes, and the preview caveat addresses a key stability concern. A small gap is the lack of explicit sibling-tool routing, but that is not essential given the schema richness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline applies. The description adds high-level context like 'human name' and 'bounded filtering and pagination,' but the individual parameter semantics are already fully documented in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool finds service organizations, customers, sites, and organization units by human name or bounded filtering and pagination. This is a specific verb plus resource, though it does not explicitly differentiate itself from sibling tools like search_devices.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage contexts: name-based search versus bounded filtering/pagination, and warns that customer-scoped site listing is PREVIEW. However, it does not explicitly say when to prefer this tool over search_devices or other siblings, nor does it mention exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_sessionA
Read-only

Confirm that the current authenticated N-central API session is valid without returning token material.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYes
metaYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, and destructiveHint=false, covering safety and side-effect profile. The description adds the behavioral trait that no token material is returned, which is a valuable security detail beyond annotations. It also implies a boolean/success response. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that is front-loaded with the verb and resource, followed by a concise behavioral qualifier. There is zero wasted text, and the structure is ideal for quick agent comprehension.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has no parameters, a simple purpose, and an output schema exists (so return values are structured elsewhere). The description covers the purpose and a key behavioral trait. Given the annotations, everything an agent needs to call and interpret this tool is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the input schema trivially covers everything. With no parameters, there is nothing for the description to explain. The description does not need to add parameter meaning; baseline for 0 params is 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Confirm') and a clear resource ('current authenticated N-central API session'), and adds the qualifier 'without returning token material', which precisely defines what the tool does and distinguishes it from any sibling that might return session or user data. It is unambiguous and actionable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies its use case (validating the current session) and the 'without returning token material' phrase helps differentiate it from tools like get_current_user. However, it does not explicitly name alternatives or state when NOT to use it, leaving some inference to the agent. This is a minor gap.

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.

  1. 91 tool updatesv3.0.0
    • Removedadd_device_note
    • Removedadd_notes_bulk
    • Removedcreate_access_group
    • Removedcreate_custom_psa_ticket
    • Removedcreate_customer
    • Removedcreate_device
    • Removedcreate_device_access_group
    • Removedcreate_maintenance_windows
    • Removedcreate_service_org
    • Removedcreate_site
    • Removedcreate_user_role
    • Removedgenerate_patch_comparison_report
    • Removedgenerate_software_download_link
    • Removedget_access_group
    • Removedget_appliance_task
    • Changedget_current_user3 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / detailLevel
        Added value: +{
        +  "description": "compact (default) omits contact and postal profile fields.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "data": {},
        +    "meta": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "errors": {
        +          "items": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "code": {
        +                "type": "string"
        +              },
        +              "component": {
        +                "type": "string"
        +              },
        +              "message": {
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "component",
        +              "code",
        +              "message"
        +            ],
        +            "type": "object"
        +          },
        +          "type": "array"
        +        },
        +        "operations": {
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "page": {},
        +        "partial": {
        +          "type": "boolean"
        +        },
        +        "truncated": {
        +          "type": "boolean"
        +        }
        +      },
        +      "required": [
        +        "operations",
        +        "partial",
        +        "errors",
        +        "page",
        +        "truncated"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "data",
        +    "meta"
        +  ],
        +  "type": "object"
        +}
    • Removedget_custom_psa_ticket_detail
    • Removedget_customer
    • Removedget_device
    • Removedget_device_activation_key
    • Removedget_device_assets
    • Addedget_device_context
    • Removedget_device_custom_property
    • Removedget_device_default_custom_property
    • Removedget_device_lifecycle
    • Removedget_device_status
    • Removedget_maintenance_windows
    • Removedget_org_custom_property_default
    • Removedget_org_unit
    • Removedget_org_unit_limits
    • Removedget_org_unit_property
    • Addedget_organization_context
    • Removedget_psa_customer_mapping
    • Removedget_registration_token
    • Removedget_report
    • Removedget_scheduled_task
    • Addedget_scheduled_task_context
    • Removedget_scheduled_task_status
    • Removedget_server_info
    • Removedget_server_info_authenticated
    • Addedget_server_status
    • Removedget_server_time
    • Removedget_service_org
    • Removedget_site
    • Removedget_software_installers
    • Removedget_user_role
    • Removedlist_access_groups
    • Changedlist_active_issues13 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / all
        Added value: +{
        +  "description": "Fetch bounded pages, up to 20 pages or 10,000 records.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / detailLevel
        Added value: +{
        +  "description": "compact (default) removes the verbose _extra object; full returns complete issue records.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
      • removedInput schema / properties / format
        Removed value: -{
        -  "description": "Output format: \"csv\" or \"json\". Default varies by tool — list_* default to json; report_* default to csv.",
        -  "enum": [
        -    "csv",
        -    "json"
        -  ],
        -  "type": "string"
        -}
      • addedInput schema / properties / orgUnitId / anyOf
        Added value: +[
        +  {
        +    "description": "Organization unit identifier.",
        +    "type": "string"
        +  },
        +  {
        +    "description": "Organization unit identifier.",
        +    "type": "number"
        +  }
        +]
      • changedInput schema / properties / orgUnitId / description
        Previous value: -"The organization unit ID"New value: +"Organization unit identifier."
      • removedInput schema / properties / orgUnitId / type
        Removed value: -"number"
      • addedInput schema / properties / pageNumber
        Added value: +{
        +  "description": "Page number, starting at 1.",
        +  "maximum": 9007199254740991,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / pageSize
        Added value: +{
        +  "description": "Positive active-issue page size from 1-1000; defaults to 10 when omitted.",
        +  "maximum": 1000,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / select
        Added value: +{
        +  "description": "N-central FIQL/RSQL row filter.",
        +  "type": "string"
        +}
      • addedInput schema / properties / sortBy
        Added value: +{
        +  "description": "Field used to sort results.",
        +  "type": "string"
        +}
      • addedInput schema / properties / sortOrder
        Added value: +{
        +  "description": "Sort direction.",
        +  "enum": [
        +    "asc",
        +    "ascending",
        +    "natural",
        +    "desc",
        +    "descending",
        +    "reverse"
        +  ],
        +  "type": "string"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "data": {},
        +    "meta": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "errors": {
        +          "items": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "code": {
        +                "type": "string"
        +              },
        +              "component": {
        +                "type": "string"
        +              },
        +              "message": {
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "component",
        +              "code",
        +              "message"
        +            ],
        +            "type": "object"
        +          },
        +          "type": "array"
        +        },
        +        "operations": {
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "page": {},
        +        "partial": {
        +          "type": "boolean"
        +        },
        +        "truncated": {
        +          "type": "boolean"
        +        }
        +      },
        +      "required": [
        +        "operations",
        +        "partial",
        +        "errors",
        +        "page",
        +        "truncated"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "data",
        +    "meta"
        +  ],
        +  "type": "object"
        +}
    • Removedlist_all_users
    • Removedlist_custom_psa_tickets
    • Removedlist_customers
    • Removedlist_device_custom_properties
    • Removedlist_device_filters
    • Removedlist_device_notes
    • Addedlist_device_scheduled_tasks
    • Removedlist_device_tasks
    • Removedlist_devices
    • Removedlist_devices_by_org_unit
    • Changedlist_job_statuses13 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / detailLevel
        Added value: +{
        +  "description": "compact (default) removes the unbounded _extra object; full retains complete rows.",
        +  "enum": [
        +    "compact",
        +    "full"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / deviceId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "Optional exact device identifier filter.",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Optional exact device identifier filter.",
        +      "type": "number"
        +    }
        +  ],
        +  "description": "Optional exact device identifier filter."
        +}
      • removedInput schema / properties / format
        Removed value: -{
        -  "description": "Output format: \"csv\" or \"json\". Default varies by tool — list_* default to json; report_* default to csv.",
        -  "enum": [
        -    "csv",
        -    "json"
        -  ],
        -  "type": "string"
        -}
      • addedInput schema / properties / jobId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "Optional exact job identifier filter.",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Optional exact job identifier filter.",
        +      "type": "number"
        +    }
        +  ],
        +  "description": "Optional exact job identifier filter."
        +}
      • addedInput schema / properties / orgUnitId / anyOf
        Added value: +[
        +  {
        +    "description": "Organization unit identifier.",
        +    "type": "string"
        +  },
        +  {
        +    "description": "Organization unit identifier.",
        +    "type": "number"
        +  }
        +]
      • changedInput schema / properties / orgUnitId / description
        Previous value: -"The organization unit ID"New value: +"Organization unit identifier."
      • removedInput schema / properties / orgUnitId / type
        Removed value: -"number"
      • addedInput schema / properties / pageNumber
        Added value: +{
        +  "description": "Local result page number; defaults to 1.",
        +  "maximum": 9007199254740991,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / pageSize
        Added value: +{
        +  "description": "Local result page size from 1-100; defaults to 25.",
        +  "maximum": 100,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / since
        Added value: +{
        +  "description": "Keep jobs scheduled or completed at or after this ISO 8601 timestamp.",
        +  "type": "string"
        +}
      • addedInput schema / properties / status
        Added value: +{
        +  "description": "Optional case-insensitive exact status filter.",
        +  "maxLength": 100,
        +  "minLength": 1,
        +  "pattern": ".*\\S.*",
        +  "type": "string"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "data": {},
        +    "meta": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "errors": {
        +          "items": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "code": {
        +                "type": "string"
        +              },
        +              "component": {
        +                "type": "string"
        +              },
        +              "message": {
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "component",
        +              "code",
        +              "message"
        +            ],
        +            "type": "object"
        +          },
        +          "type": "array"
        +        },
        +        "operations": {
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "page": {},
        +        "partial": {
        +          "type": "boolean"
        +        },
        +        "truncated": {
        +          "type": "boolean"
        +        }
        +      },
        +      "required": [
        +        "operations",
        +        "partial",
        +        "errors",
        +        "page",
        +        "truncated"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "data",
        +    "meta"
        +  ],
        +  "type": "object"
        +}
    • Removedlist_org_custom_properties
    • Removedlist_org_unit_children
    • Removedlist_org_units
    • Removedlist_psa_companies
    • Removedlist_psa_company_contacts
    • Removedlist_psa_company_sites
    • Removedlist_psa_customer_mappings
    • Removedlist_scheduled_tasks
    • Removedlist_service_orgs
    • Removedlist_sites
    • Removedlist_user_roles
    • Removedlist_users
    • Removedlogout
    • Removedpatch_device_lifecycle
    • Removedreport_all_users_by_so
    • Removedreport_customer_site_summary
    • Removedreport_devices_bulk
    • Removedreport_devices_by_so
    • Removedreport_org_hierarchy
    • Addedrun_report
    • Addedsearch_devices
    • Addedsearch_organizations
    • Removedupdate_device_custom_property
    • Removedupdate_device_lifecycle
    • Removedupdate_device_note
    • Removedupdate_maintenance_windows
    • Removedupdate_org_custom_property_default
    • Removedupdate_org_unit_custom_property
    • Removedupdate_org_unit_limits
    • Removedupdate_psa_customer_mappings
    • Removedvalidate_psa_credential
    • Addedvalidate_session
  2. 82 tool updatesv2.1.0
    • First observedadd_device_note
    • First observedadd_notes_bulk
    • First observedcreate_access_group
    • First observedcreate_custom_psa_ticket
    • First observedcreate_customer
    • First observedcreate_device
    • First observedcreate_device_access_group
    • First observedcreate_maintenance_windows
    • First observedcreate_service_org
    • First observedcreate_site
    • First observedcreate_user_role
    • First observedgenerate_patch_comparison_report
    • First observedgenerate_software_download_link
    • First observedget_access_group
    • First observedget_appliance_task
    • First observedget_current_user
    • First observedget_custom_psa_ticket_detail
    • First observedget_customer
    • First observedget_device
    • First observedget_device_activation_key
    • First observedget_device_assets
    • First observedget_device_custom_property
    • First observedget_device_default_custom_property
    • First observedget_device_lifecycle
    • First observedget_device_status
    • First observedget_maintenance_windows
    • First observedget_org_custom_property_default
    • First observedget_org_unit
    • First observedget_org_unit_limits
    • First observedget_org_unit_property
    • First observedget_psa_customer_mapping
    • First observedget_registration_token
    • First observedget_report
    • First observedget_scheduled_task
    • First observedget_scheduled_task_status
    • First observedget_server_info
    • First observedget_server_info_authenticated
    • First observedget_server_time
    • First observedget_service_org
    • First observedget_site
    • First observedget_software_installers
    • First observedget_user_role
    • First observedlist_access_groups
    • First observedlist_active_issues
    • First observedlist_all_users
    • First observedlist_custom_psa_tickets
    • First observedlist_customers
    • First observedlist_device_custom_properties
    • First observedlist_device_filters
    • First observedlist_device_notes
    • First observedlist_device_tasks
    • First observedlist_devices
    • First observedlist_devices_by_org_unit
    • First observedlist_job_statuses
    • First observedlist_org_custom_properties
    • First observedlist_org_unit_children
    • First observedlist_org_units
    • First observedlist_psa_companies
    • First observedlist_psa_company_contacts
    • First observedlist_psa_company_sites
    • First observedlist_psa_customer_mappings
    • First observedlist_scheduled_tasks
    • First observedlist_service_orgs
    • First observedlist_sites
    • First observedlist_user_roles
    • First observedlist_users
    • First observedlogout
    • First observedpatch_device_lifecycle
    • First observedreport_all_users_by_so
    • First observedreport_customer_site_summary
    • First observedreport_devices_bulk
    • First observedreport_devices_by_so
    • First observedreport_org_hierarchy
    • First observedupdate_device_custom_property
    • First observedupdate_device_lifecycle
    • First observedupdate_device_note
    • First observedupdate_maintenance_windows
    • First observedupdate_org_custom_property_default
    • First observedupdate_org_unit_custom_property
    • First observedupdate_org_unit_limits
    • First observedupdate_psa_customer_mappings
    • First observedvalidate_psa_credential

TDQS

A4/5.0

Scored across 12 tools

Disambiguation5/5

Each tool targets a distinct resource and action: server status, session validation, user profile, organization search/context, device search/context, scheduled tasks, active issues, reports, and jobs. The closest pair is list_device_scheduled_tasks versus get_scheduled_task_context, but one is a device-scoped listing and the other is a definition/status context, so they remain clearly separable.

Naming Consistency5/5

All tool names follow a consistent lower_snake_case verb_noun pattern, mixing list_, get_, search_, validate_, and run_. There is no camelCase or inconsistent verb style, making the naming predictable and easy to navigate.

Tool Count5/5

Twelve tools is a well-scoped size for an N-central monitoring and reporting server. Each tool covers a distinct capability, and none feels redundant or like filler.

Completeness4/5

The tool set covers the main read-only workflows: authentication, server health, organizations, devices, scheduled tasks, active issues, reports, and async job status. A broader management server might also expect create/update/delete actions, but given the clearly read-only report stance, the only real gap is the absence of any mutation/lifecycle operations.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Exposes Zerobyte backup platform's REST API as MCP tools, enabling read-only queries on repositories, backups, snapshots, volumes, and system info.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables interaction with N-able RMM (N-sight) API to manage clients, sites, devices, and retrieve monitoring data such as checks, patches, and performance history.
    Apache 2.0
  • F
    license
    Not graded
    quality
    B
    maintenance
    Exposes the CloudRadial REST API (client portal / PSA-adjacent MSP platform) as MCP tools, enabling operations on companies, articles, feedback, archives, flexible assets, and more via 34 tools with HTTP Basic Auth.
    -