@continuumdao/ctm-mpc-defi 0.2.9 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/agent/catalog.cjs +522 -19
  2. package/dist/agent/catalog.cjs.map +1 -1
  3. package/dist/agent/catalog.d.ts +639 -14
  4. package/dist/agent/catalog.js +510 -20
  5. package/dist/agent/catalog.js.map +1 -1
  6. package/dist/agent/skills/hyperliquid/SKILL.md +34 -6
  7. package/dist/agent/skills/morpho/SKILL.md +63 -0
  8. package/dist/core/index.cjs +9 -0
  9. package/dist/core/index.cjs.map +1 -1
  10. package/dist/core/index.d.ts +3 -1
  11. package/dist/core/index.js +8 -1
  12. package/dist/core/index.js.map +1 -1
  13. package/dist/index.cjs +9 -0
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.js +8 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
  19. package/dist/protocols/evm/aave-v4/index.js.map +1 -1
  20. package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
  21. package/dist/protocols/evm/euler-v2/index.js.map +1 -1
  22. package/dist/protocols/evm/hyperliquid/index.cjs +407 -34
  23. package/dist/protocols/evm/hyperliquid/index.cjs.map +1 -1
  24. package/dist/protocols/evm/hyperliquid/index.d.ts +168 -15
  25. package/dist/protocols/evm/hyperliquid/index.js +390 -35
  26. package/dist/protocols/evm/hyperliquid/index.js.map +1 -1
  27. package/dist/protocols/evm/maple/index.cjs.map +1 -1
  28. package/dist/protocols/evm/maple/index.js.map +1 -1
  29. package/dist/protocols/evm/morpho/index.cjs +1971 -0
  30. package/dist/protocols/evm/morpho/index.cjs.map +1 -0
  31. package/dist/protocols/evm/morpho/index.d.ts +522 -0
  32. package/dist/protocols/evm/morpho/index.js +1918 -0
  33. package/dist/protocols/evm/morpho/index.js.map +1 -0
  34. package/dist/protocols/evm/sky/index.cjs.map +1 -1
  35. package/dist/protocols/evm/sky/index.js.map +1 -1
  36. package/package.json +6 -1
