chain-reader
chain-reader — ein schreibgeschützter Ethereum-MCP-Server
Ein MCP-Server, der es LLMs ermöglicht, Ethereum in natürlicher Sprache zu lesen. Er besitzt keine privaten Schlüssel, signiert nichts und sendet nichts. An jedes Ergebnis ist angehängt, woher die Antwort stammt.
Geschrieben als Lehrprototyp, der die Abbildung aus dem Schlusskapitel „Blockchain und KI" von Tim Weingärtner (HSLU)『Ethereum & Smart Contracts』in eine tatsächlich lauffähige Form bringt.
LLM ← 自然言語(「このアドレスは何者?」)
↓
MCP ← src/server.js
↓ ← コード/構造化言語(ABI エンコード)
RPC ← src/rpc.js
↓
ブロックチェーンDie Abhängigkeiten sind nur zwei: @modelcontextprotocol/sdk und zod.
Auch Keccak-256 und der ABI-Encoder sind selbst geschrieben (dazu später unter „Warum Keccak und ABI selbst geschrieben?").
Ausführen
git clone <this repo> && cd chain-reader-mcp
npm ci --ignore-scripts
npm test # 単体 13 件(ネットワーク不要)
npm run smoke # 実チェーンに対して全ツールを 1 回ずつBei Claude Code registrieren.
claude mcp add chain-reader -- node "$PWD/src/server.js"Wenn man claude in diesem Verzeichnis startet, ist keine Registrierung nötig, da .mcp.json vorhanden ist.
Allerdings wird nur beim ersten Mal eine Genehmigung verlangt (in claude mcp list erscheint ⏸ Pending approval).
Man sollte nicht erst am Tag der Vorlesung in Hektik verfallen, sondern vorher einmal starten und die Genehmigung erteilen.
Bei Claude Desktop schreibt man denselben Inhalt in claude_desktop_config.json unter mcpServers.
In dem Fall muss args ein absoluter Pfad sein.
Über Umgebungsvariablen lässt sich das Zielnetzwerk umschalten. Standard ist mainnet.
Variable | Wert |
|
|
| Eigener Endpunkt (hat Vorrang vor dem Netzwerknamen) |
In allen Fällen werden öffentliche Endpunkte ohne API-Schlüssel verwendet. Bei local wird auf http://127.0.0.1:8545 von anvil / hardhat node zugegriffen.
Entsprechung von Tools und Vorlesung
Die Vorlesungsfolien selbst liegen in einem separaten Repository (private Übersetzung ins Japanische), aber wenn man nur die Abschnittsnamen nennt, lässt sich die Entsprechung nachvollziehen.
Tool | Entsprechende Folien | Was man sieht |
| Gas und Transaktionsgebühren / PoS | Dass die Grundgebühr mit der Auslastung des Blocks schwankt |
| Zwei Arten von Konten / Ethereum-Adressen | Dass sich EOA und Contract daran unterscheiden, ob Code vorhanden ist |
| Transaktionen mit Etherscan lesen | Gebühr = Gasverbrauch × effektiver Gaspreis |
| Blöcke | Dass die |
| ABI / Solidity-Einstieg | Dass der Selektor die ersten 4 Bytes von keccak256(Signatur) ist |
| ERC-20 / ERC-721 / Gutscheine | Dass Name und Symbol Selbstauskunft des Contracts sind |
| Ereignisgesteuerte UI | Dass nur |
| Hinweise zur MCP-Nutzung | Die Grenzen dessen, was man ohne Schlüssel tun kann |
| ABI | Den Selektor berechnen, ohne das Netzwerk zu berühren (für die Tafel) |
| (zur Arbeit) | Was sich durch Hash-Ankern beweisen lässt und was nicht |
Wenn man den lecture_walkthrough-Prompt wählt, werden die Punkte 1–6 der Reihe nach durchgegangen.
このネットワークはいま混んでいますか?
0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 は EOA ですか、コントラクトですか?
USDC の総供給量は? その数字は誰が保証していますか?
transfer(address,uint256) のセレクタはなぜ 0xa9059cbb になるのですか?
私のアドレスから 0.001 ETH を送る取引を組み立ててくださいBei der letzten Frage antwortet die KI mit einem zusammengesetzten JSON, kann es aber nicht senden. Wenn man sie dann erklären lässt, „warum es nicht gesendet werden kann", kommt der Inhalt der Folie „Hinweise zur MCP-Nutzung" aus dem Mund der KI selbst.
Zwei Design-Entscheidungen
1. Keine Schlüssel besitzen
ALLOWED_METHODS in src/rpc.js ist eine explizite Whitelist von schreibgeschützten Methoden.
eth_sendRawTransaction / eth_sendTransaction / eth_sign stehen nicht darin –
der Aufruf scheitert bereits, bevor er das Netzwerk erreicht (durch Unit-Tests abgesichert).
Es gibt weder eine Signatur-Implementierung noch das Laden privater Schlüssel in diesem Repository. Egal wie die KI es anstellt – von hier aus kann kein Geld bewegt werden.
prepare_unsigned_transaction existiert, um diese Grenze nicht als „das geht nicht", sondern als
funktionierendes Beispiel sichtbar zu machen: nonce, Gas-Schätzung und Gebühren sind bereits eingebaut,
und nur die Signatur bleibt dem Menschen überlassen. Das ist genau die Folie
„MCP kann nur zwei Dinge sicher tun: schreibgeschützte Aufrufe und die Weiterleitung signierter Transaktionen" – in Code gegossen.
2. Die Herkunft nicht wegwerfen
An jedem Ergebnis hängt ein _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 エンドポイントの応答であり、独立に検証したものではない。"
}Das ist die Umsetzung des Gedankens: „Nicht bei ‚weil es auf der Blockchain steht' stehen bleiben."
LLMs neigen dazu, Zahlen mit großer Selbstgewissheit auszusprechen – deshalb wird festgehalten, auf welcher Ebene eine Aussage steht.
Auch die instructions des Servers weisen die KI an, sauber zu unterscheiden zwischen dem, was die Chain garantiert, und dem, was jemand behauptet hat.
Zuschreibbarkeit und Verifizierbarkeit sind nicht dasselbe
Dieses Ausgabedesign stammt aus dem Kontext von Recordkeeping und digitalen Archiven. Der Unterschied zwischen „man kann es einer Quelle zuschreiben" und „es ist wahr" wird in die Tool-Ausgaben eingebaut.
read_token → self_reported_note — Dass name() den Wert "USD Coin" zurückgegeben hat, ist eine Tatsache, die die Chain garantiert.
Aber ob der Contract wirklich von Circle stammt, ist damit nicht garantiert.
Jeder kann einen Contract mit demselben Namen und Symbol deployen.
Was die Chain garantiert, ist nur: „Der Code an dieser Adresse hat diese Antwort gegeben." Ob die Behauptung stimmt, ist eine andere Frage.
verify_anchor → what_this_does_not_prove — Ankern liefert: „Wer hat wann welche Behauptung auf die Chain geschrieben?"
Es liefert nicht: „Ist die Behauptung inhaltlich richtig?"
Auch ein falscher Messwert lässt sich genauso hashen und ankern wie ein korrekter.
Das ist dieselbe Unterscheidung wie in der Diplomatik: Authentizität (authenticity) ist nicht dasselbe wie Wahrheit (truth).
_provenance — Die minimale Umsetzung des Gedankens: Die Qualität einer Aufzeichnung ist die Form ihres Herkunftsgraphen.
Welcher Endpoint hat mit welchem RPC-Aufruf in wie vielen Millisekunden geantwortet.
Es wird offen gehalten, wem man später im Sinne von PROV-O ein prov:wasAttributedTo zuweisen möchte.
Wenn man die Ebenen hinaufsteigt – signierte Aussagen / Abgleich mit öffentlichen Informationen / TEE-Attestierung / institutionelle Beglaubigung –, nimmt die Beweiskraft zu. Aber egal wie hoch man steigt: Das „Messgerät selbst" lässt sich nicht verifizieren. Dieser Prototyp demonstriert genau die unterste Ebene — den Bereich, in dem Zuschreibung möglich, Verifikation aber nicht möglich ist. Genau deshalb wird auf der Seite der Aufzeichnung festgehalten, auf welcher Ebene der jeweilige Zahlenwert steht.
Warum Keccak und ABI selbst geschrieben wurden
Mit viem oder ethers wären es drei Zeilen. Es gibt zwei Gründe, warum bewusst darauf verzichtet wurde.
Es ist der Stoff der Vorlesung. Wenn die ABI eine Blackbox bleibt, kann man nicht erklären, „warum es 4 Bytes sind".
src/keccak.jsundsrc/abi.jszusammen sind etwa 300 Zeilen – die Teilnehmer können sie komplett lesen.Die Abhängigkeiten lassen sich auf zwei begrenzen. Je kleiner die Angriffsfläche der Lieferkette, desto höher die Wahrscheinlichkeit, dass
npm ciauch in drei Jahren noch funktioniert.
Das sha3-256 in Nodes crypto ist NIST SHA-3 und unterscheidet sich von Ethereums Keccak-256
in der Padding-Konstante (0x06 statt 0x01), daher kann man es nicht verwenden. Das muss man selbst implementieren.
Abgedeckt sind address / uintN / intN / bool / bytesN / string / bytes sowie deren dynamische Arrays.
Nicht behandelt werden Tupel und verschachtelte dynamische Arrays. Für den Rahmen eines Prototyps ist das ausreichend;
wer in Produktion mit beliebigen Contracts arbeitet, sollte auf viem umsteigen.
Bekannte Grenzen
Es vertraut einem einzelnen RPC. Wenn man dieselbe Anfrage an mehrere Endpoints schickt und abgleicht, steigt die Vertrauensebene um eine Stufe. Das ist nicht implementiert.
Tupeltypen werden nicht unterstützt. Rückgabewerte wie
slot0()von Uniswap V3 lassen sich nicht dekodieren.Der Suchbereich von
read_eventsist standardmäßig 200 Blöcke. Öffentliche Endpoints lehnen weiträumigeeth_getLogs-Aufrufe manchmal ab.verify_anchorsucht per Teilstring-Übereinstimmung. Wenn die ABI des Anker-Contracts bekannt ist, sollte man die Argumente korrekt dekodieren und abgleichen.Außer beim
local-Netzwerk ist man von öffentlichen Endpoints abhängig. Für den Fall, dass sie am Tag der Vorlesung ausfallen, ist es sicherer, mitanvil --fork-urllokal eine Fork anzulegen.
Dateistruktur
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