Lido MCP Server
Enables AI agents to interact with the Lido protocol for ETH staking, position management, and governance participation across Ethereum and L2 networks. It provides tools for querying balances, simulating transactions, and executing complex workflows like withdrawals and DAO voting through a safety-first interface.
README
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 patterns - Position 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 | lido_get_balances |
ETH, stETH, wstETH balances for any address |
lido_get_staking_apr |
Current APR + N-day SMA | |
lido_get_rewards |
Historical staking rewards with configurable lookback | |
lido_get_protocol_status |
Stake limits, queue mode, withdrawal bounds | |
lido_convert_amounts |
stETH ↔ wstETH rate conversion | |
lido_get_withdrawal_requests |
All withdrawal NFTs and their status | |
lido_get_claimable_eth |
Total ETH available to claim | |
| Intelligence | lido_analyze_position |
Position analysis with bounds checking and recommendations |
lido_estimate_withdrawal_time |
Predict withdrawal finalization time from queue depth and mode | |
lido_check_steth_rate |
Share rate, pool composition, DEX discount detection | |
lido_check_gas_conditions |
Gas price tiers, operation costs, break-even analysis | |
lido_get_swap_quote |
Price quote for ETH → LDO swap via Uniswap V3 | |
| Stake | lido_stake_eth |
Stake ETH → stETH (with dry_run) |
| Wrap | lido_wrap_steth_to_wsteth |
Wrap stETH → wstETH (with dry_run) |
lido_wrap_eth_to_wsteth |
Stake + wrap in one tx (with dry_run) | |
lido_unwrap_wsteth_to_steth |
Unwrap wstETH → stETH (with dry_run) | |
| Withdraw | lido_request_withdrawal |
Request withdrawal with auto-splitting (with dry_run) |
lido_claim_withdrawal |
Claim finalized withdrawals (with dry_run) | |
| Swap | lido_swap_eth_for_ldo |
Swap ETH for LDO tokens via Uniswap V3 (with dry_run) |
| Governance | ||
| Dual Governance | lido_get_governance_state |
Dual governance state, config, veto signalling, warning status |
lido_lock_steth_governance |
Lock stETH in veto signalling escrow (with dry_run) | |
lido_unlock_steth_governance |
Unlock stETH from governance escrow (with dry_run) | |
lido_get_voting_power |
Cross-system governance power: LDO, stETH, escrow balances | |
lido_estimate_veto_impact |
Estimate impact of locking stETH in veto escrow | |
lido_get_veto_thresholds |
Veto threshold config: first/second seal, current level | |
lido_get_governance_timeline |
Unified timeline across all governance systems | |
lido_get_governance_position_impact |
Analyze how governance state affects a staking position | |
| Aragon DAO | lido_get_aragon_vote |
Query Aragon DAO votes — recent list or specific vote details |
lido_vote_on_proposal |
Cast vote on DAO proposal (with dry_run) | |
lido_analyze_aragon_vote |
Deep analysis: quorum, phase, pass/fail projection, top voters | |
lido_get_aragon_vote_script |
Decode EVM script into human-readable actions | |
lido_get_aragon_vote_timeline |
Vote timeline: phases, time remaining, projections | |
| Snapshot | lido_get_snapshot_proposals |
List governance proposals from Lido Snapshot space |
lido_get_snapshot_proposal |
Full details of a specific Snapshot proposal | |
lido_vote_on_snapshot |
Cast vote on Snapshot proposal via EIP-712 (with dry_run) | |
| Easy Track | lido_get_easytrack_motions |
List Easy Track motions with optional status filter |
lido_get_easytrack_motion |
Detailed view of a specific Easy Track motion | |
lido_get_easytrack_config |
Easy Track system config: thresholds, duration, factories | |
lido_get_easytrack_factories |
List registered EVM script factories with descriptions | |
lido_object_easytrack_motion |
Object to an active Easy Track motion (with dry_run) | |
| stVaults V3 | lido_list_vaults |
List staking vaults with connection status and value |
lido_get_vault |
Full vault details: owner, operator, health, locked ETH | |
lido_get_vault_hub_stats |
VaultHub overview: total vault count, addresses | |
lido_vault_fund |
Deposit ETH into a staking vault (with dry_run) | |
lido_vault_withdraw |
Withdraw ETH from a staking vault (with dry_run) | |
lido_vault_pause_beacon_deposits |
Pause beacon chain deposits for a vault (with dry_run) | |
lido_vault_resume_beacon_deposits |
Resume beacon chain deposits for a vault (with dry_run) | |
lido_vault_mint_shares |
Mint stETH shares against vault collateral (with dry_run) | |
lido_vault_burn_shares |
Burn stETH shares to reduce vault liability (with dry_run) | |
lido_vault_rebalance |
Rebalance vault to restore health (with dry_run) | |
lido_vault_create |
Create a new staking vault via VaultFactory (with dry_run) | |
lido_vault_request_validator_exit |
Request validator exit from a vault (with dry_run) | |
| Protocol Info | lido_get_protocol_info |
TVL, fee structure, total shares, buffered ETH, APR |
lido_get_staking_modules |
List all staking router modules with IDs and status | |
lido_get_node_operators |
List curated module node operators with validator counts | |
lido_get_contract_addresses |
All Lido contract addresses for the current chain | |
| Token Management | lido_get_token_info |
stETH/wstETH/LDO metadata: name, symbol, supply |
lido_get_allowance |
Check token allowance for a spender address | |
lido_approve_token |
Approve stETH/wstETH/LDO for a spender (with dry_run) | |
lido_transfer_token |
Transfer stETH/wstETH/LDO to an address (with dry_run) | |
lido_revoke_approval |
Revoke a previous token approval (with dry_run) | |
| Withdrawal NFTs | lido_get_withdrawal_nft_owner |
Check owner of a withdrawal request NFT |
lido_transfer_withdrawal_nft |
Transfer a withdrawal NFT (with dry_run) | |
lido_approve_withdrawal_nft |
Approve address to transfer a withdrawal NFT (with dry_run) | |
| L2 wstETH | lido_l2_get_wsteth_balance |
wstETH + ETH balances on Base, Optimism, or Arbitrum |
lido_l2_transfer_wsteth |
Transfer wstETH on L2 (with dry_run) | |
lido_l2_get_wsteth_info |
L2 wstETH contract info + total bridged supply | |
lido_get_all_l2_balances |
Cross-chain wstETH balances across 11 L2s | |
| L2 stETH | lido_l2_get_steth_balance |
Rebasing stETH + ETH balances on Optimism |
| (Optimism only) | lido_l2_transfer_steth |
Transfer rebasing stETH on Optimism (with dry_run) |
6 Prompts (Guided Workflows)
| Prompt | What It Does |
|---|---|
stake-eth-safely |
Walks through protocol check → balance check → APR review → dry run → execution |
manage-position |
Comprehensive position analysis with monitoring bounds setup |
withdraw-steth |
Full withdrawal lifecycle: request → monitor → claim |
review-governance |
Governance state analysis with plain-language interpretation |
manage-vault |
stVaults V3 management: list → inspect → fund/withdraw → verify |
participate-governance |
Cross-system governance participation: check power, review proposals, vote |
4 Resources (Live Data)
| Resource URI | Description |
|---|---|
lido://position/{address} |
JSON snapshot of a staking position |
lido://protocol/status |
Protocol status: limits, queue mode, APR |
lido://governance/state |
Governance state, veto signalling, escrow |
lido://governance/votes |
Active governance items: Snapshot proposals, Easy Track motions |
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 install
Configure
cp .env.example .env
Edit .env:
LIDO_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY
LIDO_PRIVATE_KEY=0xYOUR_PRIVATE_KEY
LIDO_CHAIN_ID=1
L1 (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 start
Connect to Claude / Cursor
Add to your MCP configuration:
{
"mcpServers": {
"lido": {
"command": "bash",
"args": ["/path/to/lido-mcp-server/start.sh"],
"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, analyze Aragon DAO proposals
│ ├── governance-actions.ts Lock/unlock stETH in veto signalling escrow
│ ├── governance-analysis.ts Veto impact, thresholds, timeline, position impact
│ ├── snapshot.ts Snapshot proposal queries + voting
│ ├── easytrack.ts Easy Track motions, config, factories, objections
│ ├── swap.ts ETH → LDO swap quotes + execution via Uniswap V3
│ ├── 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 + NFT operations
│ ├── withdrawal-time.ts Withdrawal finalization time estimator
│ ├── wrap.ts Wrap/unwrap stETH ↔ wstETH
│ ├── stvaults.ts stVaults V3: list, inspect, fund, withdraw, pause/resume, create, exit
│ ├── protocol-info.ts Protocol TVL, staking modules, node operators, addresses
│ ├── tokens.ts Token management: info, allowances, approve, transfer, revoke
│ ├── l2-wsteth.ts L2 wstETH balance, transfer, info + cross-chain queries
│ └── 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 validation
├── vaulthub-abi.ts VaultHub + StakingVault ABIs and addresses
└── easytrack-abi.ts Easy Track contract ABIs and addresses
Key design decisions:
- Real SDK, no mocks — all operations go through
@lidofinance/lido-ethereum-sdkandviemto actual Ethereum contracts - Dry-run by default — every state-changing tool defaults to
dry_run: true(simulation only). Agents must explicitly setdry_run: falseto execute real transactions - Protocol-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 confirmation - Parallel queries — tools that need multiple data points use
Promise.allfor performance - L2 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
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.