Skip to main content
Glama
search-icons.ts4.59 kB
import type Database from "better-sqlite3"; import { listIconTypes, searchIcons } from "../db/queries.js"; export interface SearchIconsInput { query: string; type?: string; size?: number; limit?: number; } export function handleSearchIcons( db: Database.Database, input: SearchIconsInput ): { content: Array<{ type: "text"; text: string }> } { const { query, type, size, limit = 20 } = input; if (!query || query.trim().length === 0) { // If no query, list available icon types const types = listIconTypes(db); return { content: [ { type: "text", text: JSON.stringify( { message: "Please provide a search query. Here are the available icon types:", types: types.map((t) => `${t.type} (${t.count} icons)`), example: 'search_icons({ query: "arrow", type: "navigation" })', }, null, 2 ), }, ], }; } // Build FTS query with prefix matching const searchStrategies = buildSearchStrategies(query); // Try each strategy until we find results for (const ftsQuery of searchStrategies) { try { const results = searchIcons(db, ftsQuery, { type, size, limit }); if (results.length > 0) { return formatResults(results, query, type, size); } } catch { // FTS5 syntax error - try next strategy continue; } } // No results found const types = listIconTypes(db); return { content: [ { type: "text", text: JSON.stringify( { query, resultCount: 0, message: `No icons found for "${query}". Try a different search term.`, availableTypes: types.map((t) => t.type), }, null, 2 ), }, ], }; } // Build multiple FTS5 search strategies from strict to fuzzy function buildSearchStrategies(query: string): string[] { // Clean query - remove special characters, normalize spaces const cleaned = query.replace(/[^\w\s]/g, " "); const terms = cleaned .trim() .split(/\s+/) .filter((term) => term.length > 1); if (terms.length === 0) { return [`${query.trim()}*`]; } if (terms.length === 1) { return [`${terms[0]}*`]; } // Multiple terms: try AND then OR return [terms.map((t) => `${t}*`).join(" AND "), terms.map((t) => `${t}*`).join(" OR ")]; } function formatResults( results: Array<{ name: string; iconName: string; type: string; size: number; viewBox: string; }>, query: string, type?: string, size?: number ): { content: Array<{ type: "text"; text: string }> } { // Group by icon name to show available sizes const grouped = new Map<string, { iconName: string; type: string; sizes: number[] }>(); for (const icon of results) { const key = icon.iconName; if (!grouped.has(key)) { grouped.set(key, { iconName: icon.iconName, type: icon.type, sizes: [], }); } grouped.get(key)?.sizes.push(icon.size); } const output = { query, filters: { type: type || "all", size: size || "all" }, resultCount: results.length, uniqueIcons: grouped.size, icons: Array.from(grouped.values()).map((g) => ({ name: g.iconName, type: g.type, availableSizes: g.sizes.sort((a, b) => a - b), usage: { react: `import { ${g.iconName}${g.sizes[0]} } from "@mozaic-ds/icons/js/icons"`, vue: `<MIcon name="${g.iconName}${g.sizes[0]}" />`, }, })), }; return { content: [ { type: "text", text: JSON.stringify(output, null, 2), }, ], }; } // Tool definition for MCP export const searchIconsTool = { name: "search_icons", description: "Search Mozaic Design System icons by name, type (navigation, media, social, etc.), or size (16, 24, 32, 48, 64)", inputSchema: { type: "object" as const, properties: { query: { type: "string", description: 'Search query for icon name (e.g., "arrow", "cart", "user", "check")', }, type: { type: "string", description: 'Filter by icon type/category (e.g., "navigation", "media", "social", "payment")', }, size: { type: "number", description: "Filter by icon size in pixels (16, 24, 32, 48, or 64)", }, limit: { type: "number", default: 20, description: "Maximum number of results to return", }, }, required: ["query"], }, };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MerzoukeMansouri/adeo-mozaic-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server