search_icons

Fuzzy search across 222+ icon libraries (~285k icons) using PostgreSQL trigram similarity. Returns (libraryId, name) pairs.

Icons live in a separate Postgres database from the main registry — there are too many of them (~285,000 across 222 libraries) to stuff into the JSON search index. search_icons gives agents a ranked fuzzy search directly against the icons DB.

When to use

  • The agent needs an icon and the user gave a keyword ("magnifying glass", "settings", "arrow-right").
  • You want cross-library candidates in one call — Lucide, Heroicons, Tabler, Simple Icons all together.
  • Before calling get_icon, which needs the exact (library, name) pair.

How it works

  1. Calls searchIcons(query, limit) from services/icons-db.ts.

  2. Runs a raw SQL query using the pg_trgm extension:

    SELECT library_id, name, similarity(name, $1) AS sim
    FROM icons
    WHERE name % $1
    ORDER BY sim DESC, name
    LIMIT $2
    • The % operator is pg_trgm's "similar to" — requires the two strings to share trigrams above a threshold (default 0.3).
    • similarity() returns a 0–1 score that powers the ranking.
  3. Maps the rows to { libraryId, name, similarity } objects.

Because the match is trigram-based, it tolerates typos and word order variations much better than a plain substring search. "mag glass" will surface magnifying-glass from Heroicons; "setngs" still finds settings.

Source: lib/mcp/tools.ts#search_icons + services/icons-db.ts#searchIcons.

Arguments

NameTypeRequiredNotes
querystring (min length 1)Icon name to search for
limitnumber (1–100)Default 25

Response

{
  "count": 4,
  "results": [
    { "libraryId": "lucide", "name": "search", "similarity": 1.0 },
    { "libraryId": "heroicons", "name": "magnifying-glass", "similarity": 0.82 },
    { "libraryId": "simple-icons", "name": "google-search-console", "similarity": 0.71 },
    { "libraryId": "tabler", "name": "search", "similarity": 0.68 }
  ]
}
  • Results are sorted by similarity descending, then by name alphabetically.
  • The (libraryId, name) tuple is the primary key on the icons table — feed it straight into get_icon.

Example prompts

use shadcnio to find a magnifying-glass icon from Lucide or Heroicons
use shadcnio to search for a "github" brand icon
use shadcnio to find the five closest matches to "up arrow"

Manual invocation

curl -s -X POST "https://www.shadcn.io/api/mcp?token=YOUR_TOKEN" \
  -H "content-type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "search_icons",
      "arguments": { "query": "magnifying", "limit": 10 }
    }
  }' | jq '.result.content[0].text | fromjson | .results'

Tips + gotchas

  • Trigram threshold is server-side. Queries shorter than 3 characters won't match anything — trigrams need 3 chars minimum. Ask for "up" and you'll get zero results; "upload" works fine.
  • No library filter in the public API. The underlying SQL doesn't expose a library filter to this tool, by design — cross-library results are usually what agents want. If you need to restrict to Lucide only, filter the results client-side on libraryId === "lucide".
  • Ranking favors short names. An icon literally named search ranks higher than google-search-console for the query "search". This is the intended behavior — pg_trgm considers string length.
  • Icon catalog is ~285k rows. Raising limit to 100 doesn't materially slow the query, but downstream the agent pays token cost for every row.
  • Not indexed in the main search_items tool. Icons were deliberately left out of public/search-index.json to keep that file small. Always use search_icons for icon discovery.

Was this page helpful?

Sign in to leave feedback.