{
  "markdown": "# IconServe\n\nA free, agent-readable service that aggregates **10,000+ open-source icons** — [Lucide](https://lucide.dev),\n[Heroicons](https://heroicons.com), [Tabler](https://tabler.io/icons), and [Simple Icons](https://simpleicons.org) —\nand serves them as **SVG or PNG** at predictable URLs, with keyword + semantic search, an `llms.txt`, and an MCP server.\n\nRuns entirely within the **Cloudflare free tier** (Workers + R2 + Workers AI).\n\n## How an agent uses it\n\n| Need | Do this |\n|---|---|\n| Embed an icon you know the name of | `GET /i/{name}.svg` (best match) or `/icons/{set}/{name}.svg` |\n| Find the right icon | `GET /api/search?q=shopping+cart` → names + ready URLs |\n| Read the whole API in one shot | `GET /llms.txt` (or `/llms-full.txt`) |\n| Native tool calls | MCP server at `/mcp` (`search_icons`, `get_icon`, `list_sets`) |\n| OpenAPI | `GET /openapi.json` |\n\n### Discoverability surfaces (for crawling/browsing agents)\n\n- `GET /icon/{set}/{name}` — crawlable HTML page per icon (preview, usage, JSON-LD `ImageObject` + breadcrumb). `/icon/{name}` 302-redirects to the best match.\n- `GET /sitemap.xml` — every icon page (~10k URLs).\n- `GET /robots.txt` — explicitly **allows** AI crawlers (GPTBot, OAI-SearchBot, ClaudeBot, PerplexityBot, Google-Extended, …) and points to the sitemap.\n- Landing page carries `WebSite`+`SearchAction` and `WebAPI` JSON-LD and Open Graph tags.\n- **IndexNow**: key file served at `/{INDEXNOW_KEY}.txt`; `npm run indexnow` pings Bing/Yandex to crawl new or changed URLs instantly (pass paths to submit a subset, e.g. `npm run indexnow /icon/lucide/house`).\n\n### Transforms (query params on any icon URL)\n\n- `color=` hex / CSS color / `currentColor` — e.g. `?color=%23e11d48`\n- `size=` `1..2048` px\n- `stroke=` `0..20` (line icons)\n- `style=` e.g. `solid` (Heroicons), `filled` (Tabler)\n- `format=` `svg` | `png`\n\nExample: `/i/shopping-cart.svg?color=crimson&size=48&stroke=1.5`\n\n## Architecture\n\n```\nBuild (offline, on your machine — no Cloudflare cost)\n  scripts/ingest.mjs  → data/pack/icons.json  (id → normalized SVG, currentColor-driven)\n                        data/pack/catalog.json (names, tags, aliases, license, styles)\n                        data/pack/corpus.json  (search text per icon)\n  scripts/embed.mjs   → data/pack/embeddings.bin  (10k × 384, bge-small-en-v1.5)\n                        data/pack/embed-index.json\n\nCloudflare\n  R2 (ICONS)   holds the 4 packed artifacts; loaded once per isolate into memory\n  Workers AI   embeds ONLY the query string at search time (same 384-dim model)\n  Worker       routing, color/size/stroke transforms, PNG (resvg-wasm), search, MCP, docs\n  Assets       public/index.html landing page\n```\n\nSemantic search = keyword ranking **fused** (reciprocal-rank fusion) with cosine similarity over the\nin-memory embeddings. No Vectorize, no per-vector billing, no dimension cap. If `embeddings.bin` is\nabsent, search gracefully falls back to keyword-only.\n\n## Local development\n\n```bash\nnpm install\nnpm run build:data     # ingest + embed  (embed downloads a ~40MB model once)\nnpm run upload:r2      # push artifacts into the LOCAL R2 store\nnpm run dev            # http://localhost:8787\n```\n\n> In `wrangler dev --local` the Workers AI binding is offline, so search runs keyword-only locally.\n> Semantic search activates once deployed (or when running against the remote AI binding).\n\n## Deploy (Cloudflare free tier)\n\n```bash\nwrangler login         # one-time, opens a browser\nnpm run deploy         # creates the R2 bucket, uploads artifacts, deploys the Worker\n```\n\n`npm run deploy` runs [`scripts/deploy.mjs`](scripts/deploy.mjs): it creates the `iconserve-icons`\nbucket (idempotent), uploads the four artifacts to **remote** R2, then `wrangler deploy`.\n\n## Adding / updating icon sets\n\nEdit [`scripts/lib/sets.mjs`](scripts/lib/sets.mjs), then re-run `npm run build:data && npm run upload:r2`\n(local) or `npm run deploy` (remote). Set priority for `/i/{name}` best-match is `DEFAULT_SET_ORDER` in\n[`wrangler.toml`](wrangler.toml).\n\n## Licensing\n\nIcons are redistributed under their original permissive licenses: Lucide (ISC), Heroicons (MIT),\nTabler (MIT), Simple Icons (CC0). Brand marks from Simple Icons are trademarks of their respective\nowners — use them per each brand's guidelines.\n",
  "bytes": 4285,
  "sha": "50bc12f988a332240a4b5116e8a57c3309dbabcba1adb8dcb0db254e5b676312",
  "repo_slug": "asr-aditya/iconserve",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_asr_aditya_iconserve_bd941dde/readme"
}