diff --git a/package-lock.json b/package-lock.json index 98bf1bd3..2b55923f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "mongodb-log-writer": "^2.4.1", "mongodb-redact": "^1.1.6", "mongodb-schema": "^12.6.2", - "native-machine-id": "^0.1.0", + "node-machine-id": "^1.1.12", "openapi-fetch": "^0.13.5", "simple-oauth2": "^5.1.0", "yargs-parser": "^21.1.1", @@ -6271,6 +6271,7 @@ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "license": "MIT", + "optional": true, "dependencies": { "file-uri-to-path": "1.0.0" } @@ -8533,7 +8534,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/filelist": { "version": "1.0.4", @@ -11225,29 +11227,6 @@ "license": "MIT", "optional": true }, - "node_modules/native-machine-id": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/native-machine-id/-/native-machine-id-0.1.0.tgz", - "integrity": "sha512-Po7OPcXGsWZ/o+n93ZOhmF3G5RQsEUMTnVddX45u5GfoEnk803ba7lhztwMkDaPhUFHy5FpXLiytIFitVxMkTA==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "bindings": "^1.5.0", - "node-addon-api": "^8.0.0" - }, - "bin": { - "native-machine-id": "dist/bin/machine-id.js" - } - }, - "node_modules/native-machine-id/node_modules/node-addon-api": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.1.tgz", - "integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==", - "license": "MIT", - "engines": { - "node": "^18 || ^20 || >= 21" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -11358,6 +11337,12 @@ "dev": true, "license": "MIT" }, + "node_modules/node-machine-id": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz", + "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==", + "license": "MIT" + }, "node_modules/node-readfiles": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/node-readfiles/-/node-readfiles-0.2.0.tgz", diff --git a/package.json b/package.json index dd4aa259..9a4df8a4 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "mongodb-log-writer": "^2.4.1", "mongodb-redact": "^1.1.6", "mongodb-schema": "^12.6.2", - "native-machine-id": "^0.1.0", + "node-machine-id": "^1.1.12", "openapi-fetch": "^0.13.5", "simple-oauth2": "^5.1.0", "yargs-parser": "^21.1.1", diff --git a/src/logger.ts b/src/logger.ts index 19a311c2..3a098bf1 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -18,6 +18,7 @@ export const LogId = { telemetryEmitStart: mongoLogId(1_002_003), telemetryEmitSuccess: mongoLogId(1_002_004), telemetryMetadataError: mongoLogId(1_002_005), + telemetryDeviceIdFailure: mongoLogId(1_002_006), toolExecute: mongoLogId(1_003_001), toolExecuteFailure: mongoLogId(1_003_002), diff --git a/src/telemetry/constants.ts b/src/telemetry/constants.ts index 7ae139b5..7fe85b75 100644 --- a/src/telemetry/constants.ts +++ b/src/telemetry/constants.ts @@ -1,11 +1,11 @@ -import { getMachineIdSync } from "native-machine-id"; import { packageInfo } from "../packageInfo.js"; import { type CommonStaticProperties } from "./types.js"; +import { getDeviceId } from "./device-id.js"; /** * Machine-specific metadata formatted for telemetry */ export const MACHINE_METADATA: CommonStaticProperties = { - device_id: getMachineIdSync(), + device_id: getDeviceId(), mcp_server_version: packageInfo.version, mcp_server_name: packageInfo.mcpServerName, platform: process.platform, diff --git a/src/telemetry/device-id.ts b/src/telemetry/device-id.ts new file mode 100644 index 00000000..e9c48d63 --- /dev/null +++ b/src/telemetry/device-id.ts @@ -0,0 +1,21 @@ +import { createHmac } from "crypto"; +import nodeMachineId from "node-machine-id"; +import logger, { LogId } from "../logger.js"; + +export function getDeviceId(): string { + try { + const originalId = nodeMachineId.machineIdSync(true); + // Create a hashed format from the all uppercase version of the machine ID + // to match it exactly with the denisbrodbeck/machineid library that Atlas CLI uses. + const hmac = createHmac("sha256", originalId.toUpperCase()); + + /** This matches the message used to create the hashes in Atlas CLI */ + const DEVICE_ID_HASH_MESSAGE = "atlascli"; + + hmac.update(DEVICE_ID_HASH_MESSAGE); + return hmac.digest("hex"); + } catch (error) { + logger.debug(LogId.telemetryDeviceIdFailure, "telemetry", String(error)); + return "unknown"; + } +}