registry  /  romdevtools  /  0.85.0

romdevtools@0.85.0

Tool server giving coding agents full control of homebrew ROM development AND reverse-engineering/romhacking across 17 retro platforms (NES, SNES, GB, Genesis, Atari, C64, PC Engine, MSX, PlayStation, N64, Dreamcast, ...) via WASM toolchains + emulator co

AI Security Review

scanned 14d ago · by lpm-firewall-ai

No confirmed malicious attack surface was established. The package is a ROM development MCP/HTTP tool server with explicit user-invoked build, emulator, file-output, and palette-fetch capabilities.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
npm install postinstall; user runs romdevtools/romdev-mcp or invokes MCP/HTTP tools
Impact
Package-aligned local ROM build/debug/playtest operations; no confirmed credential theft, persistence, or exfiltration
Mechanism
local tool server plus bundled WASM/native emulator tooling
Rationale
Static source inspection shows powerful ROM-dev/debug capabilities and an install hook, but they are disclosed, package-aligned, mostly user-invoked, and not tied to credential harvesting, persistence, or unauthorized agent control-surface mutation. The scanner’s dangerous-file and lifecycle hints are explained by the MCP server entrypoint and optional SDL binary bootstrap.
Evidence
package.jsonsrc/install/postinstall.mjssrc/mcp/server.jssrc/http/routes.jssrc/host/coreLoader.jssrc/playtest/playtest.jssrc/mcp/tools/index.jssrc/mcp/util.jssrc/mcp/tools/project.jssrc/mcp/tools/lospec.jssrc/install/postinstall.mjs may create @kmamal/sdl/dist/sdl.node via dependency installersrc/mcp/util.js writes caller-provided outputPathsrc/mcp/tools/project.js writes caller-requested project filessrc/playtest/playtest.js writes playtest screenshot/artifact paths
Network endpoints3
127.0.0.1:7331/mcplocalhost:7331/skills/romdev/SKILL.mdlospec.com/palette-list

Decision evidence

public snapshot
AI called this Clean at 86.0% confidence as Benign with medium false-positive risk.
Evidence for block
  • package.json defines postinstall and CLI/MCP bins.
  • src/install/postinstall.mjs runs @kmamal/sdl install.mjs if dist/sdl.node is missing.
  • src/mcp/server.js starts a local HTTP/MCP server and re-execs node with --experimental-vm-modules.
  • Tool surface can write user-requested outputs/projects and run WASM workers/SDL playtest.
Evidence against
  • Postinstall is narrowly scoped to optional @kmamal/sdl prebuilt binary, soft-fails, exits 0, and disables build-from-source flags.
  • No credential/env harvesting or exfiltration logic found in inspected entrypoints.
  • HTTP server defaults to loopback with localhost host validation; non-loopback requires explicit host/env.
  • Network use found is package-aligned: local MCP/HTTP routes and optional Lospec palette fetch by user tool call.
  • Dynamic imports load bundled emulator/toolchain modules or declared dependencies for ROM development.
  • File writes are explicit tool outputs/project scaffolding/playtest artifacts, not persistence or agent config mutation.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsMinifiedUrlStrings
ManifestNo manifest risk signals triggered.
scanned 200 file(s), 3.15 MB of source, external domains: github.com, lospec.com

Source & flagged code

7 flagged · loading source
package.jsonView file
scripts.postinstall = node src/install/postinstall.mjs
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.postinstall = node src/install/postinstall.mjs
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
src/host/LibretroHost.jsView file
336// GL deps lazily (clear install hint if absent). L337: const { LibretroGL } = await import("./LibretroGL.js"); L338: const { loadWebGl2Context } = await import("./glOptionalDep.js");
Medium
Dynamic Require

Package source references dynamic require/import behavior.

src/host/LibretroHost.jsView on unpkg · L336
src/platforms/gba/lib/libgba/crtend.oView file
path = [redacted].o kind = native_binary sizeBytes = 1040 magicHex = [redacted]
Medium
Ships Native Binary

Package ships native binary artifacts.

src/platforms/gba/lib/libgba/crtend.oView on unpkg
src/analysis/wasm/rizin.wasmView file
path = src/analysis/wasm/rizin.wasm kind = wasm_module sizeBytes = 30762096 magicHex = [redacted]
Medium
Ships Wasm Module

Package ships WebAssembly modules.

src/analysis/wasm/rizin.wasmView on unpkg
src/platforms/snes/lib/pvsneslib/source/MakefileView file
path = [redacted] kind = build_helper sizeBytes = 2332 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

src/platforms/snes/lib/pvsneslib/source/MakefileView on unpkg
src/mcp/server.jsView file
matchType = previous_version_dangerous_delta matchedPackage = romdevtools@0.84.1 matchedIdentity = npm:cm9tZGV2dG9vbHM:0.84.1 similarity = 0.942 summary = stored previous version shares package body but lacks this dangerous source file
Critical
Previous Version Dangerous Delta

This package version adds a dangerous source file absent from the previous stored version.

src/mcp/server.jsView on unpkg

Findings

1 Critical1 High8 Medium4 Low
CriticalPrevious Version Dangerous Deltasrc/mcp/server.js
HighInstall Time Lifecycle Scriptspackage.json
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumDynamic Requiresrc/host/LibretroHost.js
MediumNetwork
MediumEnvironment Vars
MediumShips Native Binarysrc/platforms/gba/lib/libgba/crtend.o
MediumShips Wasm Modulesrc/analysis/wasm/rizin.wasm
MediumShips Build Helpersrc/platforms/snes/lib/pvsneslib/source/Makefile
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings