mcpField
T
TrueIcon

TrueIcon

本地服务
github.com/manikumarkv开发工具04 周前更新

关于 TrueIcon

TrueIcon 是面向 AI 编码助手的 MCP 服务,可按项目实际使用的图标包和版本搜索图标,并返回名称、导入路径及导入语句。它覆盖 React、Vue 和 Svelte 的多种图标包,结果对应所选版本中真实存在的图标。

主要功能

  1. 01按项目依赖和版本索引图标
  2. 02搜索图标并返回导入语句
  3. 03支持 React、Vue 和 Svelte 图标包
  4. 04可选语义搜索与本地缓存

适用场景

  1. 01为项目界面查找可用图标
  2. 02核对图标名称及对应导入路径
  3. 03按指定图标包版本生成导入代码

MCP 相关

TrueIcon 作为 MCP 服务向客户端提供 search_icons、get_icon 和 list_providers 等图标查询工具。客户端启动该服务后,它会读取项目配置并搜索对应图标包。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"manikumarkv-trueicon": {
"command": "npx",
"args": [
"-y",
"trueicon"
],
"env": {
"TRUEICON_PROJECT_DIR": "<TRUEICON_PROJECT_DIR>",
"TRUEICON_CACHE": "<TRUEICON_CACHE>"
}
}
}
}
启动命令npx -y trueicon
需要配置的环境变量
TRUEICON_PROJECT_DIRAbsolute path to the project whose icon packages to search. Defaults to the working directory.
TRUEICON_CACHEDirectory for the downloaded icon package cache. Defaults to ~/.trueicon/cache.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmtrueicon0.6.0

工具

4

收录的工具列表 · 更新于 3 周前

此工具无需参数。

详细介绍

TrueIcon

npm Install in VS Code Install in VS Code Insiders Install in Cursor

TrueIcon 是一个 MCP 服务,可为 AI 编码助手提供准确且与版本匹配的图标引用。助手会搜索项目实际使用的图标包(lucide-react、react-icons、@heroicons/react、@phosphor-icons/react、@tabler/icons-react、iconoir-react、@fluentui/react-icons、@carbon/icons-react、@ant-design/icons、@mui/icons-material、@radix-ui/react-icons、@remixicon/react、Font Awesome Free 包,以及 Lucide、Heroicons、Tabler 和 Phosphor 的 Vue 与 Svelte 包),并返回真实的图标名称、导入路径和可直接粘贴的 import 语句。

为什么选择 TrueIcon

AI 助手经常会猜测图标名称。它们猜到的图标可能根本不存在,可能在几个版本之前就已更名,也可能属于其他图标库;只有在构建失败时,你才会发现问题。TrueIcon 可以弥补这一缺口:

  • 它会读取项目使用的图标包及其版本。
  • 它会从 npm 下载这些确切版本,并为其中的每个图标建立索引。
  • 助手会调用 search_icons,并获得保证存在于该版本中的搜索结果,例如 import { Trash2 } from 'lucide-react';。

支持的提供方

