get_vault_risk_breakdown
Analyze DeFi vault risk by retrieving detailed breakdowns of asset composition, platform code, and governance scores with sub-metrics for due diligence.
Instructions
Get a detailed breakdown of a vault's risk vectors: Asset Composition, Platform Code, and Governance scores with sub-metrics.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| network | Yes | Network slug (e.g. ethereum, base, arbitrum) | |
| address | Yes | Vault contract address (0x...) |
Implementation Reference
- Main handler function that executes the get_vault_risk_breakdown tool logic. Fetches vault data via API, extracts risk vectors, and formats a detailed breakdown of Asset Composition, Platform Code, and Governance scores with sub-metrics into a human-readable markdown response.async (params) => { const result = await apiGet<{ data: any }>(`/v1/vault/${params.network}/${params.address}`); const vault = result.data.vault; const round = (n: number) => Math.round(n * 100) / 100; const sections = [ `## Risk Breakdown: ${vault.name}`, `**Overall Score:** ${round(vault.total_score ?? vault.risk_score ?? 0)}/10 (${vault.risk_tier})`, ]; const rv = vault.risk_vectors; if (!rv) { sections.push('\nNo detailed risk vector data available for this vault.'); return { content: [{ type: 'text' as const, text: sections.join('\n') }] }; } // Asset Composition sections.push('\n### Vector 1: Asset Composition (40% weight)'); if (rv.asset) { sections.push(`**Score:** ${round(rv.asset.score)}/10`); if (rv.asset.details?.breakdown?.length) { sections.push('**Collateral mix:**'); for (const item of rv.asset.details.breakdown) { const weight = (item.weight * 100).toFixed(1); sections.push(`- ${item.asset}: ${item.score}/10 (${weight}% weight)`); } } } else { sections.push('No asset composition data.'); } // Platform Code sections.push('\n### Vector 2: Platform Code (40% weight)'); if (rv.platform) { sections.push(`**Score:** ${round(rv.platform.score)}/10`); if (rv.platform.details) { const d = rv.platform.details; if (d.lindyScore !== undefined) sections.push(`- Lindy Score (time-based safety): ${round(d.lindyScore)}/10`); if (d.auditScore !== undefined) sections.push(`- Audit Density Score: ${d.auditScore}/10`); if (d.dependencyCount !== undefined) sections.push(`- Dependencies: ${d.dependencyCount}`); if (d.dependencies?.length) { for (const dep of d.dependencies) { sections.push( ` - ${dep.protocolId}: score ${dep.score}/10, safety factor ${dep.safetyFactor}x` ); } } if (d.daysSinceIncident !== undefined) sections.push(`- Days Since Incident: ${d.daysSinceIncident}`); if (d.incidentPenaltyApplied) sections.push( `- Incident Penalty: Applied (capped at ${d.incidentPenaltyCap ?? 'N/A'})` ); } } else { sections.push('No platform code data.'); } // Governance sections.push('\n### Vector 3: Governance (20% weight)'); if (rv.control) { sections.push(`**Score:** ${round(rv.control.score)}/10`); if (rv.control.details) { const d = rv.control.details; if (d.isImmutable !== undefined) sections.push(`- Immutable: ${d.isImmutable ? 'Yes' : 'No'}`); if (d.timelock !== undefined) { const hours = Math.floor(d.timelock / 3600); const days = Math.floor(d.timelock / 86400); sections.push( `- Timelock: ${d.timelock >= 86400 ? `${days} days` : `${hours} hours`} (${d.timelock}s)` ); } if (d.governanceType) sections.push(`- Governance Type: ${d.governanceType}`); } } else { sections.push('No governance data.'); } return { content: [{ type: 'text' as const, text: sections.join('\n') }] }; }
- Tool registration with schema definition. Defines the tool name 'get_vault_risk_breakdown', its description, and the input schema with two required parameters: network (string) and address (string).export function registerGetVaultRiskBreakdown(server: McpServer) { server.tool( 'get_vault_risk_breakdown', "Get a detailed breakdown of a vault's risk vectors: Asset Composition, Platform Code, and Governance scores with sub-metrics.", { network: z.string().describe('Network slug (e.g. ethereum, base, arbitrum)'), address: z.string().describe('Vault contract address (0x...)'), },
- src/server.ts:6-6 (registration)Import statement for the registerGetVaultRiskBreakdown function.import { registerGetVaultRiskBreakdown } from './tools/get-vault-risk-breakdown';
- src/server.ts:33-33 (registration)Tool registration call that registers get_vault_risk_breakdown with the MCP server instance.registerGetVaultRiskBreakdown(server);
- src/api-client.ts:3-19 (helper)API client helper function used by the handler to fetch vault data from the Philidor API endpoint.export async function apiGet<T = any>(path: string): Promise<T> { const res = await fetch(`${API_BASE}${path}`, { headers: { Accept: 'application/json' }, }); if (!res.ok) { let message: string; try { const json = (await res.json()) as Record<string, any>; message = json?.error?.message || json?.message || JSON.stringify(json); } catch { message = res.statusText || `HTTP ${res.status}`; } throw new Error(`API ${res.status}: ${message}`); } const json = await res.json(); return json as T; }