Polymarket Thin Book Detection
pm_micro_thinDetects thin order book markets susceptible to slippage or manipulation. Shows markets below a liquidity threshold with spread metrics.
Instructions
Detect markets with thin order books that may be susceptible to slippage or manipulation. Shows markets below a liquidity threshold with spread metrics. Cost: $0.005 per query. Source: Polymarket order book analysis.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| threshold | No | Liquidity threshold in USD (markets below this are flagged) | |
| limit | No | Maximum results (default 25) |
Implementation Reference
- src/tools/pm_micro.ts:89-138 (handler)Handler function for the pm_micro_thin tool. Calls /api/v1/pm/micro/thin with threshold and limit params, returns API results or error.
server.registerTool( "pm_micro_thin", { title: "Polymarket Thin Book Detection", description: "Detect markets with thin order books that may be susceptible to slippage or " + "manipulation. Shows markets below a liquidity threshold with spread metrics. " + "Cost: $0.005 per query. Source: Polymarket order book analysis.", inputSchema: { threshold: z .number() .optional() .describe("Liquidity threshold in USD (markets below this are flagged)"), limit: z .number() .int() .min(1) .max(100) .optional() .describe("Maximum results (default 25)"), }, }, async ({ threshold, limit }) => { const res = await apiGet<PmMicroQueryResponse>("/api/v1/pm/micro/thin", { threshold: threshold ?? 50, limit: limit ?? 25, }); 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 warn = stalenessWarning(res); const summary = `${warn}Found ${count} thin book market(s).`; const json = JSON.stringify(data, null, 2); return { content: [{ type: "text" as const, text: `${summary}\n\n${json}` }], }; }, ); - src/tools/pm_micro.ts:97-109 (schema)Input schema for pm_micro_thin: optional threshold (number) and limit (int 1-100).
inputSchema: { threshold: z .number() .optional() .describe("Liquidity threshold in USD (markets below this are flagged)"), limit: z .number() .int() .min(1) .max(100) .optional() .describe("Maximum results (default 25)"), }, - src/index.ts:58-58 (registration)Registration call in the main index.ts that wires up all pm_micro tools including pm_micro_thin.
registerPmMicroTools(server); - src/tools/pm_micro.ts:28-28 (registration)The registration function that calls server.registerTool for pm_micro_thin (and other pm_micro tools).
export function registerPmMicroTools(server: McpServer): void { - src/client.ts:44-76 (helper)The apiGet helper used by the handler to make HTTP GET requests to the Verilex API, including staleness detection.
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:35-41 (helper)The stalenessWarning helper used by the handler to append stale data warnings to the output.
export function stalenessWarning(res: ApiResponse): string { if (!res.stale) return ""; const parts = ["[STALE DATA]"]; if (res.lastUpdated) parts.push(`Last updated: ${res.lastUpdated}`); if (res.ageSeconds != null) parts.push(`Age: ${res.ageSeconds}s`); return parts.join(" ") + "\n\n"; }