registry  /  tapmarket-connect  /  0.1.0

tapmarket-connect@0.1.0

Give your AI assistant the power to hire paid specialists on TapMarket — with spending limits enforced on-chain.

AI Security Review

scanned 1d 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
User runs tapmarket-connect setup, then Claude/MCP invokes serve and hire_specialist.
Impact
Agent can spend funded testnet USDC within declared smart-contract permissions and transmit tool inputs to TapMarket endpoints.
Mechanism
guarded MCP agent capability with blockchain payment and package-aligned service calls
Policy narrative
The package is an MCP connector for Claude. It does not execute on npm install, but the setup command creates a wallet and modifies Claude Desktop config to launch the MCP server via npx. Once active, the MCP tool can pay TapMarket smart contracts and send job inputs to package-defined specialist endpoints. This is powerful agent-facing behavior, but it is explicit, package-aligned, and not an unconsented lifecycle control-surface hijack.
Rationale
Static inspection confirms guarded, user-invoked MCP registration and dangerous agent capability, but not install-time execution, credential exfiltration, persistence, or unconsented foreign agent hijack. Warn is appropriate for the agent/payment capability surface rather than publish-blocking as malware.
Evidence
package.jsoncli.jsserver.jsinit-lib.jscatalog.jsowner-tools.jsREADME.md~/.tapmarket/wallet.jsonClaude/claude_desktop_config.json./hires.jsonl./wallet.json../.env.local
Network endpoints5
sepolia.base.orgrpc.zerodev.app/api/v3/{ZERODEV_PROJECT_ID}/chain/84532hermes.tappayment.io/assessscribe.tappayment.io/writesepolia.basescan.org/tx/

Decision evidence

public snapshot
AI called this Suspicious at 86.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • cli.js setup writes Claude Desktop mcpServers.tapmarket to run npx -y tapmarket-connect serve.
  • server.js exposes MCP hire_specialist tool that can approve USDC and buy TapMarket packs via ZeroDev wallet.
  • server.js sends hire_specialist input and buyer address to catalog endpoints with TAP_SERVICE_TOKEN/public fallback.
  • server.js writes local hires.jsonl receipts after specialist calls.
Evidence against
  • package.json has no install/preinstall/postinstall lifecycle scripts.
  • Claude config mutation is only under explicit tapmarket-connect setup, not install/import time.
  • init-lib.js generates wallet keys locally and stores them in ~/.tapmarket/wallet.json mode 0600.
  • No child_process, eval, shell startup, VCS hook, daemon, or broad file harvesting found.
  • Network endpoints are aligned with Base Sepolia, ZeroDev RPC, and TapMarket specialist service behavior.
Behavioral surface
Source
EnvironmentVarsFilesystemNetwork
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 5 file(s), 19.1 KB of source, external domains: faucet.circle.com, hermes.tappayment.io, rpc.zerodev.app, scribe.tappayment.io, sepolia.base.org, sepolia.basescan.org

Source & flagged code

3 flagged · loading source
server.jsView file
17L18: const WALLET_FILE = process.env.TAPMARKET_WALLET ?? new URL("./wallet.json", import.meta.url).pathname; L19: if (!existsSync(WALLET_FILE)) { ... L22: } L23: const wallet = JSON.parse(readFileSync(WALLET_FILE, "utf8")); L24: ... L33: const usdcAbi = parseAbi(["function approve(address,uint256)", "function balanceOf(address) view returns (uint256)"]); L34: const publicClient = createPublicClient({ chain: baseSepolia, transport: http("https://sepolia.base.org") }); L35: const account = await deserializePermissionAccount( ... L75: if (!spec) return { content: [{ type: "text", text: `Unknown specialist '${args.specialist}'. Use list_specialists.` }], isError: true }; L76: const route = { url: spec.endpoint, body: spec.shape }; L77: const esc = await publicClient.readContract({ address: TAP_MARKET, abi: marketAbi, functionName: "escrows", args: [BigInt(spec.listingId), account.address] });
Critical
Credential Exfiltration

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

server.jsView on unpkg · L17
17Trigger-reachable chain: manifest.bin -> cli.js -> server.js L17: L18: const WALLET_FILE = process.env.TAPMARKET_WALLET ?? new URL("./wallet.json", import.meta.url).pathname; L19: if (!existsSync(WALLET_FILE)) { ... L22: } L23: const wallet = JSON.parse(readFileSync(WALLET_FILE, "utf8")); L24: ... L33: const usdcAbi = parseAbi(["function approve(address,uint256)", "function balanceOf(address) view returns (uint256)"]); L34: const publicClient = createPublicClient({ chain: baseSepolia, transport: http("https://sepolia.base.org") }); L35: const account = await deserializePermissionAccount( ... L75: if (!spec) return { content: [{ type: "text", text: `Unknown specialist '${args.specialist}'. Use list_specialists.` }], isError: true }; L76: const route = { url: spec.endpoint, body: spec.shape }; L77: const esc = await publicClient.readContract({ address: TAP_MARKET, abi: marketAbi, functionName: "escrows", args: [BigInt(spec.listingId), account.address] });
Critical
Trigger Reachable Dangerous Capability

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

server.jsView on unpkg · L17
package.jsonView file
scripts registry_only=start
Critical
Manifest Confusion

Tarball package.json differs from the npm registry version manifest for scripts or dependency sets.

package.jsonView on unpkg

Findings

3 Critical3 Medium4 Low
CriticalCredential Exfiltrationserver.js
CriticalTrigger Reachable Dangerous Capabilityserver.js
CriticalManifest Confusionpackage.json
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings