{"serverId":"mcp-registry/io.github.icmoore/echoledger-mcp","tools":[{"name":"AnalyzeBalancerLP","fixed":{"name":"AnalyzeBalancerLP","description":"Analyze a 2-asset Balancer weighted-pool LP position's PnL. Decomposes impermanent loss using the weighted-pool formula where the base token's weight affects IL magnitude. Values are denominated in opp-token units per BalancerImpLoss's convention; fee income is not attributed in v1 because Balancer pools only expose vault-level fees with no per-LP attribution.","inputSchema":{"type":"object","required":["lp_init_amt","entry_base_amt","entry_opp_amt","pool_address","rpc_url","pool_type"],"properties":{"rpc_url":{"type":"string","description":"An Ethereum (or L2) JSON-RPC URL used to read live pool state. Required; supplied by you per call (BYO-RPC) and may carry your provider key. The endpoint stores and logs nothing — the URL is never persisted or written to logs."},"chain_id":{"type":"integer","description":"Optional guard. If supplied and the RPC reports a different chain id, the call is rejected. Defaults to 1 (Ethereum mainnet) conceptually; omit to skip the check."},"pool_type":{"enum":["balancer"],"type":"string","description":"Which protocol the pool at pool_address belongs to. This tool accepts only balancer (2-asset weighted pool)."},"lp_init_amt":{"type":"number","description":"Pool shares held by this position, in human units."},"block_number":{"type":"integer","description":"Optional block number to pin the read to a historical block. Omit to read the latest block."},"pool_address":{"type":"string","description":"On-chain address of the pool/pair to analyze (Uniswap V2/V3 pair, Balancer weighted pool, or Curve stableswap pool). Required. Lowercase, uppercase, or checksum casing all work."},"entry_opp_amt":{"type":"number","description":"Amount of opp (second) token originally deposited."},"entry_base_amt":{"type":"number","description":"Amount of base (first) token originally deposited."},"holding_period_days":{"type":["number","null"],"description":"Optional holding period in days. If supplied, real_apr is annualized from net_pnl."}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":563,"tokensAfter":563},{"name":"AnalyzePosition","fixed":{"name":"AnalyzePosition","description":"Analyze why a Uniswap V2 or V3 LP position is gaining or losing money. Decomposes PnL into impermanent loss, accumulated fees, and net result, with optional real APR if a holding period is supplied. Returns current value, hold value, IL percentage, fee income, net PnL, real APR, and a diagnosis label.","inputSchema":{"type":"object","required":["lp_init_amt","entry_x_amt","entry_y_amt","pool_address","rpc_url","pool_type"],"properties":{"rpc_url":{"type":"string","description":"An Ethereum (or L2) JSON-RPC URL used to read live pool state. Required; supplied by you per call (BYO-RPC) and may carry your provider key. The endpoint stores and logs nothing — the URL is never persisted or written to logs."},"chain_id":{"type":"integer","description":"Optional guard. If supplied and the RPC reports a different chain id, the call is rejected. Defaults to 1 (Ethereum mainnet) conceptually; omit to skip the check."},"lwr_tick":{"type":["integer","null"],"description":"Lower tick of the position (V3 positions only; null for V2)."},"upr_tick":{"type":["integer","null"],"description":"Upper tick of the position (V3 positions only; null for V2)."},"pool_type":{"enum":["uniswap_v2","uniswap_v3"],"type":"string","description":"Which protocol the pool at pool_address belongs to. This tool accepts uniswap_v2 | uniswap_v3."},"entry_x_amt":{"type":"number","description":"Amount of token0 originally deposited at position entry."},"entry_y_amt":{"type":"number","description":"Amount of token1 originally deposited at position entry."},"lp_init_amt":{"type":"number","description":"LP token amount held by the position (position size in human units)."},"block_number":{"type":"integer","description":"Optional block number to pin the read to a historical block. Omit to read the latest block."},"pool_address":{"type":"string","description":"On-chain address of the pool/pair to analyze (Uniswap V2/V3 pair, Balancer weighted pool, or Curve stableswap pool). Required. Lowercase, uppercase, or checksum casing all work."},"holding_period_days":{"type":["number","null"],"description":"Optional holding period in days. If supplied, real_apr is annualized from net_pnl."}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":616,"tokensAfter":616},{"name":"AnalyzeStableswapLP","fixed":{"name":"AnalyzeStableswapLP","description":"Analyze a 2-asset Curve-style Stableswap LP position's PnL using the amplified-invariant IL formula where small depegs can produce surprisingly large IL at high A. Values are in peg-numeraire (tokens valued 1:1); fee income is not attributed in v1 (pool-global only); positions whose implied alpha is in the unreachable regime return None on il_percentage, net_pnl, and real_apr.","inputSchema":{"type":"object","required":["lp_init_amt","entry_amounts","pool_address","rpc_url","pool_type"],"properties":{"rpc_url":{"type":"string","description":"An Ethereum (or L2) JSON-RPC URL used to read live pool state. Required; supplied by you per call (BYO-RPC) and may carry your provider key. The endpoint stores and logs nothing — the URL is never persisted or written to logs."},"chain_id":{"type":"integer","description":"Optional guard. If supplied and the RPC reports a different chain id, the call is rejected. Defaults to 1 (Ethereum mainnet) conceptually; omit to skip the check."},"pool_type":{"enum":["stableswap"],"type":"string","description":"Which protocol the pool at pool_address belongs to. This tool accepts only stableswap (2-asset plain Curve pool)."},"lp_init_amt":{"type":"number","description":"LP tokens held by this position, in human units."},"block_number":{"type":"integer","description":"Optional block number to pin the read to a historical block. Omit to read the latest block."},"pool_address":{"type":"string","description":"On-chain address of the pool/pair to analyze (Uniswap V2/V3 pair, Balancer weighted pool, or Curve stableswap pool). Required. Lowercase, uppercase, or checksum casing all work."},"entry_amounts":{"type":"array","items":{"type":"number"},"maxItems":2,"minItems":2,"description":"Per-token entry amounts in pool insertion order. Exactly 2 entries (2-asset pools only in v1)."},"holding_period_days":{"type":["number","null"],"description":"Optional holding period in days. If supplied, real_apr is annualized from net_pnl."}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":563,"tokensAfter":563},{"name":"CalculateSlippage","fixed":{"name":"CalculateSlippage","description":"Calculate slippage and price-impact decomposition for a proposed swap on a Uniswap V2 or V3 pool. Returns spot vs execution price, slippage percentage, slippage cost in output-token units, and price impact. Also returns the maximum trade size that stays within 1% slippage for V2 pools; V3 returns null for that field because tick-crossing math has not yet been inverted.","inputSchema":{"type":"object","required":["pool_address","rpc_url","pool_type","token_in_name"],"properties":{"rpc_url":{"type":"string","description":"An Ethereum (or L2) JSON-RPC URL used to read live pool state. Required; supplied by you per call (BYO-RPC) and may carry your provider key. The endpoint stores and logs nothing — the URL is never persisted or written to logs."},"chain_id":{"type":"integer","description":"Optional guard. If supplied and the RPC reports a different chain id, the call is rejected. Defaults to 1 (Ethereum mainnet) conceptually; omit to skip the check."},"lwr_tick":{"type":["integer","null"],"description":"Lower tick of the position (V3 only; null for V2)."},"upr_tick":{"type":["integer","null"],"description":"Upper tick of the position (V3 only; null for V2)."},"amount_in":{"type":"number","description":"Amount of token_in to trade, in human units. Must be > 0."},"pool_type":{"enum":["uniswap_v2","uniswap_v3"],"type":"string","description":"Which protocol the pool at pool_address belongs to. This tool accepts uniswap_v2 | uniswap_v3."},"amounts_in":{"type":"array","items":{"type":"number"},"maxItems":256,"description":"Optional batch form of 'amount_in': an array of values to evaluate in a single call. The pool is read once and the result is an array with one entry per element, in input order. Supply EITHER 'amount_in' (single) OR 'amounts_in' (batch), not both. Max 256 entries."},"block_number":{"type":"integer","description":"Optional block number to pin the read to a historical block. Omit to read the latest block."},"pool_address":{"type":"string","description":"On-chain address of the pool/pair to analyze (Uniswap V2/V3 pair, Balancer weighted pool, or Curve stableswap pool). Required. Lowercase, uppercase, or checksum casing all work."},"token_in_name":{"type":"string","description":"Symbol of the input token for the trade (e.g. 'USDC', 'WETH'). Must be one of the two tokens in the pool."}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":661,"tokensAfter":661},{"name":"CheckPoolHealth","fixed":{"name":"CheckPoolHealth","description":"Snapshot pool-level health metrics for a Uniswap V2 or V3 pool: TVL in token0 numeraire, reserves, accumulated fees, LP concentration, and swap activity. Answers 'is this a pool I would deposit into?' at the pool level (not position level). num_swaps and fee_accrual_rate_recent are V2-only; V3 returns null for these because V3 has no per-swap history array. A single-block live snapshot also returns null for the LP-concentration and swap metrics (unrecoverable from state alone).","inputSchema":{"type":"object","required":["pool_address","rpc_url","pool_type"],"properties":{"rpc_url":{"type":"string","description":"An Ethereum (or L2) JSON-RPC URL used to read live pool state. Required; supplied by you per call (BYO-RPC) and may carry your provider key. The endpoint stores and logs nothing — the URL is never persisted or written to logs."},"chain_id":{"type":"integer","description":"Optional guard. If supplied and the RPC reports a different chain id, the call is rejected. Defaults to 1 (Ethereum mainnet) conceptually; omit to skip the check."},"pool_type":{"enum":["uniswap_v2","uniswap_v3"],"type":"string","description":"Which protocol the pool at pool_address belongs to. This tool accepts uniswap_v2 | uniswap_v3."},"block_number":{"type":"integer","description":"Optional block number to pin the read to a historical block. Omit to read the latest block."},"pool_address":{"type":"string","description":"On-chain address of the pool/pair to analyze (Uniswap V2/V3 pair, Balancer weighted pool, or Curve stableswap pool). Required. Lowercase, uppercase, or checksum casing all work."},"recent_window":{"type":["integer","null"],"description":"Rolling window size for fee_accrual_rate_recent, in swap counts. Default 20. V2-only; ignored for V3."}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":503,"tokensAfter":503}],"toolsChanged":5,"tokensSaved":0,"todo":[],"note":"Deterministic fixes. Changes marked verify need a human look before shipping (renames, inferred annotations, inferred types, removed text). Parameter descriptions in `todo` need to be written by someone who knows the API."}