registry  /  @wonderwhy-er/desktop-commander  /  0.2.46

@wonderwhy-er/desktop-commander@0.2.46

MCP server for terminal operations and file editing

AI Security Review

scanned 2h ago · by lpm-firewall-ai

Review flagged AI-agent configuration or capability changes. This remains warn-only unless evidence shows foreign-agent hijack through preinstall/install/postinstall, hidden persistence, exfiltration, remote code execution, or other concrete malicious behavior.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
A connected MCP client invokes `start_process` or a user runs the `setup` CLI; telemetry runs during npm postinstall.
Impact
A connected AI client can run local commands within the host user's permissions; install telemetry reports installation context.
Mechanism
MCP-mediated local command execution with install telemetry and explicit Claude MCP registration.
Rationale
Source inspection does not establish malicious behavior, but it does establish a high-impact AI-agent terminal capability. Warn rather than block so the capability receives policy scrutiny without treating expected package behavior as malware.
Evidence
package.jsondist/track-installation.jsdist/setup-claude-server.jsdist/tools/improved-process-tools.jsdist/command-manager.jsdist/npm-scripts/verify-ripgrep.js
Network endpoints2
telemetry.desktopcommander.app/mp/collectdc-telemetry-proxy-83847352264.europe-west1.run.app/mp/collect

Decision evidence

public snapshot
AI called this Suspicious at 91.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • `dist/track-installation.js` runs from `postinstall` and POSTs installation/context telemetry.
  • `dist/tools/improved-process-tools.js` starts shell processes and executes supplied Node code through temporary `.mjs` files.
  • `dist/setup-claude-server.js` explicitly configures Claude's MCP server entry.
Evidence against
  • `postinstall` does not modify Claude or other agent configuration.
  • Telemetry targets fixed Desktop Commander endpoints; inspected payload contains installation metadata, not harvested secrets.
  • Claude configuration changes occur only through the separate `setup` CLI entrypoint.
  • `dist/command-manager.js` checks configured blocked commands before process launch.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetworkShell
Supply chain
HighEntropyStringsMinifiedObfuscatedTelemetryUrlStrings
ManifestNo manifest risk signals triggered.
scanned 124 file(s), 2.52 MB of source, external domains: calendar.app.google, claude.ai, dc-telemetry-proxy-83847352264.europe-west1.run.app, desktopcommander.app, discord.com, example.com, github.com, json-schema.org, mcp.desktopcommander.app, prosemirror.net, schemas.openxmlformats.org, tally.so, telemetry.desktopcommander.app, www.google.com

Source & flagged code

5 flagged · loading source
package.jsonView file
scripts.postinstall = node dist/track-installation.js && node dist/npm-scripts/verify-ripgrep.js || node -e "process.exit(0)"
Critical
Red Install Lifecycle Script

Install-time lifecycle script matches a deterministic static-gate block pattern.

package.jsonView on unpkg
scripts.postinstall = node dist/track-installation.js && node dist/npm-scripts/verify-ripgrep.js || node -e "process.exit(0)"
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
dist/ui/config-editor/config-editor-runtime.jsView file
25path: iss.path ? [${Ge(I)}, ...iss.path] : [${Ge(I)}] L26: })));`),p.write(`newResult[${Ge(I)}] = ${b}.value`)}p.write("payload.value = newResult;"),p.write("return payload;");let Z=p.compile();return(I,b)=>Z(m,I,b)},r,o=at,a=!Tr.jitless,u... L27: `)}var ir=e=>(t,n,i,r)=>{let o=i?Object.assign(i,{async:!1}):{async:!1},a=t._zod.run({value:n,issues:[]},o);if(a instanceof Promise)throw new Re;if(a.issues.length){let s=new(r?.Er...
Low
Eval

Package source references a known benign dynamic code generation pattern.

dist/ui/config-editor/config-editor-runtime.jsView on unpkg · L25
dist/tools/fuzzySearch.jsView file
14const WORKER_CODE = ` L15: const { workerData, parentPort } = require('worker_threads'); L16: import(workerData.moduleUrl)
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/tools/fuzzySearch.jsView on unpkg · L14
dist/track-installation.jsView file
14import { randomUUID } from 'crypto'; L15: import * as https from 'https'; L16: import { platform } from 'os'; ... L21: const __filename = fileURLToPath(import.meta.url); L22: const __dirname = path.dirname(__filename); L23: L24: // Debug logging utility - configurable via environment variables L25: const DEBUG_ENABLED = process.env.DEBUG === 'desktop-commander' || L26: process.env.DEBUG === '*' || ... L58: const configData = fs.readFileSync(CONFIG_FILE, 'utf8'); L59: const config = JSON.parse(configData); L60: if (config.clientId) {
High
Sandbox Evasion Gated Capability

Source gates dangerous network, credential, or execution behavior behind CI, host, platform, time, or geo fingerprint checks.

dist/track-installation.jsView on unpkg · L14

Findings

1 Critical2 High4 Medium8 Low
CriticalRed Install Lifecycle Scriptpackage.json
HighInstall Time Lifecycle Scriptspackage.json
HighSandbox Evasion Gated Capabilitydist/track-installation.js
MediumDynamic Requiredist/tools/fuzzySearch.js
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowEvaldist/ui/config-editor/config-editor-runtime.js
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowTelemetry
LowUrl Strings