registry  /  usrcp-imessage  /  0.2.1

usrcp-imessage@0.2.1

iMessage capture+reader adapter for USRCP — macOS-only, shells out to steipete/imsg for chat.db access

AI Security Review

scanned 3d ago · by lpm-firewall-ai

No confirmed malicious attack surface. The package is a macOS iMessage adapter with an install-time native rebuild workaround and user-invoked runtime capture/reply behavior.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
npm install postinstall; user runs usrcp-imessage or setup
Impact
May read allowlisted iMessage chats and call Anthropic when configured by the user; no unauthorized exfiltration or payload behavior identified.
Mechanism
package-aligned child_process calls to imsg/brew/usrcp and Anthropic SDK use
Rationale
Static source inspection shows risky primitives, but they match the advertised iMessage adapter workflow and require install/setup/runtime user action. I found no concrete malicious behavior such as stealth exfiltration, credential harvesting, persistence, destructive action, or unconsented AI-agent control mutation.
Evidence
package.jsonREADME.mddist/index.jsdist/setup.jsdist/config.jsdist/capture.jsdist/reader.jsdist/llm.jsdist/stream-capture.jsnode_modules/better-sqlite3/buildnode_modules/usrcp-core/node_modules/better-sqlite3/buildnode_modules/usrcp-stream/node_modules/better-sqlite3/build~/.usrcp/imessage-config.json

Decision evidence

public snapshot
AI called this Clean at 89.0% confidence as Benign with medium false-positive risk.
Evidence for block
  • package.json postinstall runs install-time shell to rm better-sqlite3 build dirs and npm rebuild better-sqlite3
  • dist/index.js spawns imsg watch and sends replies with imsg send at runtime
  • dist/setup.js can install imsg via brew and validates Anthropic key during interactive setup
Evidence against
  • README.md and dist/index.js describe an iMessage adapter; imsg child_process use is package-aligned
  • dist/index.js only starts watcher when run as entrypoint, not on import
  • dist/index.js gates capture/replies to configured allowlisted chats
  • dist/config.js stores config via usrcp-adapter-kit with anthropic_api_key marked secret
  • dist/reader.js sends ledger context to the configured LLM only for triggered allowlisted incoming messages
  • No credential harvesting, hidden exfiltration endpoint, persistence, destructive payload, or AI-agent control-surface writes found
Behavioral surface
Source
ChildProcessEnvironmentVars
Supply chain
UrlStrings
ManifestNo manifest risk signals triggered.
scanned 7 file(s), 48.8 KB of source, external domains: console.anthropic.com

Source & flagged code

3 flagged · loading source
package.jsonView file
scripts.postinstall = node -e "const fs=require(\"fs\"); for (const p of [\"node_modules/better-sqlite3/build\",\"node_modules/usrcp-core/node_modules/better-sqlite3/build\",\"node_modules/usrcp-stream/...
Critical
Red Install Lifecycle Script

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

package.jsonView on unpkg
scripts.postinstall = node -e "const fs=require(\"fs\"); for (const p of [\"node_modules/better-sqlite3/build\",\"node_modules/usrcp-core/node_modules/better-sqlite3/build\",\"node_modules/usrcp-stream/...
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
dist/setup.jsView file
197package = usrcp-imessage; repositoryIdentity = usrcp; dependency = @anthropic-ai/sdk L197: try { L198: const { default: Anthropic } = await import("@anthropic-ai/sdk"); L199: const client = new Anthropic({ apiKey });
High
Copied Package Dependency Bridge

Package metadata claims a different repository identity while copied source loads a runtime dependency bridge.

dist/setup.jsView on unpkg · L197

Findings

1 Critical2 High2 Medium2 Low
CriticalRed Install Lifecycle Scriptpackage.json
HighInstall Time Lifecycle Scriptspackage.json
HighCopied Package Dependency Bridgedist/setup.js
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowScripts Present
LowUrl Strings