get_curator_info
Retrieve detailed curator analytics including managed vaults, TVL, chain distribution, and performance metrics for DeFi risk assessment.
Instructions
Get detailed information about a vault curator including their managed vaults, TVL, chain distribution, and performance.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| curatorId | Yes | Curator ID |
Implementation Reference
- src/tools/get-curator-info.ts:6-18 (handler)Main handler implementation for get_curator_info tool. Registers the tool with input schema (curatorId) and executes the async handler that fetches curator data via API and formats the response.export function registerGetCuratorInfo(server: McpServer) { server.tool( 'get_curator_info', 'Get detailed information about a vault curator including their managed vaults, TVL, chain distribution, and performance.', { curatorId: z.string().describe('Curator ID'), }, async (params) => { const result = await apiGet<{ data: any }>(`/v1/curators/${params.curatorId}`); const text = formatCuratorInfo(result.data); return { content: [{ type: 'text' as const, text }] }; } );
- src/tools/get-curator-info.ts:10-12 (schema)Input schema definition using zod. Validates that curatorId is a required string parameter.{ curatorId: z.string().describe('Curator ID'), },
- src/server.ts:37-37 (registration)Registration of get_curator_info tool in the server initialization. Calls registerGetCuratorInfo to register the tool with the MCP server.registerGetCuratorInfo(server);
- src/lib/formatters.ts:145-170 (helper)formatCuratorInfo helper function that formats the raw API response data into a human-readable markdown string with curator name, TVL, vault count, APR, chain distribution, and top vaults.export function formatCuratorInfo(data: any): string { const { curator, vaults, chainDistribution } = data; const sections = [ `## ${curator.name}`, curator.one_liner ? `\n${curator.one_liner}` : '', `\n**TVL:** $${formatNumber(curator.tvl_total)} | **Vaults:** ${curator.vault_count} | **Avg APR:** ${formatPercent(curator.avg_apr)}`, ].filter(Boolean); if (chainDistribution?.length) { sections.push('\n### Chain Distribution'); for (const c of chainDistribution) { sections.push(`- **${c.name}**: ${c.vault_count} vaults, $${formatNumber(c.tvl)} TVL`); } } if (vaults?.length) { sections.push(`\n### Top Vaults (${Math.min(vaults.length, 5)} of ${vaults.length})`); for (const v of vaults.slice(0, 5)) { sections.push( `- **${v.name}** (${v.chain_name || 'Unknown'}): $${formatNumber(v.tvl_usd)} TVL, ${formatPercent(v.apr_net)} APR, Score ${v.total_score ?? v.risk_score ?? 'N/A'}/10` ); } } return sections.join('\n'); }
- src/api-client.ts:3-19 (helper)apiGet helper function that makes HTTP GET requests to the Philidor API with proper error handling and JSON response parsing.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; }