提供方 IDnpm 包图标命名
lucidelucide-reactLucide 的文件名,例如 trash-2 → Trash2
heroicons@heroicons/react<icon>-<size>-<style>,例如 trash-24-outline → TrashIcon
react-iconsreact-icons<set>-<icon>,例如 fa6-beer-mug-empty → FaBeerMugEmpty
phosphor@phosphor-icons/react常规粗细使用 <icon>,其他情况使用 <icon>-<weight>,例如 trash-bold → TrashIcon,并设置 weight="bold"
tabler@tabler/icons-reactTabler 的图标名称,例如 trash → IconTrash,trash-filled → IconTrashFilled
iconoiriconoir-react常规样式使用 <icon>,实心样式使用 <icon>-solid,例如 trash-solid → TrashSolid
fluentui@fluentui/react-icons<icon>-<style>,其中 style 为 regular、filled 或 color,例如 delete-regular → DeleteRegular。仅索引可缩放(1em)的图标,不索引特定尺寸的变体
carbon@carbon/icons-reactCarbon 的导出名称,采用 kebab case,例如 trash-can → TrashCan。变体会添加 -filled、-alt 或 -color,例如 accessibility-filled → AccessibilityFilled
antdesign@ant-design/icons<icon>-<theme>,其中 theme 为 outlined、filled 或 two-tone,例如 delete-outlined → DeleteOutlined
mui@mui/icons-materialMUI 的导出名称,采用 kebab case,例如 delete → Delete。主题会添加 -outlined、-rounded、-sharp 或 -two-tone,例如 delete-outlined → DeleteOutlined;基础图标的样式为 filled
radix@radix-ui/react-iconsRadix 的图标名称,例如 trash → TrashIcon,github-logo → GitHubLogoIcon
remix@remixicon/reactRemix 的图标名称,使用 -line 或 -fill 样式,例如 delete-bin-line → RiDeleteBinLine
fontawesome-solid@fortawesome/free-solid-svg-iconsFont Awesome 的图标名称,例如 trash-can → faTrashCan。旧名称仍可解析:get_icon 会将 trash-alt 或 faTrashAlt 解析为 faTrashCan,并将 faSearch 解析为 faMagnifyingGlass
fontawesome-regular@fortawesome/free-regular-svg-icons与 fontawesome-solid 相同,例如 star → faStar
fontawesome-brands@fortawesome/free-brands-svg-icons与 fontawesome-solid 相同,例如 github → faGithub
Vue 和 Svelte

这些包索引的插画与上面的 React 包相同,但使用各自的组件名称和导入路径。

提供方 IDnpm 包图标命名
lucide-vue@lucide/vue与 lucide 相同,例如 trash → Trash
lucide-vue-nextlucide-vue-next与 lucide 相同。上游已弃用,推荐使用 @lucide/vue,但目前仍广泛使用
lucide-svelte5@lucide/svelte与 lucide 相同(Svelte 5)
lucide-sveltelucide-svelte与 lucide 相同。上游已弃用,推荐使用 @lucide/svelte
heroicons-vue@heroicons/vue与 heroicons 相同,例如 trash-24-outline → 来自 @heroicons/vue/24/outline 的 TrashIcon
tabler-vue@tabler/icons-vue与 tabler 相同,例如 trash → IconTrash
tabler-svelte@tabler/icons-svelte与 tabler 相同
phosphor-vue@phosphor-icons/vue与 phosphor 相同,例如 trash-bold → PhTrash,并设置 weight="bold"
phosphor-sveltephosphor-svelte与 phosphor 相同,例如 trash-bold → TrashIcon,并设置 weight="bold"

Heroicons 没有官方的 Svelte 包。Angular 包暂不支持。

工具接受提供方 ID 或 npm 包名称("lucide" 或 "lucide-react")。用法示例是导入语句,在 React、Vue 和 Svelte 中的写法相同。Phosphor 的所有字重共用一个组件,因此请将记录的 style 作为 weight 属性传入(例如,<TrashIcon weight="bold" />);用法示例仅显示导入语句。Font Awesome 的导入项是图标定义,而不是组件:请使用 @fortawesome/react-fontawesome 渲染,例如 <FontAwesomeIcon icon={faTrashCan} />。

安装

TrueIcon 需要 Node.js 20 或更高版本。

# Run without installing (this is what the MCP configs below do)
npx -y trueicon

# Or install globally and run the `trueicon` binary
npm i -g trueicon
trueicon

trueicon 是一个 stdio MCP 服务。MCP 客户端会启动它;手动运行时,它只会向 stderr 输出 trueicon: v<version> running on stdio,然后等待从 stdin 接收 JSON-RPC。

快速开始

  1. 在 MCP 客户端中注册 TrueIcon(Claude Code、Claude Desktop 或 VS Code 和 Cursor)。
  2. 请助手提供一个图标。

大多数项目到这里就完成了。TrueIcon 会查找 package.json 中列出的图标包,以及安装在 node_modules 中的版本。首次搜索每个包时,TrueIcon 会下载并为其建立索引,这需要几秒钟。之后的搜索会使用本地缓存。

配置

