registry  /  indelible-mcp  /  4.9.1

indelible-mcp@4.9.1

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

AI Security Review

scanned 12h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. The package is a Claude Code MCP client that can register itself and install persistent Claude hooks. These mutations occur when a user explicitly runs its setup flow, not during npm installation.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
User runs `indelible-mcp setup` or launches the interactive TTY wizard.
Impact
Adds commands to Claude Code's user configuration; hooks can save context, restore context, and emit a saved interaction style.
Mechanism
Explicit CLI-driven Claude MCP registration and hook configuration.
Rationale
Source inspection confirms an explicit-user-command agent-extension setup rather than the scanner's claimed credential exfiltration or install-time attack. The persistent Claude hook mutation warrants a warning under the stated policy.
Evidence
package.jsonsrc/index.js~/.indelible/config.json~/.indelible/indelible-context.jsonl~/.claude/settings.local.json~/.claude.json~/.claude/settings.json
Network endpoints3
indelible.oneapi.openai.com/v1/chat/completions155.138.238.167:8080

Decision evidence

public snapshot
AI called this Suspicious at 93.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for warning
  • `src/index.js` has no npm lifecycle hook, but its CLI `setup` installs Claude hooks.
  • `installHooks()` writes `~/.claude/settings.local.json` with PreCompact, SessionStart, and PreToolUse commands.
  • Interactive wizard invokes `claude mcp add --scope user indelible -- indelible-mcp`.
  • Interactive wizard can run `npm install -g @anthropic-ai/claude-code` after the user starts it.
  • Hook commands can save/restore context and inject a stored AI style at session start.
Evidence against
  • `package.json` contains no preinstall, install, or postinstall script.
  • The Claude configuration mutation is reached only through explicit CLI setup/wizard paths.
  • No source evidence of silent install-time execution, remote code loading, or credential exfiltration.
  • Wallet key material is encrypted locally and network calls are feature-aligned blockchain/API operations.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 1 file(s), 337 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