Why this verdict
- suspicious: finding mcp-server:.:.mcp.json:5:SUPPLY
- suspicious: finding mcp-server:.:src/index.ts:110:EXFIL
- suspicious: finding mcp-server:.:src/index.ts:193:PRIVESC
- suspicious: finding mcp-server:.:src/index.ts:592:EXFIL
- suspicious: finding mcp-server:.:src/index.ts:95:EXFIL
Security findings 5
Supply chain
highContextual riskmedium confidenceThe MCP launch config runs `npx -y minia2a-mcp` without a pinned version, so whatever the registry serves at that moment executes with no confirmation prompt.
"args": ["-y", "minia2a-mcp"]
conceal:remotevector:metadata
Counter-argument considered
The launch config really does run an unpinned `npx -y minia2a-mcp`. That is a genuine supply-chain exposure and no mitigation is present.
Data exfiltration
highContextual riskmedium confidenceA persistent per-machine ID is read from or written to ~/.minia2a-agent-id and sent in the X-Agent-ID header to minia2a.uk on every request. This is disclosed adoption tracking and gives the operator a stable identifier.
headers: { "X-Agent-ID": agentId() },vector:code
Counter-argument considered
A persistent per-machine identifier is sent on every catalog request. Disclosure is only in code comments, not in tool descriptions, and this is not a listed carve-out.
Data exfiltration
highContextual risklow confidenceminia2a_call_service sends the persistent X-Agent-ID and wallet trial signature headers to whatever endpoint the remote catalog supplies, which may be a third-party host, despite comments saying identity is kept off third-party URLs.
"X-Agent-ID": agentId(),
vector:code
Counter-argument considered
The request headers, including X-Agent-ID and the wallet signature, are sent to whatever endpoint the remote catalog supplies. This contradicts the code comment that identity stays off third-party URLs.
Data exfiltration
highContextual riskmedium confidenceThe server reads or creates a persistent per-machine ID in ~/.minia2a-agent-id and sends it as an X-Agent-ID header on every minia2a.uk request; this tracking identifier is undeclared in the tool descriptions and server.json, though code comments document it.
writeFileSync(file, _agentId, { mode: 0o600 })vector:code
Counter-argument considered
A persistent identifier file is written and its value is sent as a header on every minia2a.uk request. It is mentioned only in code comments, not in user-facing tool declarations.
Privilege escalation
mediumContextual risklow confidenceWith autoPay and a private key (including the MINIA2A_PRIVATE_KEY env var), the server wraps fetch to pay any HTTP 402 automatically with spendControls disabled. The endpoint comes from a remotely fetched catalog or a caller-supplied path, so a malicious endpoint could drain the wallet.
spendControls: false,
vector:code
Counter-argument considered
autoPay is opt-in and declared, but spendControls are disabled. The 402 payment target can be a remote-catalog endpoint, so no cap limits a malicious payment request.
Open questions 2
What the analysis could not settle from the code alone.
How does minia2a_call_service obtain and use the wallet private key for EIP-191/x402 signing, and where do the signed requests go? The tool implementation is not shown in this batch.
Credential access
[file request dist/index.js] Does the shipped build match the source, and does it perform undeclared file reads, env reads, or network sends?
Data exfiltration
Refuted findings 3
Candidates the review stage examined and rejected, kept for transparency.
Credential access
highRefutedlow confidenceThe minia2a_register tool generates a wallet when none is supplied and returns the private key through the tool output, which exposes key material to the agent transcript.
If no wallet is supplied, one is generated
Why it was refuted
The tool description openly says a fresh wallet is generated and its key returned. That is the declared register capability and concerns a new wallet, not an existing credential. Nothing shows the key being sent anywhere.
Credential access
highRefutedlow confidenceThe call_service tool description steers the agent to pass a wallet private key as a tool parameter or fall back to the MINIA2A_PRIVATE_KEY env var, and to enable autoPay, which spends USDC. The description claims the key stays local, and the code only signs with it, so this is plausibly honest for a payment wrapper.
pass privateKey (or set MINIA2A_PRIVATE_KEY) for your wallet's own 5 trials — the key never leaves this process
Why it was refuted
The description is honest. The private key is only used locally to sign the trial message or, with autoPay, to pay, and it is never transmitted. This is the declared core capability of a payment wrapper using an env key for the wrapped service.
Supply chain
mediumRefutedlow confidenceThe package declares an npm postinstall script that runs automatically on install; it only prints a marketing banner, but it is an install-time execution hook.
scripts.postinstall: node -e
Why it was refuted
The postinstall script only runs console.log to print a banner with catalog and register URLs. It does no network access, file access or code fetching, so there is no harm.
Coverage gaps 1
Parts of the artifact the static analysis could not fully examine.
skill_manifest_missing no readable SKILL.md for skill target
package.json