Click on "Install 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., "@Lido MCP Servercheck my stETH balance and current staking APR"
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.
Lido MCP Server
The reference MCP server for Lido — making stETH staking, position management, and governance natively callable by any AI agent.
Point Claude, Cursor, or any MCP-compatible agent at this server and stake ETH from a conversation. No custom integration code needed.
Why This Exists
AI agents need to interact with DeFi protocols, but bridging the gap between natural language and on-chain transactions is hard. You need to handle private keys, gas estimation, protocol-specific quirks (like stETH rebasing), and transaction safety — all without the agent making a costly mistake.
This MCP server solves that by giving agents a structured, safe interface to the Lido protocol:
Every write operation supports dry-run simulation — agents always preview gas costs and verify transactions before executing
A mental model document (
lido.skill.md) teaches agents Lido-specific concepts before they act — rebasing mechanics, wstETH vs stETH tradeoffs, safe staking patternsPosition monitoring with bounds — agents can autonomously manage staking positions within human-set parameters
Guided workflows via MCP prompts — pre-built multi-step workflows for staking, withdrawing, and governance review
What's Included
Category | Tool | Description |
Query |
| ETH, stETH, wstETH balances for any address |
| Current APR + N-day SMA | |
| Historical staking rewards with configurable lookback | |
| Stake limits, queue mode, withdrawal bounds | |
| stETH ↔ wstETH rate conversion | |
| All withdrawal NFTs and their status | |
| Total ETH available to claim | |
| Dual governance state, config, veto signalling, warning status | |
Intelligence |
| Position analysis with bounds checking and recommendations |
| Predict withdrawal finalization time from queue depth and mode | |
| Share rate, pool composition, DEX discount detection | |
| Gas price tiers, operation costs, break-even analysis | |
Stake |
| Stake ETH → stETH (with dry_run) |
Wrap |
| Wrap stETH → wstETH (with dry_run) |
| Stake + wrap in one tx (with dry_run) | |
| Unwrap wstETH → stETH (with dry_run) | |
Withdraw |
| Request withdrawal with auto-splitting (with dry_run) |
| Claim finalized withdrawals (with dry_run) | |
Governance |
| Query Aragon DAO votes — recent list or specific vote details |
| Cast vote on DAO proposal (with dry_run) | |
| Lock stETH in veto signalling escrow (with dry_run) | |
| Unlock stETH from governance escrow (with dry_run) | |
L2 wstETH |
| wstETH + ETH balances on Base, Optimism, or Arbitrum |
| Transfer wstETH on L2 (with dry_run) | |
| L2 wstETH contract info + total bridged supply | |
L2 stETH |
| Rebasing stETH + ETH balances on Optimism |
(Optimism only) |
| Transfer rebasing stETH on Optimism (with dry_run) |
4 Prompts (Guided Workflows)
Prompt | What It Does |
| Walks through protocol check → balance check → APR review → dry run → execution |
| Comprehensive position analysis with monitoring bounds setup |
| Full withdrawal lifecycle: request → monitor → claim |
| Governance state analysis with plain-language interpretation |
3 Resources (Live Data)
Resource URI | Description |
| JSON snapshot of a staking position |
| Protocol status: limits, queue mode, APR |
| Governance state, veto signalling, escrow |
Agent Mental Model (lido.skill.md)
A structured document that teaches AI agents Lido-specific knowledge:
stETH rebasing mechanics and the shares model
wstETH vs stETH tradeoffs and when to use each
Safe staking patterns (always dry-run first)
Withdrawal lifecycle (request → wait → claim)
Dual governance states and what they mean for stakers
Common mistakes to avoid (dust amounts, exact comparisons, forgetting claims)
Setup
Prerequisites
Node.js 18+
An Ethereum RPC URL (Alchemy, Infura, etc.)
A private key for the wallet that will execute transactions
Install
git clone <repo-url>
cd lido-mcp-server
npm installConfigure
cp .env.example .envEdit .env:
LIDO_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY
LIDO_PRIVATE_KEY=0xYOUR_PRIVATE_KEY
LIDO_CHAIN_ID=1L1 (full Lido SDK — staking, wrapping, governance):
LIDO_CHAIN_ID=1for Ethereum mainnetLIDO_CHAIN_ID=17000for Holesky testnetLIDO_CHAIN_ID=560048for Hoodi testnet (recommended for testing)
L2 (wstETH balance queries + transfers):
LIDO_CHAIN_ID=8453for BaseLIDO_CHAIN_ID=10for Optimism (also supports rebasing stETH)LIDO_CHAIN_ID=42161for Arbitrum
Build & Run
npm run build
npm startConnect to Claude / Cursor
Add to your MCP configuration:
{
"mcpServers": {
"lido": {
"command": "node",
"args": ["/path/to/lido-mcp-server/dist/index.js"],
"env": {
"LIDO_RPC_URL": "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY",
"LIDO_PRIVATE_KEY": "0xYOUR_PRIVATE_KEY",
"LIDO_CHAIN_ID": "1"
}
}
}
}Target Use Cases
1. Developer stakes ETH via Claude — zero integration code
User: "Stake 1 ETH with Lido"
Claude: Let me walk you through this safely.
→ Checks protocol status (not paused, limits ok)
→ Checks your balance (1.5 ETH available)
→ Shows current APR (3.4%, 7-day SMA 3.3%)
→ Dry-runs the transaction (gas: 0.002 ETH)
→ "Ready to stake 1 ETH. Gas cost ~0.002 ETH. Confirm?"
User: "Yes"
Claude: → Executes stake
→ "Done. TX: 0xabc... You received 1.0 stETH."2. Agent monitors and manages position within bounds
User: "Monitor my Lido position. Alert me if APR drops below 3%
or my staked amount exceeds 100 ETH."
Claude: → Calls lido_analyze_position with min_apr=3.0, max_position_eth=100
→ "Position: 85.2 ETH staked, APR 3.4%. All within bounds."
[Later, APR drops]
Claude: → Calls lido_analyze_position again
→ "⚠ APR is 2.8% — below your minimum of 3.0%.
7-day SMA is 3.1%, suggesting this may be temporary.
Recommend: wait 24h and re-check before withdrawing."3. DAO contributor queries and votes on governance proposals
User: "Show me the latest Lido DAO votes"
Claude: → Calls lido_get_aragon_vote
→ "5 most recent votes:
Vote #185: Open — Yea 15.2M LDO (92%), Nay 1.3M LDO (8%)
Vote #184: Executed — passed with 98% support
..."
User: "Vote yes on #185"
Claude: → Calls lido_vote_on_proposal (dry_run=true)
→ "Dry run: Vote Yea on #185. You have 5,000 LDO. Gas: ~0.001 ETH. Confirm?"
User: "Yes"
Claude: → Calls lido_vote_on_proposal (dry_run=false)
→ "Done. Voted Yea on #185. TX: 0xabc..."4. Staker signals opposition via Dual Governance
User: "I want to signal opposition to the latest proposal."
Claude: → Calls lido_get_governance_state
→ "Governance is in Normal state. Veto signalling is at 0.12%,
well below the first seal threshold of 1%."
→ Dry-runs lock of 10 stETH in escrow
→ "Ready to lock 10 stETH for governance. Gas: ~0.003 ETH. Confirm?"
User: "Yes"
Claude: → Approves stETH for escrow + locks
→ "Done. 10 stETH locked in veto signalling escrow. TX: 0xdef..."5. L2 wstETH management on Base
User: "Check my wstETH balance on Base"
Claude: → Calls lido_l2_get_wsteth_balance
→ "Balances on Base:
ETH: 0.5
wstETH: 10.0
Note: wstETH on L2 is a bridged token whose value tracks the L1 rate."Architecture
src/
├── index.ts MCP server entry — registers tools, prompts, resources
├── config.ts Environment validation (RPC, private key, chain)
├── sdk-factory.ts Viem clients + Lido SDK initialization
├── types.ts Shared TypeScript types
├── prompts.ts MCP prompt definitions (guided workflows)
├── resources.ts MCP resource definitions (live data endpoints)
├── tools/
│ ├── index.ts Tool router (registration + dispatch)
│ ├── apr.ts Staking APR queries
│ ├── balances.ts ETH/stETH/wstETH balance queries
│ ├── convert.ts Token amount conversion
│ ├── gas.ts Gas price analysis + break-even calculator
│ ├── governance.ts Dual governance state + config + warnings
│ ├── aragon-voting.ts Query & vote on Aragon DAO proposals
│ ├── governance-actions.ts Lock/unlock stETH in veto signalling escrow
│ ├── position.ts Position analysis with bounds checking
│ ├── protocol-status.ts Stake limits, queue status
│ ├── steth-rate.ts Share rate + pool composition monitor
│ ├── rewards.ts Historical staking rewards
│ ├── stake.ts Stake ETH → stETH
│ ├── withdraw.ts Request & claim withdrawals
│ ├── withdrawal-status.ts Check withdrawal request status
│ ├── withdrawal-time.ts Withdrawal finalization time estimator
│ ├── wrap.ts Wrap/unwrap stETH ↔ wstETH
│ ├── l2-wsteth.ts L2 wstETH balance, transfer, info (Base/Optimism/Arbitrum)
│ └── l2-steth.ts L2 rebasing stETH balance + transfer (Optimism only)
└── utils/
├── dry-run.ts Transaction simulation engine
├── errors.ts Protocol-aware error translation
├── format.ts Formatting utilities + Zod schemas
├── governance-labels.ts Shared governance state labels
└── security.ts Receiver allowlist + amount cap validationKey design decisions:
Real SDK, no mocks — all operations go through
@lidofinance/lido-ethereum-sdkandviemto actual Ethereum contractsDry-run by default — every state-changing tool defaults to
dry_run: true(simulation only). Agents must explicitly setdry_run: falseto execute real transactionsProtocol-aware errors — raw blockchain errors (insufficient funds, reverts, nonce conflicts, stake limits, paused) are translated to human-readable messages
Zod validation — all tool inputs are validated before any SDK call
MCP annotations — every tool declares
readOnlyHint,destructiveHint,idempotentHint, andopenWorldHintso agents know which tools are safe to call without confirmationParallel queries — tools that need multiple data points use
Promise.allfor performanceL2 aware — set
LIDO_CHAIN_IDto Base (8453), Optimism (10), or Arbitrum (42161) and the server exposes wstETH-specific tools. On Optimism, rebasing stETH tools are also available. L1-only tools (staking, governance) are excluded automatically
License
MIT
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.