madeonsol_kol_compare_wallets
Compare 2-5 KOL wallets side-by-side by strategy, winrates, ROI, and percentile. PRO+ reveals tokens bought by multiple wallets in the last 30 days.
Instructions
Side-by-side comparison of 2-5 KOL wallets — strategy, winrates, ROI, percentile. PRO+ adds 30d overlap tokens (bought by 2+ of the wallets).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| wallets | Yes | 2-5 wallet addresses. BASIC=2, PRO=4, ULTRA=5. |
Implementation Reference
- src/index.ts:268-278 (registration)The tool is registered with the MCP server under the name 'madeonsol_kol_compare_wallets'. It accepts 2-5 wallet addresses as an array of strings via Zod schema validation.
server.tool( "madeonsol_kol_compare_wallets", "Side-by-side comparison of 2-5 KOL wallets — strategy, winrates, ROI, percentile. PRO+ adds 30d overlap tokens (bought by 2+ of the wallets).", { wallets: z.array(z.string()).min(2).max(5).describe("2-5 wallet addresses. BASIC=2, PRO=4, ULTRA=5."), }, readOnlyAnnotations, async ({ wallets }) => ({ content: [{ type: "text" as const, text: await query("/api/x402/kol/compare", { wallets: wallets.join(",") }) }], }) ); - src/index.ts:275-278 (handler)The handler function joins the wallets array into a comma-separated string and calls the query() helper which proxies the request to the MadeOnSol API endpoint /api/x402/kol/compare. The response is returned as text content.
async ({ wallets }) => ({ content: [{ type: "text" as const, text: await query("/api/x402/kol/compare", { wallets: wallets.join(",") }) }], }) ); - src/index.ts:271-273 (schema)The input schema uses Zod to validate a 'wallets' parameter: an array of strings with a minimum of 2 and maximum of 5 entries.
{ wallets: z.array(z.string()).min(2).max(5).describe("2-5 wallet addresses. BASIC=2, PRO=4, ULTRA=5."), }, - src/index.ts:60-80 (helper)The query() helper function is used by the handler to make HTTP requests to the MadeOnSol API. It handles auth-mode-based routing (x402 vs api/v1), constructs URLs with params, and returns JSON-stringified responses.
async function query(path: string, params?: Record<string, string | number>) { // API key uses /api/v1/ endpoints; x402 uses /api/x402/ const apiPath = authMode === "x402" || authMode === "none" ? path : path.replace("/api/x402/", "/api/v1/"); const url = new URL(apiPath, BASE_URL); if (params) { for (const [k, v] of Object.entries(params)) { if (v !== undefined) url.searchParams.set(k, String(v)); } } const headers = apiKeyHeaders(); const res = authMode === "x402" ? await paidFetch(url.toString()) : await fetch(url.toString(), { headers }); if (!res.ok) { const body = await res.text().catch(() => ""); return `Error ${res.status}: ${body}`; } return JSON.stringify(await res.json(), null, 2); }