搜索哪些图标包
  • 默认情况下,会搜索 package.json 的 dependencies 或 devDependencies 中列出的所有受支持的软件包。
  • 如果项目中有 .iconmcp.json,则只搜索其中列出的软件包。可用它仅搜索部分图标包、添加 package.json 未列出的图标包(例如通过 UI 套件引入的图标包),或锁定版本。
{
  "providers": [
    { "package": "lucide-react" },
    { "package": "react-icons", "version": "5.3.0" },
    { "package": "@heroicons/react", "version": "^2.1.0" }
  ]
}
字段类型必填含义
providers数组是要搜索的图标包。如果其中列出了任何图标包,就不会使用 package.json 来选择软件包。
providers[].package字符串是受支持提供程序的 npm 软件包名称,例如 lucide-react、@lucide/vue 或 @tabler/icons-svelte(参见受支持的提供程序)。
providers[].version字符串否精确版本或 npm 版本范围。会覆盖已安装的版本(参见版本)。
semantic布尔值否启用语义搜索(默认值为 false)。参见下文。
  • .iconmcp.json 中不受支持的软件包会被跳过,search_icons 会将其报告为警告。
  • 无效的 JSON 或格式错误的条目会导致工具返回错误,并指出文件名和错误字段。
  • 如果两个文件都未列出受支持的软件包,search_icons 会返回错误,说明它检查了哪个目录。你仍可以在工具调用中传入 provider。
语义搜索(可选启用)

在 .iconmcp.json 中设置 "semantic": true,即可为 search_icons 添加基于含义的排序。每个查询都会通过一个小型本地模型(all-MiniLM-L6-v2,约 90 MB,只会下载一次到 transformers.js 缓存)生成嵌入,并与索引构建时生成的每个图标向量进行匹配;随后通过倒数排名融合将语义候选结果与关键词结果合并,因此精确名称匹配仍会优先,而“移除背景”这类概念性查询也能找到 eraser。

{
  "providers": [{ "package": "lucide-react" }],
  "semantic": true
}

语义搜索基于 @huggingface/transformers 运行。它是可选的同级依赖,默认不会安装,因此从不启用该标志的安装会保持轻量。要启用语义搜索,请将其与 trueicon 一起安装一次(约 400 MB):

npm install @huggingface/transformers

如果启用了该标志,但缺少此软件包,search_icons 和 get_icon 会回退到仅使用关键词的索引,并返回一行警告及安装命令。

切换此标志会重建一次索引(向量会与每条记录一同存储在 index.json 中,meta.json 则会记录嵌入模型)。整个过程完全在本地运行:数据不会离开你的设备。TRUEICON_SEMANTIC=1(或 0)可在单次运行中覆盖此标志。

项目目录指什么

TrueIcon 会从项目目录读取 package.json、.iconmcp.json 和 node_modules。它会按以下顺序选择目录:

  1. 设置了 $TRUEICON_PROJECT_DIR 时,使用其指定的目录。
  2. MCP 客户端与服务共享的文件夹(MCP 根目录),其中包含 package.json 或 .iconmcp.json。支持根目录的客户端(如 VS Code)会告知 TrueIcon 你正在使用哪些文件夹,因此无需任何设置,它就能跟随你打开的项目。
  3. 服务的工作目录(其中包含上述文件之一)。Claude Code 会在你的项目中启动服务,因此 TrueIcon 通过此方式找到项目。
  4. 首个共享文件夹;如果没有,则使用工作目录。

list_providers 会显示当前使用的目录以及选用该目录的规则,方便你检查客户端的行为。

环境变量
变量默认值用途
TRUEICON_PROJECT_DIR共享文件夹,否则为工作目录存放 package.json 和 .iconmcp.json 的项目根目录
TRUEICON_CACHE~/.trueicon/cache存储下载的软件包和索引的位置
TRUEICON_SEMANTIC.iconmcp.json 标志1/0,强制本次运行启用/关闭语义搜索

版本

自动检测

提供方的版本按以下顺序确定:

  1. 如果有,使用传递给工具调用的 version 参数。
  2. 使用 .iconmcp.json 中提供方的 version。
  3. 使用 node_modules 中安装的版本;先检查项目目录,再逐级检查父目录,以便找到提升到 monorepo 根目录的软件包。
  4. 使用项目 package.json 中为该软件包声明的版本范围;先检查 dependencies,再检查 devDependencies。

