chain-reader
chain-reader — servidor MCP de Ethereum de solo lectura
Un servidor MCP para que un LLM lea Ethereum en lenguaje natural. No tiene claves privadas, no firma ni envía nada. Todos los resultados llevan «de dónde ha salido esa respuesta».
Escrito como prototipo didáctico que convierte en algo funcional la figura del último capítulo «Blockchain e IA» de "Ethereum & Smart Contracts" de Tim Weingärtner (HSLU).
LLM ← 自然言語(「このアドレスは何者?」)
↓
MCP ← src/server.js
↓ ← コード/構造化言語(ABI エンコード)
RPC ← src/rpc.js
↓
ブロックチェーンLas únicas dependencias son @modelcontextprotocol/sdk y zod.
Tanto el Keccak-256 como el codificador ABI están implementados a mano (ver más abajo «Por qué lo escribí a mano»).
Ponerlo en marcha
git clone <this repo> && cd chain-reader-mcp
npm ci --ignore-scripts
npm test # 単体 13 件(ネットワーク不要)
npm run smoke # 実チェーンに対して全ツールを 1 回ずつRegistrarlo en Claude Code.
claude mcp add chain-reader -- node "$PWD/src/server.js"Si arrancas claude en este directorio, no hace falta registrarlo porque ya hay un .mcp.json.
Pero solo la primera vez te pedirá aprobación (en claude mcp list aparece ⏸ Pending approval).
Para no llevarte un susto el día de la clase, arráncalo una vez antes y confírmalo.
En Claude Desktop, escribe el mismo contenido en mcpServers de claude_desktop_config.json.
En ese caso, args debe ser una ruta absoluta.
Se puede cambiar la red de destino con variables de entorno. Por defecto es mainnet.
Variable | Valor |
|
|
| Endpoint propio (si se indica, tiene prioridad sobre el nombre de la red) |
En todos los casos se usan endpoints públicos que no requieren API key. local mira el http://127.0.0.1:8545 de anvil / hardhat node.
Correspondencia entre herramientas y la clase
Las diapositivas de la clase están en otro repositorio (traducción privada al japonés), pero con los nombres de las secciones basta para seguir la correspondencia.
Herramienta | Diapositiva correspondiente | Qué se ve |
| Gas y tarifas de transacción / PoS | La tarifa base se mueve según la congestión del bloque |
| Los dos tipos de cuenta / Direcciones de Ethereum | Que EOA y contrato se distinguen por la presencia de código |
| Leer una transacción en Etherscan | Tarifa = gas usado × precio del gas efectivo |
| Bloque | La cadena de |
| ABI / Introducción a Solidity | Que el selector son los primeros 4 bytes de keccak256(firma) |
| ERC-20 / ERC-721 / la ficha del guardarropa | Que nombre y símbolo son autodeclarados por el contrato |
| UI dirigida por eventos | Que solo los argumentos |
| Aviso al usar MCP | El límite de lo que puede hacer quien no tiene la clave |
| ABI | Calcula el selector sin tocar la red (para la pizarra) |
| (lado del artículo) | Qué puede y qué no puede probar el anclaje de un hash |
Si eliges el prompt lecture_walkthrough, se incluyen instrucciones para recorrer del 1 al 6 en orden.
Preguntas que se pueden usar tal cual en clase
このネットワークはいま混んでいますか?
0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 は EOA ですか、コントラクトですか?
USDC の総供給量は? その数字は誰が保証していますか?
transfer(address,uint256) のセレクタはなぜ 0xa9059cbb になるのですか?
私のアドレスから 0.001 ETH を送る取引を組み立ててくださいEn la última pregunta, la IA devuelve el JSON que ha montado, pero no puede enviarlo. Si le pides que explique «por qué no puede enviarlo», el contenido de la diapositiva «Aviso al usar MCP» sale de la propia boca de la IA.
Dos compromisos de diseño
1. No tener claves
ALLOWED_METHODS en src/rpc.js es una lista blanca explícita de métodos de solo lectura.
eth_sendRawTransaction / eth_sendTransaction / eth_sign no están en ella:
si se intentan llamar, fallan antes de salir a la red (está fijado en las pruebas unitarias).
En este repositorio no existe ni implementación de firma ni carga de claves privadas. Por mucho que se intente engañar al LLM, desde aquí no se mueve dinero.
prepare_unsigned_transaction existe para mostrar este límite en forma funcional, no como «lo que no se puede hacer». Devuelve el producto terminado con nonce, estimación de gas y tarifa ya rellenados, y deja solo la firma para el humano. La diapositiva de la clase
«Lo único que MCP puede hacer con seguridad se limita a dos cosas: llamadas de solo lectura y retransmisión de transacciones firmadas»
está implementada tal cual.
2. No descartar la procedencia de las respuestas
Todos los resultados llevan _provenance.
"_provenance": {
"endpoint": "https://ethereum-rpc.publicnode.com",
"network": "mainnet (Ethereum Mainnet)",
"rpc_calls": ["eth_blockNumber (1309ms)", "eth_gasPrice (1416ms)", "eth_chainId (1769ms)", "eth_getBlockByNumber (1023ms)"],
"note": "これは単一の RPC エンドポイントの応答であり、独立に検証したものではない。"
}Es un mecanismo para no quedarse en «es correcto porque es blockchain».
Los LLM tienen la costumbre de afirmar números con total seguridad, así que el propio resultado lleva incorporado qué afirmación se apoya en qué capa. Las instructions del servidor también indican que se distinga entre los hechos garantizados por la cadena y los contenidos declarados por alguien.
Poder atribuir no es lo mismo que poder verificar
El diseño de salida de este servidor viene del contexto de la gestión documental y los archivos digitales. La diferencia entre lo que se puede afirmar y que sea verdad está incrustada en la salida de las herramientas.
self_reported_note de read_token — el hecho de que name() haya devuelto "USD Coin" lo garantiza la cadena. Pero no garantiza que ese contrato sea realmente de Circle.
Cualquiera puede desplegar un contrato con el mismo nombre y el mismo símbolo.
Lo que la cadena garantiza llega hasta «el código de esta dirección ha respondido esto», no hasta la verdad de esa afirmación.
what_this_does_not_prove de verify_anchor — lo que da el anclaje es «cuándo, quién y qué afirmó», no «si esa afirmación es correcta».
El hash de una medición errónea se puede grabar igual que el de una medición correcta.
Sale directamente la distinción de la diplomática: la autenticidad (authenticity) no es la verdad (truth).
_provenance — la implementación mínima de la idea de que la calidad de un registro es la forma de su grafo de procedencia.
Qué endpoint respondió, con qué llamada RPC y en cuántos milisegundos.
Deja en un estado en el que se pueda decidir después a quién asignar el prov:wasAttributedTo de PROV-O.
Si se sube de capa — declaraciones firmadas / contraste con información pública / atestación TEE / autenticación institucional — la fuerza de la verificación aumenta, pero por mucho que se suba, «el propio instrumento de medición» no se puede verificar. Lo que este prototipo demuestra es la capa más baja de todas: el territorio donde se puede atribuir pero no verificar. Por eso se deja en el registro sobre qué capa se apoya cada cifra.
Por qué escribí a mano también el Keccak y el ABI
Con viem o ethers bastarían tres líneas. Hay dos razones por las que lo hice a propósito.
Porque es material de clase. Si el ABI sigue siendo magia, no se puede explicar «por qué son 4 bytes».
src/keccak.jsysrc/abi.jssuman unas 300 líneas, así que los estudiantes pueden leerlas enteras.Porque permite reducir las dependencias a dos. Cuanto menor es la superficie de la cadena de suministro, mayor es la probabilidad de que
npm cisiga funcionando dentro de tres años.
El sha3-256 que hay en crypto de Node es NIST SHA-3 y no se puede reutilizar para el Keccak-256 de Ethereum porque el padding es distinto (0x06 y 0x01). Aquí no queda más remedio que implementarlo.
La cobertura llega a address / uintN / intN / bool / bytesN / string / bytes y sus arrays dinámicos. No se manejan tuplas ni arrays dinámicos anidados. Para un prototipo es suficiente, pero si en producción vas a tratar con contratos arbitrarios, sustitúyelo por viem.
Limitaciones conocidas
Confía en un único RPC. Si se lanzara la misma pregunta a varios endpoints y se contrastaran las respuestas, la capa de confianza subiría un nivel. No está implementado.
No puede manejar tipos tupla. No puede decodificar valores de retorno como
slot0()de Uniswap V3.El rango de exploración de
read_eventses de 200 bloques por defecto. Los endpoints públicos pueden rechazareth_getLogsdemasiado amplios.verify_anchorbusca por coincidencia de subcadenas. Si se conoce el ABI del contrato de anclaje, debería decodificar los argumentos correctamente y contrastarlos.Excepto en la red
local, depende de endpoints públicos. Por si acaso se cae el día de la clase, es seguro hacer un fork local conanvil --fork-url.
Estructura de archivos
src/keccak.js Keccak-256(既知ベクタで固定)
src/abi.js ABI エンコード/デコード
src/rpc.js JSON-RPC クライアント + 読み取り専用ホワイトリスト
src/tools.js ツール 10 個の実体。MCP から独立していて単体で呼べる
src/server.js MCP サーバ(stdio)
test/unit.test.js ネットワーク不要の単体テスト
test/smoke.mjs 実チェーンに対する疎通確認
test/mcp-handshake.mjs MCP プロトコルの往復確認This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Free OpenAI-compatible inference with signed provenance receipts and 3 focused MCP tools.
Read-only MCP server for Robinhood Chain token discovery, research, and due diligence via GMGN.
MCP server for Blockscout
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/nakamura196/chain-reader-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server