Skip to main content
Glama

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

ETH_NETWORK

mainnet / sepolia / holesky / local

ETH_RPC_URL

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

chain_info

Gas und Transaktionsgebühren / PoS

Dass die Grundgebühr mit der Auslastung des Blocks schwankt

account_info

Zwei Arten von Konten / Ethereum-Adressen

Dass sich EOA und Contract daran unterscheiden, ob Code vorhanden ist

read_transaction

Transaktionen mit Etherscan lesen

Gebühr = Gasverbrauch × effektiver Gaspreis

read_block

Blöcke

Dass die parentHash-Kette der eigentliche Kern von „nicht fälschbar" ist

call_contract

ABI / Solidity-Einstieg

Dass der Selektor die ersten 4 Bytes von keccak256(Signatur) ist

read_token

ERC-20 / ERC-721 / Gutscheine

Dass Name und Symbol Selbstauskunft des Contracts sind

read_events

Ereignisgesteuerte UI

Dass nur indexed-Argumente im topic stehen

prepare_unsigned_transaction

Hinweise zur MCP-Nutzung

Die Grenzen dessen, was man ohne Schlüssel tun kann

explain_selector

ABI

Den Selektor berechnen, ohne das Netzwerk zu berühren (für die Tafel)

verify_anchor

(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_tokenself_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_anchorwhat_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.

  1. Es ist der Stoff der Vorlesung. Wenn die ABI eine Blackbox bleibt, kann man nicht erklären, „warum es 4 Bytes sind". src/keccak.js und src/abi.js zusammen sind etwa 300 Zeilen – die Teilnehmer können sie komplett lesen.

  2. Die Abhängigkeiten lassen sich auf zwei begrenzen. Je kleiner die Angriffsfläche der Lieferkette, desto höher die Wahrscheinlichkeit, dass npm ci auch 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_events ist standardmäßig 200 Blöcke. Öffentliche Endpoints lehnen weiträumige eth_getLogs-Aufrufe manchmal ab.

  • verify_anchor sucht 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, mit anvil --fork-url lokal 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 プロトコルの往復確認
-
license - not tested
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

View all MCP Connectors

Latest Blog Posts

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