@@ -523,6 +523,9 @@ var chainDetailSchema = zod.z.object({
523
523
  "Optional gas config: { legacy?, gasLimit?, gasMultiplier?, gasPrice?, baseFee?, priorityFee?, baseFeeMultiplier? }."
524
524
  );
525
525
  var evmMultisignCommonInputSchema = zod.z.object({
526
+ keyGenId: zod.z.string().min(1).optional().describe(
527
+ "KeyGen request id from get_preferred_key_gen / conversation context. MCP server resolves keyGen, executorAddress, rpcUrl, and chainDetail \u2014 do not pass those fields when keyGenId is set."
528
+ ),
526
529
  keyGen: keyGenSchema,
527
530
  purposeText: zod.z.string().min(1).describe(
528
531
  "Human-readable purpose for the sign request. Stored in bodyForSign.purpose (may be appended with an automatic batch suffix)."
@@ -927,6 +930,74 @@ var mcpEulerV2CollateralWithdrawInputSchema = mcpMultisignInput({
927
930
  collateralAsset: evmAddressSchema,
928
931
  amountHuman: zod.z.string().min(1)
929
932
  });
933
+ var mcpMorphoVaultDepositInputSchema = mcpMultisignInput({
934
+ vault: evmAddressSchema,
935
+ underlying: evmAddressSchema.describe("Underlying asset; use wrapped native with isNativeIn for ETH."),
936
+ amountHuman: zod.z.string().min(1),
937
+ isNativeIn: zod.z.boolean().optional()
938
+ });
939
+ var mcpMorphoVaultWithdrawInputSchema = mcpMultisignInput({
940
+ vault: evmAddressSchema,
941
+ amountHuman: zod.z.string().min(1)
942
+ });
943
+ var mcpMorphoBlueCollateralDepositInputSchema = mcpMultisignInput({
944
+ marketId: zod.z.string().min(1).describe("Morpho Blue marketId from API."),
945
+ collateralToken: evmAddressSchema,
946
+ amountHuman: zod.z.string().min(1),
947
+ isNativeIn: zod.z.boolean().optional()
948
+ });
949
+ var mcpMorphoBlueBorrowInputSchema = mcpMultisignInput({
950
+ marketId: zod.z.string().min(1),
951
+ loanToken: evmAddressSchema,
952
+ amountHuman: zod.z.string().min(1)
953
+ });
954
+ var mcpMorphoBlueRepayInputSchema = mcpMultisignInput({
955
+ marketId: zod.z.string().min(1),
956
+ loanToken: evmAddressSchema,
957
+ amountHuman: zod.z.string().min(1)
958
+ });
959
+ var mcpMorphoBlueCollateralWithdrawInputSchema = mcpMultisignInput({
960
+ marketId: zod.z.string().min(1),
961
+ amountHuman: zod.z.string().min(1),
962
+ collateralDecimals: zod.z.number().int().min(0).max(36).optional()
963
+ });
964
+ var mcpMorphoMerklClaimInputSchema = mcpMultisignInput({
965
+ claimData: zod.z.string().min(1).describe("Hex calldata for Merkl Distributor.claim from Merkl API."),
966
+ distributor: evmAddressSchema.optional(),
967
+ valueWei: zod.z.string().optional()
968
+ });
969
+ var morphoExposureRowSchema = zod.z.object({
970
+ label: zod.z.string(),
971
+ allocatedUsdLabel: zod.z.string(),
972
+ allocationPercentLabel: zod.z.string()
973
+ });
974
+ var mcpMorphoFetchEarnVaultsInputSchema = zod.z.object({
975
+ chainId: zod.z.number().int().positive(),
976
+ underlying: zod.z.string().trim().min(1).optional().describe("Deposit asset symbol (e.g. USDC) or ERC-20 address. Omit to search all listed vaults on the chain."),
977
+ query: zod.z.string().trim().min(1).optional().describe("Case-insensitive filter on vault name, symbol, address, or underlying symbol (e.g. Steakhouse, bbqUSDC)."),
978
+ limit: zod.z.number().int().min(1).max(200).optional().describe("Max rows (default 50).")
979
+ });
980
+ var mcpMorphoFetchEarnVaultsOutputSchema = zod.z.object({
981
+ vaults: zod.z.array(
982
+ zod.z.object({
983
+ vaultAddress: zod.z.string(),
984
+ vaultName: zod.z.string(),
985
+ vaultSymbol: zod.z.string(),
986
+ underlyingAddress: zod.z.string(),
987
+ underlyingSymbol: zod.z.string(),
988
+ apy: zod.z.string(),
989
+ netApy: zod.z.string(),
990
+ netApy7d: zod.z.string(),
991
+ netApy30d: zod.z.string(),
992
+ netApy90d: zod.z.string(),
993
+ performanceFee: zod.z.string(),
994
+ managementFee: zod.z.string().nullable(),
995
+ totalDepositsUsd: zod.z.string(),
996
+ liquidityUsd: zod.z.string(),
997
+ exposure: zod.z.array(morphoExposureRowSchema)
998
+ })
999
+ )
1000
+ });
930
1001
  function mcpGmxMultisignInput(fields) {
931
1002
  return evmMultisignCommonInputSchema.extend(fields);
932
1003
  }
@@ -1131,7 +1202,8 @@ var mcpHyperliquidFetchMarketsOutputSchema = zod.z.object({
1131
1202
  asset: zod.z.number(),
1132
1203
  szDecimals: zod.z.number(),
1133
1204
  maxLeverage: zod.z.number(),
1134
- onlyIsolated: zod.z.boolean().optional()
1205
+ onlyIsolated: zod.z.boolean().optional(),
1206
+ dex: zod.z.string().optional()
1135
1207
  })
1136
1208
  ),
1137
1209
  dexes: zod.z.array(
@@ -1141,6 +1213,30 @@ var mcpHyperliquidFetchMarketsOutputSchema = zod.z.object({
1141
1213
  })
1142
1214
  )
1143
1215
  });
1216
+ var mcpHyperliquidSearchMarketsInputSchema = zod.z.object({
1217
+ chainId: zod.z.number().int().positive(),
1218
+ query: zod.z.string().min(1),
1219
+ dex: zod.z.string().optional(),
1220
+ limit: zod.z.number().int().positive().max(50).optional()
1221
+ });
1222
+ var mcpHyperliquidSearchMarketsOutputSchema = zod.z.object({
1223
+ matches: zod.z.array(
1224
+ zod.z.object({
1225
+ coin: zod.z.string(),
1226
+ symbol: zod.z.string(),
1227
+ dex: zod.z.string().optional(),
1228
+ asset: zod.z.number(),
1229
+ szDecimals: zod.z.number(),
1230
+ maxLeverage: zod.z.number(),
1231
+ onlyIsolated: zod.z.boolean().optional(),
1232
+ displayName: zod.z.string().optional(),
1233
+ category: zod.z.string().optional(),
1234
+ keywords: zod.z.array(zod.z.string()).optional(),
1235
+ matchScore: zod.z.number(),
1236
+ matchReason: zod.z.string()
1237
+ })
1238
+ )
1239
+ });
1144
1240
  var mcpHyperliquidFetchOpenContextInputSchema = zod.z.object({
1145
1241
  chainId: zod.z.number().int().positive(),
1146
1242
  executorAddress: evmAddressSchema,
@@ -1183,25 +1279,70 @@ var mcpHyperliquidFetchMarketSnapshotInputSchema = zod.z.object({
1183
1279
  chainId: zod.z.number().int().positive(),
1184
1280
  coin: zod.z.string().min(1),
1185
1281
  interval: hyperliquidOhlcvIntervalSchema.optional(),
1186
- dex: zod.z.string().optional()
1282
+ dex: zod.z.string().optional(),
1283
+ /** Recent OHLCV bars to return (default 48, max 200). Live price is always current. */
1284
+ candleLimit: zod.z.number().int().positive().max(200).optional()
1285
+ });
1286
+ var hyperliquidOhlcvCandleSchema = zod.z.object({
1287
+ timestampMs: zod.z.number(),
1288
+ open: zod.z.string(),
1289
+ high: zod.z.string(),
1290
+ low: zod.z.string(),
1291
+ close: zod.z.string(),
1292
+ volume: zod.z.string()
1293
+ });
1294
+ var hyperliquidLivePriceSchema = zod.z.object({
1295
+ markPx: zod.z.string().nullable(),
1296
+ midPx: zod.z.string().nullable(),
1297
+ oraclePx: zod.z.string().nullable(),
1298
+ prevDayPx: zod.z.string().nullable(),
1299
+ midUsd: zod.z.string(),
1300
+ source: zod.z.enum(["midPx", "markPx", "allMids"])
1187
1301
  });
1188
1302
  var mcpHyperliquidFetchMarketSnapshotOutputSchema = zod.z.object({
1189
1303
  snapshot: zod.z.object({
1190
1304
  coin: zod.z.string(),
1191
- midUsd: zod.z.string().nullable(),
1305
+ dex: zod.z.string().nullable(),
1306
+ livePrice: hyperliquidLivePriceSchema,
1307
+ midUsd: zod.z.string(),
1192
1308
  fetchedAtMs: zod.z.number(),
1193
1309
  interval: hyperliquidOhlcvIntervalSchema,
1194
- candles: zod.z.array(
1195
- zod.z.object({
1196
- timestampMs: zod.z.number(),
1197
- open: zod.z.string(),
1198
- high: zod.z.string(),
1199
- low: zod.z.string(),
1200
- close: zod.z.string(),
1201
- volume: zod.z.string()
1202
- })
1203
- )
1204
- })
1310
+ latestCandle: hyperliquidOhlcvCandleSchema.nullable(),
1311
+ candles: zod.z.array(hyperliquidOhlcvCandleSchema),
1312
+ candleCount: zod.z.number()
1313
+ }),
1314
+ resolvedCoin: zod.z.string(),
1315
+ dex: zod.z.string().nullable()
1316
+ });
1317
+ var mcpHyperliquidFetchOhlcvInputSchema = zod.z.object({
1318
+ chainId: zod.z.number().int().positive(),
1319
+ coin: zod.z.string().min(1),
1320
+ interval: hyperliquidOhlcvIntervalSchema.optional(),
1321
+ dex: zod.z.string().optional(),
1322
+ /** Calendar-day lookback ending now (e.g. 7 = last week). Preferred for agent requests. */
1323
+ lookbackDays: zod.z.number().positive().max(90).optional(),
1324
+ /** Hour lookback ending now. Alternative to lookbackDays. */
1325
+ lookbackHours: zod.z.number().positive().max(90 * 24).optional(),
1326
+ /** Explicit range start (ms since epoch). Use with endTimeMs. */
1327
+ startTimeMs: zod.z.number().int().positive().optional(),
1328
+ /** Explicit range end (ms since epoch). Defaults to now. */
1329
+ endTimeMs: zod.z.number().int().positive().optional()
1330
+ });
1331
+ var mcpHyperliquidFetchOhlcvOutputSchema = zod.z.object({
1332
+ ohlcv: zod.z.object({
1333
+ coin: zod.z.string(),
1334
+ dex: zod.z.string().nullable(),
1335
+ interval: hyperliquidOhlcvIntervalSchema,
1336
+ startTimeMs: zod.z.number(),
1337
+ endTimeMs: zod.z.number(),
1338
+ expectedBars: zod.z.number(),
1339
+ candleCount: zod.z.number(),
1340
+ latestCandle: hyperliquidOhlcvCandleSchema.nullable(),
1341
+ candles: zod.z.array(hyperliquidOhlcvCandleSchema),
1342
+ fetchedAtMs: zod.z.number()
1343
+ }),
1344
+ resolvedCoin: zod.z.string(),
1345
+ dex: zod.z.string().nullable()
1205
1346
  });
1206
1347
  var mcpHyperliquidFetchUsdClassBalancesInputSchema = zod.z.object({
1207
1348
  chainId: zod.z.number().int().positive(),
@@ -1612,6 +1753,87 @@ var MCP_PROTOCOL_TOOL_DEFINITIONS = [
1612
1753
  handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2BorrowCollateralWithdrawBatch" },
1613
1754
  inputZod: mcpEulerV2CollateralWithdrawInputSchema
1614
1755
  }),
1756
+ defineProtocolMcpTool({
1757
+ name: "ctm_morpho_build_vault_deposit_multisign",
1758
+ actionId: "morpho.vault-deposit",
1759
+ protocolId: "morpho",
1760
+ chainCategory: "evm",
1761
+ description: "Build Morpho vault deposit batch (wrap/approve + deposit). Works with listed V1 and V2 vaults.",
1762
+ prerequisites: [
1763
+ "keyGenId",
1764
+ "chainId",
1765
+ "vaultAddress from ctm_morpho_fetch_earn_vaults",
1766
+ "underlying",
1767
+ "amountHuman"
1768
+ ],
1769
+ handler: { importPath: "protocols/evm/morpho", exportName: "buildEvmMultisignBodyMorphoVaultDepositBatch" },
1770
+ inputZod: mcpMorphoVaultDepositInputSchema
1771
+ }),
1772
+ defineProtocolMcpTool({
1773
+ name: "ctm_morpho_build_vault_withdraw_multisign",
1774
+ actionId: "morpho.vault-withdraw",
1775
+ protocolId: "morpho",
1776
+ chainCategory: "evm",
1777
+ description: "Build Morpho vault withdraw batch. Works with listed V1 and V2 vaults.",
1778
+ prerequisites: [
1779
+ "keyGenId",
1780
+ "chainId",
1781
+ "vaultAddress from ctm_morpho_fetch_earn_vaults or user positions",
1782
+ "amountHuman"
1783
+ ],
1784
+ handler: { importPath: "protocols/evm/morpho", exportName: "buildEvmMultisignBodyMorphoVaultWithdraw" },
1785
+ inputZod: mcpMorphoVaultWithdrawInputSchema
1786
+ }),
1787
+ defineProtocolMcpTool({
1788
+ name: "ctm_morpho_build_blue_collateral_deposit_multisign",
1789
+ actionId: "morpho.blue-collateral-deposit",
1790
+ protocolId: "morpho",
1791
+ chainCategory: "evm",
1792
+ description: "Build Morpho Blue supplyCollateral batch.",
1793
+ prerequisites: ["keyGenId", "chainId", "marketId", "collateralToken", "amountHuman"],
1794
+ handler: { importPath: "protocols/evm/morpho", exportName: "buildEvmMultisignBodyMorphoBlueSupplyCollateralBatch" },
1795
+ inputZod: mcpMorphoBlueCollateralDepositInputSchema
1796
+ }),
1797
+ defineProtocolMcpTool({
1798
+ name: "ctm_morpho_build_blue_borrow_multisign",
1799
+ actionId: "morpho.blue-borrow",
1800
+ protocolId: "morpho",
1801
+ chainCategory: "evm",
1802
+ description: "Build Morpho Blue borrow batch.",
1803
+ prerequisites: ["keyGenId", "chainId", "marketId", "loanToken", "amountHuman"],
1804
+ handler: { importPath: "protocols/evm/morpho", exportName: "buildEvmMultisignBodyMorphoBlueBorrowBatch" },
1805
+ inputZod: mcpMorphoBlueBorrowInputSchema
1806
+ }),
1807
+ defineProtocolMcpTool({
1808
+ name: "ctm_morpho_build_blue_repay_multisign",
1809
+ actionId: "morpho.blue-repay",
1810
+ protocolId: "morpho",
1811
+ chainCategory: "evm",
1812
+ description: "Build Morpho Blue repay batch.",
1813
+ prerequisites: ["keyGenId", "chainId", "marketId", "loanToken", "amountHuman"],
1814
+ handler: { importPath: "protocols/evm/morpho", exportName: "buildEvmMultisignBodyMorphoBlueRepayBatch" },
1815
+ inputZod: mcpMorphoBlueRepayInputSchema
1816
+ }),
1817
+ defineProtocolMcpTool({
1818
+ name: "ctm_morpho_build_blue_collateral_withdraw_multisign",
1819
+ actionId: "morpho.blue-collateral-withdraw",
1820
+ protocolId: "morpho",
1821
+ chainCategory: "evm",
1822
+ description: "Build Morpho Blue withdrawCollateral batch.",
1823
+ prerequisites: ["keyGenId", "chainId", "marketId", "amountHuman"],
1824
+ handler: { importPath: "protocols/evm/morpho", exportName: "buildEvmMultisignBodyMorphoBlueWithdrawCollateralBatch" },
1825
+ inputZod: mcpMorphoBlueCollateralWithdrawInputSchema
1826
+ }),
1827
+ defineProtocolMcpTool({
1828
+ name: "ctm_morpho_build_merkl_claim_multisign",
1829
+ actionId: "morpho.merkl-claim",
1830
+ protocolId: "morpho",
1831
+ chainCategory: "evm",
1832
+ description: "Build Morpho Merkl Distributor.claim transaction.",
1833
+ prerequisites: ["keyGenId", "chainId", "claim calldata from Merkl API"],
1834
+ handler: { importPath: "protocols/evm/morpho", exportName: "buildEvmMultisignBodyMorphoMerklDistributorClaim" },
1835
+ inputZod: mcpMorphoMerklClaimInputSchema
1836
+ }),
1615
1837
  defineProtocolMcpTool({
1616
1838
  name: "ctm_gmx_build_increase_multisign",
1617
1839
  actionId: "gmx.increase",
@@ -2135,19 +2357,31 @@ var CORE_MCP_TOOL_DEFINITIONS = [
2135
2357
  actionId: "hyperliquid.fetch-markets",
2136
2358
  protocolId: "hyperliquid",
2137
2359
  chainCategory: "evm",
2138
- description: "List Hyperliquid perp markets (coin, maxLeverage, szDecimals) and HIP-3 dex names. chainId 999 mainnet or 998 testnet.",
2360
+ description: "List Hyperliquid perp markets (native + all HIP-3 dexes when dex omitted). Each market has coin name, maxLeverage, szDecimals, and optional dex (e.g. xyz for xyz:AAPL). chainId 999 mainnet or 998 testnet.",
2139
2361
  prerequisites: ["chainId 999 or 998"],
2140
2362
  followUp: ["ctm_hyperliquid_fetch_open_context", "ctm_hyperliquid_build_limit_order_multisign"],
2141
2363
  handler: { importPath: "protocols/evm/hyperliquid", exportName: "hyperliquidFetchMarketsSummary" },
2142
2364
  inputZod: mcpHyperliquidFetchMarketsInputSchema,
2143
2365
  outputZod: mcpHyperliquidFetchMarketsOutputSchema
2144
2366
  }),
2367
+ defineMcpTool({
2368
+ name: "ctm_hyperliquid_search_markets",
2369
+ actionId: "hyperliquid.search-markets",
2370
+ protocolId: "hyperliquid",
2371
+ chainCategory: "evm",
2372
+ description: "Search Hyperliquid perp markets across all dexes by ticker (AAPL, BTC), display name, or keyword (Apple, tesla). Case-insensitive. Returns canonical coin names (e.g. xyz:AAPL).",
2373
+ prerequisites: ["chainId 999 or 998", "query"],
2374
+ followUp: ["ctm_hyperliquid_fetch_open_context", "ctm_hyperliquid_build_limit_order_multisign"],
2375
+ handler: { importPath: "protocols/evm/hyperliquid", exportName: "hyperliquidSearchMarketsSummary" },
2376
+ inputZod: mcpHyperliquidSearchMarketsInputSchema,
2377
+ outputZod: mcpHyperliquidSearchMarketsOutputSchema
2378
+ }),
2145
2379
  defineMcpTool({
2146
2380
  name: "ctm_hyperliquid_fetch_open_context",
2147
2381
  actionId: "hyperliquid.fetch-open-context",
2148
2382
  protocolId: "hyperliquid",
2149
2383
  chainCategory: "evm",
2150
- description: "Per-market trading context: account value, withdrawable, margin used, leverage setting, mark price, available buy/sell size.",
2384
+ description: "Per-market trading context: account value, withdrawable, margin used, leverage setting, mark price, available buy/sell size. Resolves ticker/name (AAPL, Apple) across dexes.",
2151
2385
  prerequisites: ["chainId", "executorAddress", "coin from fetch_markets"],
2152
2386
  followUp: ["ctm_hyperliquid_build_limit_order_multisign"],
2153
2387
  handler: { importPath: "protocols/evm/hyperliquid", exportName: "hyperliquidFetchOpenContextSummary" },
@@ -2183,13 +2417,25 @@ var CORE_MCP_TOOL_DEFINITIONS = [
2183
2417
  actionId: "hyperliquid.fetch-market-snapshot",
2184
2418
  protocolId: "hyperliquid",
2185
2419
  chainCategory: "evm",
2186
- description: "Mid price and OHLCV candles for a Hyperliquid perp coin. Default interval 15m.",
2420
+ description: "Live mark/mid price plus recent OHLCV candles for a Hyperliquid perp. Uses metaAndAssetCtxs for live prices (not stale candle close). Default interval 15m, 48 bars. Throws if live price unavailable.",
2187
2421
  prerequisites: ["chainId", "coin"],
2188
2422
  followUp: ["ctm_hyperliquid_fetch_open_context", "ctm_hyperliquid_build_limit_order_multisign"],
2189
2423
  handler: { importPath: "protocols/evm/hyperliquid", exportName: "hyperliquidFetchMarketSnapshotSummary" },
2190
2424
  inputZod: mcpHyperliquidFetchMarketSnapshotInputSchema,
2191
2425
  outputZod: mcpHyperliquidFetchMarketSnapshotOutputSchema
2192
2426
  }),
2427
+ defineMcpTool({
2428
+ name: "ctm_hyperliquid_fetch_ohlcv",
2429
+ actionId: "hyperliquid.fetch-ohlcv",
2430
+ protocolId: "hyperliquid",
2431
+ chainCategory: "evm",
2432
+ description: "OHLCV candle history for a Hyperliquid perp over an explicit lookback or time range. Requests only the needed window from Hyperliquid (e.g. lookbackDays: 7, interval: 15m \u2192 ~672 bars). Max 2000 bars \u2014 use coarser interval for longer history. Resolves ticker/name across dexes.",
2433
+ prerequisites: ["chainId 999 or 998", "coin", "lookbackDays or lookbackHours or startTimeMs"],
2434
+ followUp: ["ctm_hyperliquid_fetch_market_snapshot", "ctm_hyperliquid_build_limit_order_multisign"],
2435
+ handler: { importPath: "protocols/evm/hyperliquid", exportName: "hyperliquidFetchOhlcvSummary" },
2436
+ inputZod: mcpHyperliquidFetchOhlcvInputSchema,
2437
+ outputZod: mcpHyperliquidFetchOhlcvOutputSchema
2438
+ }),
2193
2439
  defineMcpTool({
2194
2440
  name: "ctm_hyperliquid_fetch_usd_class_balances",
2195
2441
  actionId: "hyperliquid.fetch-usd-balances",
@@ -2249,6 +2495,21 @@ var CORE_MCP_TOOL_DEFINITIONS = [
2249
2495
  handler: { importPath: "protocols/evm/hyperliquid", exportName: "hyperliquidFetchDelegationsForExecutor" },
2250
2496
  inputZod: mcpHyperliquidFetchDelegationsInputSchema,
2251
2497
  outputZod: mcpHyperliquidFetchDelegationsOutputSchema
2498
+ }),
2499
+ defineMcpTool({
2500
+ name: "ctm_morpho_fetch_earn_vaults",
2501
+ actionId: "morpho.fetch-earn-vaults",
2502
+ protocolId: "morpho",
2503
+ chainCategory: "evm",
2504
+ description: "Morpho-listed earn vaults (V1 + V2 unified). Filter by deposit asset symbol/address and/or case-insensitive vault name search. Returns vaultAddress for deposit/withdraw multisign tools.",
2505
+ prerequisites: ["chainId"],
2506
+ followUp: [
2507
+ "ctm_morpho_build_vault_deposit_multisign",
2508
+ "ctm_morpho_build_vault_withdraw_multisign"
2509
+ ],
2510
+ handler: { importPath: "protocols/evm/morpho", exportName: "morphoFetchEarnVaultsSummary" },
2511
+ inputZod: mcpMorphoFetchEarnVaultsInputSchema,
2512
+ outputZod: mcpMorphoFetchEarnVaultsOutputSchema
2252
2513
  })
2253
2514
  ];
2254
2515
  var MCP_TOOL_DEFINITIONS = [
@@ -2475,7 +2736,30 @@ registerProtocolModule(ethenaProtocolModule);
2475
2736
  function isMapleSyrupSupportedChain(chainId) {
2476
2737
  return chainId === 1 || chainId === 11155111;
2477
2738
  }
2739
+
2740
+ // src/core/defiProxy.ts
2741
+ var aaveGraphqlProxyUrl;
2742
+ var morphoGraphqlProxyUrl;
2743
+ function getAaveGraphqlProxyUrl() {
2744
+ return aaveGraphqlProxyUrl;
2745
+ }
2746
+ function getMorphoGraphqlProxyUrl() {
2747
+ return morphoGraphqlProxyUrl;
2748
+ }
2478
2749
  async function postJsonViaOptionalProxy(args) {
2750
+ const proxy = args.proxyUrl?.trim();
2751
+ if (proxy) {
2752
+ const r2 = await fetch(proxy, {
2753
+ method: "POST",
2754
+ headers: { "content-type": "application/json" },
2755
+ body: JSON.stringify(args.proxyEnvelope ?? args.body)
2756
+ });
2757
+ if (!r2.ok) {
2758
+ const t = await r2.text().catch(() => "");
2759
+ throw new Error(t ? `Proxy HTTP ${r2.status}: ${t.slice(0, 200)}` : `Proxy HTTP ${r2.status}`);
2760
+ }
2761
+ return await r2.json();
2762
+ }
2479
2763
  const r = await fetch(args.directUrl, {
2480
2764
  method: "POST",
2481
2765
  headers: { "content-type": "application/json" },
@@ -2538,7 +2822,10 @@ async function aaveV4Gql(query, variables) {
2538
2822
  const body = { query, variables: variables ?? {} };
2539
2823
  const j = await postJsonViaOptionalProxy({
2540
2824
  directUrl: AAVE_V4_GRAPHQL_URL,
2541
- body});
2825
+ body,
2826
+ proxyUrl: getAaveGraphqlProxyUrl(),
2827
+ proxyEnvelope: body
2828
+ });
2542
2829
  if (j.errors?.length) {
2543
2830
  const msg = j.errors.map((e) => e.message ?? "Unknown").join("; ");
2544
2831
  throw new Error(msg);
@@ -3011,6 +3298,175 @@ var hyperliquidProtocolModule = {
3011
3298
  ]
3012
3299
  };
3013
3300
  registerProtocolModule(hyperliquidProtocolModule);
3301
+ var MORPHO_GRAPHQL_URL = "https://api.morpho.org/graphql";
3302
+ async function morphoGql(query, variables) {
3303
+ const body = { query, variables: variables ?? {} };
3304
+ const j = await postJsonViaOptionalProxy({
3305
+ directUrl: MORPHO_GRAPHQL_URL,
3306
+ body,
3307
+ proxyUrl: getMorphoGraphqlProxyUrl(),
3308
+ proxyEnvelope: body
3309
+ });
3310
+ if (j.errors?.length) {
3311
+ const msg = j.errors.map((e) => e.message ?? "Unknown").join("; ");
3312
+ throw new Error(msg);
3313
+ }
3314
+ if (j.data == null) throw new Error("Morpho API: empty response");
3315
+ return j.data;
3316
+ }
3317
+ async function fetchMorphoChains() {
3318
+ const d = await morphoGql(`
3319
+ query { chains { id network } }
3320
+ `);
3321
+ return d.chains ?? [];
3322
+ }
3323
+ async function loadMorphoSupportedChainIds() {
3324
+ const rows = await fetchMorphoChains();
3325
+ const s = /* @__PURE__ */ new Set();
3326
+ for (const c of rows) {
3327
+ if (typeof c.id === "number" && Number.isFinite(c.id)) s.add(c.id);
3328
+ }
3329
+ return s;
3330
+ }
3331
+ var VAULT_PAGE_SIZE = 100;
3332
+ async function fetchMorphoVaultsForChain(chainId, first = 100) {
3333
+ const d = await morphoGql(
3334
+ `
3335
+ query MorphoVaults($chainId: Int!, $first: Int!) {
3336
+ vaults(first: $first, where: { chainId_in: [$chainId], listed: true }, orderBy: TotalAssetsUsd, orderDirection: Desc) {
3337
+ items {
3338
+ address symbol name listed
3339
+ asset { address symbol decimals price { usd } }
3340
+ chain { id }
3341
+ state { apy netApy fee totalAssetsUsd allRewards { supplyApr asset { address symbol } } }
3342
+ }
3343
+ }
3344
+ }
3345
+ `,
3346
+ { chainId, first }
3347
+ );
3348
+ return d.vaults?.items ?? [];
3349
+ }
3350
+ async function fetchMorphoVaultV2sForChain(chainId, first = 100, skip = 0) {
3351
+ const d = await morphoGql(
3352
+ `
3353
+ query MorphoVaultV2s($chainId: Int!, $first: Int!, $skip: Int!) {
3354
+ vaultV2s(
3355
+ first: $first
3356
+ skip: $skip
3357
+ where: { chainId_in: [$chainId], listed: true }
3358
+ orderBy: TotalAssetsUsd
3359
+ orderDirection: Desc
3360
+ ) {
3361
+ items {
3362
+ address symbol name listed
3363
+ asset { address symbol decimals price { usd } }
3364
+ chain { id }
3365
+ apy netApy performanceFee managementFee totalAssetsUsd
3366
+ rewards { supplyApr asset { address symbol } }
3367
+ }
3368
+ }
3369
+ }
3370
+ `,
3371
+ { chainId, first, skip }
3372
+ );
3373
+ return d.vaultV2s?.items ?? [];
3374
+ }
3375
+ async function fetchAllMorphoVaultV2AssetAddresses(chainId) {
3376
+ const out = /* @__PURE__ */ new Set();
3377
+ let skip = 0;
3378
+ for (let page = 0; page < 20; page++) {
3379
+ const batch = await fetchMorphoVaultV2sForChain(chainId, VAULT_PAGE_SIZE, skip);
3380
+ if (!batch.length) break;
3381
+ for (const v of batch) {
3382
+ const a = (v.asset?.address ?? "").trim();
3383
+ if (viem.isAddress(a)) out.add(viem.getAddress(a).toLowerCase());
3384
+ }
3385
+ if (batch.length < VAULT_PAGE_SIZE) break;
3386
+ skip += VAULT_PAGE_SIZE;
3387
+ }
3388
+ return out;
3389
+ }
3390
+ var chainAssetCache = /* @__PURE__ */ new Map();
3391
+ async function ensureMorphoChainAssetCache(chainId) {
3392
+ const hit = chainAssetCache.get(chainId);
3393
+ if (hit) return hit;
3394
+ const modes = /* @__PURE__ */ new Map();
3395
+ const [v1Vaults, v2Assets] = await Promise.all([
3396
+ fetchMorphoVaultsForChain(chainId, 300),
3397
+ fetchAllMorphoVaultV2AssetAddresses(chainId)
3398
+ ]);
3399
+ for (const v of v1Vaults) {
3400
+ const a = (v.asset?.address ?? "").trim();
3401
+ if (!viem.isAddress(a)) continue;
3402
+ const k = viem.getAddress(a).toLowerCase();
3403
+ const prev = modes.get(k) ?? { earn: false, borrow: false, collateral: false };
3404
+ prev.earn = true;
3405
+ modes.set(k, prev);
3406
+ }
3407
+ for (const k of v2Assets) {
3408
+ const prev = modes.get(k) ?? { earn: false, borrow: false, collateral: false };
3409
+ prev.earn = true;
3410
+ modes.set(k, prev);
3411
+ }
3412
+ const marketsD = await morphoGql(
3413
+ `
3414
+ query MorphoMarketsAssets($chainId: Int!) {
3415
+ markets(first: 500, where: { chainId_in: [$chainId] }) {
3416
+ items {
3417
+ loanAsset { address }
3418
+ collateralAsset { address }
3419
+ }
3420
+ }
3421
+ }
3422
+ `,
3423
+ { chainId }
3424
+ );
3425
+ for (const m of marketsD.markets?.items ?? []) {
3426
+ const loanAddr = (m.loanAsset?.address ?? "").trim();
3427
+ const colAddr = (m.collateralAsset?.address ?? "").trim();
3428
+ if (viem.isAddress(loanAddr)) {
3429
+ const k = viem.getAddress(loanAddr).toLowerCase();
3430
+ const prev = modes.get(k) ?? { earn: false, borrow: false, collateral: false };
3431
+ prev.borrow = true;
3432
+ modes.set(k, prev);
3433
+ }
3434
+ if (viem.isAddress(colAddr)) {
3435
+ const k = viem.getAddress(colAddr).toLowerCase();
3436
+ const prev = modes.get(k) ?? { earn: false, borrow: false, collateral: false };
3437
+ prev.collateral = true;
3438
+ modes.set(k, prev);
3439
+ }
3440
+ }
3441
+ const cache = { modesByUnderlying: modes, nativeWrapped: null };
3442
+ chainAssetCache.set(chainId, cache);
3443
+ return cache;
3444
+ }
3445
+
3446
+ // src/protocols/evm/morpho/index.ts
3447
+ var MORPHO_PROTOCOL_ID = "morpho";
3448
+ var morphoProtocolModule = {
3449
+ id: MORPHO_PROTOCOL_ID,
3450
+ chainCategory: "evm",
3451
+ isChainSupported(ctx) {
3452
+ return ctx.chainCategory === "evm";
3453
+ },
3454
+ isTokenSupported(token) {
3455
+ return token.category === "evm" && (token.kind === "native" || token.kind === "erc20");
3456
+ },
3457
+ actions: [
3458
+ { id: "morpho.fetch-earn-vaults", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Search Morpho-listed earn vaults by asset or name", commonParams: [], params: {} },
3459
+ { id: "morpho.vault-deposit", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Deposit into Morpho-listed earn vault (V1 or V2)", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
3460
+ { id: "morpho.vault-withdraw", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Withdraw from Morpho earn vault (V1 or V2)", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
3461
+ { id: "morpho.blue-collateral-deposit", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Supply collateral to Morpho Blue market", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
3462
+ { id: "morpho.blue-borrow", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Borrow from Morpho Blue market", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
3463
+ { id: "morpho.blue-repay", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Repay Morpho Blue borrow", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
3464
+ { id: "morpho.blue-collateral-withdraw", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Withdraw Morpho Blue collateral", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
3465
+ { id: "morpho.merkl-claim", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Claim Morpho Merkl rewards", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
3466
+ { id: "morpho.midnight-borrow", protocolId: MORPHO_PROTOCOL_ID, chainCategory: "evm", description: "Morpho Midnight fixed-rate borrow (coming soon)", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
3467
+ ]
3468
+ };
3469
+ registerProtocolModule(morphoProtocolModule);
3014
3470
  var skillsDir = path.join(path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('catalog.cjs', document.baseURI).href)))), "skills");
3015
3471
  var SKILL_PROTOCOL_IDS = [
3016
3472
  "aave-v4",
@@ -3022,7 +3478,8 @@ var SKILL_PROTOCOL_IDS = [
3022
3478
  "maple-syrup",
3023
3479
  "sky",
3024
3480
  "gmx",
3025
- "hyperliquid"
3481
+ "hyperliquid",
3482
+ "morpho"
3026
3483
  ];
3027
3484
  function getToolsForProtocol(protocolId) {
3028
3485
  return MCP_TOOL_DEFINITIONS.filter((t) => t.protocolId === protocolId);
@@ -3236,6 +3693,37 @@ var PROTOCOL_SUPPORT_ADVISORS = {
3236
3693
  return { tokens: [] };
3237
3694
  }
3238
3695
  }),
3696
+ morpho: advisor("morpho", "api_underlyings", {
3697
+ async supportedChainIds() {
3698
+ const set = await loadMorphoSupportedChainIds();
3699
+ return [...set].sort((a, b) => a - b);
3700
+ },
3701
+ async supportedTokens(chainId) {
3702
+ const cache = await ensureMorphoChainAssetCache(chainId);
3703
+ const tokens = [...cache.modesByUnderlying.entries()].map(([address, modes]) => ({
3704
+ address,
3705
+ roles: [
3706
+ ...modes.earn ? ["vault_underlying"] : [],
3707
+ ...modes.borrow ? ["loan"] : [],
3708
+ ...modes.collateral ? ["collateral"] : []
3709
+ ]
3710
+ }));
3711
+ return {
3712
+ tokens,
3713
+ notes: "Morpho vault assets and Blue market loan/collateral tokens from api.morpho.org."
3714
+ };
3715
+ },
3716
+ async isTokenSupported(chainId, address) {
3717
+ const cache = await ensureMorphoChainAssetCache(chainId);
3718
+ let normalized;
3719
+ try {
3720
+ normalized = viem.getAddress(address).toLowerCase();
3721
+ } catch {
3722
+ return false;
3723
+ }
3724
+ return cache.modesByUnderlying.has(normalized);
3725
+ }
3726
+ }),
3239
3727
  "euler-v2": advisor("euler-v2", "subgraph_vaults", {
3240
3728
  async supportedChainIds() {
3241
3729
  return [...EULER_V2_SUBGRAPH_CHAIN_IDS];
@@ -3317,6 +3805,7 @@ registerProtocolModule(aaveV4ProtocolModule);
3317
3805
  registerProtocolModule(eulerV2ProtocolModule);
3318
3806
  registerProtocolModule(gmxProtocolModule);
3319
3807
  registerProtocolModule(hyperliquidProtocolModule);
3808
+ registerProtocolModule(morphoProtocolModule);
3320
3809
  function getAgentCatalog() {
3321
3810
  return {
3322
3811
  protocols: getProtocolModules(),
@@ -3335,6 +3824,7 @@ function getAgentCatalog() {
3335
3824
  eulerV2: eulerV2ProtocolModule,
3336
3825
  gmx: gmxProtocolModule,
3337
3826
  hyperliquid: hyperliquidProtocolModule,
3827
+ morpho: morphoProtocolModule,
3338
3828
  /** Prefer getAgentCatalogForMcp() or getMcpToolDefinitions() for MCP servers. */
3339
3829
  mcp: getAgentCatalogForMcp()
3340
3830
  };
@@ -3416,6 +3906,8 @@ exports.mcpHyperliquidFetchMarketSnapshotInputSchema = mcpHyperliquidFetchMarket
3416
3906
  exports.mcpHyperliquidFetchMarketSnapshotOutputSchema = mcpHyperliquidFetchMarketSnapshotOutputSchema;
3417
3907
  exports.mcpHyperliquidFetchMarketsInputSchema = mcpHyperliquidFetchMarketsInputSchema;
3418
3908
  exports.mcpHyperliquidFetchMarketsOutputSchema = mcpHyperliquidFetchMarketsOutputSchema;
3909
+ exports.mcpHyperliquidFetchOhlcvInputSchema = mcpHyperliquidFetchOhlcvInputSchema;
3910
+ exports.mcpHyperliquidFetchOhlcvOutputSchema = mcpHyperliquidFetchOhlcvOutputSchema;
3419
3911
  exports.mcpHyperliquidFetchOpenContextInputSchema = mcpHyperliquidFetchOpenContextInputSchema;
3420
3912
  exports.mcpHyperliquidFetchOpenContextOutputSchema = mcpHyperliquidFetchOpenContextOutputSchema;
3421
3913
  exports.mcpHyperliquidFetchOpenOrdersInputSchema = mcpHyperliquidFetchOpenOrdersInputSchema;
@@ -3431,6 +3923,8 @@ exports.mcpHyperliquidFetchUserVaultEquitiesOutputSchema = mcpHyperliquidFetchUs
3431
3923
  exports.mcpHyperliquidFetchVaultsInputSchema = mcpHyperliquidFetchVaultsInputSchema;
3432
3924
  exports.mcpHyperliquidFetchVaultsOutputSchema = mcpHyperliquidFetchVaultsOutputSchema;
3433
3925
  exports.mcpHyperliquidLimitOrderInputSchema = mcpHyperliquidLimitOrderInputSchema;
3926
+ exports.mcpHyperliquidSearchMarketsInputSchema = mcpHyperliquidSearchMarketsInputSchema;
3927
+ exports.mcpHyperliquidSearchMarketsOutputSchema = mcpHyperliquidSearchMarketsOutputSchema;
3434
3928
  exports.mcpHyperliquidStakeInputSchema = mcpHyperliquidStakeInputSchema;
3435
3929
  exports.mcpHyperliquidUndelegateInputSchema = mcpHyperliquidUndelegateInputSchema;
3436
3930
  exports.mcpHyperliquidUnstakeInputSchema = mcpHyperliquidUnstakeInputSchema;
@@ -3444,6 +3938,15 @@ exports.mcpLidoUnwrapWstEthInputSchema = mcpLidoUnwrapWstEthInputSchema;
3444
3938
  exports.mcpLidoWrapStEthInputSchema = mcpLidoWrapStEthInputSchema;
3445
3939
  exports.mcpMapleDepositInputSchema = mcpMapleDepositInputSchema;
3446
3940
  exports.mcpMapleRequestRedeemInputSchema = mcpMapleRequestRedeemInputSchema;
3941
+ exports.mcpMorphoBlueBorrowInputSchema = mcpMorphoBlueBorrowInputSchema;
3942
+ exports.mcpMorphoBlueCollateralDepositInputSchema = mcpMorphoBlueCollateralDepositInputSchema;
3943
+ exports.mcpMorphoBlueCollateralWithdrawInputSchema = mcpMorphoBlueCollateralWithdrawInputSchema;
3944
+ exports.mcpMorphoBlueRepayInputSchema = mcpMorphoBlueRepayInputSchema;
3945
+ exports.mcpMorphoFetchEarnVaultsInputSchema = mcpMorphoFetchEarnVaultsInputSchema;
3946
+ exports.mcpMorphoFetchEarnVaultsOutputSchema = mcpMorphoFetchEarnVaultsOutputSchema;
3947
+ exports.mcpMorphoMerklClaimInputSchema = mcpMorphoMerklClaimInputSchema;
3948
+ exports.mcpMorphoVaultDepositInputSchema = mcpMorphoVaultDepositInputSchema;
3949
+ exports.mcpMorphoVaultWithdrawInputSchema = mcpMorphoVaultWithdrawInputSchema;
3447
3950
  exports.mcpMultisignInput = mcpMultisignInput;
3448
3951
  exports.mcpMultisignOutputSchema = multisignOutputSchema;
3449
3952
  exports.mcpMultisignSubmitOutputSchema = mcpServerSubmitOutputSchema;