registry  /  indelible-mcp  /  4.9.3

indelible-mcp@4.9.3

Blockchain-backed memory and code storage for Claude Code. Save AI conversations and source code permanently on BSV.

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
Running `indelible-mcp setup` or completing the interactive CLI wizard
Impact
Expands an AI-agent control surface and can transmit user session content through declared package services.
Mechanism
Explicit Claude MCP/hook registration plus transcript capture and remote blockchain/API synchronization
Rationale
Source inspection does not support a malicious verdict: there are no npm lifecycle hooks and no confirmed WIF/PIN exfiltration. The explicit setup-driven Claude configuration mutation and automatic session persistence remain a real agent-control/data-handling risk requiring a warning.
Evidence
package.jsonsrc/index.js~/.indelible/config.json~/.claude/settings.local.json~/.claude/projects
Network endpoints6
indelible.oneapi.openai.com/v1/chat/completions144.202.48.217:9333149.28.243.56:933345.63.77.31:9333155.138.238.167:8080

Decision evidence

public snapshot
AI called this Suspicious at 91.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for warning
  • `src/index.js` `setup` installs hooks in `~/.claude/settings.local.json`.
  • Hooks read Claude transcripts and save/restores session content through the package's blockchain workflow.
  • Interactive wizard runs global Claude CLI install and `claude mcp add --scope user` after user launches the CLI.
  • `report_bug` posts wallet address, receipts, OS, and Node version only when invoked.
  • `diary_chat` sends supplied API key and conversation data to OpenAI.
Evidence against
  • `package.json` contains no preinstall/install/postinstall lifecycle script.
  • Wallet WIF is encrypted locally and PIN is stored via keychain when available.
  • No source path sends the WIF, PIN, or arbitrary environment variables to a hard-coded endpoint.
  • Claude configuration mutation is reached from explicit `setup` or interactive CLI execution, not npm install.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 1 file(s), 339 KB of source, external domains: 104.238.138.113, 144.202.48.217, 149.28.243.56, 155.138.238.167, 45.63.70.235, 45.63.77.31, 45.63.86.122, 66.135.31.144, api.openai.com, cdn.jsdelivr.net, huggingface.co, indelible.one

Source & flagged code

3 flagged · loading source
src/index.jsView file
17// lib/crypto.js L18: import { createCipheriv, createDecipheriv, createHash, randomBytes, pbkdf2Sync } from "crypto"; L19: function deriveKey(wif) { ... L115: } L116: if (!pin) pin = process.env.INDELIBLE_PIN; L117: if (!pin) return null; ... L128: init_crypto(); L129: CONFIG_DIR = join(homedir(), ".indelible"); L130: CONFIG_FILE = join(CONFIG_DIR, "config.json"); ... L135: // lib/spv.js L136: import { Transaction, P2PKH, PrivateKey, SatoshisPerKilobyte, LockingScript, OP } from "@bsv/sdk"; L137: import { Transaction as Transaction2, P2PKH as P2PKH2, PrivateKey as PrivateKey2, SatoshisPerKilobyte as SatoshisPerKilobyte2, LockingScript as LockingScript2, OP as OP2 } from "@b...
Critical
Credential Exfiltration

Source appears to send environment or credential material to an external endpoint.

src/index.jsView on unpkg · L17
17Trigger-reachable chain: manifest.main -> src/index.js L17: // lib/crypto.js L18: import { createCipheriv, createDecipheriv, createHash, randomBytes, pbkdf2Sync } from "crypto"; L19: function deriveKey(wif) { ... L115: } L116: if (!pin) pin = process.env.INDELIBLE_PIN; L117: if (!pin) return null; ... L128: init_crypto(); L129: CONFIG_DIR = join(homedir(), ".indelible"); L130: CONFIG_FILE = join(CONFIG_DIR, "config.json"); ... L135: // lib/spv.js L136: import { Transaction, P2PKH, PrivateKey, SatoshisPerKilobyte, LockingScript, OP } from "@bsv/sdk"; L137: import { Transaction as Transaction2, P2PKH as P2PKH2, PrivateKey as PrivateKey2, SatoshisPerKilobyte as SatoshisPerKilobyte2, LockingScript as LockingScript2, OP as OP2 } from "@b...
Critical
Trigger Reachable Dangerous Capability

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

src/index.jsView on unpkg · L17
111try { L112: const { getPassword } = await import("cross-keychain"); L113: pin = await getPassword("indelible", config.address);
Medium
Dynamic Require

Package source references dynamic require/import behavior.

src/index.jsView on unpkg · L111

Findings

2 Critical4 Medium4 Low
CriticalCredential Exfiltrationsrc/index.js
CriticalTrigger Reachable Dangerous Capabilitysrc/index.js
MediumDynamic Requiresrc/index.js
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings