design_search_styles
Search for design inspiration by style, including color palettes, typography, layouts, or animation references. Combines image and web search results to provide visual references.
Instructions
Search for a specific aesthetic direction — color palettes, typography, layouts, or animation references. Runs image and web search in parallel and returns combined results.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| style | Yes | Design style to search for. Examples: "minimalist dark theme", "brutalist web design", "glassmorphism" | |
| type | No | Type of style inspiration to search for | general |
| num | No | Number of results (1-20, default: 10) |
Implementation Reference
- src/index.ts:307-393 (handler)The registration and handler implementation for the 'design_search_styles' tool, which performs parallel image and web searches using the Serper API based on the user's style and type preferences.
server.registerTool("design_search_styles", { title: "Search design styles", description: `Search for a specific aesthetic direction — color palettes, typography, layouts, or animation references. Runs image and web search in parallel and returns combined results.`, inputSchema: SearchStyleInputSchema, annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true, }, }, async (params: SearchStyleInput) => { try { const typeKeywords: Record<string, string> = { "color-palette": "color palette scheme", typography: "typography fonts", layout: "layout grid structure", animation: "animation motion design", general: "", }; const query = `${params.style} ${typeKeywords[params.type]} UI design inspiration`; const allSites = Object.values(DESIGN_SITES); const siteFilter = allSites.map((s) => `site:${s}`).join(" OR "); const fullQuery = `${query} (${siteFilter})`; const [imageData, searchData] = await Promise.all([ serperRequest<SerperImagesResponse>("/images", { q: fullQuery, num: params.num }), serperRequest<SerperSearchResponse>("/search", { q: fullQuery, num: params.num }), ]); const images = imageData.images || []; const results = searchData.organic || []; const lines = [`# Style Inspiration: "${params.style}" (${params.type})`, ""]; if (images.length) { lines.push("## Images", ""); for (const img of images.slice(0, 5)) { lines.push(`- **${img.title}**: ${img.imageUrl}`); lines.push(` Source: ${img.source} | [View](${img.link})`); } lines.push(""); } if (results.length) { lines.push("## References", ""); for (const r of results) { lines.push(`- **${r.title}**`); lines.push(` ${r.snippet}`); lines.push(` [View](${r.link})`); lines.push(""); } } let text = lines.join("\n"); if (text.length > CHARACTER_LIMIT) { text = text.slice(0, CHARACTER_LIMIT) + "\n\n...(truncated)"; } return { content: [{ type: "text" as const, text }], structuredContent: { style: params.style, type: params.type, images: images.slice(0, 5).map((img) => ({ title: img.title, imageUrl: img.imageUrl, source: img.source, link: img.link, })), references: results.map((r) => ({ title: r.title, link: r.link, snippet: r.snippet, })), }, }; } catch (error) { return { content: [ { type: "text" as const, text: error instanceof Error ? error.message : `Error: ${String(error)}`, }, ], }; } - src/index.ts:290-303 (schema)The Zod input schema definition for 'design_search_styles', validating style, type, and number of results.
), type: z .enum(["color-palette", "typography", "layout", "animation", "general"]) .default("general") .describe("Type of style inspiration to search for"), num: z .number() .int() .min(1) .max(20) .default(10) .describe("Number of results (1-20, default: 10)"), }) .strict();