mcp server
iconify-mcp
MCP server for Iconify icons (as browsed on Icônes): search icons and view them as images
Set up
Runs on your computer. Pick your agent and operating system.
Before you start
- Node.js 20 or newer
{
"mcpServers": {
"sohampatwardhan-iconify-mcp": {
"command": "npx",
"args": [
"-y",
"@sohampatwardhan/iconify-mcp"
]
}
}
}same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12
Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs
README
synced Nov 1, 2026@sohampatwardhan/iconify-mcp
Unofficial community MCP server for Iconify. It searches the public Iconify catalog, returns each collection's license, and sends PNG previews back as MCP image content so a model can see the icons.
Icon pages link to Icônes, Anthony Fu's icon browser, which is a front end over the same catalog.
Tools
| Tool | What you get |
|---|---|
list_collections | Filter the catalog by name, prefix, or category. Each hit includes author, license, icon count, and sample ids. |
get_collection | One collection: license, categories, a page of icon names, and a PNG of its sample icons. |
search_icons | Keyword search (query, optional prefix / prefixes / category, limit, start). Results include Iconify ids, licenses, and Icônes links, plus a contact-sheet PNG. |
get_icon | One icon (prefix:name): SVG, dimensions, collection, license, alias parent, Icônes URL, and a PNG. Snippets cover SVG, data URL, Vue, React, Svelte, UnoCSS, Tailwind, and the Iconify name. |
preview_icons | One labeled contact sheet for a list of ids, or for the top search matches. size, color, background, and columns are configurable. |
search_icons and get_collection include a preview image by default. Pass preview: false when you only want the JSON.
Iconify search matches names and keywords. It does not search by visual similarity. Use the contact sheet to compare candidates.
Code snippets
get_icon returns the formats Icônes offers:
- Iconify name:
lucide:house - SVG and a data URL
- Iconify SVG URL:
https://api.iconify.design/lucide/house.svg - Vue, React, and Svelte components
- UnoCSS:
<div class="i-lucide-house"></div> - Tailwind (Iconify plugin):
<span class="icon-[lucide--house]"></span>
Snippet SVGs keep currentColor so they inherit text color. Pass color (for example #b45309) when the SVG and the PNG should use a fixed color. PNGs default to #1c1917 on white. Palette icons that do not use currentColor keep their original colors.
Resources
| URI | Body |
|---|---|
iconify://collections | Collection list with licenses |
iconify://collection/{prefix} | One collection, including up to 200 icon names |
iconify://icon/{prefix}/{name}.svg | SVG |
iconify://icon/{prefix}/{name}.png | 128px PNG on white |
iconify://icon/{prefix}/{name}.json | Metadata and snippets |
iconify:// is the scheme to use. The same resources are also registered on icones:// so older URIs keep working.
Icônes links look like https://icones.js.org/collection/lucide?icon=lucide:house.
Setup
Requires Node.js 20 or newer.
npx -y @sohampatwardhan/iconify-mcp@latest
The published bin is iconify-mcp. icones-mcp is a compatibility alias for the same program. Stdio is the default. Logs go to stderr so they stay off the JSON-RPC stream. The MCP server name is iconify-mcp.
Cursor
Add this to ~/.cursor/mcp.json or the project's .cursor/mcp.json:
{
"mcpServers": {
"iconify": {
"command": "npx",
"args": ["-y", "@sohampatwardhan/iconify-mcp@latest"]
}
}
}
Claude Desktop
The same mcpServers block goes in the desktop config:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
Restart Claude Desktop after saving.
Claude Code
claude mcp add iconify -- npx -y @sohampatwardhan/iconify-mcp@latest
VS Code
Create .vscode/mcp.json:
{
"servers": {
"iconify": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@sohampatwardhan/iconify-mcp@latest"]
}
}
}
Streamable HTTP
HTTP mode is stateless and has no authentication. Bind it to localhost.
npx -y @sohampatwardhan/iconify-mcp@latest --http --port 3333
The MCP endpoint is http://127.0.0.1:3333/mcp. A client config looks like:
{
"mcpServers": {
"iconify": {
"url": "http://127.0.0.1:3333/mcp"
}
}
}
GET /health returns ok.
MCP Inspector
The web UI:
npm install
npm run build
npx @modelcontextprotocol/inspector node dist/cli.js
A non-interactive check of the stdio server:
npx @modelcontextprotocol/inspector --cli --method tools/list node dist/cli.js
npx @modelcontextprotocol/inspector --cli --method tools/call \
--tool-name get_icon \
--tool-args-json '{"icon":"lucide:house","size":64}' \
node dist/cli.js
Examples
Search and look at the sheet:
{
"name": "search_icons",
"arguments": { "query": "arrow", "prefix": "lucide", "limit": 8 }
}
Fetch one icon as a React component and a 128px PNG:
{
"name": "get_icon",
"arguments": { "icon": "lucide:house", "formats": ["react", "svg", "iconify"] }
}
Compare a hand-picked set. This is the call that produced the image at the top of the README:
{
"name": "preview_icons",
"arguments": {
"title": "Lucide",
"columns": 4,
"size": 72,
"icons": [
"lucide:house", "lucide:search", "lucide:heart", "lucide:star",
"lucide:sun", "lucide:moon", "lucide:cloud", "lucide:camera",
"lucide:bell", "lucide:settings", "lucide:user", "lucide:mail"
]
}
}
Prompts that work well once the server is connected:
- "Search Lucide for a house icon and show me the candidates."
- "Get the SVG and a Svelte component for
tabler:brand-github." - "Make a contact sheet of weather icons from Phosphor."
Licenses
This server is MIT. See LICENSE.
Icon artwork is not relicensed. Every collection on Iconify has its own license (MIT, Apache-2.0, ISC, CC BY 4.0, and others). list_collections, get_collection, search_icons, get_icon, and preview_icons return that license's title, SPDX id, and URL. SVG snippets include a comment with the collection, author, and license. Read that license before shipping an icon.
Contact-sheet labels are set in Inter, which is bundled under the SIL Open Font License. The license text is in assets/fonts/OFL.txt. Rasterized labels in a PNG are pixels. The font file itself stays under the OFL.
Data source
This server calls the public Iconify API at https://api.iconify.design. Icônes (icones.js.org) is the browsing UI those icon links open. The client uses:
GET /collectionsandGET /collectionGET /searchGET /{prefix}.json?icons=...
SVGs are built locally with @iconify/utils and rasterized with @resvg/resvg-js. The client keeps at least 100ms between requests, caches collection metadata, search results, and icon bodies in memory, and retries 429 and 5xx responses.
The public API is a shared service. Point ICONIFY_API_URL at your own Iconify API instance if you need higher volume.
| Variable | Default | Purpose |
|---|---|---|
ICONIFY_API_URL | https://api.iconify.design | API origin |
ICONES_MIN_INTERVAL_MS | 100 | Minimum gap between API calls |
ICONES_CACHE | enabled | Set to 0 to disable the memory cache |
Development
npm install
npm run lint
npm test
npm run typecheck
npm run build
node dist/cli.js --help
npm run smoke
npm run lint checks TSDoc comments with eslint-plugin-tsdoc (tsdoc/syntax). npm test includes rendering tests and a live call against the public API. npm run smoke starts the built stdio server, calls preview_icons, and writes docs/contact-sheet.png unless CONTACT_SHEET_OUT is set. It also copies the PNG to contact-sheet.png inside SMOKE_OUT, or the system temp directory when SMOKE_OUT is unset. CI runs npm ci, then lint, typecheck, test, build, and smoke.
prepublishOnly compiles TypeScript into dist/ before the package is packed.
Releasing
@sohampatwardhan/iconify-mcp is published only by .github/workflows/release.yml, using GitHub OIDC trusted publishing. 0.2.1 was published that way. Do not run npm publish from a laptop or an agent session, and do not create an npm token.
Bump the version on main after the release commit is there. npm version updates package.json and package-lock.json and creates the matching tag. src/version.ts reads the version from package.json, so leave that file's version line alone.
npm version patch # or minor, or major
git push --follow-tags
Run those commands from main. A tag pushed from a feature branch does not release. Do not move a tag or publish the same version again.
The workflow rejects a tag that is not v plus the package.json version, then runs npm ci, lint, typecheck, test, build, and smoke, publishes with npm publish --provenance --access public, and opens a GitHub Release with generated notes.