Morpho vaults
The io.b3os/morpho pack: 2 actions with call snippets, fixture outputs, connection setup and error codes, generated from version 1.0.0.
io.b3os/morpho 1.0.0 · defi, crypto, yield · MIT
Yields of Morpho (MetaMorpho) lending vaults from Morpho's public API, no key needed: the current gross and net APY, TVL and asset of one vault, and the Morpho-listed vaults with the best net APY for a token on Ethereum, Optimism, Polygon, Base and Arbitrum. Read-only: no deposits, withdrawals or claims.
Every call's result carries upstream_status and timing: validate_ms, inject_ms, render_ms, upstream_ms, map_ms and total_ms. upstream is the service's time; the others are B3OS's own (call actions). The snippets below show no timing values, because a fixture records none.
Connection
No credential: a keyless public API. Calls name no connection.
Hosts it reaches: blue-api.morpho.org.
Actions
| Action | Effect | MCP tool | Title |
|---|---|---|---|
get-vault-apy | read | morpho__get-vault-apy | Morpho Get Vault APY |
get-best-apy | read | morpho__get-best-apy | Morpho Get Best APY |
get-vault-apy
Morpho Get Vault APY. Get the current APY for a specific Morpho vault by its contract address. Returns gross APY, net APY (after fees), TVL, and underlying asset info. Unlike 'Morpho Get Best APY' which discovers the highest-yielding vault for a token, this action looks up a known vault directly — use it when you already know which vault to check (e.g., after a deposit or withdrawal). Supports Ethereum (1), Optimism (10), Polygon (137), Base (8453), Arbitrum (42161). Ideal for: post-deposit APY reporting, vault monitoring, Slack/Telegram notifications with accurate yield data.
Ref io.b3os/morpho/get-vault-apy@1.0.0 · effect read · no connection · MCP tool morpho__get-vault-apy
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/morpho/get-vault-apy@1", "input": { "vaultAddress": "0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB", "chainId": 1 } }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/morpho/get-vault-apy@1", input: { vaultAddress: "0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB", chainId: 1, },});console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/morpho/get-vault-apy@1", "input": { "vaultAddress": "0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB", "chainId": 1, },})print(result["output"])
json{ "method": "tools/call", "params": { "name": "morpho__get-vault-apy", "arguments": { "vaultAddress": "0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB", "chainId": 1 } }}
Expose the pack as tools with --packs morpho on the local server or ?packs=morpho on the remote URL, and the agent calls morpho__get-vault-apy with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Morpho Get Vault APY (response recorded 2026-10-26). From the bundle's fixtures/get-vault-apy.json, not a live call.
json{ "vaultAddress": "0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB", "vaultName": "Steakhouse USDC", "chainId": 1, "chainName": "ethereum", "apy": 0.04529931837636922, "netApy": 0.04298637199839875, "apyPercent": 4.529931837636922, "netApyPercent": 4.298637199839875, "totalAssets": "63660977431758", "totalAssetsUsd": 63643025.68580706, "assetAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "assetSymbol": "USDC", "assetDecimals": 6}
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
not_found | matched on the response body | no | Morpho has no vault at that address on that chain. |
invalid_request | matched on the response body | no | built from the service's response |
rate_limited | 429 | yes | Morpho's API is rate limiting this address; retry shortly. |
get-best-apy
Morpho Get Best APY. Get the best vault APY for a token on Morpho Blue protocol. Only returns Morpho-curated vaults (excludes unlisted/test vaults). Requires a token contract address. Omit chainId to search all supported chains at once. Supports minApyPercent and limit filters for targeted vault discovery. Supports Ethereum (1), Optimism (10), Polygon (137), Base (8453), Arbitrum (42161). Ideal for: yield optimization, vault discovery, APY comparison, DeFi strategy selection, cross-chain yield alerts.
Ref io.b3os/morpho/get-best-apy@1.0.0 · effect read · no connection · MCP tool morpho__get-best-apy
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/morpho/get-best-apy@1", "input": { "tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "chainId": 1, "limit": 3 } }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/morpho/get-best-apy@1", input: { tokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", chainId: 1, limit: 3, },});console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/morpho/get-best-apy@1", "input": { "tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "chainId": 1, "limit": 3, },})print(result["output"])
json{ "method": "tools/call", "params": { "name": "morpho__get-best-apy", "arguments": { "tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "chainId": 1, "limit": 3 } }}
Expose the pack as tools with --packs morpho on the local server or ?packs=morpho on the remote URL, and the agent calls morpho__get-best-apy with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Morpho Get Best APY (response recorded 2026-10-26). From the bundle's fixtures/get-best-apy.json, not a live call.
json{ "tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "tokenSymbol": "USDC", "chainId": 1, "bestVault": { "address": "0xbeEF346d7099865208Ff331e4f648f4154DDAa05", "name": "Waterline Reservoir USDC", "state": { "apy": 0.08019315771107231, "netApy": 0.07603488380906098, "totalAssets": "580969291127", "totalAssetsUsd": 580805.4637159178 }, "chainId": 1, "chainName": "ethereum" }, "allVaults": [ { "address": "0xbeEF346d7099865208Ff331e4f648f4154DDAa05", "name": "Waterline Reservoir USDC", "state": { "apy": 0.08019315771107231, "netApy": 0.07603488380906098, "totalAssets": "580969291127", "totalAssetsUsd": 580805.4637159178 }, "chainId": 1, "chainName": "ethereum" }, { "address": "0xF9bdDd4A9b3A45f980e11fDDE96e16364dDBEc49", "name": "Yearn OG USDC", "state": { "apy": 0.06232364521884255, "netApy": 0.06457036690612555, "totalAssets": "10208638915106", "totalAssetsUsd": 10205760.183115035 }, "chainId": 1, "chainName": "ethereum"
The first 40 of 56 lines; the fixture file has the rest.
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
not_found | matched on the response body | no | Morpho has no vault at that address on that chain. |
invalid_request | matched on the response body | no | built from the service's response |
rate_limited | 429 | yes | Morpho's API is rate limiting this address; retry shortly. |