如果以上都不可用,工具会要求你固定版本或将软件包添加到 package.json。TrueIcon 不会读取你的锁文件,而是从 npm 下载自己的软件包副本,不会使用 node_modules 中的文件。对于版本范围,它会为范围的基础版本建立索引:^0.460.0 会为 [email protected] 建立索引。对于 a || b 范围,只会采用第一部分。在运行 npm install 之前,该基础版本可能比你最终获得的版本更旧;如果确切版本很重要,请在 .iconmcp.json 中固定版本。

版本策略

索引按 major.minor 编号:

  • 忽略补丁版本。 一个索引适用于所有 0.460.x。基于 0.460.0 构建的索引会响应针对 0.460.3 的请求。
  • 次版本变更会建立独立索引。 将 lucide-react 从 0.460 升级到 0.461 后,下次搜索时会建立新索引,无需手动操作。
  • 主版本严格区分。 不同的主版本始终使用独立索引,绝不会使用其他主版本的索引。
  • 缓存的索引会在捆绑的 synonyms.json 变更(通过哈希检测)或索引格式变更时自动重建。

在 Claude 中使用

Claude Code

在项目目录中添加 TrueIcon:

claude mcp add trueicon -- npx -y trueicon

或者在项目根目录提交 .mcp.json,与团队共享:

{
  "mcpServers": {
    "trueicon": {
      "command": "npx",
      "args": ["-y", "trueicon"]
    }
  }
}

Claude Code 会在项目目录中启动服务,因此无需设置就能在那里找到 package.json。如果它从其他位置运行,请添加 "env": { "TRUEICON_PROJECT_DIR": "/absolute/path/to/project" }。

Claude Desktop

Claude Desktop 不会在项目目录中启动服务,因此请设置 TRUEICON_PROJECT_DIR。如果你的 Claude Desktop 版本会与服务共享文件夹,TrueIcon 会改用这些文件夹;list_providers 会显示它选择的目录。编辑 claude_desktop_config.json:macOS 上的路径为 ~/Library/Application Support/Claude/claude_desktop_config.json,Windows 上的路径为 %APPDATA%\Claude\claude_desktop_config.json。

{
  "mcpServers": {
    "trueicon": {
      "command": "npx",
      "args": ["-y", "trueicon"],
      "env": {
        "TRUEICON_PROJECT_DIR": "/absolute/path/to/your/project"
      }
    }
  }
}

编辑文件后重启 Claude Desktop。

在 VS Code 和 Cursor 中使用

使用本 README 顶部的安装徽章。它们会添加 TrueIcon,并将 TRUEICON_PROJECT_DIR 设置为 ${workspaceFolder},以便搜索你当前打开的项目。

要在 VS Code 中手动添加,请在项目中创建 .vscode/mcp.json:

{
  "servers": {
    "trueicon": {
      "command": "npx",
      "args": ["-y", "trueicon"],
      "env": {
        "TRUEICON_PROJECT_DIR": "${workspaceFolder}"
      }
    }
  }
}

在 Cursor 中,请在 .cursor/mcp.json 的 "mcpServers" 下使用相同的条目。

工具

每个工具都会返回一个 JSON 文本块。发生失败时,该文本块为 {"error": "..."},且 MCP 结果会标记为 isError: true。

search_icons

搜索索引并返回按相关性排序的匹配项及导入语句。

ArgumentTypeRequiredDescription
querystringyes图标应描绘的内容,例如 "trash"
providerstringno提供方 ID 或包。默认值:项目使用的所有提供方(参见配置)
versionstringno版本或范围。默认值:按版本中所述解析
stylestringno精确的样式筛选条件,例如 "outline"、"solid"、"filled"(tabler)、"regular"(fluentui)、"two-tone"(antdesign、mui)、"line"(remix)、"brands"(Font Awesome),或 phosphor 的某种粗细,如 "bold"。Lucide 图标全部为 outline;基础 carbon 图标和 radix 图标没有样式
setstringno精确的图标集筛选条件,例如 react-icons 的 "fa6" 或 "md"
limitintegerno最大结果数,范围为 1 到 50,默认值为 10

调用示例:

{ "query": "trash", "provider": "lucide", "limit": 3 }

响应:

