registry  /  tdpilot  /  2.1.0

tdpilot@2.1.0

Build, debug, and verify TouchDesigner networks by talking to your AI. Live MCP control of a running TD session: create and wire operators, set real parameter values, screenshot-verify the render, roll back transactionally. No signup, no API key — npx tdp

AI Security Review

scanned 3h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. The npm package is a CLI wrapper that bootstraps and runs a Python MCP server from the package's upstream GitHub repo. It has dangerous user-invoked remote execution and agent/plugin setup capability, but no unconsented npm lifecycle mutation or confirmed malicious chain.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
User runs npx tdpilot or explicit subcommands such as install, plugin-install, update, or brains.
Impact
Executes package-aligned upstream code from ~/.tdpilot and may configure TouchDesigner or Claude Code integration when requested.
Mechanism
User-invoked remote repository bootstrap and MCP/plugin setup
Rationale
Static inspection confirms scanner findings are mostly package-aligned bootstrap behavior for a CLI/MCP wrapper and are activated by user commands, not npm lifecycle hooks. The Claude Code and TouchDesigner integration is explicit/first-party setup, so this warrants a warning for agent extension lifecycle risk rather than a publish block.
Evidence
package.jsonrun.jsplugin.jsinstall.jsbrains.js~/.tdpilot~/.tdpilot_path~/Library/Application Support/Derivative/TouchDesigner099/pref.txt~/AppData/Roaming/Derivative/TouchDesigner099/pref.txt/tmp/tdpilot.zip/tmp/tdpilot-extract/tmp/tdpilot-selected-brains.json
Network endpoints4
github.com/dreamrec/TDPilot.gitgithub.com/dreamrec/TDPilot/archive/refs/heads/main.zipastral.sh/uv/0.6.10/install.shastral.sh/uv/0.6.10/install.ps1

Decision evidence

public snapshot
AI called this Suspicious at 84.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • run.js bin entrypoint bootstraps ~/.tdpilot by cloning https://github.com/dreamrec/TDPilot.git or downloading main.zip.
  • run.js/plugin.js install uv by piping https://astral.sh/uv/0.6.10 installer to sh or PowerShell iex when uv is missing.
  • run.js executes the downloaded checkout with uv run --directory ~/.tdpilot tdpilot.
  • plugin.js explicit plugin-install adds dreamrec/TDPilot marketplace and installs tdpilot@dreamrec-TDPilot into Claude Code.
Evidence against
  • package.json defines no preinstall/install/postinstall lifecycle scripts; risky behavior is user-invoked via bin/subcommands.
  • Remote endpoints are package-aligned with declared repository/homepage and expected uv toolchain bootstrap.
  • run.js pins git clones to latest reachable tag and only auto-updates when TDPILOT_AUTO_UPDATE=1.
  • No credential harvesting, stealth persistence, destructive behavior, or exfiltration found in inspected package files.
Behavioral surface
Source
ChildProcessEnvironmentVarsFilesystem
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 4 file(s), 32.0 KB of source, external domains: astral.sh, claude.com, docs.astral.sh, github.com

Source & flagged code

3 flagged · loading source
brains.jsView file
13const { join, dirname } = require("path"); L14: const { spawnSync } = require("child_process"); L15: const os = require("os");
High
Child Process

Package source references child process execution.

brains.jsView on unpkg · L13
run.jsView file
14* L15: * IMPORTANT — stdout discipline (v1.6.12 fix): L16: * When invoked without a subcommand, this wrapper eventually spawns the Python ... L27: L28: const { execSync, spawn } = require("child_process"); L29: const { existsSync } = require("fs"); ... L32: L33: const REPO = "https://github.com/dreamrec/TDPilot.git"; L34: const INSTALL_DIR = join(os.homedir(), ".tdpilot"); L35: ... L42: // of main. Without this, `npx tdpilot@1.5.1` would happily run whatever L43: // bleeding-edge code is on main at fetch time — package.json's `version`
Critical
Download Execute

Source downloads or fetches remote code and executes it.

run.jsView on unpkg · L14
14Trigger-reachable chain: manifest.bin -> run.js L14: * L15: * IMPORTANT — stdout discipline (v1.6.12 fix): L16: * When invoked without a subcommand, this wrapper eventually spawns the Python ... L27: L28: const { execSync, spawn } = require("child_process"); L29: const { existsSync } = require("fs"); ... L32: L33: const REPO = "https://github.com/dreamrec/TDPilot.git"; L34: const INSTALL_DIR = join(os.homedir(), ".tdpilot"); L35: ... L42: // of main. Without this, `npx tdpilot@1.5.1` would happily run whatever L43: // bleeding-edge code is on main at fetch time — package.json's `version`
Critical
Trigger Reachable Dangerous Capability

A package entrypoint or install-time lifecycle script reaches a source file with blocking dangerous behavior.

run.jsView on unpkg · L14

Findings

2 Critical1 High2 Medium3 Low
CriticalDownload Executerun.js
CriticalTrigger Reachable Dangerous Capabilityrun.js
HighChild Processbrains.js
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings