Near-Liquidation Cohort Signals
query_cohort_criticalMonitor borrower health factor tiers to get early warning of near-liquidation cohorts. Track entry/exit rates and deterioration velocity for critical, high, and moderate tiers.
Instructions
Get near-liquidation cohort signals showing account populations by health factor tier (critical/high/moderate), entry/exit rates, and deterioration velocity. Early warning on borrowers entering critical health factor tiers. Source: Liquidationbot real-time telemetry.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| window | No | Time window for aggregation (default: 1h) | |
| network | No | Filter by blockchain network | |
| protocol | No | Filter by lending protocol |
Implementation Reference
- src/tools/crypto.ts:166-229 (registration)The 'query_cohort_critical' tool is registered via server.registerTool() in the registerCryptoTools() function.
server.registerTool( "query_cohort_critical", { title: "Near-Liquidation Cohort Signals", description: "Get near-liquidation cohort signals showing account populations by health " + "factor tier (critical/high/moderate), entry/exit rates, and deterioration " + "velocity. Early warning on borrowers entering critical health factor tiers. " + "Source: Liquidationbot real-time telemetry.", inputSchema: { window: z .enum(["5m", "1h", "24h"]) .optional() .describe("Time window for aggregation (default: 1h)"), network: z .enum(["ethereum", "arbitrum", "polygon", "base", "bsc", "avalanche"]) .optional() .describe("Filter by blockchain network"), protocol: z .enum([ "aave_v3", "compound_v3", "venus", "radiant", "morpho_blue", "llamalend", "zerolend", "makerdao", ]) .optional() .describe("Filter by lending protocol"), }, }, async ({ window, network, protocol }) => { const res = await apiGet<CryptoQueryResponse>( "/api/v1/crypto/cohorts/critical", { window: window ?? "1h", network, protocol, }, ); if (!res.ok) { return { content: [ { type: "text" as const, text: `API error (${res.status}): ${JSON.stringify(res.data)}`, }, ], isError: true, }; } const { count, data } = res.data; const summary = `Found ${count} cohort record(s) for window=${window ?? "1h"}.`; const json = JSON.stringify(data, null, 2); return { content: [{ type: "text" as const, text: `${summary}\n\n${json}` }], }; }, ); - src/tools/crypto.ts:199-228 (handler)The handler is an async callback passed to server.registerTool(). It calls apiGet to "/api/v1/crypto/cohorts/critical" and returns the response as text content.
async ({ window, network, protocol }) => { const res = await apiGet<CryptoQueryResponse>( "/api/v1/crypto/cohorts/critical", { window: window ?? "1h", network, protocol, }, ); if (!res.ok) { return { content: [ { type: "text" as const, text: `API error (${res.status}): ${JSON.stringify(res.data)}`, }, ], isError: true, }; } const { count, data } = res.data; const summary = `Found ${count} cohort record(s) for window=${window ?? "1h"}.`; const json = JSON.stringify(data, null, 2); return { content: [{ type: "text" as const, text: `${summary}\n\n${json}` }], }; }, - src/tools/crypto.ts:175-197 (schema)Input schema using Zod: optional window (5m/1h/24h), optional network (6 chains), optional protocol (8 lending protocols).
inputSchema: { window: z .enum(["5m", "1h", "24h"]) .optional() .describe("Time window for aggregation (default: 1h)"), network: z .enum(["ethereum", "arbitrum", "polygon", "base", "bsc", "avalanche"]) .optional() .describe("Filter by blockchain network"), protocol: z .enum([ "aave_v3", "compound_v3", "venus", "radiant", "morpho_blue", "llamalend", "zerolend", "makerdao", ]) .optional() .describe("Filter by lending protocol"), }, - src/client.ts:44-76 (helper)The apiGet helper from src/client.ts is used by the handler to make HTTP GET requests to the Verilex API server.
export async function apiGet<T = unknown>( path: string, params?: Record<string, string | number | undefined>, ): Promise<ApiResponse<T>> { const url = buildUrl(path, params); const headers: Record<string, string> = { Accept: "application/json", "User-Agent": "verilex-mcp-server/0.1.0", }; // Forward x402 payment token if present in env (for paid endpoints) const paymentToken = process.env.VERILEX_PAYMENT_TOKEN; if (paymentToken) { headers["X-Payment-Token"] = paymentToken; } const res = await fetch(url, { headers }); const data = (await res.json()) as T; const stale = res.headers.get("X-Data-Stale"); const lastUpdated = res.headers.get("X-Data-Last-Updated"); const ageSeconds = res.headers.get("X-Data-Age-Seconds"); return { ok: res.ok, status: res.status, data, stale: stale === "true", lastUpdated: lastUpdated ?? undefined, ageSeconds: ageSeconds ? Number(ageSeconds) : undefined, }; } - src/client.ts:17-23 (helper)The CryptoQueryResponse interface defines the shape of the API response used by the query_cohort_critical handler.
if (v !== undefined && v !== "") { url.searchParams.set(k, String(v)); } } } return url.toString(); }