Leveraged-yield router on Morpho. List strategies, simulate, and build UNSIGNED txs.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
mcp read-data backbone (Step 1a)The composition authority + read API for Spiral Stake strategy data. It ports the app's client-side data composition server-side and serves it back as JSON, so three consumers run off one core:
/strategies contract.Read-only. No contract writes, no tx building, no signing, no private keys. It composes
numbers and serves JSON. The MCP tool layer, execution/build_*, and partner auth are later
steps β the seams are pre-cut (core + http) but not built.
Data flow: warmer fetches upstreams on the CONTRACT cadence β writes raw to the cache
(last-good on failure) β core composes strategies from warm raw only β http serves them.
A stale/failed upstream serves last-good with a visible stale age per field-group β never
dropped, never coerced to 0.
/health (liveness + cache diagnostics) and /ready (503 until the warmer primes the required
data) are available immediately on boot.
Every data read the app performs in v2-client/src/api-services/* maps to an endpoint here
(positions stay on the dashboard backend and are not reimplemented):
App read (api-services/*) | mcp endpoint |
|---|---|
getTokenApy, getAllMorphoMarketsData, fetchMerklSpotIncentives, prices, on-chain value β composed markets | GET /v1/strategies, GET /v1/strategies/:id |
FlashLeverage.createInstance β the app's full client-side Market[] composition | GET /v1/app/markets (raw domain model; BigNumberβ{"$bn":β¦}, bigintβ{"$bigint":β¦} β revive before use) |
morpho.ts getAllBorrowApyHistories / getBorrowApyHistory | GET /v1/markets/borrow-apy-history, GET /v1/markets/:id/borrow-apy-history |
apy.ts resolveTokenApyHistory (DeFiLlama/Royco/StableWatch history), chart.ts getApyChart | GET /v1/collateral/apy-history, GET /v1/collateral/:id/apy-history |
merkl.ts fetchMerklIncentiveData (borrow-incentive APR history) | GET /v1/markets/:id/incentive-history |
token.ts getAllLoanTokenPrices / getTokenPrice | GET /v1/prices |
chart.ts getMarketChart (CoinGecko price chart) | GET /v1/prices/chart?coinId=&days=¤cy= (on-demand proxy) |
dashboard.ts getApySnapshot (StableWatch stable APY) | GET /v1/stable-apy β fetched directly from StableWatch as a warmed upstream; the mcp owns this data now and no longer depends on the dashboard /apy endpoint |
| swap/meta-dex aggregators, referral, positions | out of scope (execution / backend domains) |
Cross-cutting: /v1 versioning, CORS limited to CORS_ORIGINS, a consistent error envelope
({ error: { code, message, correlationId } }), a correlation id per request (echoed as
x-correlation-id), structured JSON logs, and an OpenAPI 3.1 spec at /openapi.json (+ committed
openapi.json).
leverage.ts golden-vector β test/golden/leverage.golden.test.ts freezes fixed inputs β
exact outputs; leverage.parity.test.ts asserts the file is a byte-for-byte copy of the
app's leverage.ts. This locks every APY/LTV/ladder number to the app./strategies composition β test/parity/strategies.compose.test.ts seeds the raw cache
with a controlled fixture and asserts the composed contract field-by-field (sourcing, LTV math,
ladder via the verbatim leverage.ts, freshness cadences, null-vs-absent, spiralHints
isolation). Runs offline in CI.scripts/capture-parity.ts primes the warmer
against real upstreams and writes the composed /strategies (+ apy/borrow histories) for a
fixed market set to test/fixtures/. The parity diff vs the app is produced by feeding the
same fixed inputs to the app's client-side composition and comparing (the app logs its composed
markets); the PR commits the fixtures and the empty diff. This is the gate that lets us offload
TVL safely.bignumber.js pinned to the app's 9.3.1; no global BigNumber.config change β
toFixed(2) / rounding (ROUND_HALF_UP) identical.getCollateralValueInLoanToken (multicall3), stUSDS
str(), spUSDG vsr() (chain 4663). The app's (intentionally lossy) BigInt(liqLtv) from the
JSON number is matched exactly, not "fixed".maxLeverage = calcLeverage(maxLtv); defaultLeverage = calcLeverage(safeLtv),
safeLtv = maxLtv% β 0.75 β exactly as the app derives them. Ladder = integer steps
1x β¦ βmaxLeverageβ (LTV =(1 β 1/lev)Β·100) then the exact max.collateralTokens.json by the app's weekly refresh script; its file
mtime is the exitLiquidity.asOf. The tier (the only verdict) lives in spiralHints with
its thresholds; raw slippagePct stays under exitLiquidity, null (no route) preserved.No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/leverage-2)<a href="https://allmcps.com/mcp/leverage-2"><img src="https://allmcps.com/api/badge/leverage-2?style=directory" alt="Leverage on AllMCPs" /></a>