@aristanetworks/eos-mcp-server 0.6.1-beta

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.
Files changed (170) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/LICENSE +203 -0
  3. package/README.md +652 -0
  4. package/dist/cli.d.ts +16 -0
  5. package/dist/cli.js +188 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/printServerInfo.d.ts +2 -0
  8. package/dist/commands/printServerInfo.js +14 -0
  9. package/dist/commands/printServerInfo.js.map +1 -0
  10. package/dist/commands/probe.d.ts +2 -0
  11. package/dist/commands/probe.js +26 -0
  12. package/dist/commands/probe.js.map +1 -0
  13. package/dist/commands/validateInventory.d.ts +9 -0
  14. package/dist/commands/validateInventory.js +59 -0
  15. package/dist/commands/validateInventory.js.map +1 -0
  16. package/dist/config/loadConfig.d.ts +3 -0
  17. package/dist/config/loadConfig.js +84 -0
  18. package/dist/config/loadConfig.js.map +1 -0
  19. package/dist/config/schema.d.ts +151 -0
  20. package/dist/config/schema.js +54 -0
  21. package/dist/config/schema.js.map +1 -0
  22. package/dist/configuration/getRunningConfig.d.ts +24 -0
  23. package/dist/configuration/getRunningConfig.js +38 -0
  24. package/dist/configuration/getRunningConfig.js.map +1 -0
  25. package/dist/connection/eosDeviceReader.d.ts +18 -0
  26. package/dist/connection/eosDeviceReader.js +13 -0
  27. package/dist/connection/eosDeviceReader.js.map +1 -0
  28. package/dist/connection/resolveConnection.d.ts +4 -0
  29. package/dist/connection/resolveConnection.js +58 -0
  30. package/dist/connection/resolveConnection.js.map +1 -0
  31. package/dist/connection/validateStartupConnections.d.ts +4 -0
  32. package/dist/connection/validateStartupConnections.js +28 -0
  33. package/dist/connection/validateStartupConnections.js.map +1 -0
  34. package/dist/core/errors.d.ts +8 -0
  35. package/dist/core/errors.js +22 -0
  36. package/dist/core/errors.js.map +1 -0
  37. package/dist/core/version.d.ts +2 -0
  38. package/dist/core/version.js +7 -0
  39. package/dist/core/version.js.map +1 -0
  40. package/dist/eapi/client.d.ts +8 -0
  41. package/dist/eapi/client.js +159 -0
  42. package/dist/eapi/client.js.map +1 -0
  43. package/dist/eapi/commands.d.ts +2 -0
  44. package/dist/eapi/commands.js +25 -0
  45. package/dist/eapi/commands.js.map +1 -0
  46. package/dist/eapi/transport.d.ts +21 -0
  47. package/dist/eapi/transport.js +143 -0
  48. package/dist/eapi/transport.js.map +1 -0
  49. package/dist/eapi/types.d.ts +49 -0
  50. package/dist/eapi/types.js +15 -0
  51. package/dist/eapi/types.js.map +1 -0
  52. package/dist/facts/getFacts.d.ts +33 -0
  53. package/dist/facts/getFacts.js +50 -0
  54. package/dist/facts/getFacts.js.map +1 -0
  55. package/dist/index.d.ts +2 -0
  56. package/dist/index.js +66 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/inventory/buildModel.d.ts +3 -0
  59. package/dist/inventory/buildModel.js +79 -0
  60. package/dist/inventory/buildModel.js.map +1 -0
  61. package/dist/inventory/effectiveVars.d.ts +2 -0
  62. package/dist/inventory/effectiveVars.js +52 -0
  63. package/dist/inventory/effectiveVars.js.map +1 -0
  64. package/dist/inventory/graph.d.ts +6 -0
  65. package/dist/inventory/graph.js +81 -0
  66. package/dist/inventory/graph.js.map +1 -0
  67. package/dist/inventory/internalTypes.d.ts +17 -0
  68. package/dist/inventory/internalTypes.js +2 -0
  69. package/dist/inventory/internalTypes.js.map +1 -0
  70. package/dist/inventory/internalUtils.d.ts +10 -0
  71. package/dist/inventory/internalUtils.js +68 -0
  72. package/dist/inventory/internalUtils.js.map +1 -0
  73. package/dist/inventory/listInventoryView.d.ts +23 -0
  74. package/dist/inventory/listInventoryView.js +22 -0
  75. package/dist/inventory/listInventoryView.js.map +1 -0
  76. package/dist/inventory/loadInventory.d.ts +4 -0
  77. package/dist/inventory/loadInventory.js +87 -0
  78. package/dist/inventory/loadInventory.js.map +1 -0
  79. package/dist/inventory/normalize.d.ts +4 -0
  80. package/dist/inventory/normalize.js +251 -0
  81. package/dist/inventory/normalize.js.map +1 -0
  82. package/dist/inventory/parse.d.ts +6 -0
  83. package/dist/inventory/parse.js +31 -0
  84. package/dist/inventory/parse.js.map +1 -0
  85. package/dist/inventory/policy.d.ts +11 -0
  86. package/dist/inventory/policy.js +27 -0
  87. package/dist/inventory/policy.js.map +1 -0
  88. package/dist/inventory/resolveTarget.d.ts +14 -0
  89. package/dist/inventory/resolveTarget.js +55 -0
  90. package/dist/inventory/resolveTarget.js.map +1 -0
  91. package/dist/inventory/types.d.ts +50 -0
  92. package/dist/inventory/types.js +2 -0
  93. package/dist/inventory/types.js.map +1 -0
  94. package/dist/inventory/validateNormalized.d.ts +2 -0
  95. package/dist/inventory/validateNormalized.js +64 -0
  96. package/dist/inventory/validateNormalized.js.map +1 -0
  97. package/dist/inventory/varValidation.d.ts +2 -0
  98. package/dist/inventory/varValidation.js +60 -0
  99. package/dist/inventory/varValidation.js.map +1 -0
  100. package/dist/inventory/writePolicy.d.ts +2 -0
  101. package/dist/inventory/writePolicy.js +36 -0
  102. package/dist/inventory/writePolicy.js.map +1 -0
  103. package/dist/logging/loggingQuery.d.ts +15 -0
  104. package/dist/logging/loggingQuery.js +38 -0
  105. package/dist/logging/loggingQuery.js.map +1 -0
  106. package/dist/logging/showLogging.d.ts +28 -0
  107. package/dist/logging/showLogging.js +37 -0
  108. package/dist/logging/showLogging.js.map +1 -0
  109. package/dist/mcp/createServer.d.ts +3 -0
  110. package/dist/mcp/createServer.js +82 -0
  111. package/dist/mcp/createServer.js.map +1 -0
  112. package/dist/mcp/toolResult.d.ts +7 -0
  113. package/dist/mcp/toolResult.js +13 -0
  114. package/dist/mcp/toolResult.js.map +1 -0
  115. package/dist/mcp/tools/getFacts.d.ts +21 -0
  116. package/dist/mcp/tools/getFacts.js +17 -0
  117. package/dist/mcp/tools/getFacts.js.map +1 -0
  118. package/dist/mcp/tools/getRunningConfig.d.ts +21 -0
  119. package/dist/mcp/tools/getRunningConfig.js +17 -0
  120. package/dist/mcp/tools/getRunningConfig.js.map +1 -0
  121. package/dist/mcp/tools/getServerInfo.d.ts +10 -0
  122. package/dist/mcp/tools/getServerInfo.js +9 -0
  123. package/dist/mcp/tools/getServerInfo.js.map +1 -0
  124. package/dist/mcp/tools/listInventory.d.ts +16 -0
  125. package/dist/mcp/tools/listInventory.js +15 -0
  126. package/dist/mcp/tools/listInventory.js.map +1 -0
  127. package/dist/mcp/tools/probeDevices.d.ts +21 -0
  128. package/dist/mcp/tools/probeDevices.js +14 -0
  129. package/dist/mcp/tools/probeDevices.js.map +1 -0
  130. package/dist/mcp/tools/runShow.d.ts +30 -0
  131. package/dist/mcp/tools/runShow.js +34 -0
  132. package/dist/mcp/tools/runShow.js.map +1 -0
  133. package/dist/mcp/tools/showLogging.d.ts +24 -0
  134. package/dist/mcp/tools/showLogging.js +20 -0
  135. package/dist/mcp/tools/showLogging.js.map +1 -0
  136. package/dist/operations/readExecution.d.ts +57 -0
  137. package/dist/operations/readExecution.js +132 -0
  138. package/dist/operations/readExecution.js.map +1 -0
  139. package/dist/probe/probeDevices.d.ts +24 -0
  140. package/dist/probe/probeDevices.js +24 -0
  141. package/dist/probe/probeDevices.js.map +1 -0
  142. package/dist/serverInfo/buildServerInfo.d.ts +2 -0
  143. package/dist/serverInfo/buildServerInfo.js +49 -0
  144. package/dist/serverInfo/buildServerInfo.js.map +1 -0
  145. package/dist/serverInfo/types.d.ts +46 -0
  146. package/dist/serverInfo/types.js +2 -0
  147. package/dist/serverInfo/types.js.map +1 -0
  148. package/dist/show/runShow.d.ts +29 -0
  149. package/dist/show/runShow.js +40 -0
  150. package/dist/show/runShow.js.map +1 -0
  151. package/dist/utils/json.d.ts +1 -0
  152. package/dist/utils/json.js +4 -0
  153. package/dist/utils/json.js.map +1 -0
  154. package/dist/utils/path.d.ts +2 -0
  155. package/dist/utils/path.js +14 -0
  156. package/dist/utils/path.js.map +1 -0
  157. package/dist/utils/value.d.ts +6 -0
  158. package/dist/utils/value.js +28 -0
  159. package/dist/utils/value.js.map +1 -0
  160. package/docs/CHECKPOINT.md +46 -0
  161. package/docs/CODE_WALKTHROUGH.md +112 -0
  162. package/docs/DESIGN.md +56 -0
  163. package/docs/DEVELOPMENT.md +72 -0
  164. package/docs/EXAMPLES.md +178 -0
  165. package/docs/IMPLEMENTATION_PLAN.md +32 -0
  166. package/docs/QUICKSTART.md +152 -0
  167. package/example-inventories/canonical-fabric.yaml +45 -0
  168. package/example-inventories/multi-password.yaml +35 -0
  169. package/example-inventories/simplified-lab.yaml +33 -0
  170. package/package.json +57 -0
