You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A user asked: "there was recently a 51% attack on Litecoin — can you summarize what's known based on data you can extract from the LTC chain?"
The agent had nothing to extract with. Neither BTC nor LTC has a forensic-tier read surface in this MCP, even though both share an Esplora-style indexer abstraction internally. The agent had to decline the analytical request entirely.
Inventory of what's already wired
BTC (exposed as MCP tools):
get_btc_block_tip — current tip header only (height, hash, timestamp, MTP, optional difficulty). Single block deep.
(Internal LitecoinIndexer.getBlockTip() exists at src/modules/litecoin/indexer.ts:191 but is NOT registered as an MCP tool — get_ltc_block_tip is missing from src/index.ts.)
No fee estimator, no chain-wide read of any kind.
Tool gaps (same for BTC and LTC unless noted)
For 51%/reorg/double-spend forensics — and more general "is this chain healthy right now" questions — agents need:
get_{btc,ltc}_block — fetch a block by height OR hash. Full header (prev_hash, merkle root, version, bits, nonce, timestamp, MTP, difficulty), tx count, size, weight. Walk-back primitive.
get_{btc,ltc}_blocks_recent — last N blocks (capped, e.g. 100), each with (height, hash, timestamp, ageSeconds, miner-pool-tag-if-decoded, txCount, size, totalFees). Backbone for "any unusually long/short blocks?" / "any orphans?" / "what's miner concentration looking like over the last hour?".
get_{btc,ltc}_coinbase — coinbase tx for a given block, with parsed scriptSig (BIP-34 height + miner pool tag — Foundry, AntPool, F2Pool, ViaBTC, Litecoinpool, etc.), payout addresses, total reward, fee subsidy split. This is the single most important signal for a 51% attack: an attacker's coinbases will tag as either a known pool (compromised/coerced) or as anonymous/never-seen-before scriptSigs.
get_{btc,ltc}_chain_tips(RPC-only — see below) — equivalent of bitcoin-cli getchaintips. Lists active, valid-fork, valid-headers, and headers-only tips with branch-length. This is THE fork-detection primitive. Esplora indexers cannot expose this — they only know the chain they followed.
get_{btc,ltc}_block_stats — for a height range: fee distribution, feerate percentiles, tx count, size, witness/non-witness ratio. Lets the agent spot "empty blocks" (a strong reorg-mining signal) and unusual txfee patterns.
get_{btc,ltc}_difficulty_timeline — last N retargets (BTC every 2016 blocks ≈ 2 weeks; LTC every 2016 blocks ≈ 3.5 days). % change per retarget. A sudden drop after a hashrate crash is a classic post-attack signature.
get_{btc,ltc}_tx_chain_status — given a txid, return: confirmed, blockHeight, blockHash, isOnActiveChain (i.e. did the block survive any reorgs), confirmationsOnActiveChain. Sharper than getTxStatus for forensics — answers "was my tx in an orphaned block?".
get_{btc,ltc}_mempool_summary(RPC-only — see below) — total tx count, total fees, vsize, size buckets. Used to spot mempool poisoning / spam attacks adjacent to or instead of 51%.
The RPC question — should BITCOIN_RPC_URL / LITECOIN_RPC_URL be a first-class config?
This is the key design decision and I'd argue yes. Reasoning:
The current architecture is Esplora-style HTTP indexers (mempool.space for BTC, litecoinspace.org for LTC). That works perfectly for wallet-tier reads — UTXOs, address tx history, fee estimates — because those are exactly what Esplora was built for. But for the 51%-attack / reorg-forensics use case, public indexers are structurally wrong:
Indexers have a single view of "canonical" chain. If an attacker reorgs N blocks deep, the indexer simply rewrites its index to follow the longest chain. There's no getchaintips equivalent — you can't see the forks that were live yesterday.
No coinbase scriptSig decoding — Esplora returns the raw tx but doesn't surface "this was mined by AntPool". The agent would have to fetch every coinbase and parse it client-side, which is fine if we add it but means we always need the raw scriptSig.
Rate limits — walking 144 blocks (a day) on a public indexer hits per-IP throttling fast. mempool.space's free tier is generous but not unlimited; litecoinspace.org's tier is much tighter and the existing LITECOIN_INDEXER_PARALLELISM=8 cap exists for exactly that reason.
Trust shift — if we're using indexer X to detect that indexer X was reorged, we have no second opinion. A self-hosted (or paid) RPC node IS the second opinion.
No mempool visibility beyond the indexer's view. Esplora exposes mempool but it's whatever that one node sees. Forensics on a double-spend / RBF replacement needs ours.
Proposed config schema:
BITCOIN_RPC_URL (with optional BITCOIN_RPC_USER / BITCOIN_RPC_PASSWORD for basic-auth, or BITCOIN_RPC_COOKIE path)
When unset: forensic-tier tools degrade gracefully — return what Esplora can give, mark RPC-only fields as null with a requiresRpc: true hint in the response so the agent can tell the user "this analysis needs RPC; here's how to set one up".
Wallet-tier tools (balance, tx history, fee estimate) keep using the existing Esplora indexer — no migration, no regression, no slowdown.
User options for the RPC backend:
(a) Public/paid RPC provider — Quicknode / Getblock / Blockdaemon / NOWNodes all support BTC; for LTC the lineup is thinner but Getblock and NOWNodes both have LTC mainnet RPC. Lowest setup; trust shifts to provider but at least it's a second trust anchor distinct from mempool.space.
(b) Self-hosted pruned node — bitcoind -prune=10000 is ~10GB on disk, ~2 days to IBD. litecoind -prune=5000 is ~5GB, ~6 hours to IBD. Trustless. For LTC specifically this is very cheap — the chain is small, and given how thin the LTC indexer ecosystem is (litecoinspace.org is essentially the only viable public Esplora-compat LTC indexer), a self-hosted LTC node also reduces single-point-of-indexer risk for ALL LTC tools, not just forensic ones.
Bonus: when RPC is configured, also use it as a cross-check on Esplora's tip — if bitcoind getbestblockhash disagrees with mempool.space /blocks/tip/hash by more than 1 block, surface a warning. Cheapest reorg early-warning signal possible.
Concrete repro for the original failure
user: \"there was a 51% attack on Litecoin recently — what can you extract from the chain?\"
agent: [no tool can read past block tip on LTC, and even on BTC only the tip header is exposed]
agent: declines analytically, has to ask user for a tx hash / block height to web-fetch instead.
Why this matters beyond 51% analysis
The same surface (#1–#7) is what an agent needs to answer: "is this tx safely confirmed?" (#7 with reorg-aware status), "is the network healthy right now?" (#2 + #6), "who's mining the chain my tx will land in?" (#3), "is the mempool congested or spammed?" (#8). It's general-purpose chain-health tooling that a 51%-attack question just made acute.
Submitted via the request_capability tool in vaultpilot-mcp by an AI agent (Claude Code).
Use case that surfaced this gap
A user asked: "there was recently a 51% attack on Litecoin — can you summarize what's known based on data you can extract from the LTC chain?"
The agent had nothing to extract with. Neither BTC nor LTC has a forensic-tier read surface in this MCP, even though both share an Esplora-style indexer abstraction internally. The agent had to decline the analytical request entirely.
Inventory of what's already wired
BTC (exposed as MCP tools):
get_btc_block_tip— current tip header only (height, hash, timestamp, MTP, optional difficulty). Single block deep.get_btc_balance/get_btc_balances/get_btc_account_balance— wallet-scoped.get_btc_tx_history— wallet-scoped.get_btc_fee_estimates— fee estimator.LTC (exposed as MCP tools):
get_ltc_balance— wallet-scoped.LitecoinIndexer.getBlockTip()exists atsrc/modules/litecoin/indexer.ts:191but is NOT registered as an MCP tool —get_ltc_block_tipis missing fromsrc/index.ts.)Tool gaps (same for BTC and LTC unless noted)
For 51%/reorg/double-spend forensics — and more general "is this chain healthy right now" questions — agents need:
get_{btc,ltc}_block— fetch a block by height OR hash. Full header (prev_hash, merkle root, version, bits, nonce, timestamp, MTP, difficulty), tx count, size, weight. Walk-back primitive.get_{btc,ltc}_blocks_recent— last N blocks (capped, e.g. 100), each with (height, hash, timestamp, ageSeconds, miner-pool-tag-if-decoded, txCount, size, totalFees). Backbone for "any unusually long/short blocks?" / "any orphans?" / "what's miner concentration looking like over the last hour?".get_{btc,ltc}_coinbase— coinbase tx for a given block, with parsed scriptSig (BIP-34 height + miner pool tag — Foundry, AntPool, F2Pool, ViaBTC, Litecoinpool, etc.), payout addresses, total reward, fee subsidy split. This is the single most important signal for a 51% attack: an attacker's coinbases will tag as either a known pool (compromised/coerced) or as anonymous/never-seen-before scriptSigs.get_{btc,ltc}_chain_tips(RPC-only — see below) — equivalent ofbitcoin-cli getchaintips. Listsactive,valid-fork,valid-headers, andheaders-onlytips with branch-length. This is THE fork-detection primitive. Esplora indexers cannot expose this — they only know the chain they followed.get_{btc,ltc}_block_stats— for a height range: fee distribution, feerate percentiles, tx count, size, witness/non-witness ratio. Lets the agent spot "empty blocks" (a strong reorg-mining signal) and unusual txfee patterns.get_{btc,ltc}_difficulty_timeline— last N retargets (BTC every 2016 blocks ≈ 2 weeks; LTC every 2016 blocks ≈ 3.5 days). % change per retarget. A sudden drop after a hashrate crash is a classic post-attack signature.get_{btc,ltc}_tx_chain_status— given a txid, return: confirmed, blockHeight, blockHash, isOnActiveChain (i.e. did the block survive any reorgs), confirmationsOnActiveChain. Sharper thangetTxStatusfor forensics — answers "was my tx in an orphaned block?".get_{btc,ltc}_mempool_summary(RPC-only — see below) — total tx count, total fees, vsize, size buckets. Used to spot mempool poisoning / spam attacks adjacent to or instead of 51%.The RPC question — should
BITCOIN_RPC_URL/LITECOIN_RPC_URLbe a first-class config?This is the key design decision and I'd argue yes. Reasoning:
The current architecture is Esplora-style HTTP indexers (
mempool.spacefor BTC,litecoinspace.orgfor LTC). That works perfectly for wallet-tier reads — UTXOs, address tx history, fee estimates — because those are exactly what Esplora was built for. But for the 51%-attack / reorg-forensics use case, public indexers are structurally wrong:getchaintipsequivalent — you can't see the forks that were live yesterday.LITECOIN_INDEXER_PARALLELISM=8cap exists for exactly that reason.Proposed config schema:
BITCOIN_RPC_URL(with optionalBITCOIN_RPC_USER/BITCOIN_RPC_PASSWORDfor basic-auth, orBITCOIN_RPC_COOKIEpath)LITECOIN_RPC_URL+ same auth pairgetchaintips,getblockstats,getrawmempool,getblock <hash> 2(block with prevout-resolved txs).nullwith arequiresRpc: truehint in the response so the agent can tell the user "this analysis needs RPC; here's how to set one up".User options for the RPC backend:
mempool.space.bitcoind -prune=10000is ~10GB on disk, ~2 days to IBD.litecoind -prune=5000is ~5GB, ~6 hours to IBD. Trustless. For LTC specifically this is very cheap — the chain is small, and given how thin the LTC indexer ecosystem is (litecoinspace.org is essentially the only viable public Esplora-compat LTC indexer), a self-hosted LTC node also reduces single-point-of-indexer risk for ALL LTC tools, not just forensic ones.My recommendation, in priority order:
get_ltc_block_tipregistration. This alone would have let the agent answer ~70% of the user's question.bitcoind getbestblockhashdisagrees withmempool.space /blocks/tip/hashby more than 1 block, surface a warning. Cheapest reorg early-warning signal possible.Concrete repro for the original failure
Why this matters beyond 51% analysis
The same surface (#1–#7) is what an agent needs to answer: "is this tx safely confirmed?" (#7 with reorg-aware status), "is the network healthy right now?" (#2 + #6), "who's mining the chain my tx will land in?" (#3), "is the mempool congested or spammed?" (#8). It's general-purpose chain-health tooling that a 51%-attack question just made acute.
Submitted via the
request_capabilitytool in vaultpilot-mcp by an AI agent (Claude Code).