{
  "results": [
    { "name": "trash", "importName": "Trash", "importPath": "lucide-react", "package": "lucide-react",
      "version": "0.460.0", "style": "outline", "set": "lucide",
      "usage": "import { Trash } from 'lucide-react';", "score": 0 },
    { "name": "trash-2", "importName": "Trash2", "importPath": "lucide-react", "package": "lucide-react",
      "version": "0.460.0", "style": "outline", "set": "lucide",
      "usage": "import { Trash2 } from 'lucide-react';", "score": 0.02 },
    { "name": "delete", "importName": "Delete", "importPath": "lucide-react", "package": "lucide-react",
      "version": "0.460.0", "style": "outline", "set": "lucide",
      "usage": "import { Delete } from 'lucide-react';", "score": 0.6 }
  ]
}

搜索工作原理:

  • provider、style 和 set 是精确且不区分大小写的筛选条件。它们会在排序前应用。

  • 候选项来自 Fuse.js 对图标名称、导入名称、关键词和标签进行的模糊匹配。允许少量拼写错误:"detele" 可以找到 Delete。

  • 名称与查询相符的图标会优先排序,比较时会去掉名称中的样式后缀(delete-bin-line → delete-bin):

    1. 名称与查询相同:delete 可以找到 delete、delete-outlined、DeleteRegular
    2. 名称以查询开头:delete-bin-line
    3. 名称中包含查询短语:"arrow right" 可以找到 circle-arrow-right
    4. 查询中的每个词都出现在名称、同义词或标签中:trash 可以找到 restore-from-trash,而 delete 可以通过 trash → delete 这一同义词找到相关图标

    同一层级内,名称较短的排在前面,因此普通图标优先于组合图标(delete 在 restore-from-trash 之前),且每个图标的各个样式会排在一起,默认样式优先。除非查询中包含变体编号,否则会忽略编号,因此 trash 的排序是 trash,然后是 trash-2。其余结果(如拼写错误匹配)按模糊匹配分数排序。

  • score 的取值范围为 0(完全匹配)到 1,因此越低越好。它体现了上述排序规则,因此来自多个提供方的结果可以合并并按分数排序,同时保留分数。

  • 多词查询会进行分词:每个词单独匹配,只保留匹配所有词的图标,并按平均分数排序。因此,"trash can" 可以找到 trash-can 图标。较短的关键词查询("trash"、"settings"、"beer")仍会尽可能广泛地搜索。

  • 如果某个提供方失败,例如无法解析其版本或下载失败,则会跳过该提供方的结果,并通过 warnings 数组说明原因。其他提供方仍会返回结果。

list_providers

不接受任何参数。返回 TrueIcon 读取的项目目录及其查找方式、项目使用的提供方及其解析后的版本,以及 TrueIcon 支持的所有提供方。

