N-central MCP Server
This server lets MCP clients query and manage N-able N-central through a curated, read-only-by-default tool catalog (with opt-in write/full modes), plus resources and prompts for context and reports.
Inventory and manage devices: list/search devices, get details/status/assets/lifecycle, create devices, update lifecycle, list device tasks/notes/custom properties/maintenance windows.
Organization hierarchy: list/search service orgs, customers, sites, org units/children, get context and limits, create org/customer/site (PREVIEW), update limits and custom-property defaults.
Users and access: get current user, list users and roles, access groups, create roles/groups.
Custom properties: read/update device and org-unit custom properties, propagate defaults down the hierarchy.
Scheduled tasks and monitoring: list scheduled tasks, task/status/details, device tasks, active issues, job statuses.
Reporting: run reports, bulk device reports (custom properties/assets/monitor status), user/device/site summaries, org hierarchy, patch comparison.
Administration: device filters, registration tokens, activation keys, software installers/download links, server info/time, logout.
PSA integrations: customer mappings, companies/contacts/sites, custom PSA tickets, credential validation (TigerPaw 3.0 only), with limitations flagged.
Deployment and safety: stdio or HTTP transport, single/multi-tenant isolation, JWT auth, retries, rate limiting, redaction, bounded pagination.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@N-central MCP Serverlist all devices in the Production org"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 deprecatedcompatibilitytoolsetsThree write modes:
read-only(default),write,full— authority is intersected with selected toolsets, so visibility never grants writes by itselfStructured results with stable
dataandmetafields, readable text fallback, operation provenance, partial-error reporting, redaction, and bounded 256 KiB outputBounded report workflows with safe auto-pagination;
run_reportsupports JSON or CSV outputMCP Resources for live org-hierarchy context (
ncentral://org-tree) and per-entity lookups via templated URIsMCP 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 GuideProduction-grade auth: JWT exchange with auto-refresh, hash-based bearer-token auth for the HTTP endpoint, CORS allow-list, rate limiting, audit log
Operability:
/healthzand/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-existsflag andfetch)An N-central instance you can reach over HTTPS
A User-API JWT token generated in the N-central UI
1. Install dependencies
npm install2. 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 |
| single-tenant | Your N-central URL, e.g. |
| single-tenant | User-API JWT from the N-central UI. Not needed in multi-tenant mode |
| hosted mode | Set to |
| multi-tenant | Comma-separated host suffixes a client may target — SSRF guard (exact or DNS-suffix match) |
| optional | Comma-separated catalogs; defaults to |
| optional |
|
| HTTP mode only | Setting this enables HTTP mode (omit for stdio) |
| HTTP mode | Bearer token clients must present. Generate with |
| optional | Interface to bind. |
| 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 |
| read and non-destructive write |
| 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
Keep the version 3 defaults (
NC_TOOLSETS=core,NC_WRITE_MODE=read-only) for the twelve-tool task-oriented catalog.If an existing integration still needs supported 2.x names, stage it with
NC_TOOLSETS=core,compatibility; addNC_WRITE_MODE=writeorfullonly when that authority is deliberately required.Review Migrating to 3.0 for all 87 names. In particular,
list_custom_psa_ticketsis removed because the upstream route returns navigation links; useget_psa_ticketwith a known identifier.Run
node --test test/contract/mcp/compatibility.contract.test.jsbefore 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 startOr 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/metricsTo 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 -dCompose 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.jsEach 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_ALLOWLISTrestricts 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:
get_server_statusvalidate_sessionget_current_usersearch_organizationsget_organization_contextsearch_devicesget_device_contextlist_active_issueslist_device_scheduled_tasksget_scheduled_task_contextrun_reportlist_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_contextreturns compact organization, child, and custom-property projections; child/property components default to page 1 with 25 rows. Use their option objects anddetailLevel: "full"when broader context is intentional.search_devicesreturns compact discovery fields by default; requestdetailLevel: "full"only when complete device records are required.get_current_useromits contact and postal-profile fields by default; request full detail only for workflows that need the broader profile.list_active_issuesdefaults to 10 compact rows; usedetailLevel: "full"explicitly for the complete upstream issue fields.list_job_statusesdefaults to 25 compact rows and supports localstatus,deviceId,jobId,since,pageNumber, andpageSizefiltering/pagination. The upstream REST route itself remains unpaged, so these options reduce MCP context rather than upstream latency.report_devices_bulkdefaults to one compact 25-device page. Useall: trueonly for an explicit complete-inventory fan-out,detailLevel: "full"for raw data, andpropertyNamesto restrict a compact custom-property report to named properties.report_all_users_by_service_orgdefaults to one compact 25-user page. Page through the deduped roster, or requestall: 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 |
| Bounded SO → Customer → Site hierarchy with IDs/names and partial/unlinked diagnostics |
| Server health + version snapshot |
| Templated — full device record by ID |
| Templated — customer details by ID |
| Templated — org unit details by ID |
Prompts
Name | Description |
| Comprehensive customer/site report with org custom properties |
| Active issues and monitoring status across the environment |
| Find sites with missing or low device counts |
| 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 messagefield 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:
deviceClassValueanddeviceClassLabelare alwaysnull(known N-central API bug)get_deviceby ID:lastLoggedInUserandstillLoggedInmay returnnull— uselist_devicesinstead for these fields. (lastApplianceCheckinTimewas also missing pre-v2025.3.1.9 — now fixed.)Active issues at SO level: The
/active-issuesendpoint only supports customer/site org unit types, not service orgScheduled task
/details: does NOT accept DEVICE-level task IDs — only SYSTEM and CUSTOMER. Navigate viaparentIdif you have a device task ID.Scheduled-task root:
GET /api/scheduled-tasksis a link-discovery root, not a pageable global task list. Use a device's scheduled-task route to discover DEVICE-level IDs, then followparentIdwhen 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_companiesconverts that ambiguous condition into an empty result withintegrationStatus: "unavailable"; it does not claim the integration is definitively absent.Per-endpoint concurrency limits: N-central enforces concurrency per-endpoint (range 1-50).
/api/devicesallows 5 concurrent;/api/devices/{id}/assets/lifecycle-infoonly 1. Bulk reports default to safe values; tune via theconcurrencyparameter.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_credentialand the compatibility aliasget_custom_psa_ticket_detailtransmit plaintext credentials in request bodies — use them only over HTTPS. The credential-bearing authenticated server-information operation is intentionally not exposed.selectis a filter, not a projection: despite the name, theselectquery 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 withField 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_devicedeliberately enforces the five valid required fields (customerId,networkAddress,longName,supportedOs, anddeviceClass) 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 | 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 |
| 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 |
HTTP mode exits with "FATAL: MCP_PORT is set but MCP_API_KEY is not" | Safety check — HTTP mode requires an API key | Set |
| Server bound or published to localhost only | Set |
Client connects but queries the wrong N-central / | Server not started with | In single-tenant mode the headers are ignored and env |
| Missing/invalid | Send both; FQDN must be |
"FATAL: NC_MULTI_TENANT=1 requires HTTP mode" | Multi-tenant needs per-request headers, which stdio can't carry | Set |
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.0The 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 |
| Invoke |
Claude Code |
| Invoke |
GitHub Copilot |
| In Agent mode, ask Copilot to use |
Establish the constitution once. For each feature, use the shared workflow:
constitution (once) -> specify -> clarify (optional) -> plan -> tasks -> analyze (optional) -> implement -> convergeCodex 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.ymlLicense
Released under the MIT License — see the LICENSE file for the full text.
Available Tools
12 toolsget_current_userARead-only
Return compact current-user identity and authorization context, or explicit full profile detail.
| Name | Required | Description | Default |
|---|---|---|---|
| detailLevel | No | compact (default) omits contact and postal profile fields. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes |
TDQS
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.
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.
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.
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.
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.
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_contextARead-only
Load a device plus selected monitoring, asset, lifecycle, note, custom-property, and task context.
| Name | Required | Description | Default |
|---|---|---|---|
| include | No | Optional components; details are always the primary component. | |
| deviceId | Yes | Device identifier. | |
| noteOptions | No | Pagination used only when notes are selected. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes |
TDQS
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.
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.
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.
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.
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.
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_contextARead-only
Load compact organization details plus selected bounded children, limits, and custom-property context. Request full/all explicitly.
| Name | Required | Description | Default |
|---|---|---|---|
| include | No | Optional components; details are always the primary component. | |
| orgUnitId | Yes | Organization unit identifier. | |
| detailLevel | No | compact (default) returns task-focused fields; full retains upstream records. | |
| childrenOptions | No | Pagination for children; defaults to page 1 with 25 rows. | |
| propertyOptions | No | Pagination for custom properties; defaults to page 1 with 25 rows. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes |
TDQS
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.
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.
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.
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.
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.
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_contextARead-only
Load a scheduled-task definition and optionally its aggregate or per-device execution status.
| Name | Required | Description | Default |
|---|---|---|---|
| taskId | Yes | Scheduled-task identifier. | |
| includeStatus | No | Include execution status. | |
| detailedStatus | No | Use per-device status; valid only for system/customer task IDs. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes |
TDQS
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.
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.
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.
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.
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.
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_statusARead-only
Check N-central service health and API version, optionally including the server clock.
| Name | Required | Description | Default |
|---|---|---|---|
| includeTime | No | Include the N-central server time. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes |
TDQS
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.
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.
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.
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.
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.
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_issuesARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| all | No | Fetch bounded pages, up to 20 pages or 10,000 records. | |
| select | No | N-central FIQL/RSQL row filter. | |
| sortBy | No | Field used to sort results. | |
| pageSize | No | Positive active-issue page size from 1-1000; defaults to 10 when omitted. | |
| orgUnitId | Yes | Organization unit identifier. | |
| sortOrder | No | Sort direction. | |
| pageNumber | No | Page number, starting at 1. | |
| detailLevel | No | compact (default) removes the verbose _extra object; full returns complete issue records. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes |
TDQS
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.
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.
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.
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.
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.
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_tasksARead-only
List scheduled tasks associated with one N-central device.
| Name | Required | Description | Default |
|---|---|---|---|
| deviceId | Yes | Device identifier. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes |
TDQS
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.
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.
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.
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.
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.
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_statusesARead-only
List asynchronous N-central job statuses with local filtering, bounded pagination, and a compact default projection.
| Name | Required | Description | Default |
|---|---|---|---|
| jobId | No | Optional exact job identifier filter. | |
| since | No | Keep jobs scheduled or completed at or after this ISO 8601 timestamp. | |
| status | No | Optional case-insensitive exact status filter. | |
| deviceId | No | Optional exact device identifier filter. | |
| pageSize | No | Local result page size from 1-100; defaults to 25. | |
| orgUnitId | Yes | Organization unit identifier. | |
| pageNumber | No | Local result page number; defaults to 1. | |
| detailLevel | No | compact (default) removes the unbounded _extra object; full retains complete rows. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes |
TDQS
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.
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.
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.
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.
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.
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_reportBRead-only
Run one reviewed read-only report adapter; arbitrary REST methods or paths are not accepted.
| Name | Required | Description | Default |
|---|---|---|---|
| all | No | Fetch bounded pages, up to 20 pages or 10,000 records. | |
| format | No | Requested presentation format. | |
| select | No | N-central FIQL/RSQL row filter. | |
| sortBy | No | Field used to sort results. | |
| pageSize | No | Page size from 1-1000; -1 is used only on documented operations. | |
| reportId | No | Required for a completed patch-comparison report. | |
| sortOrder | No | Sort direction. | |
| viewScope | No | Optional device-filter view scope. | |
| pageNumber | No | Page number, starting at 1. | |
| reportType | Yes | Reviewed report adapter. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes |
TDQS
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.
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.
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.
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.
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.
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_devicesARead-only
Search the global or organization-scoped N-central device inventory by human name or bounded filters and pagination.
| Name | Required | Description | Default |
|---|---|---|---|
| all | No | Fetch bounded pages, up to 20 pages or 10,000 records. | |
| name | No | Case-insensitive human-name search. Automatically scans bounded pages; do not combine with pageNumber or pageSize. | |
| select | No | N-central FIQL/RSQL row filter. | |
| sortBy | No | Field used to sort results. | |
| filterId | No | Optional N-central device filter identifier. | |
| pageSize | No | Page size from 1-1000; -1 is used only on documented operations. | |
| nameMatch | No | Human-name matching mode; requires name. | |
| orgUnitId | No | Optional organization unit scope. | |
| sortOrder | No | Sort direction. | |
| pageNumber | No | Page number, starting at 1. | |
| detailLevel | No | compact (default) returns discovery fields; full returns complete device records. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes |
TDQS
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.
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.
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.
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.
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.
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_organizationsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| all | No | Fetch bounded pages, up to 20 pages or 10,000 records. | |
| name | No | Case-insensitive human-name search. Automatically scans bounded pages; do not combine with pageNumber or pageSize. | |
| select | No | N-central FIQL/RSQL row filter. | |
| sortBy | No | Field used to sort results. | |
| pageSize | No | Page size from 1-1000; -1 is used only on documented operations. | |
| parentId | No | Service-org parent for customers or customer parent for sites. | |
| nameMatch | No | Human-name matching mode; requires name. | |
| sortOrder | No | Sort direction. | |
| pageNumber | No | Page number, starting at 1. | |
| organizationType | Yes | Organization kind to search. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes |
TDQS
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.
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.
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.
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.
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.
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_sessionARead-only
Confirm that the current authenticated N-central API session is valid without returning token material.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| meta | Yes |
TDQS
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.
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.
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.
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.
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.
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.
91 tool updates
v3.0.0- Removed
add_device_note - Removed
add_notes_bulk - Removed
create_access_group - Removed
create_custom_psa_ticket - Removed
create_customer - Removed
create_device - Removed
create_device_access_group - Removed
create_maintenance_windows - Removed
create_service_org - Removed
create_site - Removed
create_user_role - Removed
generate_patch_comparison_report - Removed
generate_software_download_link - Removed
get_access_group - Removed
get_appliance_task - Changed
get_current_user3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / detailLevelAdded value: +{ + "description": "compact (default) omits contact and postal profile fields.", + "enum": [ + "compact", + "full" + ], + "type": "string" +} - changed
Output 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" +}
- Removed
get_custom_psa_ticket_detail - Removed
get_customer - Removed
get_device - Removed
get_device_activation_key - Removed
get_device_assets - Added
get_device_context - Removed
get_device_custom_property - Removed
get_device_default_custom_property - Removed
get_device_lifecycle - Removed
get_device_status - Removed
get_maintenance_windows - Removed
get_org_custom_property_default - Removed
get_org_unit - Removed
get_org_unit_limits - Removed
get_org_unit_property - Added
get_organization_context - Removed
get_psa_customer_mapping - Removed
get_registration_token - Removed
get_report - Removed
get_scheduled_task - Added
get_scheduled_task_context - Removed
get_scheduled_task_status - Removed
get_server_info - Removed
get_server_info_authenticated - Added
get_server_status - Removed
get_server_time - Removed
get_service_org - Removed
get_site - Removed
get_software_installers - Removed
get_user_role - Removed
list_access_groups - Changed
list_active_issues13 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / allAdded value: +{ + "description": "Fetch bounded pages, up to 20 pages or 10,000 records.", + "type": "boolean" +} - added
Input schema / properties / detailLevelAdded value: +{ + "description": "compact (default) removes the verbose _extra object; full returns complete issue records.", + "enum": [ + "compact", + "full" + ], + "type": "string" +} - removed
Input schema / properties / formatRemoved value: -{ - "description": "Output format: \"csv\" or \"json\". Default varies by tool — list_* default to json; report_* default to csv.", - "enum": [ - "csv", - "json" - ], - "type": "string" -} - added
Input schema / properties / orgUnitId / anyOfAdded value: +[ + { + "description": "Organization unit identifier.", + "type": "string" + }, + { + "description": "Organization unit identifier.", + "type": "number" + } +] - changed
Input schema / properties / orgUnitId / descriptionPrevious value: -"The organization unit ID"New value: +"Organization unit identifier." - removed
Input schema / properties / orgUnitId / typeRemoved value: -"number" - added
Input schema / properties / pageNumberAdded value: +{ + "description": "Page number, starting at 1.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / pageSizeAdded value: +{ + "description": "Positive active-issue page size from 1-1000; defaults to 10 when omitted.", + "maximum": 1000, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / selectAdded value: +{ + "description": "N-central FIQL/RSQL row filter.", + "type": "string" +} - added
Input schema / properties / sortByAdded value: +{ + "description": "Field used to sort results.", + "type": "string" +} - added
Input schema / properties / sortOrderAdded value: +{ + "description": "Sort direction.", + "enum": [ + "asc", + "ascending", + "natural", + "desc", + "descending", + "reverse" + ], + "type": "string" +} - changed
Output 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" +}
- Removed
list_all_users - Removed
list_custom_psa_tickets - Removed
list_customers - Removed
list_device_custom_properties - Removed
list_device_filters - Removed
list_device_notes - Added
list_device_scheduled_tasks - Removed
list_device_tasks - Removed
list_devices - Removed
list_devices_by_org_unit - Changed
list_job_statuses13 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / detailLevelAdded value: +{ + "description": "compact (default) removes the unbounded _extra object; full retains complete rows.", + "enum": [ + "compact", + "full" + ], + "type": "string" +} - added
Input schema / properties / deviceIdAdded value: +{ + "anyOf": [ + { + "description": "Optional exact device identifier filter.", + "type": "string" + }, + { + "description": "Optional exact device identifier filter.", + "type": "number" + } + ], + "description": "Optional exact device identifier filter." +} - removed
Input schema / properties / formatRemoved value: -{ - "description": "Output format: \"csv\" or \"json\". Default varies by tool — list_* default to json; report_* default to csv.", - "enum": [ - "csv", - "json" - ], - "type": "string" -} - added
Input schema / properties / jobIdAdded value: +{ + "anyOf": [ + { + "description": "Optional exact job identifier filter.", + "type": "string" + }, + { + "description": "Optional exact job identifier filter.", + "type": "number" + } + ], + "description": "Optional exact job identifier filter." +} - added
Input schema / properties / orgUnitId / anyOfAdded value: +[ + { + "description": "Organization unit identifier.", + "type": "string" + }, + { + "description": "Organization unit identifier.", + "type": "number" + } +] - changed
Input schema / properties / orgUnitId / descriptionPrevious value: -"The organization unit ID"New value: +"Organization unit identifier." - removed
Input schema / properties / orgUnitId / typeRemoved value: -"number" - added
Input schema / properties / pageNumberAdded value: +{ + "description": "Local result page number; defaults to 1.", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / pageSizeAdded value: +{ + "description": "Local result page size from 1-100; defaults to 25.", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / sinceAdded value: +{ + "description": "Keep jobs scheduled or completed at or after this ISO 8601 timestamp.", + "type": "string" +} - added
Input schema / properties / statusAdded value: +{ + "description": "Optional case-insensitive exact status filter.", + "maxLength": 100, + "minLength": 1, + "pattern": ".*\\S.*", + "type": "string" +} - changed
Output 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" +}
- Removed
list_org_custom_properties - Removed
list_org_unit_children - Removed
list_org_units - Removed
list_psa_companies - Removed
list_psa_company_contacts - Removed
list_psa_company_sites - Removed
list_psa_customer_mappings - Removed
list_scheduled_tasks - Removed
list_service_orgs - Removed
list_sites - Removed
list_user_roles - Removed
list_users - Removed
logout - Removed
patch_device_lifecycle - Removed
report_all_users_by_so - Removed
report_customer_site_summary - Removed
report_devices_bulk - Removed
report_devices_by_so - Removed
report_org_hierarchy - Added
run_report - Added
search_devices - Added
search_organizations - Removed
update_device_custom_property - Removed
update_device_lifecycle - Removed
update_device_note - Removed
update_maintenance_windows - Removed
update_org_custom_property_default - Removed
update_org_unit_custom_property - Removed
update_org_unit_limits - Removed
update_psa_customer_mappings - Removed
validate_psa_credential - Added
validate_session
82 tool updates
v2.1.0- First observed
add_device_note - First observed
add_notes_bulk - First observed
create_access_group - First observed
create_custom_psa_ticket - First observed
create_customer - First observed
create_device - First observed
create_device_access_group - First observed
create_maintenance_windows - First observed
create_service_org - First observed
create_site - First observed
create_user_role - First observed
generate_patch_comparison_report - First observed
generate_software_download_link - First observed
get_access_group - First observed
get_appliance_task - First observed
get_current_user - First observed
get_custom_psa_ticket_detail - First observed
get_customer - First observed
get_device - First observed
get_device_activation_key - First observed
get_device_assets - First observed
get_device_custom_property - First observed
get_device_default_custom_property - First observed
get_device_lifecycle - First observed
get_device_status - First observed
get_maintenance_windows - First observed
get_org_custom_property_default - First observed
get_org_unit - First observed
get_org_unit_limits - First observed
get_org_unit_property - First observed
get_psa_customer_mapping - First observed
get_registration_token - First observed
get_report - First observed
get_scheduled_task - First observed
get_scheduled_task_status - First observed
get_server_info - First observed
get_server_info_authenticated - First observed
get_server_time - First observed
get_service_org - First observed
get_site - First observed
get_software_installers - First observed
get_user_role - First observed
list_access_groups - First observed
list_active_issues - First observed
list_all_users - First observed
list_custom_psa_tickets - First observed
list_customers - First observed
list_device_custom_properties - First observed
list_device_filters - First observed
list_device_notes - First observed
list_device_tasks - First observed
list_devices - First observed
list_devices_by_org_unit - First observed
list_job_statuses - First observed
list_org_custom_properties - First observed
list_org_unit_children - First observed
list_org_units - First observed
list_psa_companies - First observed
list_psa_company_contacts - First observed
list_psa_company_sites - First observed
list_psa_customer_mappings - First observed
list_scheduled_tasks - First observed
list_service_orgs - First observed
list_sites - First observed
list_user_roles - First observed
list_users - First observed
logout - First observed
patch_device_lifecycle - First observed
report_all_users_by_so - First observed
report_customer_site_summary - First observed
report_devices_bulk - First observed
report_devices_by_so - First observed
report_org_hierarchy - First observed
update_device_custom_property - First observed
update_device_lifecycle - First observed
update_device_note - First observed
update_maintenance_windows - First observed
update_org_custom_property_default - First observed
update_org_unit_custom_property - First observed
update_org_unit_limits - First observed
update_psa_customer_mappings - First observed
validate_psa_credential
TDQS
Scored across 12 tools
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.
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.
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.
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
Related MCP Connectors
Remote MCP for 1,500+ APIs. Vault-managed credentials; OAuth or API key. Search, load, and execute.
Unified gateway exposing 150+ tools across all NexGenData MCP servers via one endpoint.
- OneOAuthai.withone
Search, document and execute authenticated API calls across 700+ apps via one MCP server
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceExposes Zerobyte backup platform's REST API as MCP tools, enabling read-only queries on repositories, backups, snapshots, volumes, and system info.MIT
- AlicenseNot gradedqualityBmaintenanceEnables 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
- AlicenseNot gradedqualityBmaintenanceExposes ConnectWise Platform APIs as MCP tools, enabling management of companies, contacts, devices, policies, patches, and tickets through natural language.Apache 2.0
- FlicenseNot gradedqualityBmaintenanceExposes 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.-