@teamnetwork-nz/ninjaone-mcp-server 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +208 -0
- package/dist/client.d.ts +48 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +252 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +58 -0
- package/dist/config.js.map +1 -0
- package/dist/datetime.d.ts +4 -0
- package/dist/datetime.d.ts.map +1 -0
- package/dist/datetime.js +64 -0
- package/dist/datetime.js.map +1 -0
- package/dist/format.d.ts +7 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +68 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +86 -0
- package/dist/index.js.map +1 -0
- package/dist/teamlink.d.ts +2 -0
- package/dist/teamlink.d.ts.map +1 -0
- package/dist/teamlink.js +22 -0
- package/dist/teamlink.js.map +1 -0
- package/dist/tools/alerts.d.ts +3 -0
- package/dist/tools/alerts.d.ts.map +1 -0
- package/dist/tools/alerts.js +78 -0
- package/dist/tools/alerts.js.map +1 -0
- package/dist/tools/auth.d.ts +3 -0
- package/dist/tools/auth.d.ts.map +1 -0
- package/dist/tools/auth.js +24 -0
- package/dist/tools/auth.js.map +1 -0
- package/dist/tools/devices.d.ts +3 -0
- package/dist/tools/devices.d.ts.map +1 -0
- package/dist/tools/devices.js +236 -0
- package/dist/tools/devices.js.map +1 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +13 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/organizations.d.ts +3 -0
- package/dist/tools/organizations.d.ts.map +1 -0
- package/dist/tools/organizations.js +101 -0
- package/dist/tools/organizations.js.map +1 -0
- package/dist/tools/queries.d.ts +3 -0
- package/dist/tools/queries.d.ts.map +1 -0
- package/dist/tools/queries.js +137 -0
- package/dist/tools/queries.js.map +1 -0
- package/dist/types.d.ts +243 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +40 -0
package/dist/datetime.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Reads NINJAONE_DATETIMEFORMAT (default: "local").
|
|
2
|
+
// "local" → system local timezone (Intl.DateTimeFormat default)
|
|
3
|
+
// <tz> → any IANA timezone name, e.g. "Pacific/Auckland", "America/New_York", "UTC"
|
|
4
|
+
//
|
|
5
|
+
// NinjaOne timestamps are UTC — either ISO-8601 strings or epoch seconds/millis (numbers).
|
|
6
|
+
// This module renders them in the configured display timezone.
|
|
7
|
+
const ISO_RE = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?$/;
|
|
8
|
+
export function getConfiguredTz() {
|
|
9
|
+
const fmt = process.env.NINJAONE_DATETIMEFORMAT ?? 'local';
|
|
10
|
+
return fmt === 'local' ? Intl.DateTimeFormat().resolvedOptions().timeZone : fmt;
|
|
11
|
+
}
|
|
12
|
+
// Convert a UTC datetime (ISO string, or epoch seconds/millis number) into a display
|
|
13
|
+
// string in the configured timezone. Returns '' for null/undefined.
|
|
14
|
+
export function fromUtc(value) {
|
|
15
|
+
if (value === null || value === undefined || value === '')
|
|
16
|
+
return '';
|
|
17
|
+
try {
|
|
18
|
+
const d = toDate(value);
|
|
19
|
+
if (!d || isNaN(d.getTime()))
|
|
20
|
+
return String(value);
|
|
21
|
+
const tz = getConfiguredTz();
|
|
22
|
+
const parts = new Intl.DateTimeFormat('en-CA', {
|
|
23
|
+
timeZone: tz,
|
|
24
|
+
year: 'numeric',
|
|
25
|
+
month: '2-digit',
|
|
26
|
+
day: '2-digit',
|
|
27
|
+
hour: '2-digit',
|
|
28
|
+
minute: '2-digit',
|
|
29
|
+
second: '2-digit',
|
|
30
|
+
hour12: false,
|
|
31
|
+
timeZoneName: 'short',
|
|
32
|
+
}).formatToParts(d);
|
|
33
|
+
const get = (type) => parts.find((p) => p.type === type)?.value ?? '';
|
|
34
|
+
const h = get('hour') === '24' ? '00' : get('hour');
|
|
35
|
+
return `${get('year')}-${get('month')}-${get('day')} ${h}:${get('minute')}:${get('second')} ${get('timeZoneName')}`;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return String(value);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// NinjaOne epoch timestamps may be seconds (10-digit) or millis (13-digit), sometimes
|
|
42
|
+
// fractional seconds. Normalise to a Date.
|
|
43
|
+
function toDate(value) {
|
|
44
|
+
if (typeof value === 'number') {
|
|
45
|
+
// Heuristic: values below ~1e12 are seconds, otherwise millis.
|
|
46
|
+
const ms = value < 1e12 ? value * 1000 : value;
|
|
47
|
+
return new Date(ms);
|
|
48
|
+
}
|
|
49
|
+
const s = value.trim();
|
|
50
|
+
if (/^\d+(\.\d+)?$/.test(s)) {
|
|
51
|
+
const n = Number(s);
|
|
52
|
+
return toDate(n);
|
|
53
|
+
}
|
|
54
|
+
return new Date(s);
|
|
55
|
+
}
|
|
56
|
+
// Apply fromUtc to any value that looks like an ISO datetime; pass everything else
|
|
57
|
+
// through unchanged. Numbers are left alone here (ambiguous — could be a count), so
|
|
58
|
+
// epoch fields should be rendered explicitly via fromUtc().
|
|
59
|
+
export function maybeFromUtc(val) {
|
|
60
|
+
if (typeof val !== 'string')
|
|
61
|
+
return val;
|
|
62
|
+
return ISO_RE.test(val.trim()) ? fromUtc(val) : val;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=datetime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datetime.js","sourceRoot":"","sources":["../src/datetime.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,mEAAmE;AACnE,0FAA0F;AAC1F,EAAE;AACF,2FAA2F;AAC3F,+DAA+D;AAE/D,MAAM,MAAM,GAAG,0EAA0E,CAAC;AAE1F,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,OAAO,CAAC;IAC3D,OAAO,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;AAClF,CAAC;AAED,qFAAqF;AACrF,oEAAoE;AACpE,MAAM,UAAU,OAAO,CAAC,KAAyC;IAC/D,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IACrE,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;YAC7C,QAAQ,EAAE,EAAE;YACZ,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,SAAS;YACd,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,KAAK;YACb,YAAY,EAAE,OAAO;SACtB,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;QAC9E,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpD,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;IACtH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,2CAA2C;AAC3C,SAAS,MAAM,CAAC,KAAsB;IACpC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,+DAA+D;QAC/D,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAC/C,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;IACD,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACpB,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;AACrB,CAAC;AAED,mFAAmF;AACnF,oFAAoF;AACpF,4DAA4D;AAC5D,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACxC,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACtD,CAAC"}
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function humanBytes(bytes: number | undefined | null): string;
|
|
2
|
+
export declare function formatClock(value: number | undefined | null): string;
|
|
3
|
+
export declare function joinList(value: unknown): string;
|
|
4
|
+
export declare function percentUsed(free: number | undefined, capacity: number | undefined): string;
|
|
5
|
+
export declare function table(title: string, headers: string[], rows: string[][]): string;
|
|
6
|
+
export declare function objectBlock(label: string, obj: Record<string, unknown>): string;
|
|
7
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAGA,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAOnE;AAID,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAIpE;AAID,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAK/C;AAGD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAI1F;AAGD,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,CAUhF;AAID,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAK/E"}
|
package/dist/format.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { maybeFromUtc } from './datetime.js';
|
|
2
|
+
// Humanize a byte count to GB/TB with one decimal.
|
|
3
|
+
export function humanBytes(bytes) {
|
|
4
|
+
if (bytes === undefined || bytes === null || !Number.isFinite(bytes))
|
|
5
|
+
return '';
|
|
6
|
+
const gb = bytes / 1024 ** 3;
|
|
7
|
+
if (gb >= 1024)
|
|
8
|
+
return `${(gb / 1024).toFixed(1)} TB`;
|
|
9
|
+
if (gb >= 1)
|
|
10
|
+
return `${gb.toFixed(1)} GB`;
|
|
11
|
+
const mb = bytes / 1024 ** 2;
|
|
12
|
+
return `${mb.toFixed(0)} MB`;
|
|
13
|
+
}
|
|
14
|
+
// Format a CPU clock speed. NinjaOne reports this in Hz (e.g. 2095000000 → "2.10 GHz");
|
|
15
|
+
// smaller values are treated as MHz for safety.
|
|
16
|
+
export function formatClock(value) {
|
|
17
|
+
if (value === undefined || value === null || !Number.isFinite(value))
|
|
18
|
+
return '';
|
|
19
|
+
if (value >= 1e7)
|
|
20
|
+
return `${(value / 1e9).toFixed(2)} GHz`; // Hz → GHz
|
|
21
|
+
return `${value} MHz`;
|
|
22
|
+
}
|
|
23
|
+
// Normalise a NinjaOne "list" field that may arrive as an array, or as a string with
|
|
24
|
+
// ';' / ',' separators, into a comma-joined display string.
|
|
25
|
+
export function joinList(value) {
|
|
26
|
+
if (Array.isArray(value))
|
|
27
|
+
return value.filter(Boolean).join(', ');
|
|
28
|
+
if (typeof value === 'string')
|
|
29
|
+
return value.split(/[;,]/).map((s) => s.trim()).filter(Boolean).join(', ');
|
|
30
|
+
if (value === undefined || value === null)
|
|
31
|
+
return '';
|
|
32
|
+
return String(value);
|
|
33
|
+
}
|
|
34
|
+
// Percent used given free & capacity (both bytes).
|
|
35
|
+
export function percentUsed(free, capacity) {
|
|
36
|
+
if (!capacity || free === undefined)
|
|
37
|
+
return '';
|
|
38
|
+
const used = capacity - free;
|
|
39
|
+
return `${((used / capacity) * 100).toFixed(0)}%`;
|
|
40
|
+
}
|
|
41
|
+
// Render a Markdown table from headers + rows. Empty rows → "No records" line.
|
|
42
|
+
export function table(title, headers, rows) {
|
|
43
|
+
if (!rows.length)
|
|
44
|
+
return `**${title}**\n\nNo records found.`;
|
|
45
|
+
const sep = headers.map(() => '---');
|
|
46
|
+
const body = rows.map((r) => `| ${r.map((c) => c ?? '').join(' | ')} |`);
|
|
47
|
+
return [
|
|
48
|
+
`**${title} (${rows.length})**\n`,
|
|
49
|
+
`| ${headers.join(' | ')} |`,
|
|
50
|
+
`| ${sep.join(' | ')} |`,
|
|
51
|
+
...body,
|
|
52
|
+
].join('\n');
|
|
53
|
+
}
|
|
54
|
+
// Render a single object as a key/value block, dropping empty values and converting
|
|
55
|
+
// ISO datetime strings to the configured timezone.
|
|
56
|
+
export function objectBlock(label, obj) {
|
|
57
|
+
const lines = Object.entries(obj)
|
|
58
|
+
.filter(([, v]) => v !== null && v !== undefined && v !== '' && !(Array.isArray(v) && v.length === 0))
|
|
59
|
+
.map(([k, v]) => `- **${k}**: ${render(v)}`);
|
|
60
|
+
return `**${label}**\n\n${lines.join('\n')}`;
|
|
61
|
+
}
|
|
62
|
+
function render(v) {
|
|
63
|
+
const converted = maybeFromUtc(v);
|
|
64
|
+
if (typeof converted === 'object')
|
|
65
|
+
return JSON.stringify(converted);
|
|
66
|
+
return String(converted);
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
6
|
+
import { loadConfig } from './config.js';
|
|
7
|
+
import { NinjaClient } from './client.js';
|
|
8
|
+
import { allTools } from './tools/index.js';
|
|
9
|
+
const config = loadConfig();
|
|
10
|
+
const client = new NinjaClient(config);
|
|
11
|
+
const server = new Server({ name: 'ninjaone-mcp-server', version: '0.1.0' }, {
|
|
12
|
+
capabilities: { tools: {} },
|
|
13
|
+
instructions: `
|
|
14
|
+
NinjaOne RMM MCP server — remote monitoring and management via the NinjaOne Public API v2.
|
|
15
|
+
|
|
16
|
+
## Mode
|
|
17
|
+
- Read-only by default (Phase 1 exposes only read tools). Write operations require NINJAONE_READWRITE=true, and the API app must hold the "management" scope.
|
|
18
|
+
- Check the startup banner / ninja_test_connection for the active mode and granted scope.
|
|
19
|
+
|
|
20
|
+
## Hierarchy
|
|
21
|
+
- Devices belong to an Organization (the client) and a Location. Call ninja_list_organizations first to discover organization ids, then filter devices with organizationId.
|
|
22
|
+
- Organization and location ids are resolved to names automatically (cached).
|
|
23
|
+
|
|
24
|
+
## Device filtering
|
|
25
|
+
- ninja_list_devices and the ninja_query_* tools accept organizationId, locationId, deviceClass, online, or a raw NinjaOne device-filter (df) via deviceFilter.
|
|
26
|
+
- Device classes include WINDOWS_WORKSTATION, WINDOWS_SERVER, MAC, LINUX_SERVER, etc.
|
|
27
|
+
|
|
28
|
+
## Common workflows
|
|
29
|
+
|
|
30
|
+
### Find a machine
|
|
31
|
+
ninja_list_devices with organizationId (and optionally deviceClass or online).
|
|
32
|
+
|
|
33
|
+
### Inspect one machine
|
|
34
|
+
- ninja_get_device — identity, OS, system, last contact/boot.
|
|
35
|
+
- ninja_get_device_volumes / _disks / _processors / _network — hardware & capacity.
|
|
36
|
+
- ninja_get_device_software / _os_patches — inventory & patch state.
|
|
37
|
+
|
|
38
|
+
### Fleet stats & reporting
|
|
39
|
+
- ninja_query_device_health — health rollup across all/selected devices.
|
|
40
|
+
- ninja_query_volumes — disk capacity/usage fleet-wide.
|
|
41
|
+
- ninja_query_operating_systems / _computer_systems / _antivirus_status / _os_patches.
|
|
42
|
+
|
|
43
|
+
### Alerts
|
|
44
|
+
- ninja_list_alerts — currently triggered conditions (scope by device or org).
|
|
45
|
+
|
|
46
|
+
## Pagination
|
|
47
|
+
- List tools use cursor pagination: pass the reported after=<id>.
|
|
48
|
+
- ninja_query_* tools return a cursor name; pass it back as cursor=<name>.
|
|
49
|
+
|
|
50
|
+
## Datetime
|
|
51
|
+
- All NinjaOne timestamps are UTC (ISO or epoch). The server renders them in NINJAONE_DATETIMEFORMAT (default: system local). Present values as-is.
|
|
52
|
+
`.trim(),
|
|
53
|
+
});
|
|
54
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
55
|
+
tools: allTools.map((t) => ({
|
|
56
|
+
name: t.name,
|
|
57
|
+
description: t.description,
|
|
58
|
+
inputSchema: zodToJsonSchema(t.inputSchema),
|
|
59
|
+
})),
|
|
60
|
+
}));
|
|
61
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
62
|
+
const tool = allTools.find((t) => t.name === request.params.name);
|
|
63
|
+
if (!tool) {
|
|
64
|
+
return {
|
|
65
|
+
isError: true,
|
|
66
|
+
content: [{ type: 'text', text: `Unknown tool: ${request.params.name}` }],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const args = tool.inputSchema.parse(request.params.arguments ?? {});
|
|
71
|
+
const text = await tool.handler(client, args);
|
|
72
|
+
return { content: [{ type: 'text', text }] };
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
76
|
+
return {
|
|
77
|
+
isError: true,
|
|
78
|
+
content: [{ type: 'text', text: `Error in ${request.params.name}: ${message}` }],
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
const transport = new StdioServerTransport();
|
|
83
|
+
await server.connect(transport);
|
|
84
|
+
const mode = config.readWrite ? '✏️ read-write' : '🔒 read-only';
|
|
85
|
+
process.stderr.write(`NinjaOne MCP server started — ${allTools.length} tools registered. Targeting: ${config.baseUrl} [${mode}]\n`);
|
|
86
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teamlink.d.ts","sourceRoot":"","sources":["../src/teamlink.ts"],"names":[],"mappings":"AAiBA,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAIxF"}
|
package/dist/teamlink.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// TEAMlinkID — the link key to the internal TEAMlink CRM.
|
|
2
|
+
//
|
|
3
|
+
// It is NOT a native NinjaOne field. By convention it is the 5-digit integer beginning
|
|
4
|
+
// with 8 at the END of an organisation's name, e.g.:
|
|
5
|
+
// "TEAMnetwork Systems - 81674" -> 81674
|
|
6
|
+
// "TEAMnetwork Products - archiveMAIL - 80660" -> 80660
|
|
7
|
+
// "BSPKL - 84107" -> 84107
|
|
8
|
+
// "Internal Infrastructure" -> undefined (no id)
|
|
9
|
+
//
|
|
10
|
+
// It is derived from the org name and surfaced as `TEAMlinkID` on organisation- and
|
|
11
|
+
// device-related objects so NinjaOne records can later be joined to TEAMlink customers.
|
|
12
|
+
// Trailing 5-digit token starting with 8, not preceded by another digit (so it can't be
|
|
13
|
+
// a slice of a longer number). Trailing whitespace tolerated.
|
|
14
|
+
const TEAMLINK_RE = /(?:^|\D)(8\d{4})\s*$/;
|
|
15
|
+
// Extract the TEAMlinkID from an organisation name. Returns undefined when absent.
|
|
16
|
+
export function extractTeamlinkId(orgName) {
|
|
17
|
+
if (!orgName)
|
|
18
|
+
return undefined;
|
|
19
|
+
const m = orgName.match(TEAMLINK_RE);
|
|
20
|
+
return m ? m[1] : undefined;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=teamlink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teamlink.js","sourceRoot":"","sources":["../src/teamlink.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,EAAE;AACF,uFAAuF;AACvF,qDAAqD;AACrD,2DAA2D;AAC3D,2DAA2D;AAC3D,2DAA2D;AAC3D,uEAAuE;AACvE,EAAE;AACF,oFAAoF;AACpF,wFAAwF;AAExF,wFAAwF;AACxF,8DAA8D;AAC9D,MAAM,WAAW,GAAG,sBAAsB,CAAC;AAE3C,mFAAmF;AACnF,MAAM,UAAU,iBAAiB,CAAC,OAAkC;IAClE,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACrC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alerts.d.ts","sourceRoot":"","sources":["../../src/tools/alerts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAuC,MAAM,aAAa,CAAC;AAIlF,eAAO,MAAM,UAAU,EAAE,cAAc,EA2EtC,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { table } from '../format.js';
|
|
3
|
+
import { fromUtc } from '../datetime.js';
|
|
4
|
+
export const alertTools = [
|
|
5
|
+
{
|
|
6
|
+
name: 'ninja_list_alerts',
|
|
7
|
+
description: 'List currently triggered alerts (conditions). Optionally scope to one device, or to one organization / raw device-filter (df).',
|
|
8
|
+
inputSchema: z
|
|
9
|
+
.object({
|
|
10
|
+
deviceId: z.number().int().optional().describe('Restrict to a single device (uses /v2/device/{id}/alerts)'),
|
|
11
|
+
organizationId: z.number().int().optional().describe('Restrict to one organization (df: org = <id>)'),
|
|
12
|
+
deviceFilter: z.string().optional().describe('Raw NinjaOne device-filter (df) expression'),
|
|
13
|
+
})
|
|
14
|
+
.strict(),
|
|
15
|
+
handler: async (client, args) => {
|
|
16
|
+
let alerts;
|
|
17
|
+
if (args.deviceId !== undefined) {
|
|
18
|
+
alerts = await client.get(`/v2/device/${args.deviceId}/alerts`);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
const params = {};
|
|
22
|
+
const df = client.buildDeviceFilter({ organizationId: args.organizationId, raw: args.deviceFilter });
|
|
23
|
+
if (df)
|
|
24
|
+
params['df'] = df;
|
|
25
|
+
alerts = await client.get('/v2/alerts', params);
|
|
26
|
+
}
|
|
27
|
+
const rows = await Promise.all((alerts ?? []).map(async (a) => [
|
|
28
|
+
await client.resolveDeviceLabel(a.deviceId),
|
|
29
|
+
a.severity ?? a.priority ?? '',
|
|
30
|
+
a.sourceType ?? '',
|
|
31
|
+
a.message ?? '',
|
|
32
|
+
fromUtc(a.createTime),
|
|
33
|
+
]));
|
|
34
|
+
return table('Active Alerts', ['Device', 'Severity', 'Source', 'Message', 'Since'], rows);
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'ninja_list_activities',
|
|
39
|
+
description: 'Tenant-wide activity log. Optionally scope to one organization / device-filter, cap with pageSize, and filter by activity class or type.',
|
|
40
|
+
inputSchema: z
|
|
41
|
+
.object({
|
|
42
|
+
organizationId: z.number().int().optional().describe('Restrict to one organization (df: org = <id>)'),
|
|
43
|
+
deviceFilter: z.string().optional().describe('Raw NinjaOne device-filter (df) expression'),
|
|
44
|
+
activityClass: z
|
|
45
|
+
.string()
|
|
46
|
+
.optional()
|
|
47
|
+
.describe('Activity class filter, e.g. SYSTEM, DEVICE, USER, ALL'),
|
|
48
|
+
pageSize: z.number().int().min(1).max(1000).optional().describe('Max entries to return'),
|
|
49
|
+
after: z.number().int().min(0).optional().describe('Cursor: activityId from a previous page (older <)'),
|
|
50
|
+
})
|
|
51
|
+
.strict(),
|
|
52
|
+
handler: async (client, args) => {
|
|
53
|
+
const params = {};
|
|
54
|
+
const df = client.buildDeviceFilter({ organizationId: args.organizationId, raw: args.deviceFilter });
|
|
55
|
+
if (df)
|
|
56
|
+
params['df'] = df;
|
|
57
|
+
if (args.activityClass)
|
|
58
|
+
params['class'] = args.activityClass;
|
|
59
|
+
if (args.pageSize)
|
|
60
|
+
params['pageSize'] = args.pageSize;
|
|
61
|
+
if (args.after !== undefined)
|
|
62
|
+
params['olderThan'] = args.after;
|
|
63
|
+
const resp = await client.get('/v2/activities', params);
|
|
64
|
+
const activities = Array.isArray(resp) ? resp : resp.activities ?? [];
|
|
65
|
+
const rows = await Promise.all(activities.map(async (a) => [
|
|
66
|
+
fromUtc(a.activityTime),
|
|
67
|
+
await client.resolveDeviceLabel(a.deviceId),
|
|
68
|
+
a.activityType ?? a.type ?? '',
|
|
69
|
+
a.status ?? a.statusCode ?? '',
|
|
70
|
+
a.message ?? '',
|
|
71
|
+
]));
|
|
72
|
+
const out = table('Activities', ['Time', 'Device', 'Type', 'Status', 'Message'], rows);
|
|
73
|
+
const lastId = !Array.isArray(resp) ? resp.lastActivityId : activities[activities.length - 1]?.id;
|
|
74
|
+
return lastId ? `${out}\n\n_Page older entries with after=${lastId}._` : out;
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
//# sourceMappingURL=alerts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alerts.js","sourceRoot":"","sources":["../../src/tools/alerts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAgB,MAAM,aAAa,CAAC;AAE3D,eAAO,MAAM,SAAS,EAAE,cAAc,EAsBrC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const authTools = [
|
|
3
|
+
{
|
|
4
|
+
name: 'ninja_test_connection',
|
|
5
|
+
description: 'Test connectivity to NinjaOne: acquires an OAuth token and makes a cheap call. Reports base URL, granted scope, and read-only/read-write mode.',
|
|
6
|
+
inputSchema: z.object({}).strict(),
|
|
7
|
+
handler: async (client) => {
|
|
8
|
+
// A minimal, cheap read that also proves the token works.
|
|
9
|
+
const orgs = await client.get('/v2/organizations', { pageSize: 1 });
|
|
10
|
+
const mode = client.isReadWrite()
|
|
11
|
+
? '✏️ read-write'
|
|
12
|
+
: '🔒 read-only (set NINJAONE_READWRITE=true to enable write operations)';
|
|
13
|
+
const scope = client.getGrantedScope() ?? '(unknown)';
|
|
14
|
+
return [
|
|
15
|
+
'NinjaOne connection successful.',
|
|
16
|
+
`- **Base URL**: ${client.getBaseUrl()}`,
|
|
17
|
+
`- **Granted scope**: ${scope}`,
|
|
18
|
+
`- **Mode**: ${mode}`,
|
|
19
|
+
`- **Reachable**: organizations endpoint returned ${orgs?.length ?? 0} record(s) (probe with pageSize=1).`,
|
|
20
|
+
].join('\n');
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,CAAC,MAAM,SAAS,GAAqB;IACzC;QACE,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EACT,gJAAgJ;QAClJ,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;QAClC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACxB,0DAA0D;YAC1D,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAiB,mBAAmB,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;YACpF,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,EAAE;gBAC/B,CAAC,CAAC,eAAe;gBACjB,CAAC,CAAC,uEAAuE,CAAC;YAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,eAAe,EAAE,IAAI,WAAW,CAAC;YACtD,OAAO;gBACL,iCAAiC;gBACjC,mBAAmB,MAAM,CAAC,UAAU,EAAE,EAAE;gBACxC,wBAAwB,KAAK,EAAE;gBAC/B,eAAe,IAAI,EAAE;gBACrB,oDAAoD,IAAI,EAAE,MAAM,IAAI,CAAC,qCAAqC;aAC3G,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,CAAC;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devices.d.ts","sourceRoot":"","sources":["../../src/tools/devices.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EAWf,MAAM,aAAa,CAAC;AAwBrB,eAAO,MAAM,WAAW,EAAE,cAAc,EAkOvC,CAAC"}
|