registry  /  tower-mcp  /  0.7.0

tower-mcp@0.7.0

Air-traffic control for AI agents editing a shared repo — semantic pre-flight collision detection over MCP. Model-agnostic (Claude Code, Cursor, Codex).

AI Security Review

scanned 2h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. No install-time or import-time attack behavior is established. Explicit CLI setup modifies project-local agent integration files, and the optional worker can delegate tasks to a local coding-agent runner.

Static reason
No blocking static signals were detected.
Trigger
Explicit `tower setup`, optional `tower setup --hooks`, or `tower work --auto` invocation.
Impact
May alter project-local agent configuration and hooks; auto mode can let Tower task content direct a local agent within the current repository.
Mechanism
User-invoked MCP extension setup and delegated coding-agent execution.
Rationale
No concrete malicious chain was found. Flag as warn because explicit first-party agent integration and optional unattended agent execution are sensitive capabilities, not because of install-time compromise.
Evidence
package.jsondist/index.jsdist/worker.jsdist/remote.jsdist/lib.js.mcp.jsonCLAUDE.mdAGENTS.md.git/hooks/pre-commit.git/hooks/post-commit.tower/claim-id.tower/tower.db

Decision evidence

public snapshot
AI called this Suspicious at 91.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • `dist/index.js` `tower setup` writes `.mcp.json`, `CLAUDE.md`, and optionally Git hooks.
  • `dist/worker.js` can run `claude` or `codex exec --full-auto` for delegated tasks when explicitly auto-enabled.
Evidence against
  • `package.json` has no `preinstall`, `install`, or `postinstall` hook.
  • `dist/index.js` only invokes setup through the explicit `setup` CLI command.
  • `dist/worker.js` requires per-task confirmation by default and refuses noninteractive operation without `--auto` or remote approval.
  • Task text is passed to the runner on stdin rather than interpolated into shell commands.
  • Setup preserves invalid `.mcp.json` and does not overwrite existing Git hooks.
  • Remote networking uses operator-supplied `TOWER_URL` and optional `TOWER_TOKEN`; no fixed exfiltration endpoint was found.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 8 file(s), 295 KB of source, external domains: github.com, nodejs.org

Source & flagged code

3 flagged · loading source
dist/worker.jsView file
1import { execFile } from "node:child_process"; L2: import { existsSync } from "node:fs";
High
Child Process

Package source references child process execution.

dist/worker.jsView on unpkg · L1
9// Own the timeout instead of using execFile's: with shell:true the direct child is L10: // cmd.exe/sh, and on Windows killing only it orphans the actual agent — which keeps L11: // editing files after our git reset and holds the stdio pipes open (so the callback
High
Shell

Package source references shell execution.

dist/worker.jsView on unpkg · L9
dist/index.jsView file
2748server.on("close", () => service.store.close()); L2749: log(`Tower listening on http://${host}:${port}/mcp${token ? " (token required)" : ""}`); L2750: log(`Live board: http://${host}:${port}/board`); ... L2759: } L2760: function gitDefaults(cwd, env = process.env) { L2761: const git = (cmd) => { L2762: try { L2763: return execSync(cmd, { cwd, stdio: ["ignore", "pipe", "ignore"] }).toString().trim(); L2764: } catch {
High
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution; review context before blocking.

dist/index.jsView on unpkg · L2748

Findings

3 High2 Medium4 Low
HighChild Processdist/worker.js
HighShelldist/worker.js
HighSame File Env Network Executiondist/index.js
MediumNetwork
MediumEnvironment Vars
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings