find_safest_vaults
Discover high-risk-scored DeFi vaults with filters for asset, chain, or TVL. Returns top 10 audited vaults sorted by risk score for due diligence.
Instructions
Find the safest (highest risk-scored) DeFi vaults, optionally filtered by asset, chain, or minimum TVL. Returns top 10 audited, high-confidence vaults sorted by risk score.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| asset | No | Filter by asset symbol (e.g. USDC, WETH) | |
| chain | No | Filter by chain name (e.g. Ethereum, Base) | |
| minTvl | No | Minimum TVL in USD |
Implementation Reference
- src/tools/find-safest-vaults.ts:6-49 (handler)Main tool implementation: registerFindSafestVaults function that registers the MCP tool with the server. Contains the async handler (lines 15-47) that queries the API for audited vaults, filters and sorts them by risk score (total_score), and returns the top 10 safest vaults formatted with vault summaries.export function registerFindSafestVaults(server: McpServer) { server.tool( 'find_safest_vaults', 'Find the safest (highest risk-scored) DeFi vaults, optionally filtered by asset, chain, or minimum TVL. Returns top 10 audited, high-confidence vaults sorted by risk score.', { asset: z.string().optional().describe('Filter by asset symbol (e.g. USDC, WETH)'), chain: z.string().optional().describe('Filter by chain name (e.g. Ethereum, Base)'), minTvl: z.number().optional().describe('Minimum TVL in USD'), }, async (params) => { const qs = buildQueryString({ asset: params.asset, chain: params.chain, minTvl: params.minTvl, audited: true, sortBy: 'tvl_usd', sortOrder: 'desc', limit: 50, page: 1, }); const result = await apiGet<{ data: any[]; meta: any }>(`/v1/vaults${qs}`); const vaults = result.data; const sorted = vaults .filter((v) => v.total_score !== null && v.total_score !== undefined) .sort((a, b) => (b.total_score ?? 0) - (a.total_score ?? 0)) .slice(0, 10); if (!sorted.length) { return { content: [ { type: 'text' as const, text: 'No audited vaults found matching the given criteria.' }, ], }; } const lines = sorted.map((v, i) => `**#${i + 1}**\n${formatVaultSummary(v)}`); const text = `## Top ${sorted.length} Safest Vaults\n\n` + lines.join('\n\n---\n\n'); return { content: [{ type: 'text' as const, text }] }; } ); }
- Input schema definition using Zod: defines three optional parameters - asset (string), chain (string), and minTvl (number) for filtering vaults.{ asset: z.string().optional().describe('Filter by asset symbol (e.g. USDC, WETH)'), chain: z.string().optional().describe('Filter by chain name (e.g. Ethereum, Base)'), minTvl: z.number().optional().describe('Minimum TVL in USD'), },
- src/server.ts:8-8 (registration)Import statement for the registerFindSafestVaults function from the tools module.import { registerFindSafestVaults } from './tools/find-safest-vaults';
- src/server.ts:35-35 (registration)Registration call: invokes registerFindSafestVaults(server) to register the tool with the MCP server instance.registerFindSafestVaults(server);
- src/lib/formatters.ts:1-22 (helper)Helper function formatVaultSummary that formats vault data into a readable markdown string including name, protocol, chain, asset, TVL, APR, risk score, and curator information. Used by the handler to format each vault in the results.export function formatVaultSummary(vault: any): string { const rs = vault.risk_score; const riskTier = vault.risk_tier || (rs != null && rs >= 8 ? 'Prime' : rs != null && rs >= 5 ? 'Core' : rs != null ? 'Edge' : 'N/A'); const score = vault.total_score ?? vault.risk_score ?? 'N/A'; return [ `## ${vault.name}`, `**Protocol:** ${vault.protocol_name} | **Chain:** ${vault.chain_name} | **Asset:** ${vault.asset_symbol || 'N/A'}`, `**TVL:** $${formatNumber(vault.tvl_usd)} | **APR:** ${formatPercent(vault.apr_net)}`, `**Risk Score:** ${score}/10 (${riskTier})`, vault.curator_name ? `**Curator:** ${vault.curator_name}` : null, ] .filter(Boolean) .join('\n'); }