etherscan-actions
Provides Ethereum blockchain data access and JSON-RPC methods via Etherscan public pages, including address metadata, first funder lookup, ERC20 holdings, token holder lists, transaction history, transaction details, and standard Ethereum RPC calls such as eth_getBalance, eth_call, and eth_getTransactionReceipt.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@etherscan-actionswho first funded 0xd8da...96045?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
etherscan-actions
Ethereum-only collector and RPC alternative built entirely on etherscan.io. It provides a Python SDK, a JSON CLI (escan), and a stdio MCP server. No API key or browser is needed: requests go to the same public pages and read-only UI JSON handlers a browser uses, over a Chrome-impersonating TLS client (curl_cffi).
This is not an Etherscan API client. See endpoint coverage for how each documented API endpoint, including every PRO and PRO+ endpoint, maps to public data.
Install
Requires Python 3.11+.
uv sync
uv run escan --helpOr install it straight from GitHub:
pip install git+https://github.com/billywgd/etherscan-actionsRelated MCP server: Ethereum RPC MPC Server
Dedicated operations
These return an ActionResult with operation, target, source, chain_id (always 1), status, complete, data, per-request provenance (sources), pagination, unavailable_fields, warnings and errors.
Operation (API counterpart) | SDK | CLI | MCP |
First funder ( |
|
|
|
Address metadata ( |
|
|
|
ERC20 holdings ( |
|
|
|
Token holder list ( |
|
|
|
Transaction history ( |
|
|
|
Transaction details ( |
|
|
|
uv run escan funded-by 0xd8da6bf26964af9d7eed9e03e53415d37aa96045
uv run escan metadata 0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97
uv run escan erc20-holdings 0xd8da6bf26964af9d7eed9e03e53415d37aa96045 --all --max-pages 5
uv run escan token-holders 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 --page 3
uv run escan tx-history 0xd8da6bf26964af9d7eed9e03e53415d37aa96045 --kind erc20 --all --max-pages 5
uv run escan tx-info 0x53f109a88a180457eb8f558e73c02636f9a3ddb8d017f886a242dd2c4dc1a8e9Funded By reads the address page's first-funder annotation (funder address, its public label and the funding transaction). It then reads that transaction for
block,timeStampand an exact weivalue. The value is used only if the transaction's sender and recipient match the annotation. A contract creator is never substituted for a funder.Metadata returns the public nametag, ENS name and labels. It is always
partial: private/internal PRO+ fields are listed inunavailable_fieldsand never invented.ERC20 holdings excludes ETH and returns full-precision
balancedecimal strings plus untruncated names and symbols. Price and value are kept as displayed.balance_rawand decimals are not public and stay unavailable.Token holders returns
address, full-precisionbalanceand publiclabel(nullwhen unlabelled). Etherscan shows at most 1,000 holders. The cap and the reported total are kept inpagination, and capped results are never markedcomplete.Transaction history returns one record per row, using Etherscan API field names:
blockNumber,timeStamp,hash,from,to,value,isError,functionNameand so on. It adds public labels (fromLabel,toLabel),directionanderrorReason. ETH values are exact wei, read from full-precision tooltips.kindselectsnormal,internal,erc20ornft. Token amounts are exact decimal strings; raw units are not public in the listing. Etherscan shows only the latest 10,000 records (5,000 for token transfers).paginationreportsreported_totalandpublic_record_cap, and capped histories are nevercomplete.Transaction details returns status and failure reason, block, timestamp, and from/to with labels. Value, fee, gas price, base/max/priority fees and the burnt fee are all exact wei. It also returns gas limit/used, type, nonce, position, raw
input,methodIdand the decoded function signature. ERC-20tokenTransferscome with exact amounts, andlogsinclude raw topics/data plus decoded parameters. For contract deployments,tois empty andcontractAddressis set.
Listings resume with --page / start_page from pagination.next_page. Use --all / all_pages=True with a bounded --max-pages to walk them.
Ethereum RPC from Etherscan
escan rpc answers standard Ethereum JSON-RPC methods using only Etherscan, with no node provider or API key. Results use the usual RPC shapes (hex quantities, lowercase addresses). Fields Etherscan doesn't publish are null, never invented.
uv run escan rpc eth_getTransactionReceipt 0x53f109a88a180457eb8f558e73c02636f9a3ddb8d017f886a242dd2c4dc1a8e9
uv run escan rpc eth_getBalance 0xd8da6bf26964af9d7eed9e03e53415d37aa96045
uv run escan rpc eth_call '{"to":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","data":"0x18160ddd"}'
uv run escan rpc escan_fundedBy 0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97Method | Source | Notes |
| Etherscan's node | The node that powers etherscan.io's Read Contract tab. Only recent state (last 128 blocks). |
| Etherscan's node | Exact: an |
| Transaction page (+ block page for | Full input, exact fees, logs with block-level |
| Block page | Header fields including hash, parent, state/withdrawals roots, miner, gas, base fee, blob gas and extra data. Tags |
| constant | |
| pages | The sleuthing operations above, through the same interface. Options go in a second parameter, e.g. |
Live verification status (0.4.0): the node-backed methods and the
escan_*methods were verified against etherscan.io.eth_getTransactionByHash,eth_getTransactionReceipt,eth_getBlockByNumberandeth_getBlockByHashare tested only against saved copies of real pages: Cloudflare was challenging the test machine's IP when they shipped.pytest -m livecovers them.
Not available from Etherscan without a browser: eth_getLogs, full block transaction lists, eth_getTransactionCount, eth_estimateGas, traces, and state older than 128 blocks. Sending transactions is out of scope.
Bulk
Batches read NDJSON: full JSON-RPC requests, or plain values with a METHOD. Results stream as NDJSON in completion order, each with its request id. --resume appends to a results file and skips ids it already answered, so an interrupted run continues where it stopped.
uv run escan rpc eth_getTransactionReceipt --batch hashes.txt --resume receipts.ndjson
uv run escan rpc escan_txHistory --batch addresses.txt '{"kind":"erc20","all_pages":true,"max_pages":20}' --resume history.ndjson
uv run escan rpc --batch requests.ndjson --workers 8 > results.ndjsonwith EtherscanClient() as client:
receipt = client.rpc("eth_getTransactionReceipt", [tx_hash])
for response in client.rpc_batch(
{"id": h, "method": "eth_getTransactionByHash", "params": [h]} for h in hashes
):
...Throughput
Measured from one IP on 2026-10-06:
Etherscan's node: about 18 requests/s, with no errors at any concurrency. The default node rate is 15/s (
node_rps).Pages: short bursts of 5 to 10 requests/s succeed. But about 140 page requests within a minute got the IP challenged site-wide, and the block outlasted 20 minutes. The default page rate is therefore 1 request/s (
--interval). Raising it risks a long block.
Finalized transaction and block pages are cached permanently, so repeated lookups and transactions in the same block cost no requests. --no-block-hash skips the block-page lookup that fills blockHash, halving page requests for transactions and receipts. After a challenge, page requests pause for a cooldown that doubles from 60 s up to 15 min. Batches wait it out (up to --max-wait) rather than extending the block.
Page and section collection
The generic collectors keep every public field, table, link, inline chart dataset and ABI on a page, along with section-level status, pagination and completeness.
uv run escan discover address 0xd8da6bf26964af9d7eed9e03e53415d37aa96045 # advertised sections
uv run escan address 0xd8da6bf26964af9d7eed9e03e53415d37aa96045 --sections transactions,internals,erc20 --all --max-pages 3
uv run escan token 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 --summary
uv run escan tx 0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060
uv run escan contract 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
uv run escan history address 0xd8da6bf26964af9d7eed9e03e53415d37aa96045 transactions --page 2
uv run escan holders 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
uv run escan page /gastracker
uv run escan cache-clear--summary prints coverage and counts instead of the full record. --output FILE atomically writes the full JSON to a new file. --html keeps the original HTML.
from etherscan_actions import EtherscanClient
with EtherscanClient() as client:
funding = client.funded_by("0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97")
print(funding.data) # fundingAddress, fundingAddressLabel, fundingTxn, block, timeStamp, value
holders = client.token_holders(
"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", all_pages=True, max_pages=4
)
print(len(holders.data), holders.pagination)
token = client.token("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", sections=["holders"])
print(token.summary())MCP server
uv run etherscan-actions-mcpTools: etherscan_funded_by, etherscan_metadata, etherscan_erc20_holdings, etherscan_token_holder_list, etherscan_tx_history, etherscan_tx_info, etherscan_rpc, etherscan_address, etherscan_token, etherscan_transaction, etherscan_contract, etherscan_holders, etherscan_history, etherscan_discover, etherscan_page, etherscan_read_artifact.
If a response exceeds ETHERSCAN_ACTIONS_MCP_MAX_CHARS, the full result is written to a JSON artifact. The tool then returns its path, its SHA-256 and a coverage summary. Read the artifact in chunks with etherscan_read_artifact.
Configuration
SDK constructor options: profile, interval, timeout, proxy, cache, cache_dir, cache_ttl, node_rps. The CLI has matching flags. The CLI and MCP server also read:
Variable | Default | Purpose |
|
|
|
|
| Minimum seconds between requests |
|
| Request timeout in seconds |
| none | Explicit HTTP proxy URL |
|
| Page cache and MCP artifacts |
|
| Inline MCP response budget |
Behaviour and guarantees
Read-only. Page requests are rate-limited, restricted to
https://etherscan.io(other origins and off-origin redirects are rejected), and retried with bounded backoff on 429/5xx, honouringRetry-After. Node requests go only tonode1.web3api.com(the node etherscan.io's own frontend uses), only for its three read methods, with an etherscan.io Origin as the frontend sends.Successful responses are cached in SQLite (default TTL 300 s;
--refreshbypasses it). Finalized transaction and block pages never expire. Challenges, error documents, login walls and not-found pages are never cached.Failures are explicit: a Cloudflare challenge is
blocked, a login wall islogin_required, and a missing record isnot_found. None of these is reported as empty data.completecovers only the requested public scope, so check it, along with section status and notices, before treating a listing as a full history.
Verification
uv run pytest -q # unit + local-HTTPS end-to-end (SDK, CLI, stdio MCP)
uv run pytest -q -m live # optional requests to etherscan.io
uv run ruff check .
uv buildLive results from 2026-10-06 are in the coverage doc.
Disclaimer
This is an independent project. It is not affiliated with or endorsed by Etherscan. It reads publicly visible pages at a deliberately slow default rate. You are responsible for following Etherscan's terms of service and for keeping your usage reasonable. If you need guaranteed, high-volume or commercial access, use the official Etherscan API.
Contributing and license
Contributions are welcome; see CONTRIBUTING.md. Report security issues as described in SECURITY.md. Released under the MIT License.
This server cannot be deployed
Maintenance
Related MCP Connectors
Self-hosted MCP server: 26 deterministic dev, security, and EVM tools.
Programmatic web-scraping MCP server powered by x402 micro-transactions on Base.
- UnifAPIOAuthcom.unifapi
Hosted MCP server for live public-data APIs and Skills for AI agents.
Ethereum MCP: Chainlink feeds, gas, ERC-20, ENS, ABI, contract calls, ERC-8004, EAS.
Related MCP Servers
- AlicenseBqualityDmaintenanceAn MCP server providing comprehensive access to Ethereum blockchain data across 72+ networks via Etherscan's V2 API. It enables users to check balances, track transactions, analyze smart contracts, and monitor gas prices through natural language.2417 npm1MIT
- AlicenseNot gradedqualityCmaintenanceAn MCP server that bridges AI models with Ethereum blockchains via all JSON-RPC calls, enabling natural language queries for block numbers, balances, transactions, and smart contract data.8 npm21MIT
- AlicenseAqualityFmaintenanceProvides MCP tools to query Etherscan for Ethereum blockchain data—ETH balances, ERC-20 tokens, transactions, contract ABIs, and gas prices—without requiring an API key.88 npmMIT
- AlicenseAqualityCmaintenanceA read-only MCP server that queries multichain EVM on-chain data through Blockscout REST API, providing tools for address info, transactions, logs, and more.1614 npmMIT