list_popular
Discover top-rated AI tools by listing Spark assets with the highest download counts. Filter by asset type and set result limits to find popular agents, skills, prompts, and connectors.
Instructions
List the most popular Spark assets by download count. Great for discovering top-rated AI tools.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Filter by asset type | |
| limit | No | Number of results (1-20, default 10) |
Implementation Reference
- src/index.ts:313-343 (handler)The list_popular tool registration and handler function. It calls the Spark API with sort='popular' parameter, filters by optional asset type, formats results using formatAssetSummary helper, and returns a ranked list of assets by downloads.
server.tool( "list_popular", "List the most popular Spark assets by download count. Great for discovering top-rated AI tools.", { type: z .enum(["agent", "skill", "prompt", "prompt_chain", "mcp_connector", "bundle"]) .optional() .describe("Filter by asset type"), limit: z.number().min(1).max(20).default(10).describe("Number of results (1-20, default 10)"), }, async ({ type, limit }) => { const params = new URLSearchParams(); params.set("sort", "popular"); params.set("page_size", String(limit)); if (type) params.set("asset_type", type); const res = await sparkApi<PaginatedResponse<AssetListItem>>( `/assets?${params.toString()}` ); const text = [ `Top ${res.items.length} ${type || "all"} assets by downloads:`, "", ...res.items.map( (a, i) => `${i + 1}. ${formatAssetSummary(a)}` ), ].join("\n"); return { content: [{ type: "text" as const, text }] }; } ); - src/index.ts:115-137 (helper)The formatAssetSummary helper function used by list_popular to format each asset into a readable markdown string with badges, rating, downloads, pricing, tags, domains, and URL.
function formatAssetSummary(a: AssetListItem): string { const badges = [ a.is_featured ? "Featured" : "", a.is_verified ? "Verified" : "", ] .filter(Boolean) .join(", "); const badgeStr = badges ? ` [${badges}]` : ""; return [ `**${a.title}**${badgeStr}`, `Type: ${a.type} | Rating: ${a.rating_avg.toFixed(1)}/5 (${a.rating_count}) | Downloads: ${a.downloads_count}`, `${a.short_description}`, `Price: ${a.pricing_type === "free" ? "Free" : `${a.price_credits} EVC`}`, a.ai_tags.length ? `AI Models: ${a.ai_tags.join(", ")}` : "", a.domain_tags.length ? `Domains: ${a.domain_tags.map((d) => d.child_name).join(", ")}` : "", `URL: ${assetUrl(a)}`, ] .filter(Boolean) .join("\n"); } - src/index.ts:59-75 (schema)AssetListItem interface defining the shape of asset data returned from the Spark API, which is used by list_popular to type the response items.
interface AssetListItem { id: string; type: string; title: string; slug: string; short_description: string; ai_tags: string[]; domain_tags: { parent_name: string; child_name: string; child_slug: string }[]; pricing_type: string; price_credits: number; downloads_count: number; rating_avg: number; rating_count: number; is_featured: boolean; is_verified: boolean; created_at: string; } - src/index.ts:88-93 (schema)PaginatedResponse generic interface defining the paginated API response structure used by list_popular to type the API response.
interface PaginatedResponse<T> { items: T[]; total: number; page: number; page_size: number; } - src/index.ts:43-53 (helper)The sparkApi HTTP helper function used by list_popular to make authenticated requests to the Spark API endpoint with proper error handling.
async function sparkApi<T = unknown>(path: string): Promise<T> { const url = `${SPARK_API}${path}`; const res = await fetch(url, { headers: { Accept: "application/json" }, }); if (!res.ok) { const text = await res.text().catch(() => res.statusText); throw new Error(`Spark API ${res.status}: ${text}`); } return res.json() as Promise<T>; }