{
  "project": { "dir": "/Users/you/code/my-app", "source": "roots" },
  "providersFrom": "package.json",
  "configured": [
    { "id": "lucide", "package": "lucide-react", "version": "1.47.0", "source": "node_modules" },
    { "id": "heroicons", "package": "@heroicons/react", "version": "^2.1.0", "source": "package.json" }
  ],
  "registry": [
    { "id": "react-icons", "package": "react-icons", "description": "Aggregated icon sets (Font Awesome, Material, Feather, and more) as React components" },
    { "id": "lucide", "package": "lucide-react", "description": "Lucide icons as React components" },
    { "id": "heroicons", "package": "@heroicons/react", "description": "Heroicons by the Tailwind CSS team as React components" },
    { "id": "phosphor", "package": "@phosphor-icons/react", "description": "Phosphor icons in six weights (thin, light, regular, bold, fill, duotone) as React components" },
    { "id": "tabler", "package": "@tabler/icons-react", "description": "Tabler icons (outline and filled) as React components" },
    { "id": "iconoir", "package": "iconoir-react", "description": "Iconoir icons (regular and solid) as React components" },
    { "id": "fluentui", "package": "@fluentui/react-icons", "description": "Microsoft Fluent UI System icons (regular, filled and color) as React components" },
    { "id": "carbon", "package": "@carbon/icons-react", "description": "IBM Carbon Design System icons as React components" },
    { "id": "antdesign", "package": "@ant-design/icons", "description": "Ant Design icons (outlined, filled and two-tone) as React components" },
    { "id": "mui", "package": "@mui/icons-material", "description": "Material UI icons (filled, outlined, rounded, sharp and two-tone) as React components" },
    { "id": "radix", "package": "@radix-ui/react-icons", "description": "Radix UI icons (15x15) as React components" },
    { "id": "remix", "package": "@remixicon/react", "description": "Remix Icon (line and fill) as React components" },
    { "id": "fontawesome-solid", "package": "@fortawesome/free-solid-svg-icons", "description": "Font Awesome Free solid icons, rendered with @fortawesome/react-fontawesome" },
    { "id": "fontawesome-regular", "package": "@fortawesome/free-regular-svg-icons", "description": "Font Awesome Free regular icons, rendered with @fortawesome/react-fontawesome" },
    { "id": "fontawesome-brands", "package": "@fortawesome/free-brands-svg-icons", "description": "Font Awesome Free brand logos, rendered with @fortawesome/react-fontawesome" },
    { "id": "lucide-vue", "package": "@lucide/vue", "description": "Lucide icons as Vue components" },
    { "id": "lucide-vue-next", "package": "lucide-vue-next", "description": "Lucide icons as Vue components (deprecated package, replaced by @lucide/vue)" },
    { "id": "lucide-svelte5", "package": "@lucide/svelte", "description": "Lucide icons as Svelte 5 components" },
    { "id": "lucide-svelte", "package": "lucide-svelte", "description": "Lucide icons as Svelte components (deprecated package, replaced by @lucide/svelte)" },
    { "id": "heroicons-vue", "package": "@heroicons/vue", "description": "Heroicons by the Tailwind CSS team as Vue components" },
    { "id": "tabler-vue", "package": "@tabler/icons-vue", "description": "Tabler icons (outline and filled) as Vue components" },
    { "id": "tabler-svelte", "package": "@tabler/icons-svelte", "description": "Tabler icons (outline and filled) as Svelte components" },
    { "id": "phosphor-vue", "package": "@phosphor-icons/vue", "description": "Phosphor icons in six weights as Vue components" },
    { "id": "phosphor-svelte", "package": "phosphor-svelte", "description": "Phosphor icons in six weights as Svelte components" }
  ]
}
  • project.source 为 "TRUEICON_PROJECT_DIR"、"roots"(MCP 客户端共享的文件夹)或 "cwd"(服务的工作目录)。参见项目目录是什么。
  • providersFrom 为 "iconmcp.json"、"package.json";如果两者均未指定受支持的包,则为 null。
  • 每个提供方的 source 表示其版本来源:"iconmcp.json"、"node_modules" 或 "package.json"。如果没有任何来源提供版本,version 和 source 将为 null。对于 TrueIcon 不支持的 .iconmcp.json 中的包,id 为 null。
get_icon

获取助手已知名称的图标的完整记录和导入语句。

参数类型必填描述
namestring是图标名称("trash-2")或导入名称("Trash2")。先进行精确匹配,再进行不区分大小写的匹配
providerstring是Provider ID 或包名
versionstring否版本或范围。默认值:按 Versions 中的说明解析

调用示例:

{ "name": "Trash2", "provider": "lucide" }

响应:

{
  "id": "[email protected]:trash-2",
  "name": "trash-2",
  "importName": "Trash2",
  "importPath": "lucide-react",
  "provider": "lucide",
  "package": "lucide-react",
  "version": "0.460.0",
  "style": "outline",
  "set": "lucide",
  "categories": [],
  "tags": [],
  "keywords": ["trash", "2", "delete", "remove", "bin", "garbage", "rubbish"],
  "svg": "<path d=\"M3 6h18\"/><path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\"/>…",
  "usage": "import { Trash2 } from 'lucide-react';"
}

svg 是图标内部的 SVG 标记,也就是根 <svg> 元素的子元素。Heroicons 在所有尺寸和样式中使用相同的导入名称(TrashIcon)。传入完整的变体名称,例如 "trash-24-outline",即可获取指定变体。

ping

健康检查,返回 {"status":"ok","server":"trueicon"}。

索引与缓存

