Haiku DeFi MCP
DeFi execution for AI agents — swap, lend, bridge, and yield across 22 chains.
Open source Open in the app JSON README (API)
About
DeFi execution for AI agents — swap, lend, bridge, and yield across 22 chains.
Details
- Kind
- MCP servers
- Topic
- Finance & crypto
- Publisher
- haiku-trading
- Origin
- official
- Category
- ferramentas
- Transport
- local
- Version
- 0.0.8
- Stars
- 2
- Open pull requests
- 7
- Last push
- 2026-05-09T04:36:19Z
- Repository state
- ativo
- Language
- TypeScript
- License
- MIT
- Added
- 2026-08-29 03:01:56
- Updated
- 2026-08-29 03:01:56
- Origin id
io.github.Haiku-Trading/haiku-mcp-server
README
# Haiku MCP Server
An MCP (Model Context Protocol) server that enables AI agents to execute blockchain transactions via the [Haiku API](https://docs.haiku.trade).
[](https://www.npmjs.com/package/haiku-mcp-server)
[](https://github.com/Haiku-Trading/haiku-mcp-server)
## Features
- **Token Discovery**: List supported tokens and DeFi assets across 21 blockchain networks
- **Balance Checking**: Get wallet balances across all supported chains
- **Trading Quotes**: Get quotes for swaps and portfolio rebalancing
- **Transaction Building**: Convert quotes to unsigned EVM transactions
- **Wallet Integration**: Extract EIP-712 payloads for external wallet signing (Coinbase, AgentKit, Safe, etc.)
- **Self-Contained Execution**: Optional end-to-end execution with WALLET_PRIVATE_KEY env var
- **Yield Discovery**: Find the highest-yielding DeFi opportunities across protocols and chains, filtered by APY, TVL, and category
- **Portfolio Analysis**: Analyze a wallet's holdings and surface context-specific yield opportunities based on what it actually holds
## Installation
```bash
npm install haiku-mcp-server
```
Or run directly with npx:
```bash
npx haiku-mcp-server
```
## Configuration
### Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| `HAIKU_API_KEY` | No | Your Haiku API key for higher rate limits. Contact contact@haiku.trade to request one. |
| `HAIKU_BASE_URL` | No | API base URL. Defaults to `https://api.haiku.trade/v1` |
| `WALLET_PRIVATE_KEY` | No | Private key (0x hex) for self-contained execution via `haiku_execute`. |
| `RPC_URL_{chainId}` | No | Override RPC URL for a specific chain (e.g., `RPC_URL_42161` for Arbitrum). |
> **Note:** The API works without a key, but providing one unlocks higher rate limits for production use.
### Claude Desktop Configuration
Add to your `claude_desktop_config.json`:
```json
{
"mcpServers": {
"haiku": {
"command": "npx",
"args": ["haiku-mcp-server"]
}
}
}
```
With API key for higher rate limits:
```json
{
"mcpServers": {
"haiku": {
"command": "npx",
"args": ["haiku-mcp-server"],
"env": {
"HAIKU_API_KEY": "your-api-key-here"
}
}
}
}
```
## Available Tools
### `haiku_get_tokens`
Get supported tokens and DeFi assets for trading.
**Parameters:**
- `network` (optional): Filter by chain ID (e.g., 42161 for Arbitrum)
- `category` (optional): Filter by token category:
- `token` - Vanilla tokens (ETH, USDC, etc.)
- `collateral` - eg. Aave aTokens (deposited collateral)
- `varDebt` - eg. Aave variable debt tokens
- `vault` - eg. Yearn/Morpho yield vaults
- `weightedLiquidity` - eg. Balancer LP tokens
- `concentratedLiquidity` - eg. Uniswap V3 LP positions
**Example:**
```json
{
"network": 42161,
"category": "token"
}
```
### `haiku_get_balances`
Get token balances for a wallet address across all chains.
**Parameters:**
- `walletAddress` (optional): Wallet address or ENS name. Required when `WALLET_PRIVATE_KEY` is not set; omit to auto-derive from `WALLET_PRIVATE_KEY` when it is set.
**Example:**
```json
{
"walletAddress": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
}
```
Omit `walletAddress` when `WALLET_PRIVATE_KEY` is set to use the derived address.
### `haiku_get_quote`
Get a quote for a token swap or portfolio rebalance.
> **Note:** Quotes are valid for 5 minutes, but execute as quickly as possible after quoting — the longer you wait, the more likely prices have moved and the transaction will fail on-chain.
**Parameters:**
- `inputPositions` (required): Map of token IID to amount to spend
- `targetWeights` (required): Map of output token IID to weight (must sum to 1)
- `slippage` (optional): Max slippage as decimal (default: 0.003)
- `receiver`: Receiving wallet address. **Required when `WALLET_PRIVATE_KEY` is not set** — must be provided explicitly. When `WALLET_PRIVATE_KEY` is set, auto-derived if omitted. When `WALLET_PRIVATE_KEY` is not set (Path B), you must pass `receiver` explicitly.
**Example:**
```json
{
"inputPositions": {
"arb:0x82aF49447D8a07e3bd95BD0d56f35241523fBab1": "1.0"
},
"targetWeights": {
"arb:0xaf88d065e77c8cC2239327C5EDb3A432268e5831": 0.5,
"arb:0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9": 0.5
},
"slippage": 0.005
}
```
Example above omits `receiver` (valid when `WALLET_PRIVATE_KEY` is set). For Path B, include `"receiver": "0x..."`.
### `haiku_prepare_signatures`
Extract and normalize EIP-712 signing payloads from a quote for external wallet signing (Path B only). When using `quoteId`, the quote must have been obtained in the same session.
Use this when a wallet MCP handles signing (Coinbase Payments MCP, wallet-agent, AgentKit, Safe, etc.). Returns standardized typed data that any wallet's `signTypedData` can consume, plus step-by-step instructions.
**Parameters:**
- `quoteId` (preferred): Quote ID from `haiku_get_quote` — server resolves the full quote from session cache. QuoteId only works when the quote was returned by `haiku_get_quote` in the same MCP session; otherwise use `quoteResponse`.
- `quoteResponse` (fallback): Full response object from `haiku_get_quote`, if quoteId is unavailable
**Returns:**
- `requiresPermit2`: Whether Permit2 signature is needed
- `permit2`: EIP-712 payload to pass to `signTypedData` (if required)
- `requiresBridgeSignature`: Whether bridge signature is needed
- `bridgeIntent`: EIP-712 payload to pass to `signTypedData` (if required)
- `sourceChainId`: Chain ID for the transaction
- `instructions`: Step-by-step instructions for completing the flow
**Example:**
```json
{
"quoteId": "abc123..."
}
```
### `haiku_discover_yields`
Discover yield-bearing opportunities across DeFi protocols, ranked by APY or TVL.
Use this to answer questions like "best lending yields on Arbitrum", "highest APY vaults
with at least $1M TVL", or "what can I do with USDC on Base". The `iid` field in results
can be used directly as a key in the `targetWeights` object in `haiku_get_quote`.
**Parameters:**
- `network` (optional): Filter by chain ID (e.g., 42161 for Arbitrum)
- `category` (optional): `lending` (Aave collateral), `vault` (Yearn/Morpho), `lp` (Balancer/Uniswap), `all` (default)
- `minApy` (optional): Minimum APY as a percentage (e.g., `5` means ≥5% APY)
- `minTvl` (optional): Minimum TVL in USD (e.g., `1000000` means ≥$1M). Filters to established mainstream vaults.
- `sortBy` (optional): `apy` (default) or `tvl`, descending
- `limit` (optional): Max results (default 20)
**Example:**
```json
{
"network": 42161,
"category": "lending",
"minTvl": 1000000,
"sortBy": "apy",
"limit": 10
}
```
### `haiku_analyze_portfolio`
Analyze a wallet's DeFi portfolio and surface relevant yield opportunities.
Returns current positions enriched with available APY options, collateral health factors,
and context-specific opportunities based on what the wallet actually holds. Pair with
`haiku_discover_yields` for broader market context, then use `haiku_get_quote` to execute.
**Parameters:**
- `walletAddress` (required): Wallet address (0x...) to analyze
**Example:**
```json
{
"walletAddress": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
}
```
### `haiku_execute`
Execute a quote. Two distinct paths depending on who holds the private key.
**Path A — Self-contained** (`WALLET_PRIVATE_KEY` set in env): Haiku signs Permit2/bridge payloads internally and broadcasts. Returns a tx hash.
**Parameters:**
- `quoteId` (required): Quote ID from `haiku_get_quote`
- `sourceChainId` (recommended): Chain ID from the quote response. Omit only if the quote was obtained in the same session — the server can recover from cache.
- `permit2SigningPayload` (optional): Pass through from `haiku_get_quote` if present
- `bridgeSigningPayload` (optional): Pass through from `haiku_get_quote` if present (cross-chain only)
- `approvals` (optional): Pass through from `haiku_get_quote` if present
**Example:**
```json
{
"quoteId": "abc123...",
"sourceChainId": 42161,
"permit2SigningPayload": { /* from haiku_get_quote, if present */ },
"approvals": [ /* from haiku_get_quote, if present */ ]
}
```
---
**Path B — External wallet** (no `WALLET_PRIVATE_KEY`, using a wallet MCP): You sign and broadcast. `broadcast: false` is **required** — without `WALLET_PRIVATE_KEY`, haiku cannot sign or send the final EVM transaction. If you call `haiku_execute` with `broadcast: true` and no `WALLET_PRIVATE_KEY`, the server returns an error directing you to set `broadcast: false` and broadcast the returned transaction via your wallet MCP.
Before calling `haiku_execute`:
1. If `approvals` is non-empty in the quote: broadcast each approval as a transaction `{ to, data, value }` (include `value` when present, e.g. for native token) via your wallet MCP and wait for confirmation.
2. If signatures are required: call `haiku_prepare_signatures` with the quoteId, sign the returned EIP-712 payloads via your wallet MCP, then pass the signatures here.
**Parameters:**
- `quoteId` (required): Quote ID from `haiku_get_quote`
- `sourceChainId` (recommended): Chain ID from the quote response. Omit only if the quote was obtained in the same session — the server can recover from cache.
- `broadcast` (required): Must be `false` — haiku returns the unsigned tx for you to broadcast
- `permit2Signature` (optional): Signature from signing the Permit2 payload via your wallet MCP
- `userSignature` (optional): Signature from signing the bridge payload via your wallet MCP (cross-chain only)
**Example:**
```json
{
"quoteId": "abc123...",
"sourceChainId": 42161,
"broadcast": false,
"permit2Signature": "0x..."
}
```
Returns `{ transaction: { to, data, value, chainId } }` — pass `transaction` to your wallet MCP's `sendTransaction`.
## Token IID Format
Tokens are identified using the IID format: `chainSlug:tokenAddress`
Examples:
- `arb:0x82aF49447D8a07e3bd95BD0d56f35241523fBab1` - WETH on Arbitrum
- `arb:0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee` - Native ETH on Arbitrum
- `base:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` - USDC on Base
## Supported Chains
| Chain | Chain ID | Slug |
|-------|----------|------|
| Arbitrum | 42161 | arb |
| Avalanche | 43114 | avax |
| Base | 8453 | base |
| Berachain | 80094 | bera |
| BNB Smart Chain | 56 | bsc |
| Bob | 60808 | bob |
| Ethereum | 1 | eth |
| Gnosis | 100 | gnosis |
| Hyperliquid | 999 | hype |
| Katana | 747474 | katana |
| Lisk | 1135 | lisk |
| MegaETH | 4326 | megaeth |
| Monad | 143 | monad |
| Optimism | 10 | opt |
| Plasma | 9745 | plasma |
| Polygon | 137 | poly |
| Scroll | 534352 | scroll |
| Sei | 1329 | sei |
| Sonic | 146 | sonic |
| Unichain | 130 | uni |
| World Chain | 480 | worldchain |
| ApeChain | 33139 | ape |
## Workflow Examples
### Path A: Self-Contained Swap (WALLET_PRIVATE_KEY set)
Haiku handles all signing and broadcasting. Returns a tx hash.
```
1. haiku_get_quote(inputPositions, targetWeights) → returns quoteId, sourceChainId, permit2SigningPayload?, bridgeSigningPayload?, approvals
2. haiku_execute(quoteId, sourceChainId, permit2SigningPayload?, bridgeSigningPayload?, approvals)
→ Haiku broadcasts approvals, signs Permit2/bridge internally, broadcasts swap, returns tx hash
```
### Path B: External Wallet (wallet MCP handles signing + broadcasting)
Use when WALLET_PRIVATE_KEY is not set and a separate wallet MCP holds the keys.
**Simple swap (no Permit2 or bridge signatures needed, e.g. native ETH input):**
```
1. haiku_get_quote(inputPositions, targetWeights, receiver) → returns quoteId, sourceChainId, approvals
2. For each item in approvals: broadcast as transaction { to, data, value } (include value when present) via wallet MCP and wait for confirmation
3. haiku_execute(quoteId, sourceChainId, broadcast: false)
→ returns { transaction: { to, data, value, chainId } }
4. Broadcast transaction via wallet MCP
```
**With Permit2 or bridge signatures (e.g. ERC-20 input or cross-chain swap):**
```
1. haiku_get_quote(inputPositions, targetWeights, receiver) → returns quoteId, sourceChainId, approvals, permit2SigningPayload?, bridgeSigningPayload?
2. For each item in approvals: broadcast as transaction { to, data, value } (include value when present) via wallet MCP and wait for confirmation
3. haiku_prepare_signatures(quoteId) → returns normalized EIP-712 payloads + step-by-step instructions
4. Sign payloads via wallet MCP (e.g. coinbase_sign_typed_data) → get permit2Signature?, userSignature?
5. haiku_execute(quoteId, sourceChainId, permit2Signature?, userSignature?, broadcast: false)
→ returns { transaction: { to, data, value, chainId } }
6. Broadcast transaction via wallet MCP (e.g. coinbase_send_transaction)
```
### Yield Discovery
```
1. haiku_discover_yields with category/network/minTvl filters → find opportunities, note iid
2. haiku_get_quote with the chosen iid as a key in targetWeights
3. Execute via Path A or Path B above
```
### Portfolio Analysis & Optimization
```
1. haiku_analyze_portfolio with wallet address → review positions and opportunities
2. Optionally haiku_discover_yields for broader market context
3. haiku_get_quote to rebalance into higher-yielding positions
4. Execute via Path A or Path B above
```
## Transaction Signing
Two modes depending on your setup:
**Self-contained** (`WALLET_PRIVATE_KEY` set): `haiku_execute` signs everything internally and broadcasts. Returns a tx hash. No external signing needed.
**External wallet** (no `WALLET_PRIVATE_KEY`): Use `haiku_execute` with `broadcast: false` (required — haiku cannot sign or broadcast without the private key). If you call `haiku_execute` with `broadcast: true` and no `WALLET_PRIVATE_KEY`, the server returns an error directing you to set `broadcast: false` and broadcast the returned transaction via your wallet MCP. Returns `{ transaction: { to, data, value, chainId } }` for your wallet MCP to broadcast. If Permit2 or bridge signatures are required, call `haiku_prepare_signatures` first. If approvals are present in the quote, broadcast each approval `{ to, data, value }` (include `value` when present, e.g. for native token) via your wallet MCP before calling `haiku_execute`.
The external wallet design allows agents to use any signing infrastructure (wallet MCPs, hardware wallets, custodial services, MPC, etc.).
## Cross-Chain Bridge Signatures
For cross-chain swaps, the quote may return `isComplexBridge: true`, indicating a bridge intent signature is required in addition to (or instead of) Permit2.
**Self-contained (Path A):** Pass `bridgeSigningPayload` from the quote to `haiku_execute` — it handles the bridge signature internally.
**External wallet (Path B):** Call `haiku_prepare_signatures` with the quoteId — it returns a normalized `bridgeIntent` EIP-712 payload. Sign it via your wallet MCP and pass the result as `userSignature` to `haiku_execute`.
## Transport Modes
### Stdio (default)
Standard MCP stdio transport — used by Claude Desktop, Cursor, etc.
```bash
npx haiku-mcp-server
```
### Streamable HTTP
HTTP transport for remote hosting, Smithery, and web-based MCP clients.
```bash
npx haiku-mcp-server --http
npx haiku-mcp-server --http --port=8080
```
Endpoints:
- `POST /mcp` — MCP Streamable HTTP endpoint
- `GET /health` — Health check
## Development
```bash
# Install dependencies
npm install
# Build
npm run build
# Run locally (stdio, works without API key)
npm start
# Run locally (HTTP)
npm run start:http
# Run with API key for higher rate limits
HAIKU_API_KEY=your-key npm start
```
## License
MIT