loading…
Search for a command to run...
loading…
Multi-protocol yield intelligence for AI agents — covering Spectra Finance, Pendle, and Morpho via the Model Context Protocol.
Multi-protocol yield intelligence for AI agents — covering Spectra Finance, Pendle, and Morpho via the Model Context Protocol.
Multi-protocol yield intelligence for AI agents — covering Spectra Finance, Pendle, and Morpho via the Model Context Protocol.
55 tools · 3 protocols · 10+ chains · read-only · open emergence architecture · calibration intelligence · on-chain Curve quoting · Pendle logit AMM modeling · ERC-4626 health checks · yield curve term structure · historical eth_getLogs · full Pendle protocol parity (15 tools) · cross-protocol position map · cross-protocol Spectra↔Pendle comparison · veSPECTRA + vePENDLE governance · Pendle historical time-series · Morpho supply-side visibility with supplier cascade modeling · Morpho user positions & historical rates · Merkl campaign APR + expiry integration · entry path awareness · prescriptive observation boundaries · curator risk monitoring · withdrawal stress testing · rollover planning · multi-vault portfolio aggregation · pool expiry monitoring · zero web3 library dependencies
Any AI agent (Claude, GPT, open-source) that supports MCP can query Spectra, Pendle, and Morpho in a unified interface to:
get_dy() for exact output, falling back to math estimateseth_getLogs when API data has aged out — with dynamic RPC URL support for any chainmv_get_protocol_context (PT/YT identity, Router batching, deposit paths, glossary, fees & costs, workflow routing, externalPositions registry)The agent doesn't need to understand PT/YT mechanics -- it just calls spectra_scan_opportunities or pendle_scan_opportunities with its capital size and gets ranked, actionable data. For cross-protocol comparison, mv_scan_curator_opportunities ranks both protocols together. If it needs to understand why something works that way, it calls mv_get_protocol_context.
The server is designed so that AI agents can discover novel strategies without being taught specific strategies. Instead of hard-coding strategy identification logic, the system teaches protocol mechanics at three layers — and lets the agent compose building blocks into its own analysis.
Layer 1: Protocol Context (mv_get_protocol_context tool + resources)
→ Teaches the "physics" of the protocol: PT/YT identity, Router batching, minting
→ Available as a callable tool (on-demand) and as MCP resources
→ Static knowledge — what CAN happen, not what IS happening
Layer 2: Tool Descriptions (every tool's description string)
→ Teaches domain-specific mechanics relevant to that tool's data
→ Cross-reference nudges: "use spectra_get_portfolio to check actual holdings"
→ Uses "could be" language, not "is" — preserves ambiguity where it exists
→ Calls out hidden mechanics that could mislead (e.g., AMM_ADD_LIQUIDITY can mint YT)
Layer 3: Structured Output Hints (computed at runtime in tool output)
→ Position Shape analysis in portfolio: balance ratios (e.g., "YT/PT 4:1")
→ Portfolio Signals: concentration, maturity alerts, strategy shape across positions
→ Volume Signals: volume/liquidity ratio, buy/sell skew, trend detection
→ Morpho Market Hints: capacity warnings, utilization alerts, spread analysis, reward incentives
→ Morpho Supply-Side Analysis: supplier identification (vault/EOA/looper), concentration metrics,
supply gap warnings — surfaces where lending liquidity comes from and whether it's sufficient
→ Competing Interpretation Branches (A/B/C) in activity analysis per-address:
multiple explanations for the same observable pattern, presented with equal weight.
The agent must bring external evidence to collapse branches — the tension IS the info.
→ Statistical confidence boundaries: small-N cycle repetitions (≤5) flagged as
insufficient for extrapolation, preventing false pattern-matching
→ Flow Accounting with competing hypotheses: YT-only, PT-only, fully exited positions
each get multiple explanations that predict different future behavior
→ Address isolation mode: cycle detection, flow accounting, contract/EOA detection,
pool impact warnings, gas estimates, pool context
→ Capital-aware warnings: short maturity, low liquidity, negative effective APY
→ Yield Dimensions in scan output: fixed, variable, LP, looping side-by-side
→ Strategy Tension: competing PT looping vs YT accumulation on same pool
→ On-chain quote source indicators: "(on-chain Curve get_dy)" vs "(estimated)"
→ Yield composition: IBT APR breakdown (organic base vs external incentives) in scans and quotes
→ Incentive sustainability: flags when >50% of IBT APR or LP APY comes from incentives,
shows "organic only" APY so agents can assess yield durability without incentive assumptions
→ Pool reserves: IBT/PT amounts with ratio for AMM imbalance analysis
→ Merkl campaign APR: external incentive programs (e.g., KAT rewards) shown per-pool/market
with double-counting avoidance (skips campaigns whose reward tokens are already displayed)
→ Merkl campaign eligibility: action type (POOL/HOLD) always shown, with explicit
"[LP only — not for YT/PT holders]" flag on POOL campaigns to prevent misattribution
→ Protocol YT fees: Spectra 3% and Pendle 5% shown in every pool/market detail output
so agents apply them to yield calculations without needing external lookups
→ Points multipliers: external programs (Drops, InfiniFi, Firelight) with amounts
→ "Could be" / "at current rates" language: preserves ambiguity in ranked output
→ Makes key signals SALIENT without prescribing interpretation
Layer 4: Observation Coverage (quantifies blind spots in tool output)
→ Value coverage: what % of an address's position is explained by observable activity.
Low coverage means most behavior is invisible (direct mints, transfers, cross-chain).
→ Temporal coverage: active days vs dark periods with no observable events.
Longest gap duration surfaced so the agent can reason about invisible activity.
→ Data source coverage: which of 5 available sources were consulted vs not.
Explicitly lists what is invisible to the current analysis.
→ Activity diversity: single-type activity flagged as highest-ambiguity pattern.
→ Boundary marker: "Position sizing should assume this analysis is incomplete,
not comprehensive." — a structural admission of domain-of-validity limits.
→ Coverage metrics bound ALL interpretations above them. High-confidence strategy
assessment + low observation coverage = false confidence. The coverage section
forces the agent to size its conviction to what it actually observed.
spectra_get_portfolio after seeing activity patterns, not because it was told to.SELL_PT event might actually be YT acquisition via flash-mint. Tool descriptions teach this so agents don't draw wrong conclusions from pool data alone.spectra_get_portfolio without needing a block explorer.spectra_get_best_fixed_yields explicitly says "this ranks by raw APY — use spectra_scan_opportunities for capital-aware sizing."A cold-start agent with zero prior knowledge of the protocols can:
mv_scan_curator_opportunities — see cross-protocol (Spectra + Pendle) yield rankings with capital-aware metricsspectra_get_pool_activity — see trading patterns with ⚠ hints about ambiguous eventsspectra_get_portfolio and pendle_get_portfolio on flagged addresses — see Position Shape across both protocolsThis was validated: a subagent spawned with zero priming correctly identified a mint-and-sell-PT loop strategy (YT accumulation via PT discount) in 3 tool calls, using only the mechanics taught in descriptions and the structured hints in output.
The competing-branch design was motivated by a real failure: an agent analyzing a multi-chain wallet collapsed all activity into "YT accumulator" despite different pools showing different patterns (spread capture, market making, LP cycling). The single-narrative failure mode — where the agent picks one interpretation and defends it — is the most dangerous because it looks like good analysis from inside.
The observation coverage layer addresses a deeper problem: even perfect interpretation of observed data is misleading when the data covers a minority of behavior. Competing branches solve the narrative problem (which story fits?). Coverage metrics solve the exposure problem (how much of the picture am I seeing?). An agent that picks the best interpretation branch but ignores 65% invisible activity is sizing conviction to coherence, not evidence.
| Tool | Description |
|---|---|
spectra_get_best_fixed_yields |
Scan ALL chains for top fixed-rate opportunities. The main discovery tool. Supports compact mode. |
spectra_list_pools |
List all active pools on a specific chain, sorted by APY/TVL/maturity. Surfaces pool reserves, IBT APR composition, maturityValue, multipliers, and tags. Supports compact mode and include_expired flag. |
spectra_get_pt_details |
Deep dive on a specific Principal Token -- full data including maturityValue, multipliers (points programs), tags, pool reserves, IBT APR composition, and baseIbt for wrapper tokens. |
spectra_compare_yield |
Fixed (PT) vs. variable (IBT) yield comparison with spread mechanics and entry cost analysis. |
spectra_get_looping_strategy |
Calculate leveraged yield via PT + Morpho looping with effective liquidation margins, borrow rate sensitivity (+1/2/3%), break-even period, and failure scenario modeling. Auto-fetches live Morpho rates when a matching market exists. |
morpho_list_markets |
Find Morpho lending markets that accept Spectra PTs as collateral. Filter by chain or symbol. Shows reward incentives, vault supplier count per market. Cross-references Spectra PT addresses. |
morpho_get_rate |
Get live borrow rate, state, and supply-side context for a specific Morpho market. Includes PT spread analysis, top supplier identification, and vault allocation details (% of AUM, cap utilization). |
morpho_get_market_suppliers |
Supply-side analysis for a Morpho market: top suppliers ranked by size, vault vs EOA/looper identification, concentration analysis, supply gap warnings. Reveals where lending liquidity comes from. |
morpho_list_vaults |
List Morpho vaults on a chain with enriched allocations: Spectra PT tagging, live borrow rates and utilization per allocation, cap utilization percentages. Parallel-fetches market rates and PT addresses for zero-latency enrichment. |
morpho_get_positions |
Query a user's Morpho positions across markets and vaults on a chain (or all Morpho chains). Shows collateral, borrows, supply with USD values, vault deposits, health factors, looper detection, and position signals. |
morpho_get_history |
Historical rates and growth for a specific Morpho market. Shows borrow/supply APY, utilization, and TVL trends with min/avg/max/current stats. Includes rate stability signals, spike detection, and supply/demand squeeze alerts. |
spectra_get_protocol_stats |
SPECTRA tokenomics, emissions schedule, fee distribution, governance info. |
spectra_list_chains |
List available networks (10 chains). |
spectra_get_portfolio |
Wallet positions across PT, YT, and LP with USD values, claimable yield, and Merkl rewards (SPECTRA gauge emissions + incentive programs). Rewards matched to specific pools via reason key parsing. |
spectra_get_pool_volume |
Historical buy/sell trading volume for a specific pool. Accepts PT address or pool address. |
spectra_get_pool_activity |
Recent individual transactions (buys, sells, liquidity events) with filtering. Address isolation mode presents competing interpretation branches (A/B/C), statistical confidence boundaries on cycles, flow accounting with competing hypotheses, contract/EOA detection, gas estimates. Accepts PT or pool address. |
spectra_get_address_activity |
Cross-pool address scanner — finds all pools an address has interacted with on a chain (or all chains) in one call. Includes expired/matured pools via portfolio lookup. Per-pool breakdown + cross-pool aggregates. |
spectra_quote_trade |
PT trade quoting with on-chain Curve get_dy() for exact output (falls back to math estimate). Shows price impact, slippage, minOut, pool reserves with ratio, and IBT APR composition. |
spectra_simulate_trade |
Preview portfolio BEFORE/AFTER a hypothetical PT trade with deltas, warnings, and on-chain quoting. |
spectra_scan_opportunities |
Capital-aware opportunity scanner: price impact at your size, effective APY, Morpho looping, pool capacity, IBT APR composition, and points multipliers. Supports compact mode. |
spectra_scan_yt_arbitrage |
YT rate vs IBT rate arbitrage scanner -- finds pools where YT is mispriced relative to underlying yield. Includes IBT APR composition for spread sustainability analysis. Supports compact mode. |
spectra_get_ve_info |
Live veSPECTRA data from Base chain (total supply via on-chain read) + boost calculator with per-pool multipliers. |
spectra_list_metavaults |
List live MetaVaults across all chains (or a specific chain). Returns curator info, TVL, live APY, share price, active positions, and epoch history. |
spectra_model_metavault |
MetaVault "double loop" strategy modeler for curators. Live mode (chain + metavault_address) auto-fetches APY from API; manual mode accepts base_apy directly. Models curator economics (fee revenue, TVL creation, effective ROI). |
spectra_get_curator_dashboard |
Operational dashboard for MetaVault curators. Vault health, position status with vault allocation (when available) vs pool TVL, depositor flows, fee revenue estimates, bridge activity, and actionable alerts. Explicitly disambiguates vault allocation from pool-level TVL to prevent misinterpretation. |
pendle_list_markets |
List active Pendle markets on a given chain or all Pendle chains. Supports Pendle-only chains (Mantle, Berachain, HyperEVM, Corn). Supports compact mode. |
pendle_get_market_details |
Deep dive on a single Pendle market — implied APY, LP APY breakdown (swap fees + PENDLE incentives + boost), underlying variable APY, pool reserves, fee rate, Merkl campaigns. |
pendle_get_best_fixed_yields |
Scan all Pendle chains for top fixed-rate opportunities. Ranked by implied APY with TVL/liquidity filters. The Pendle equivalent of spectra_get_best_fixed_yields. |
pendle_get_portfolio |
Wallet positions across all Pendle chains — PT, YT, LP balances with USD values and implied APY per position. |
pendle_scan_opportunities |
Capital-aware Pendle opportunity scanner — price impact at your size using logit AMM model, effective APY, Morpho looping for Pendle PTs, Merkl campaigns. Supports compact mode. |
pendle_get_market_capacity |
Multi-size capacity curve for a Pendle market — quotes at geometric capital tiers using logit AMM model to find sweet spot and exhaustion point. |
pendle_get_yield_curve |
Term structure for a given underlying across Pendle chains. All maturities sorted chronologically with curve shape analysis (normal/inverted/flat), steepest segment, cross-chain pairs. |
pendle_list_expiring_markets |
Scan Pendle chains for markets approaching maturity. Groups by urgency (CRITICAL ≤7d, WARNING ≤14d, ALERT ≤threshold). |
pendle_scan_yt_arbitrage |
YT mispricing scanner — compares underlying variable APY vs implied rate. Pendle YT trades directly on AMM (simpler execution than Spectra's Router flash-mint/redeem). |
pendle_get_protocol_stats |
Protocol-wide aggregate stats — total TVL, market count, volume, avg APY across all Pendle chains with per-chain breakdown and Spectra overlap indicator. |
pendle_get_looping_strategy |
Leveraged PT + Morpho looping calculator for Pendle PTs — borrow rate sensitivity, break-even analysis, 30-day historical risk assessment with P(underwater) probability. Auto-detects Morpho markets. |
pendle_quote_trade |
PT trade quote using Pendle logit AMM model — expected output, price impact, effective APY after entry cost, min output with slippage tolerance. |
pendle_simulate_trade |
Portfolio impact simulation for Pendle PT trades — before/after position values, blended APY change, concentration analysis. |
mv_compare_yield |
Side-by-side Pendle vs Spectra yield comparison on overlapping chains (mainnet, base, arbitrum, optimism, sonic, bsc). Maturity-aware matching with configurable tolerance (exact ≤7d, close ≤30d, loose ≤90d). |
mv_scan_curator_opportunities |
Cross-protocol (Spectra + Pendle) capital-aware scanner for MetaVault curators. Price impact at your size, effective APY, Morpho looping (Spectra + Pendle), cross-protocol match tagging. Supports compact mode. |
spectra_get_onchain_activity |
Historical on-chain activity via eth_getLogs — recovers data when the API has aged out transactions. Supports dynamic rpc_url parameter for any chain, token_decimals for correct formatting (USDC=6, WBTC=8). Decodes Curve pool events (swaps, LP adds/removes) via pool_address AND Spectra PT vault events (Mint, Redeem, YieldClaimed) via pt_address. Both can be provided simultaneously for merged results. |
spectra_get_pool_capacity |
Multi-size capacity curve — quotes PT trades at geometric capital tiers to show price impact and effective APY degradation. Identifies sweet spot and exhaustion point. On-chain Curve quotes. |
mv_check_ibt_health |
Multi-signal IBT health assessment — on-chain ERC-4626 conversion rate, APR composition (organic vs incentive), pool balance ratio, protocol recognition, liquidity level. Returns HEALTHY/CAUTION/WARNING verdict. |
spectra_get_yield_curve |
Term structure for a given underlying across all chains. All maturities sorted chronologically with implied APY, TVL, liquidity. Curve shape analysis (normal/inverted/flat), steepest segment, cross-chain pairs. |
morpho_monitor_risk |
Liquidation risk monitor for curator Morpho positions — health factor, liquidation price, distance-to-liquidation, borrow rate drift, alert levels (ok/watch/warning/critical). |
spectra_stress_test_vault |
Withdrawal stress test for MetaVaults — liquidity waterfall (idle → maturing → LP removal → PT sale), cost to remaining depositors, maximum safe redemption size. Market stress mode (2x impact). |
mv_plan_rollover |
Position rollover planner for expiring MetaVault positions — scans Spectra + Pendle for replacement candidates, computes entry impact, yield gap, overlap windows, and net effective APY. |
mv_get_curator_portfolio |
Multi-vault portfolio aggregation — total AUM, blended APY, fee revenue projection, concentration by underlying/chain, cross-vault action items. Discovery mode (by curator address) or explicit mode. |
mv_get_calibration |
Calibration oracle — what does "normal" look like? Computes statistical baselines (percentiles, anomaly thresholds) from historical data for any Morpho market, Pendle market, or Spectra pool. Includes peer comparison and assertion-ready threshold language. The bridge between perception (monitoring) and specification (security assertions). |
mv_get_position_map |
Cross-protocol position map — sees the WHOLE wallet across Spectra + Pendle + Morpho + governance (veSPECTRA + vePENDLE) in one parallel call. Contradiction detection: unused governance boost, lending when fixed rates are higher, concentration risk, looper detection, expiring positions across protocols. Honest failure reporting (INCOMPLETE shown before numbers, not after). The first tool that sees the user, not just the protocol. |
spectra_get_gauge_votes |
Full veSPECTRA governance dashboard — gauge vote distribution, voting APRs, bribe incentives, SPECTRA emissions per pool. Shows where veSPECTRA holders direct votes, what rewards they earn, emission concentration, and bribe efficiency ($ per vote). |
pendle_get_market_history |
Historical time-series for any Pendle market — implied APY, TVL, volume, PT/YT prices over 7d/30d/90d/1y periods. First tool that answers "what happened over time?" for trend analysis, yield stability assessment, and anomaly detection. |
spectra_list_expiring_pools |
Scan all chains for pools approaching maturity (default 21-day threshold). Groups by urgency (CRITICAL ≤7d, WARNING ≤14d, ALERT ≤21d). Cross-references each expiring pool's IBT against all active pools for successor detection. Fetches gauge status from governance API. Per-pool readiness assessment (OK/CAUTION/WARNING). Operator checklist: deploy successor pool, submit gauge proposal, ready for migration. |
mv_get_protocol_context |
Returns protocol mechanics reference across 12 topics: pt_yt_mechanics, router_batching, position_analysis, looping, networks, deposit_path, glossary, fees_and_costs, pendle_morpho, workflow_routing, protocol_pulse (live TVL/emissions/expiring pools), and external_protocols (registry of non-Spectra protocols a MetaVault can hold via externalPositions — settlement windows, observation boundaries, mitigations per entry). Fees topic covers Spectra 3% / Pendle 5% YT fees, reward basis (held vs notional), Merkl campaign types, and external points program discovery. |
Spectra: Ethereum (mainnet), Base, Arbitrum, Optimism, Avalanche, Katana, Sonic, Flare, BSC, Monad, Hemi, HyperEVM, SEI
Pendle: Ethereum, Optimism, BSC, Sonic, Base, Arbitrum, Mantle, Berachain, HyperEVM, Corn
Morpho PT markets: Ethereum, Base, Arbitrum, Katana
All three lists are hardcoded in src/config.ts and must be updated by hand when a protocol deploys on a new chain:
SUPPORTED_CHAINS_INTERNAL (+ CHAIN_RPC_URLS, CHAIN_RPC_FALLBACKS, CHAIN_BLOCK_TIMES, CHAIN_GAS_ESTIMATES per-chain tables). Every Spectra-native tool (metavault list, pool list, expiring pools, protocol pulse, curator dashboard, etc.) reads from this list — so one edit propagates everywhere.PENDLE_CHAIN_IDS + PENDLE_CHAIN_NAMES. Source of truth: GET https://api-v2.pendle.finance/core/v1/chains.MORPHO_CHAIN_IDS. Source of truth: Morpho GraphQL morphoBlue queries per chain.There is no automated canary. The CONFIG_VERIFIED_DATES map in config.ts emits a stderr warning at startup when a list is >120 days old, but that's a calendar alarm, not a "new chain appeared" alarm. Practical cadence: check monthly, or when a protocol team announces a new deployment.
Known drift to eventually reconcile: the comment in MORPHO_CHAIN_IDS mentions Morpho markets on hyperliquid(999) — which is the same chain as our newly-added hyperevm. If Morpho ships PT markets on HyperEVM and we want them scanned, add hyperevm: 999 to the Morpho map.
The server reads live veSPECTRA total supply directly from the Base chain via raw eth_call (no ethers/viem dependency) and computes per-pool boost multipliers using the real Spectra formula:
B = min(2.5, 1.5 * (v/V) * (D/d) + 1)
v = your veSPECTRA balance
V = total veSPECTRA supply (read live from Base)
D = pool TVL
d = your deposit size
Full 2.5x boost when your share of total veSPECTRA >= your share of pool TVL.
Tools that accept ve_spectra_balance (spectra_scan_opportunities, spectra_scan_yt_arbitrage, spectra_compare_yield, spectra_get_ve_info) compute per-pool boost automatically. The veSPECTRA contract is an NFT-based voting escrow (veNFT) at 0x6a89228055c7c28430692e342f149f37462b478b on Base, sourced from spectra-core.
MetaVaults are ERC-7540 curated vaults that automate LP rollover and compound YT yield back into LP positions. Two tools work together:
spectra_list_metavaults — Discovery tool. Fetches live MetaVault data from the API (/v1/{network}/metavaults), scanning a single chain or all chains in parallel. Returns curator info, TVL, live APY, share price, active positions with PT/pool details, and epoch rate history.
spectra_model_metavault — Strategy modeler with two modes:
chain + metavault_address to auto-fetch the vault's live APY as base_apy. All other parameters (borrow rate, LTV, curator fee) can still be overridden.base_apy directly for hypothetical or pre-launch modeling.The "double loop" economics:
Layer 1 (inside vault): Deposit → PT/LP allocation → YT yield → more LP (compounding)
Layer 2 (on top): MV shares → Morpho collateral → borrow → deposit back (leverage)
The key insight: YT compounding raises the vault's base APY, and leverage multiplies that higher base. This creates a "double-loop premium" over raw PT looping that scales with leverage.
Curator economics are built in — the tool models fee revenue on external deposits, additional TVL created by looping, and effective ROI on the curator's own capital.
npm install -g metavault-mcp
Or run directly without installing:
npx metavault-mcp
git clone https://github.com/Finanzgoblin/metavault-mcp.git
cd metavault-mcp
npm install
npm run build
Add to your claude_desktop_config.json:
{
"mcpServers": {
"metavault-mcp": {
"command": "npx",
"args": ["metavault-mcp"]
}
}
}
Restart Claude Desktop. You'll see all 55 tools (Spectra, Pendle, Morpho, cross-protocol) available.
claude mcp add metavault-mcp -- npx metavault-mcp
The more context you give upfront, the deeper the agent can go. Each input unlocks a different tool chain:
| Input | What it unlocks |
|---|---|
Capital size ($200K) |
Price impact at your size, pool capacity limits, effective APY |
Wallet address (0x...) |
Portfolio simulation, existing position context, Merkl rewards |
| veSPECTRA balance | Real per-pool boost (not min/max range) |
| Asset preference | Filtered yield curve, targeted scans |
| Strategy type | LP vs PT vs looping vs MetaVault — determines which tools get chained |
| Maturity window | Term structure analysis, rollover timing |
The ideal prompt combines all of these. Here are examples that trigger 8-10 tool chains:
The cross-referencing between tools is where the real depth happens — no single tool tells the full story. The agent calls mv_get_protocol_context(topic="workflow_routing") to learn these compositions at runtime.
Once connected, you can ask Claude things like:
Agent (Claude/GPT/etc)
| MCP Protocol (stdio)
MetaVault MCP (this)
| HTTP (15s timeout, 1 retry on 5xx/network errors)
|
+-- api.spectra.finance/v1/{chain}/pools
+-- api.spectra.finance/v1/{chain}/pt/{address}
+-- api.spectra.finance/v1/{chain}/portfolio/{wallet}
+-- api.spectra.finance/v1/{chain}/pools/{pool}/volume
+-- api.spectra.finance/v1/{chain}/pools/{pool}/activity
+-- api.spectra.finance/v1/{chain}/metavaults
+-- app.spectra.finance/api/v1/spectra/*
+-- api.merkl.xyz/v3/userRewards (unclaimed Merkl rewards per wallet)
+-- api.merkl.xyz/v4/opportunities (Merkl campaign APR per chain)
+-- api.morpho.org/graphql (PT collateral markets, borrow rates)
+-- api-v2.pendle.finance/core/* (Pendle market data for cross-protocol comparison)
+-- mainnet.base.org (veSPECTRA on-chain reads via raw eth_call)
+-- Chain RPCs: eth_call for Curve get_dy() quotes, eth_getCode for contract detection
| (mainnet, base, arbitrum, optimism, avalanche, sonic, bsc, flare)
+-- Chain RPCs: eth_getLogs for historical pool activity (any chain via dynamic rpc_url)
Modular TypeScript server. Read-only — queries Spectra's existing API, Morpho's GraphQL API, chain RPCs for on-chain Curve get_dy() quotes and contract detection, and Base RPC for veSPECTRA data. No wallet, no transactions, no keys, no web3 libraries needed.
src/
index.ts Entry point, tool registration, Layer 1 resources (spectra-overview,
curator-strategy-guide), main(), graceful shutdown
config.ts Constants, chain config, Zod schemas, protocol parameters, veSPECTRA constants,
block time constants per chain, RPC URL resolution (hardcoded + dynamic override)
types.ts TypeScript interfaces (SpectraPt, MorphoMarket, ScanOpportunity, MerklTokenReward, MerklChainRewards, MerklCampaign, etc.)
api.ts Fetch helpers with retry, GraphQL sanitization, Morpho batch lookup,
veSPECTRA RPC with Promise-based dedup cache, 30s TTL pool data cache,
Curve get_dy() on-chain quoting, ERC-4626 convertToAssets() health check,
eth_getCode contract detection,
MetaVault multi-chain scanning, API response validation at system boundary,
chunked eth_getLogs with retry for historical event log fetching,
Merkl reward fetching and parsing (pool address extraction from reason keys,
BigInt wei→human conversion, matched/unmatched reward categorization),
Merkl v4 campaign APR fetching (60s TTL cache, inflight dedup, address-based lookup)
primitives.ts Format primitives (formatUsd, formatPct, formatDate, daysToMaturity,
estimatePriceImpact, chainIdToName) — HOME. Re-exported from formatters.ts
for backward compat with 42 consumer files.
protocols/ externalPositions registry (plugin-style extension for Spectra's whitelisted
ERC-4626 modules). types.ts (SourcedValue/InterpretedValue/ProtocolMeta + zod),
metadata.ts (avant + pendle + _unknown), cost-models.ts (zero, lp_exit_samechain,
lp_exit_crosschain_cctp, liquidation), engine.ts (renderExternalPosition,
classifyForStress, generateActionItems, DriftCollector), registry.ts (getMeta +
freshness warnings), index.ts (barrel). Spec: docs/protocols-metadata-spec.md.
formatters.ts Formatting, BigInt LLTV parsing, closed-form leverage math,
price impact, fractional-day maturity, boost computation,
slim envelope helpers, token amount formatting (BigInt → human-readable),
cross-protocol maturity matching (normalizeUnderlyingSymbol, matchByAssetAndMaturity),
Layer 3 output hints (Position Shape, LP APY breakdown,
volume signals, Morpho market hints, portfolio signals,
competing interpretation branches, statistical confidence boundaries,
flow accounting with competing hypotheses),
Layer 4 observation coverage (value coverage, temporal gaps,
data source coverage, activity diversity, boundary markers),
Merkl reward display (per-position matched rewards, unmatched/exited rewards),
Merkl campaign APR display (formatMerklCampaignLines with double-counting avoidance)
tools/ Layer 2: each tool description teaches domain-specific mechanics
context.ts mv_get_protocol_context (Layer 1 protocol mechanics, deposit paths, glossary, callable on-demand)
pt.ts spectra_get_pt_details, spectra_list_pools, spectra_get_best_fixed_yields, spectra_compare_yield
looping.ts spectra_get_looping_strategy
portfolio.ts spectra_get_portfolio (balance ratio strategy signals, portfolio-level hints, cross-ref nudges,
Merkl rewards integration — parallel fetch, per-position matching, unmatched rewards)
pool.ts spectra_get_pool_volume (with volume/liquidity hints), spectra_get_pool_activity (PT address resolution, Router batching,
address isolation w/ cycle detection, flow accounting, contract detection,
gas estimates, pool impact warnings, observation coverage metrics),
spectra_get_address_activity (cross-pool scanner with coverage boundary markers)
morpho.ts morpho_list_markets (with capacity/utilization hints), morpho_get_rate (with PT spread analysis)
protocol.ts spectra_get_protocol_stats, spectra_list_chains
quote.ts spectra_quote_trade (on-chain Curve get_dy() with math fallback)
simulate.ts spectra_simulate_trade (also uses on-chain quoting)
strategy.ts spectra_scan_opportunities (capital-aware, batch Morpho, negative-APY filtering, strategy tension)
yt_arb.ts spectra_scan_yt_arbitrage (YT execution mechanics, flash-mint/flash-redeem)
ve.ts spectra_get_ve_info
metavault.ts spectra_list_metavaults, spectra_model_metavault (live API + computational modeling),
spectra_get_curator_dashboard (vault allocation disambiguation, cross-chain position awareness)
pendle.ts pendle_list_markets, mv_compare_yield (maturity-aware cross-protocol yield comparison)
curator_scan.ts mv_scan_curator_opportunities (cross-protocol capital-aware scanner for MetaVault curators)
onchain.ts spectra_get_onchain_activity (historical eth_getLogs, Curve pool + PT vault event decoding, dynamic RPC)
capacity.ts spectra_get_pool_capacity (multi-size quote ladder, sweet spot / exhaustion detection)
ibt_health.ts mv_check_ibt_health (ERC-4626 conversion rate, APR composition, pool balance, verdict)
yield_curve.ts spectra_get_yield_curve (term structure for a given underlying across all chains)
risk_monitor.ts morpho_monitor_risk (liquidation distance, health factor, borrow rate drift, alert levels)
stress_test.ts spectra_stress_test_vault (withdrawal liquidity waterfall, market stress simulation)
rollover.ts mv_plan_rollover (expiring position rollover planner with cross-protocol candidates)
curator_portfolio.ts mv_get_curator_portfolio (multi-vault aggregation, AUM, blended APY, concentration)
expiry_monitor.ts spectra_list_expiring_pools (pool maturity monitoring, urgency grouping, successor cross-reference, gauge status, readiness assessment)
gauge_votes.ts spectra_get_gauge_votes (veSPECTRA governance: vote distribution, voting APRs, bribes, emissions)
pendle_history.ts pendle_get_market_history (historical APY, TVL, volume, PT/YT prices time-series)
position_map.ts mv_get_position_map (cross-protocol wallet view: Spectra + Pendle + Morpho + governance, contradiction detection)
test.cjs Integration test suite (405 tests, McpTestClient over stdio)
test-agent.cjs Agent reasoning test suite (82 assertions, McpTestClient over stdio)
AGENT-TESTS.md 38-question subjective test suite with grading rubrics (incl. open emergence, coverage, newcomer comprehension tiers)
EMERGENCE-AUDIT.md Open Emergence audit — competing branches, observation coverage, anomaly detection gaps
CODE-REVIEW.md Full codebase review (bugs, security, code quality, test coverage)
SECURITY-REVIEW.md Security-focused review (SSRF, GraphQL injection, dependency vulnerabilities)
docs/
recursive-meta-process.md Open Emergence metaframework specification
dissolution-conditions.md Dissolution conditions for every structural decision
architecture-review-agentic-accessibility.md Agentic accessibility review with feature proposals
Each tool file exports a register(server) function. To add a new tool: create src/tools/newtool.ts, export register(), import and call it in index.ts.
All address parameters are validated (0x + 40 hex chars). All API calls have a 15-second timeout with automatic retry on transient failures (5xx, ETIMEDOUT, ENETUNREACH, ENOTFOUND). Cross-chain scans use Promise.allSettled so one chain failing doesn't block results from others. GraphQL inputs are sanitized to prevent injection. All error returns use MCP's isError: true flag for proper error signaling to agents.
fetchSpectra() and fetchMorpho() return Promise<unknown> (not Promise<any>), forcing explicit type assertions at every call site?? (not ||) to correctly handle 0-decimal tokensnumber | null to match actual API behavior — prevents silent NaN propagationJSON.parse() — avoids stream double-consumption that masked error diagnostics10n ** BigInt(18) to avoid float intermediate overflow. Trade quoting uses amountToBigInt() (string arithmetic) to avoid precision loss when amount * 10^decimals exceeds MAX_SAFE_INTEGER.min() / .max() bounds on all numeric inputs to prevent invalid GraphQL queriesBigInt arithmetic to avoid floating-point precision loss on 18-decimal raw values (e.g., 860000000000000000 → 0.86 exactly)(1 - ltv^(n+1)) / (1 - ltv) replaces iterative loop accumulation — numerically exact and O(1)ECONNRESET, ETIMEDOUT, ENETUNREACH, ENOTFOUND, EPIPE, EHOSTUNREACH, EAI_AGAIN, and UND_ERR_SOCKET errorsvalidatePtEntries() filters malformed API responses at system boundary (validates address, maturity, name fields)first parameter capped at min(addresses * 3, 500) to avoid GraphQL response limitsget_dy() via raw eth_call on 8 chains with automatic fallback to math estimate on RPC failureconvertToAssets() via raw eth_call — graceful degradation when RPC unavailable (other health checks still run)eth_getLogs (2000 blocks/chunk) with per-chunk retry — failed chunks are skipped so partial results are still returned. Dynamic rpc_url parameter enables any chain without hardcoded RPCsMap cache for eth_getCode results (contract code doesn't change)parseWei() conversion for safe 18-decimal arithmeticisError: true so agents can distinguish errors from empty resultsspectra_get_pool_volume, spectra_get_pool_activity) accept either pool address or PT address and resolve automaticallyserver.close() called before process.exit() on SIGTERM/SIGINTFrom a source checkout:
# Full integration suite (405 tests, requires network)
npm test
# Schema/registration only (98 tests, no network)
npm run test:offline
# Unit tests (242 tests, no network)
npm run test:unit
# Agent reasoning tests (82 assertions, requires network)
npm run test:agent
api.test.ts, formatters.test.ts, config.test.ts)242 tests covering pure-function logic: GraphQL sanitization, Morpho field constants, Merkl reward parsing (pool address extraction from reason keys, wei-to-human conversion, matched/unmatched categorization), Merkl reward formatting, balance formatting, cross-protocol maturity matching (normalizeUnderlyingSymbol, matchByAssetAndMaturity), Pendle logit AMM price impact model (estimatePendlePriceImpact), Pendle date/maturity helpers (pendleDaysToMaturity), Pendle market formatters (compact + summary), and configuration validation. No network required.
test.cjs)405 tests covering tool registration, schema validation, API responses, on-chain Curve get_dy() quoting, cross-pool address scanning, address isolation mode, cross-protocol curator scanning, and malformed-address negative tests. Dynamically discovers pool and PT addresses from the live API, so tests won't go stale when pools mature.
test-agent.cjs)82 assertions across multi-tool workflow tests that verify the "reasoning surface" — can an agent using these tools detect anomalies, cross-reference data, and avoid protocol-mechanic traps? Tests include:
spectra_list_pools → spectra_get_pt_details → spectra_compare_yieldeth_getLogs address filtering missesspectra_list_pools returns only active pools; MetaVaults surface expired positionsinclude_metavaults flag correctly shows/hides MetaVault sectionAGENT-TESTS.md)38 copy-pasteable questions across 11 tiers (basic tool usage → open emergence → newcomer comprehension) with grading rubrics for evaluating LLM agent quality when using the MCP tools. Tier 8 tests "open emergence" — the ability to hold competing interpretations without collapsing to a single narrative. Tier 11 tests newcomer comprehension — can the agent explain deposit paths, recognize conservative impact estimates, and route to the right scanner? These are designed to be run by spawning subagents and scoring responses manually or with LLM-as-judge.
This server wraps these endpoints:
| Endpoint | Used By |
|---|---|
GET /v1/{chain}/pools |
spectra_list_pools, spectra_get_best_fixed_yields, spectra_scan_opportunities, spectra_scan_yt_arbitrage, spectra_get_yield_curve (30s TTL cache) |
GET /v1/{chain}/pt/{address} |
spectra_get_pt_details, spectra_compare_yield, spectra_get_looping_strategy, spectra_quote_trade, spectra_simulate_trade, spectra_get_pool_capacity, mv_check_ibt_health, spectra_get_pool_volume/spectra_get_pool_activity (PT→pool resolution) |
GET /v1/{chain}/portfolio/{wallet} |
spectra_get_portfolio, spectra_simulate_trade, spectra_get_address_activity (expired pool discovery) |
GET /v1/{chain}/pools/{pool}/volume |
spectra_get_pool_volume |
GET /v1/{chain}/pools/{pool}/activity |
spectra_get_pool_activity, spectra_get_address_activity (active + expired pools) |
GET /v1/{chain}/metavaults |
spectra_list_metavaults, spectra_model_metavault (live mode) |
GET api.merkl.xyz/v3/userRewards?user={address}&chainId={chainId} |
spectra_get_portfolio (Merkl reward fetching — SPECTRA gauge emissions + incentive programs) |
GET api.merkl.xyz/v4/opportunities?chainId={chainId} |
spectra_list_pools, spectra_get_pt_details, spectra_compare_yield, pendle_list_markets, mv_compare_yield, spectra_scan_opportunities, mv_scan_curator_opportunities, spectra_scan_yt_arbitrage (Merkl campaign APR — 60s TTL cache) |
GET api.spectra.finance/v1/governance/voting-incentives |
spectra_list_expiring_pools (gauge status — pool address presence = gauge exists) |
GET app.spectra.finance/api/v1/spectra/circulating-supply |
spectra_get_protocol_stats |
GET app.spectra.finance/api/v1/spectra/total-supply |
spectra_get_protocol_stats |
POST api.morpho.org/graphql |
morpho_list_markets, morpho_get_rate, spectra_get_looping_strategy (auto-detect), spectra_scan_opportunities (batch) |
POST mainnet.base.org (eth_call) |
spectra_get_ve_info, spectra_scan_opportunities, spectra_scan_yt_arbitrage, spectra_compare_yield (veSPECTRA total supply) |
POST {chain RPC} (eth_call: get_dy) |
spectra_quote_trade, spectra_simulate_trade, spectra_get_pool_capacity (Curve StableSwap-NG on-chain quotes) |
POST {chain RPC} (eth_call: convertToAssets) |
mv_check_ibt_health (ERC-4626 IBT conversion rate health check) |
POST {chain RPC} (eth_call: eth_getCode) |
spectra_get_pool_activity (contract vs EOA detection in address mode) |
POST {chain RPC} (eth_getLogs) |
spectra_get_onchain_activity (historical Curve pool events + Spectra PT vault events — supports dynamic rpc_url override) |
GET api-v2.pendle.finance/core/v2/{chainId}/markets/active |
pendle_list_markets (Pendle market discovery) |
GET api-v2.pendle.finance/core/v2/{chainId}/markets/active |
mv_compare_yield (maturity-aware cross-protocol comparison) |
GET api-v2.pendle.finance/core/v2/{chainId}/markets/active |
mv_scan_curator_opportunities (cross-protocol capital-aware scanning — Spectra + Pendle) |
Note: {chain} uses the slug mainnet for Ethereum (the alias ethereum is accepted by the server and mapped automatically).
13 Pendle tools provide full feature parity with the Spectra toolset, plus 2 cross-protocol tools for unified analysis:
| Category | Pendle Tool | Spectra Equivalent |
|---|---|---|
| Discovery | pendle_list_markets |
spectra_list_pools |
| Discovery | pendle_get_best_fixed_yields |
spectra_get_best_fixed_yields |
| Analysis | pendle_get_market_details |
spectra_get_pt_details |
| Analysis | pendle_get_market_capacity |
spectra_get_pool_capacity |
| Analysis | pendle_get_yield_curve |
spectra_get_yield_curve |
| Portfolio | pendle_get_portfolio |
spectra_get_portfolio |
| Strategy | pendle_scan_opportunities |
spectra_scan_opportunities |
| Strategy | pendle_scan_yt_arbitrage |
spectra_scan_yt_arbitrage |
| Strategy | pendle_get_looping_strategy |
spectra_get_looping_strategy |
| Trading | pendle_quote_trade |
spectra_quote_trade |
| Trading | pendle_simulate_trade |
spectra_simulate_trade |
| Monitoring | pendle_list_expiring_markets |
spectra_list_expiring_pools |
| Protocol | pendle_get_protocol_stats |
spectra_get_protocol_stats |
mv_compare_yield — Side-by-side comparison on overlapping chains with maturity-aware matching. Normalizes underlying symbols (wstETH↔stETH, USDC.e↔USDC) and matches by nearest maturity within configurable tolerance (exact ≤7d, close ≤30d, loose ≤90d). Shows match quality and maturity gap per pair.
mv_scan_curator_opportunities — Cross-protocol capital-aware scanner for MetaVault curators. Scans both Spectra and Pendle in parallel, computes price impact at your capital size, effective APY after entry cost, Morpho looping availability (both Spectra and Pendle PTs), and tags cross-protocol matches.
Overlapping with Spectra: Ethereum, Base, Arbitrum, Optimism, Sonic, BSC Pendle-only: Mantle, Berachain, HyperEVM, Corn
scalarRoot=50 estimate.SY↔YT). Spectra YT trades indirectly via Router flash-mint/redeem.The Spectra REST API (/v1/{network}/pools/{pool}/activity) only retains a limited time window of recent transactions. When investigating addresses or pools with older activity, spectra_get_onchain_activity reads historical event logs directly from the blockchain via eth_getLogs.
Supports two contract types:
pool_address): TokenExchange, AddLiquidity, RemoveLiquidity, RemoveLiquidityOnept_address): Mint (deposit IBT → PT+YT), Redeem (burn PT → IBT), YieldClaimedBoth can be provided simultaneously — events are fetched in parallel, merged, and sorted by block number.
Key features:
rpc_url parameter — works for chains without hardcoded RPCs (Katana, Monad)from_block/to_block or lookback_hours (default 24h, max 720h/30 days)spectra_get_pt_details for price contextComposability with existing tools:
Agent flow: spectra_get_pool_activity → empty? → spectra_get_onchain_activity(pool_address=...) → pool events
Agent flow: portfolio shows PT but no pool trades → spectra_get_onchain_activity(pt_address=...) → vault events (mint/redeem)
When adding new tools, follow the three-layer architecture:
spectra-overview in index.ts.docs/dissolution-conditions.md. Every Layer 3 hint, architectural pattern, and generative friction point carries a dissolution condition — a prompt for re-evaluation when circumstances change.The goal: a cold-start agent reading only the tool descriptions and output hints should be able to use the tool correctly and compose it with other tools into novel analytical workflows.
To enable agents to actually execute strategies, you'd add tools that construct unsigned transactions via Spectra's Router contract. The agent would return the transaction calldata for the user to sign -- never holding keys.
Query the spectra-governance subgraph for current epoch votes, bribe amounts, and voter rewards. This is valuable for agents optimizing veSPECTRA voting strategies.
These Spectra API endpoints are ready to be integrated. Create a new file in src/tools/, export register(), and import it in src/index.ts:
GET /v1/vision/{network}?tokens=... -- APR data for specific tokensGET /v1/watch-tower/{network}/transactions -- Conditional order dataGET /v1/{network}/metavaults/bridge/transactions -- MetaVault cross-chain bridge transaction data (bridged volume, in-flight amounts)MIT
Выполни в терминале:
claude mcp add metavault-mcp -- npx Безопасность
Низкий рискАвтоматическая эвристика по публичным данным — не гарантия безопасности.