工具首次需要 [email protected] 时,TrueIcon 会执行以下操作:

  1. 从 https://registry.npmjs.org 下载包 tarball,验证其 sha512 完整性,并将其解压到缓存中。
  2. 使用 Provider 的适配器解析包中随附的文件。不会执行任何内容。图标从编译后的源文件中读取。
  3. 写入 index.json(每个图标一条记录)和 meta.json(确切版本、同义词哈希、索引格式、构建时间)。

之后的调用只读取 index.json。查询时不会访问包文件。对于你的 node_modules,TrueIcon 只读取每个图标包的 package.json 以获取已安装版本,并且绝不会修改其中的任何内容。如果多个工具调用同时需要同一个索引,它们会共用一次下载。

缓存根目录为 ~/.trueicon/cache,如果设置了 $TRUEICON_CACHE,则使用该变量指定的目录:

~/.trueicon/cache/
├── [email protected]/          # extracted package + index.json + meta.json
├── [email protected]/             # extracted package + index.json + meta.json
├── [email protected]/         # extracted @heroicons/react package
└── @heroicons/[email protected]/        # index.json + meta.json for @heroicons/react
  • 下载内容存放在 <package>@<major.minor> 中,带作用域的名称会扁平化处理:@heroicons/react 会变为 heroicons-react。最后会写入 .download-complete 标记,没有该标记的目录会被视为不完整并替换。
  • 索引存放在 <package>@<major.minor>/index.json 和 meta.json 中。对于不带作用域的包,这与下载目录相同。
  • 删除缓存是安全的。需要时会重新构建,但这需要网络访问。

每条记录的 keywords 会合并名称部分、标签以及随附的 synonyms.json 中的同义词扩展。这些扩展会在索引时添加,因此搜索 "bin" 就能找到 Trash2,查询时无需额外处理。

贡献

git clone https://github.com/manikumarkv/trueicon.git
cd trueicon
npm ci
npm run build      # compile to dist/
npm test           # vitest
npm run lint       # eslint
npm run typecheck  # tsc --noEmit

CI 会在每次推送和拉取请求中,使用 Node 20 和 22 运行 lint、类型检查和测试。

在 Web 版 Claude Code 中,SessionStart 钩子(.claude/hooks/session-start.sh)会在会话开始时安装依赖,因此这些命令可以立即运行。安装时会使用 --ignore-scripts,因为沙盒会阻止可选语义搜索依赖项下载原生模块;因此,依赖该模块的语义测试会在沙盒中跳过。

测试
命令检查内容网络
npm test使用 tests/fixtures/ 中的小型固定样例,测试全部 24 个 Provider 的适配器解析和每个工具(search_icons、get_icon、list_providers)否
npm run smoke针对真实 npm 包测试每个 Provider:使用多个固定版本及当前最新版本,检查图标数量和几个知名图标是

固定样例只有在有人编辑时才会变化,因此无法检测上游 Provider 是否更改了包格式。npm run smoke 可以做到这一点。运行 npm run smoke -- lucide tabler 可仅检查部分 Provider。CI 会在更改 src/providers/、src/indexer/ 或 src/cache/ 的拉取请求中运行该命令,并在每周一针对最新版本运行。

在本地测试和调试

这些脚本会构建服务,并针对 playground/ 运行。这是一个示例项目,列出了最新版本的全部 24 个提供商。脚本使用 .cache/dev/ 中的独立缓存,因此不会影响你实际使用的 ~/.trueicon 缓存。

# Call one tool and print the result
npm run dev:call -- list_providers
npm run dev:call -- search_icons query="trash can" limit=5
npm run dev:call -- search_icons query=trash provider=lucide version=1.47.0
npm run dev:call -- get_icon name=Trash2 provider=lucide

# Open the MCP Inspector web UI on the local build
npm run dev:inspect