@@ -0,0 +1,143 @@
1
+ import fs from "node:fs/promises";
2
+ import https from "node:https";
3
+ import { AppError } from "../core/errors.js";
4
+ export class FetchEapiTransport {
5
+ fetchFn;
6
+ constructor(fetchFn) {
7
+ this.fetchFn = fetchFn;
8
+ }
9
+ async postJson(connection, requestJson, signal) {
10
+ return this.fetchFn(connection.baseUrl, {
11
+ method: "POST",
12
+ headers: {
13
+ Authorization: buildBasicAuthHeader(connection),
14
+ "Content-Type": "application/json"
15
+ },
16
+ body: requestJson,
17
+ signal
18
+ });
19
+ }
20
+ }
21
+ export class NodeHttpsEapiTransport {
22
+ caCache = new Map();
23
+ async postJson(connection, requestJson, signal) {
24
+ const url = new URL(connection.baseUrl);
25
+ const ca = connection.caFile ? await this.readCaFile(connection.caFile) : undefined;
26
+ return new Promise((resolve, reject) => {
27
+ let settled = false;
28
+ let abortListenerAttached = false;
29
+ const cleanupAbortListener = () => {
30
+ if (abortListenerAttached) {
31
+ signal.removeEventListener("abort", abortRequest);
32
+ abortListenerAttached = false;
33
+ }
34
+ };
35
+ const rejectOnce = (error) => {
36
+ if (settled) {
37
+ return;
38
+ }
39
+ settled = true;
40
+ cleanupAbortListener();
41
+ reject(error);
42
+ };
43
+ const resolveOnce = (response) => {
44
+ if (settled) {
45
+ return;
46
+ }
47
+ settled = true;
48
+ cleanupAbortListener();
49
+ resolve(response);
50
+ };
51
+ const abortRequest = () => {
52
+ request.destroy(buildAbortError(signal.reason, connection));
53
+ };
54
+ const request = https.request(url, {
55
+ method: "POST",
56
+ rejectUnauthorized: connection.validateCerts,
57
+ ...(ca !== undefined ? { ca } : {}),
58
+ headers: {
59
+ Authorization: buildBasicAuthHeader(connection),
60
+ "Content-Type": "application/json",
61
+ "Content-Length": Buffer.byteLength(requestJson)
62
+ }
63
+ }, (response) => {
64
+ const chunks = [];
65
+ let responseSizeBytes = 0;
66
+ response.on("data", (chunk) => {
67
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
68
+ responseSizeBytes += buffer.length;
69
+ if (connection.maxResponseSizeBytes !== undefined &&
70
+ responseSizeBytes > connection.maxResponseSizeBytes) {
71
+ const error = new AppError("response_size_exceeded", `EOS eAPI HTTP response size exceeded maxResponseSizeBytes ${connection.maxResponseSizeBytes}`, {
72
+ responseSizeBytes,
73
+ maxResponseSizeBytes: connection.maxResponseSizeBytes,
74
+ inventoryHostname: connection.inventoryHostname
75
+ });
76
+ rejectOnce(error);
77
+ request.destroy(error);
78
+ return;
79
+ }
80
+ chunks.push(buffer);
81
+ });
82
+ response.on("end", () => {
83
+ if (settled) {
84
+ return;
85
+ }
86
+ const text = Buffer.concat(chunks).toString("utf8");
87
+ resolveOnce({
88
+ ok: response.statusCode !== undefined && response.statusCode >= 200 && response.statusCode < 300,
89
+ status: response.statusCode ?? 0,
90
+ json: async () => JSON.parse(text),
91
+ text: async () => text
92
+ });
93
+ });
94
+ });
95
+ request.on("error", (error) => {
96
+ rejectOnce(error);
97
+ });
98
+ if (signal.aborted) {
99
+ abortRequest();
100
+ return;
101
+ }
102
+ else {
103
+ signal.addEventListener("abort", abortRequest, { once: true });
104
+ abortListenerAttached = true;
105
+ }
106
+ request.write(requestJson);
107
+ request.end();
108
+ });
109
+ }
110
+ async readCaFile(caFile) {
111
+ const existing = this.caCache.get(caFile);
112
+ if (existing) {
113
+ return existing;
114
+ }
115
+ const pending = fs.readFile(caFile, "utf8");
116
+ this.caCache.set(caFile, pending);
117
+ try {
118
+ return await pending;
119
+ }
120
+ catch (error) {
121
+ this.caCache.delete(caFile);
122
+ throw error;
123
+ }
124
+ }
125
+ }
126
+ function buildBasicAuthHeader(connection) {
127
+ return `Basic ${Buffer.from(`${connection.username}:${connection.password}`).toString("base64")}`;
128
+ }
129
+ function buildAbortError(reason, connection) {
130
+ if (reason instanceof AppError) {
131
+ return reason;
132
+ }
133
+ if (reason instanceof DOMException && reason.name === "TimeoutError") {
134
+ return new AppError("eapi_request_timeout", `EOS eAPI request for host ${connection.inventoryHostname} exceeded timeoutMs ${connection.timeoutMs}`, {
135
+ inventoryHostname: connection.inventoryHostname,
136
+ timeoutMs: connection.timeoutMs
137
+ });
138
+ }
139
+ return new AppError("eapi_request_aborted", `EOS eAPI request for host ${connection.inventoryHostname} was aborted`, {
140
+ inventoryHostname: connection.inventoryHostname
141
+ });
142
+ }
143
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/eapi/transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ export type EapiOutputFormat = "json" | "text";
2
+ export type EapiOutputMode = EapiOutputFormat | "auto";
3
+ export type EapiVersion = 1 | "latest";
4
+ export interface EapiConnectionConfig {
5
+ inventoryHostname: string;
6
+ endpointHost: string;
7
+ baseUrl: string;
8
+ username: string;
9
+ password: string;
10
+ validateCerts: boolean;
11
+ caFile?: string;
12
+ timeoutMs: number;
13
+ eapiVersion: EapiVersion;
14
+ maxResponseSizeBytes?: number;
15
+ }
16
+ export interface EapiCommandOptions {
17
+ enable?: boolean;
18
+ signal?: AbortSignal;
19
+ }
20
+ export interface RunShowCommandOptions extends EapiCommandOptions {
21
+ includeRawEntries?: boolean;
22
+ }
23
+ export interface EosCommandResult {
24
+ command: string;
25
+ output_format: EapiOutputFormat;
26
+ output: unknown;
27
+ raw_entry?: unknown;
28
+ }
29
+ export interface EosCommandRunner {
30
+ runShowCommands(connection: EapiConnectionConfig, commands: string[], outputMode: EapiOutputMode, options?: RunShowCommandOptions): Promise<EosCommandResult[]>;
31
+ }
32
+ export declare function hasEapiResultArray(payload: unknown): payload is {
33
+ result: unknown[];
34
+ };
35
+ export interface EapiRunCmdsResponse {
36
+ result: unknown[];
37
+ raw: unknown;
38
+ }
39
+ export declare function parseEapiRunCmdsResponse(payload: unknown, expectedResultCount?: number): EapiRunCmdsResponse;
40
+ export interface EapiJsonRpcRequest {
41
+ jsonrpc: "2.0";
42
+ method: "runCmds";
43
+ params: {
44
+ version: EapiVersion;
45
+ cmds: string[];
46
+ format: EapiOutputFormat;
47
+ };
48
+ id: string;
49
+ }
@@ -0,0 +1,15 @@
1
+ import { AppError } from "../core/errors.js";
2
+ import { isObject } from "../utils/value.js";
3
+ export function hasEapiResultArray(payload) {
4
+ return isObject(payload) && "result" in payload && Array.isArray(payload.result);
5
+ }
6
+ export function parseEapiRunCmdsResponse(payload, expectedResultCount) {
7
+ if (!hasEapiResultArray(payload)) {
8
+ throw new AppError("eapi_payload_invalid", "Unexpected eAPI payload structure: missing result array");
9
+ }
10
+ if (expectedResultCount !== undefined && payload.result.length !== expectedResultCount) {
11
+ throw new AppError("eapi_payload_invalid", `Unexpected eAPI payload structure: expected ${expectedResultCount} result entries but received ${payload.result.length}`);
12
+ }
13
+ return { result: payload.result, raw: payload };
14
+ }
15
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/eapi/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AA4C7C,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO,QAAQ,CAAC,OAAO,CAAC,IAAI,QAAQ,IAAI,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACnF,CAAC;AAOD,MAAM,UAAU,wBAAwB,CAAC,OAAgB,EAAE,mBAA4B;IACrF,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,QAAQ,CAAC,sBAAsB,EAAE,yDAAyD,CAAC,CAAC;IACxG,CAAC;IAED,IAAI,mBAAmB,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,mBAAmB,EAAE,CAAC;QACvF,MAAM,IAAI,QAAQ,CAChB,sBAAsB,EACtB,+CAA+C,mBAAmB,gCAAgC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAC1H,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;AAClD,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { ResolvedServerConfig } from "../config/schema.js";
2
+ import type { EosCommandResult } from "../eapi/types.js";
3
+ import type { EosDeviceReader } from "../connection/eosDeviceReader.js";
4
+ import type { InventoryModel } from "../inventory/types.js";
5
+ import { type DeviceResultSummary } from "../operations/readExecution.js";
6
+ export interface GetFactsOptions {
7
+ target: string;
8
+ include_raw: boolean;
9
+ }
10
+ export interface GetFactsResult {
11
+ target: string;
12
+ target_type: "host" | "group";
13
+ resolved_devices: string[];
14
+ summary: DeviceResultSummary;
15
+ results: Array<{
16
+ inventory_hostname: string;
17
+ resolved_endpoint: string;
18
+ status: "success" | "failed";
19
+ facts?: {
20
+ inventory_hostname: string;
21
+ device_hostname?: string;
22
+ model?: string;
23
+ serial_number?: string;
24
+ eos_version?: string;
25
+ uptime?: number;
26
+ system_mac?: string;
27
+ };
28
+ command_results?: EosCommandResult[];
29
+ error_code?: string;
30
+ message?: string;
31
+ }>;
32
+ }
33
+ export declare function getFacts(model: InventoryModel, config: ResolvedServerConfig, options: GetFactsOptions, reader: EosDeviceReader): Promise<GetFactsResult>;
@@ -0,0 +1,50 @@
1
+ import { AppError } from "../core/errors.js";
2
+ import { buildReadDeviceFailure, buildReadDeviceSuccess, buildReadOperationResultEnvelope, executeReadOperation } from "../operations/readExecution.js";
3
+ import { readNumber, readString } from "../utils/value.js";
4
+ export async function getFacts(model, config, options, reader) {
5
+ const operation = await executeReadOperation(model, config, {
6
+ target: options.target,
7
+ operationName: "eos_get_facts",
8
+ run: async (host, signal) => {
9
+ const commandResults = await reader.runShowCommands(host, ["show version"], "json", {
10
+ signal,
11
+ includeRawEntries: options.include_raw
12
+ });
13
+ const versionPayload = extractPrimaryPayload(commandResults);
14
+ const factDeviceHostname = readString(versionPayload.hostname);
15
+ const factModel = readString(versionPayload.modelName);
16
+ const factSerialNumber = readString(versionPayload.serialNumber);
17
+ const factEosVersion = readString(versionPayload.version);
18
+ const factUptime = readNumber(versionPayload.uptime);
19
+ const factSystemMac = readString(versionPayload.systemMacAddress);
20
+ return buildReadDeviceSuccess(host, {
21
+ facts: {
22
+ inventory_hostname: host.inventoryHostname,
23
+ ...(factDeviceHostname !== undefined ? { device_hostname: factDeviceHostname } : {}),
24
+ ...(factModel !== undefined ? { model: factModel } : {}),
25
+ ...(factSerialNumber !== undefined ? { serial_number: factSerialNumber } : {}),
26
+ ...(factEosVersion !== undefined ? { eos_version: factEosVersion } : {}),
27
+ ...(factUptime !== undefined ? { uptime: factUptime } : {}),
28
+ ...(factSystemMac !== undefined ? { system_mac: factSystemMac } : {})
29
+ },
30
+ ...(options.include_raw ? { command_results: commandResults } : {})
31
+ });
32
+ },
33
+ onError: (host, error) => buildReadDeviceFailure(host, "facts_collection_failed", error)
34
+ });
35
+ return buildReadOperationResultEnvelope(options.target, operation, {
36
+ responseSizeLimit: {
37
+ config,
38
+ operationName: "eos_get_facts",
39
+ narrowingGuidance: "Reduce the number of target devices or set include_raw to false to omit raw per-command eAPI entries."
40
+ }
41
+ });
42
+ }
43
+ function extractPrimaryPayload(commandResults) {
44
+ const first = commandResults[0]?.output;
45
+ if (typeof first === "object" && first !== null) {
46
+ return first;
47
+ }
48
+ throw new AppError("facts_payload_invalid", "Unexpected show version payload structure");
49
+ }
50
+ //# sourceMappingURL=getFacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getFacts.js","sourceRoot":"","sources":["../../src/facts/getFacts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env node
2
+ import { randomUUID } from "node:crypto";
3
+ import { AppError, toErrorMessage } from "./core/errors.js";
4
+ import { parseCliArgs, printHelp, printVersion } from "./cli.js";
5
+ import { runProbe } from "./commands/probe.js";
6
+ import { runValidateInventory } from "./commands/validateInventory.js";
7
+ import { printServerInfo } from "./commands/printServerInfo.js";
8
+ import { loadServerConfig } from "./config/loadConfig.js";
9
+ import { validateStartupConnections } from "./connection/validateStartupConnections.js";
10
+ import { loadInventoryModel } from "./inventory/loadInventory.js";
11
+ import { startMcpServer } from "./mcp/createServer.js";
12
+ async function main() {
13
+ const cli = parseCliArgs(process.argv.slice(2));
14
+ if (cli.version) {
15
+ printVersion();
16
+ return;
17
+ }
18
+ if (cli.help) {
19
+ printHelp(cli);
20
+ return;
21
+ }
22
+ const config = await loadServerConfig(cli);
23
+ switch (cli.command) {
24
+ case "validate-inventory": {
25
+ const exitCode = await runValidateInventory(config, {
26
+ asJson: cli.json ?? false,
27
+ inventoryOnly: cli.inventoryOnly ?? false
28
+ });
29
+ process.exitCode = exitCode;
30
+ return;
31
+ }
32
+ case "print-server-info": {
33
+ const inventoryModel = config.inventoryPath ? await loadInventoryModel(config.inventoryPath) : undefined;
34
+ const runtimeContext = {
35
+ instanceId: randomUUID(),
36
+ startedAt: new Date().toISOString(),
37
+ config,
38
+ ...(inventoryModel !== undefined ? { inventorySummary: inventoryModel.summary } : {})
39
+ };
40
+ printServerInfo(runtimeContext, cli.json ?? false);
41
+ return;
42
+ }
43
+ case "probe": {
44
+ if (!cli.target) {
45
+ throw new AppError("cli_missing_target", "probe requires a target via --target");
46
+ }
47
+ const exitCode = await runProbe(config, cli.target, cli.json ?? false);
48
+ process.exitCode = exitCode;
49
+ return;
50
+ }
51
+ case "serve": {
52
+ if (!config.inventoryPath) {
53
+ throw new AppError("cli_missing_inventory", "serve requires an inventory path via --inventory or config file");
54
+ }
55
+ const inventoryModel = await loadInventoryModel(config.inventoryPath);
56
+ validateStartupConnections(config, inventoryModel);
57
+ await startMcpServer(config, inventoryModel);
58
+ return;
59
+ }
60
+ }
61
+ }
62
+ main().catch((error) => {
63
+ console.error(toErrorMessage(error));
64
+ process.exitCode = 1;
65
+ });
66
+ //# 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,3 @@
1
+ import type { InventoryModel } from "./types.js";
2
+ import type { NormalizedInventory, ValidationContext } from "./internalTypes.js";
3
+ export declare function buildInventoryModel(inventory: NormalizedInventory, inventoryPath: string, context: ValidationContext): InventoryModel | null;
@@ -0,0 +1,79 @@
1
+ import path from "node:path";
2
+ import { evaluateHostAccess, evaluateHostEligibility } from "./policy.js";
3
+ import { resolveEffectiveHostVars } from "./effectiveVars.js";
4
+ import { buildDirectMemberships, buildGroupDepths, buildParentGroupMap, collectLineageGroups, resolveGroupHosts } from "./graph.js";
5
+ export function buildInventoryModel(inventory, inventoryPath, context) {
6
+ const parentGroups = buildParentGroupMap(inventory);
7
+ const groupDepths = buildGroupDepths(inventory, parentGroups);
8
+ const directMemberships = buildDirectMemberships(inventory);
9
+ const hostModels = new Map();
10
+ for (const [hostName, hostVars] of inventory.hosts.entries()) {
11
+ const lineageGroups = collectLineageGroups(hostName, parentGroups, directMemberships);
12
+ const effectiveVars = resolveEffectiveHostVars(hostName, hostVars, inventory, lineageGroups, groupDepths, context);
13
+ const eligibility = evaluateHostEligibility(hostName, effectiveVars);
14
+ context.errors.push(...eligibility.errors);
15
+ const access = evaluateHostAccess(eligibility.eligible, effectiveVars);
16
+ const resolvedEndpoint = typeof effectiveVars.ansible_host === "string" ? effectiveVars.ansible_host : hostName;
17
+ hostModels.set(hostName, {
18
+ inventoryHostname: hostName,
19
+ resolvedEndpoint,
20
+ effectiveVars,
21
+ eligible: eligibility.eligible,
22
+ readAllowed: access.readAllowed,
23
+ ineligibilityReasons: eligibility.ineligibilityReasons,
24
+ groupMemberships: [...lineageGroups].sort()
25
+ });
26
+ }
27
+ if (context.errors.length > 0) {
28
+ return null;
29
+ }
30
+ const groupResolutionMemo = new Map();
31
+ const groupModels = new Map();
32
+ for (const [groupName, group] of inventory.groups.entries()) {
33
+ const resolvedHosts = resolveGroupHosts(groupName, inventory, groupResolutionMemo);
34
+ const eligibleHostCount = resolvedHosts.filter((hostName) => hostModels.get(hostName)?.eligible === true).length;
35
+ const ineligibleHostCount = resolvedHosts.length - eligibleHostCount;
36
+ groupModels.set(groupName, {
37
+ name: groupName,
38
+ hosts: [...group.hosts].sort(),
39
+ children: [...group.children].sort(),
40
+ resolvedHosts,
41
+ eligibleHostCount,
42
+ ineligibleHostCount,
43
+ actionable: eligibleHostCount > 0
44
+ });
45
+ }
46
+ const allResolvedHosts = [...inventory.hosts.keys()].sort();
47
+ const allEligibleHostCount = allResolvedHosts.filter((hostName) => hostModels.get(hostName)?.eligible === true).length;
48
+ groupModels.set("all", {
49
+ name: "all",
50
+ hosts: [],
51
+ children: [...inventory.groups.keys()].sort(),
52
+ resolvedHosts: allResolvedHosts,
53
+ eligibleHostCount: allEligibleHostCount,
54
+ ineligibleHostCount: allResolvedHosts.length - allEligibleHostCount,
55
+ actionable: allEligibleHostCount > 0
56
+ });
57
+ const hosts = [...hostModels.values()].sort((left, right) => left.inventoryHostname.localeCompare(right.inventoryHostname));
58
+ const groups = [...groupModels.values()].sort((left, right) => left.name.localeCompare(right.name));
59
+ const summary = {
60
+ path: inventoryPath,
61
+ basename: path.basename(inventoryPath),
62
+ schemaKind: inventory.schemaKind,
63
+ totalHostCount: hosts.length,
64
+ totalGroupCount: groups.length,
65
+ eosEligibleHostCount: hosts.filter((host) => host.eligible).length,
66
+ readAllowedHostCount: hosts.filter((host) => host.readAllowed).length
67
+ };
68
+ return {
69
+ path: inventoryPath,
70
+ basename: path.basename(inventoryPath),
71
+ schemaKind: inventory.schemaKind,
72
+ summary,
73
+ hosts,
74
+ groups,
75
+ hostMap: new Map(hosts.map((host) => [host.inventoryHostname, host])),
76
+ groupMap: new Map(groups.map((group) => [group.name, group]))
77
+ };
78
+ }
79
+ //# sourceMappingURL=buildModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildModel.js","sourceRoot":"","sources":["../../src/inventory/buildModel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { InventoryVars, NormalizedInventory, ValidationContext } from "./internalTypes.js";
2
+ export declare function resolveEffectiveHostVars(hostName: string, hostVars: InventoryVars, inventory: NormalizedInventory, lineageGroups: Set<string>, groupDepths: Map<string, number>, context: ValidationContext): InventoryVars;
@@ -0,0 +1,52 @@
1
+ import { stableValueKey } from "./internalUtils.js";
2
+ export function resolveEffectiveHostVars(hostName, hostVars, inventory, lineageGroups, groupDepths, context) {
3
+ const effectiveVars = { ...inventory.globalVars };
4
+ const groupedValues = new Map();
5
+ for (const groupName of lineageGroups) {
6
+ const group = inventory.groups.get(groupName);
7
+ if (!group) {
8
+ continue;
9
+ }
10
+ const depth = groupDepths.get(groupName) ?? 1;
11
+ for (const [key, value] of Object.entries(group.vars)) {
12
+ const byDepth = groupedValues.get(key) ?? new Map();
13
+ const valuesAtDepth = byDepth.get(depth) ?? new Set();
14
+ valuesAtDepth.add(stableValueKey(value));
15
+ byDepth.set(depth, valuesAtDepth);
16
+ groupedValues.set(key, byDepth);
17
+ }
18
+ }
19
+ for (const [key, byDepth] of groupedValues.entries()) {
20
+ for (const [depth, valuesAtDepth] of byDepth.entries()) {
21
+ if (valuesAtDepth.size > 1) {
22
+ context.errors.push({
23
+ code: "inventory_same_level_conflict",
24
+ message: `Host ${hostName} inherits conflicting values for ${key} at group depth ${depth}`,
25
+ path: hostName
26
+ });
27
+ }
28
+ }
29
+ const winningDepth = Math.max(...byDepth.keys());
30
+ const groupValue = findGroupValueAtDepth(key, winningDepth, lineageGroups, inventory, groupDepths);
31
+ if (groupValue !== undefined) {
32
+ effectiveVars[key] = groupValue;
33
+ }
34
+ }
35
+ for (const [key, value] of Object.entries(hostVars)) {
36
+ effectiveVars[key] = value;
37
+ }
38
+ return effectiveVars;
39
+ }
40
+ function findGroupValueAtDepth(key, depth, lineageGroups, inventory, groupDepths) {
41
+ for (const groupName of lineageGroups) {
42
+ if ((groupDepths.get(groupName) ?? 1) !== depth) {
43
+ continue;
44
+ }
45
+ const group = inventory.groups.get(groupName);
46
+ if (group && key in group.vars) {
47
+ return group.vars[key];
48
+ }
49
+ }
50
+ return undefined;
51
+ }
52
+ //# sourceMappingURL=effectiveVars.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effectiveVars.js","sourceRoot":"","sources":["../../src/inventory/effectiveVars.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { NormalizedInventory } from "./internalTypes.js";
2
+ export declare function resolveGroupHosts(groupName: string, inventory: NormalizedInventory, memo: Map<string, string[]>): string[];
3
+ export declare function collectLineageGroups(hostName: string, parentGroups: Map<string, Set<string>>, directMemberships: Map<string, Set<string>>): Set<string>;
4
+ export declare function buildParentGroupMap(inventory: NormalizedInventory): Map<string, Set<string>>;
5
+ export declare function buildGroupDepths(inventory: NormalizedInventory, parentGroups: Map<string, Set<string>>): Map<string, number>;
6
+ export declare function buildDirectMemberships(inventory: NormalizedInventory): Map<string, Set<string>>;
@@ -0,0 +1,81 @@
1
+ export function resolveGroupHosts(groupName, inventory, memo) {
2
+ const existing = memo.get(groupName);
3
+ if (existing) {
4
+ return existing;
5
+ }
6
+ const group = inventory.groups.get(groupName);
7
+ if (!group) {
8
+ return [];
9
+ }
10
+ const hostNames = new Set(group.hosts);
11
+ for (const child of group.children) {
12
+ for (const childHost of resolveGroupHosts(child, inventory, memo)) {
13
+ hostNames.add(childHost);
14
+ }
15
+ }
16
+ const resolved = [...hostNames].sort();
17
+ memo.set(groupName, resolved);
18
+ return resolved;
19
+ }
20
+ export function collectLineageGroups(hostName, parentGroups, directMemberships) {
21
+ const result = new Set();
22
+ const stack = [...(directMemberships.get(hostName) ?? [])];
23
+ while (stack.length > 0) {
24
+ const groupName = stack.pop();
25
+ if (!groupName || result.has(groupName)) {
26
+ continue;
27
+ }
28
+ result.add(groupName);
29
+ for (const parent of parentGroups.get(groupName) ?? []) {
30
+ stack.push(parent);
31
+ }
32
+ }
33
+ return result;
34
+ }
35
+ export function buildParentGroupMap(inventory) {
36
+ const parentGroups = new Map();
37
+ for (const groupName of inventory.groups.keys()) {
38
+ parentGroups.set(groupName, new Set());
39
+ }
40
+ for (const [groupName, group] of inventory.groups.entries()) {
41
+ for (const child of group.children) {
42
+ const parents = parentGroups.get(child) ?? new Set();
43
+ parents.add(groupName);
44
+ parentGroups.set(child, parents);
45
+ }
46
+ }
47
+ return parentGroups;
48
+ }
49
+ export function buildGroupDepths(inventory, parentGroups) {
50
+ const memo = new Map();
51
+ const getDepth = (groupName) => {
52
+ const cached = memo.get(groupName);
53
+ if (cached !== undefined) {
54
+ return cached;
55
+ }
56
+ const parents = parentGroups.get(groupName) ?? new Set();
57
+ if (parents.size === 0) {
58
+ memo.set(groupName, 1);
59
+ return 1;
60
+ }
61
+ const depth = Math.max(...[...parents].map(getDepth)) + 1;
62
+ memo.set(groupName, depth);
63
+ return depth;
64
+ };
65
+ for (const groupName of inventory.groups.keys()) {
66
+ getDepth(groupName);
67
+ }
68
+ return memo;
69
+ }
70
+ export function buildDirectMemberships(inventory) {
71
+ const memberships = new Map();
72
+ for (const [groupName, group] of inventory.groups.entries()) {
73
+ for (const hostName of group.hosts) {
74
+ const hostMemberships = memberships.get(hostName) ?? new Set();
75
+ hostMemberships.add(groupName);
76
+ memberships.set(hostName, hostMemberships);
77
+ }
78
+ }
79
+ return memberships;
80
+ }
81
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/inventory/graph.ts"],"names":[],"mappings":"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"}