# Same, with the Node debugger on port 9229
npm run dev:debug
  • 参数是 key=value 键值对。数字和布尔值会被解析,因此 limit=5 会以数字形式传入。
  • **其他项目:**将 TRUEICON_PROJECT_DIR 设置为目标项目,以使用该项目的 package.json 和 .iconmcp.json 进行测试,例如:TRUEICON_PROJECT_DIR=~/code/my-app npm run dev:inspect。
  • **重建索引:**添加 --fresh,先删除开发缓存,例如:npm run dev:call -- --fresh search_icons query=trash。修改适配器后使用此选项。
  • **断点:**运行 npm run dev:debug,然后在 VS Code 中使用 Debug: Attach to Node Process,或在 Chrome 中打开 chrome://inspect。已启用源映射,因此可以在 src/ 下的 .ts 文件中设置断点。设置断点后,从 Inspector 调用工具。
  • **日志记录:**stdout 承载 MCP 协议,因此请使用 console.error 记录日志。运行 dev:call 时,日志会显示在终端中;运行 dev:inspect 时,则会显示在 Inspector 的服务日志中。
  • 手动测试提示词:playground/TEST-PROMPTS.md 是一份提示词检查清单,可在 MCP 客户端中针对 playground 运行,并查看预期的工具调用和结果。它涵盖所有工具、全部 15 个提供商、排序、配置错误和语义搜索。发布前请先运行此清单。
扩展 synonyms.json

src/synonyms/synonyms.json 将一个词映射到额外的搜索词:

{
  "trash": ["delete", "remove", "bin", "garbage", "rubbish"],
  "logout": ["sign-out", "signout", "exit", "leave"]
}
  • 键会与图标的名称部分(按 - 拆分的名称)及标签进行匹配。trash-2 会匹配键 trash。
  • 值会添加到该图标的 keywords 中。
  • 扩展是单向的。如果希望搜索 bin 也能找到名称为 delete 的图标,请同时添加 "trash": ["bin"] 和 "delete": ["bin"],或添加反向条目。
  • 键和值均使用小写,并确保每个键对应一个非空字符串数组。tests/synonyms.test.ts 会检查这一点。
  • 修改该文件会改变其哈希值,因此下次搜索时会自动重建缓存索引。
添加提供商
  1. 注册提供商:在 src/providers/registry.ts 中添加提供商,并设置稳定的 id、npm package 和简短的 description。
  2. 编写适配器:在 src/providers/adapters/<provider>.ts 中实现适配器,导出 parseIcons(packageDir: string): RawIcon[](参见 src/providers/adapter.ts)。它接收解压后的包目录,并为每个图标返回一个 RawIcon:
    • name:使用 kebab-case,且在包内唯一,因为它会成为记录 ID 的一部分。使用 adapter.ts 中的 toKebabCase。如果包中有组件名称冲突的变体,请将变体添加到名称中,heroicons、react-icons、phosphor 和 iconoir 适配器就是这样做的。
    • importName 和 importPath:用户导入时所用的准确导出名称和模块说明符。
    • svg:内部 SVG 标记。LiteralCursor(src/providers/jsLiteral.ts)可以解析 JS 对象和数组字面量,而无需执行代码。toSvgAttrs 和 renderSvg(src/providers/svg.ts)可将 React props 转换为 SVG 标记,parseCreateElement 则读取编译后的 createElement(...) 树。
    • 可选字段:style、set、categories 和 tags。
    • 在适配器顶部添加注释,描述包的文件布局,与现有适配器保持一致。
  3. 接入适配器:在 src/providers/adapters/index.ts 的 ADAPTERS 中,使用提供商 ID 添加该适配器。
  4. 编写测试:在 tests/fixtures/<provider>/ 下添加一个小型固定版本夹具,模拟包的布局,其中包含几个真实图标文件以及适配器必须跳过的文件。然后添加 tests/adapters/<provider>.test.ts,参照现有适配器测试,覆盖名称映射、导入路径、SVG 输出和 buildIndex 记录 ID。若已注册的提供商没有适配器,tests/adapters/common.test.ts 会报错。
  5. 将其添加到工具测试:在 tests/providers-tools.test.ts 的 CASES 中添加一个用例:包含夹具、搜索查询、一个带准确导入语句的图标,以及包中存在的弃用别名。若已注册的提供商没有对应的用例,测试会报错。
  6. 添加冒烟测试目标:在 scripts/smoke.mjs 的 TARGETS 中添加几个知名导入名称和一个远低于实际数量的最低图标数。然后运行 npm run smoke -- <provider>,检查真实发布的包。

许可证

MIT © 2026 manikumarkv

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。