@devigner-ui/icons-mcp 0.0.0-stage → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ATTRIBUTION.md ADDED
@@ -0,0 +1,85 @@
1
+ # Attribution
2
+
3
+ Devigner Icons is a free, open-source icon set. The **artwork is not original
4
+ work**: it is derived from two existing open icon sets, merged, deduplicated,
5
+ renamed and rebuilt as React components. This file records where every drawing
6
+ came from and what each upstream set asks of you in return.
7
+
8
+ If you ship these icons, you inherit these obligations. They are light, but
9
+ they are real.
10
+
11
+ ## The two upstream sets
12
+
13
+ | Set | Author | Icons here | Licence |
14
+ | --- | --- | --- | --- |
15
+ | [Iconsax](https://iconsax.io) | [Vuesax](https://vuesax.com) | 908 | Free for personal and commercial use |
16
+ | [Solar Icon Set](https://www.figma.com/community/file/1166831539721848736) | [480 Design](https://www.figma.com/@480design) | 1,055 | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) |
17
+
18
+ Every drawing in this repository sits in a `0 0 24 24` viewBox, whichever set
19
+ it came from, so the coordinate system no longer tells the two apart. The
20
+ repository does not record which set a given icon came from.
21
+
22
+ ## What Solar's CC BY 4.0 requires of you
23
+
24
+ The Solar-derived icons are the larger half of this set, and CC BY 4.0 is an
25
+ attribution licence. Using them, including in a commercial or closed-source
26
+ product, is free, but you must credit the original author. The licence asks
27
+ for the creator's name, a link to the licence, and an indication that changes
28
+ were made.
29
+
30
+ A credit line that satisfies it:
31
+
32
+ > Icons from [Devigner Icons](https://icons.devigner.cc), derived from
33
+ > [Solar Icon Set](https://www.figma.com/community/file/1166831539721848736) by
34
+ > 480 Design, licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/),
35
+ > and [Iconsax](https://iconsax.io) by Vuesax. Modified.
36
+
37
+ Put it wherever you keep third-party notices: an about page, a credits screen,
38
+ a `NOTICE` file, an open-source-licences list. It does not have to be visible
39
+ on every page that draws an icon.
40
+
41
+ CC BY 4.0 is not a copyleft licence: it does not require you to open-source
42
+ your own project, and it does not stop you from selling what you build.
43
+
44
+ ## What was changed
45
+
46
+ Neither set is shipped as it was published. The modifications, which CC BY 4.0
47
+ requires be indicated:
48
+
49
+ - **Merged.** Two sets combined into one namespace, with overlapping symbols
50
+ deduplicated.
51
+ - **Renamed.** Names normalised to a single `PascalCase` scheme and exported as
52
+ `Icon<Name>`. Upstream names were not always preserved.
53
+ - **Rebuilt as components.** Each symbol's separate style files were collapsed
54
+ into one React component with `fill` and `duotone` props selecting between
55
+ four drawings.
56
+ - **Recoloured.** Fixed fills and strokes replaced with `currentColor` so
57
+ colour comes from CSS.
58
+ - **Restroked.** Stroke width lifted to a `width` prop.
59
+ - **Annotated.** Categories, tags, descriptions and 384-dimension search
60
+ embeddings generated for each icon. That metadata is original work.
61
+
62
+ ## Brand and trademark icons
63
+
64
+ Roughly 35 icons in this set reproduce third-party logos and wordmarks: Apple,
65
+ Google, Figma, Slack, Spotify, YouTube, PayPal, Windows, Adobe products, and
66
+ around two dozen cryptocurrency marks.
67
+
68
+ **These are not licensed by this project, and no licence in this repository
69
+ grants you any right to them.** Trademarks belong to their respective owners
70
+ and are governed by each owner's brand guidelines, not by CC BY, MIT, or
71
+ anything else here. Using a company's logo to refer to that company is
72
+ generally acceptable; using it to imply endorsement, or as part of your own
73
+ branding, is generally not. Check the owner's terms before shipping one.
74
+
75
+ ## The code
76
+
77
+ Everything that is not artwork (the React wrappers, the CLI, the build scripts,
78
+ the type definitions, the website and the documentation) is original work, MIT
79
+ licensed. See [LICENSE](LICENSE).
80
+
81
+ ## Corrections
82
+
83
+ If you are one of the upstream authors and something here is wrong (a miscount,
84
+ a wrong licence, a set credited that should not be, or a request to be removed),
85
+ write to hello@remidevigner.pro and it will be fixed or the artwork pulled.
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @devigner-ui/icons-mcp
2
+
3
+ ## 3.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - First release.
package/LICENSE ADDED
@@ -0,0 +1,77 @@
1
+ Devigner Icons is a free and open-source project. Two different licences apply
2
+ to two different parts of it.
3
+
4
+ The CODE is MIT licensed and original work.
5
+ The ICON ARTWORK is derived from third-party sets and carries their terms.
6
+
7
+ See ATTRIBUTION.md for the full provenance of the artwork, what changed, and
8
+ how to credit it in your own project.
9
+
10
+
11
+ ================================================================================
12
+ CODE
13
+ ================================================================================
14
+
15
+ Applies to the React components, the CLI, the build scripts, the type
16
+ definitions, the generated metadata and embeddings, the website and the
17
+ documentation.
18
+
19
+ MIT License
20
+
21
+ Copyright (c) 2026 Devigner
22
+
23
+ Permission is hereby granted, free of charge, to any person obtaining a copy
24
+ of this software and associated documentation files (the "Software"), to deal
25
+ in the Software without restriction, including without limitation the rights
26
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27
+ copies of the Software, and to permit persons to whom the Software is
28
+ furnished to do so, subject to the following conditions:
29
+
30
+ The above copyright notice and this permission notice shall be included in all
31
+ copies or substantial portions of the Software.
32
+
33
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39
+ SOFTWARE.
40
+
41
+
42
+ ================================================================================
43
+ ICON ARTWORK
44
+ ================================================================================
45
+
46
+ The SVG path data is not original work. It is derived from two existing open
47
+ icon sets:
48
+
49
+ Iconsax, by Vuesax 909 icons
50
+ https://iconsax.io
51
+ Free for personal and commercial use.
52
+
53
+ Solar Icon Set, by 480 Design 1,055 icons
54
+ https://www.figma.com/community/file/1166831539721848736
55
+ Licensed under CC BY 4.0.
56
+ https://creativecommons.org/licenses/by/4.0/
57
+
58
+ Both sets were modified: merged, deduplicated, renamed, recoloured to
59
+ currentColor and rebuilt as React components.
60
+
61
+ CC BY 4.0 requires attribution. If you ship the Solar-derived icons, free or
62
+ commercial, open or closed, credit the original author somewhere you keep
63
+ third-party notices:
64
+
65
+ Icons from Devigner Icons, derived from Solar Icon Set by 480 Design
66
+ (CC BY 4.0) and Iconsax by Vuesax. Modified.
67
+
68
+ CC BY 4.0 does not require you to open-source your own project.
69
+
70
+
71
+ ================================================================================
72
+ TRADEMARKS
73
+ ================================================================================
74
+
75
+ Around 35 icons reproduce third-party logos and wordmarks. Those marks belong
76
+ to their respective owners. Nothing in this licence grants any right to use
77
+ them, and each owner's brand guidelines govern instead. See ATTRIBUTION.md.
package/README.md CHANGED
@@ -1,3 +1,29 @@
1
- # Temporary Holding Version
1
+ # @devigner-ui/icons-mcp
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ An [MCP](https://modelcontextprotocol.io) server for [Devigner Icons](https://icons.devigner.cc). It lets an AI coding tool find the right icon among 2,112 by what it means, then write the import and element for your framework.
4
+
5
+ ## Set up
6
+
7
+ Add it to your client's MCP config:
8
+
9
+ ```json
10
+ {
11
+ "mcpServers": {
12
+ "devigner-icons": { "command": "npx", "args": ["-y", "@devigner-ui/icons-mcp"] }
13
+ }
14
+ }
15
+ ```
16
+
17
+ ## Tools
18
+
19
+ | Tool | What it does |
20
+ | --- | --- |
21
+ | `search_icons` | Ranks icons against a description, such as "add to cart". Old names from before 3.5.0 match too. |
22
+ | `get_icon` | The code for one icon in `react`, `vue`, `svelte`, `solid`, `angular`, `react-native` or `js`, or the raw `svg`, in any style. |
23
+ | `list_categories` | Every category with its icon count. |
24
+
25
+ Search runs the `@devigner-ui/icons` CLI, so it ranks exactly as `npx @devigner-ui/icons search` does. It ranks by meaning when `@xenova/transformers` is installed, and by keywords otherwise.
26
+
27
+ ## Licence
28
+
29
+ MIT for the code, CC-BY-4.0 for the artwork. See ATTRIBUTION.md.
package/bin/server.mjs ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /*
3
+ * The MCP server on stdio. Add it to a client's config as
4
+ * `npx -y @devigner-ui/icons-mcp`.
5
+ */
6
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
+ import { createServer } from "../lib/server.mjs";
8
+
9
+ await createServer().connect(new StdioServerTransport());
package/lib/server.mjs ADDED
@@ -0,0 +1,137 @@
1
+ /*
2
+ * An MCP server over stdio, so an AI coding tool can find an icon by what it
3
+ * means and write the code that draws it.
4
+ *
5
+ * It does no searching of its own. Every lookup runs the @devigner-ui/icons
6
+ * CLI with --json, so the ranking, the old-name lookups and the SVG output
7
+ * are the ones `npx @devigner-ui/icons` gives, and cannot drift from them.
8
+ * Search is semantic when @xenova/transformers is installed beside it and
9
+ * falls back to keywords when it is not, exactly as the CLI does.
10
+ *
11
+ * bin/server.mjs connects this to stdio; scripts/check.mjs drives it in
12
+ * memory.
13
+ */
14
+ import { execFile } from "node:child_process";
15
+ import { createRequire } from "node:module";
16
+ import path from "node:path";
17
+ import { promisify } from "node:util";
18
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
19
+ import { z } from "zod";
20
+
21
+ const require = createRequire(import.meta.url);
22
+ const CLI = path.join(path.dirname(require.resolve("@devigner-ui/icons/package.json")), "bin", "cli.mjs");
23
+ const { version } = require("../package.json");
24
+
25
+ const STYLES = ["outline", "twotone", "bold", "bulk", "broken"];
26
+ const FRAMEWORKS = ["react", "vue", "svelte", "solid", "angular", "react-native", "js", "svg"];
27
+
28
+ /** Runs the CLI and returns stdout, or throws with what it printed to stderr. */
29
+ export async function cli(...args) {
30
+ try {
31
+ const { stdout } = await promisify(execFile)(process.execPath, [CLI, ...args], {
32
+ maxBuffer: 16 * 1024 * 1024,
33
+ });
34
+ return stdout;
35
+ } catch (error) {
36
+ throw new Error(String(error.stderr || error.message).trim());
37
+ }
38
+ }
39
+
40
+ /* The React package spells its styles in PascalCase; every other one in lowercase. */
41
+ const REACT_STYLE = { outline: "Outline", twotone: "TwoTone", bold: "Bold", bulk: "Bulk", broken: "Broken" };
42
+
43
+ /** How to draw one icon in one framework: the import and the element. */
44
+ export function snippet(name, framework, style) {
45
+ const C = `Icon${name}`;
46
+ const v = style === "outline" ? "" : ` variant="${style}"`;
47
+ switch (framework) {
48
+ case "react":
49
+ return `import { ${C} } from "@devigner-ui/icons/${name}";\n\n<${C}${style === "outline" ? "" : ` variant="${REACT_STYLE[style]}"`} className="size-6" />`;
50
+ case "react-native":
51
+ return `import { ${C} } from "@devigner-ui/icons-react-native";\n\n<${C}${v} size={24} color="#16161a" />`;
52
+ case "vue":
53
+ return `<script setup>\nimport { ${C} } from "@devigner-ui/icons-vue";\n</script>\n\n<${C}${v} class="size-6" />`;
54
+ case "svelte":
55
+ return `<script>\n import { ${C} } from "@devigner-ui/icons-svelte";\n</script>\n\n<${C}${v} class="size-6" />`;
56
+ case "solid":
57
+ return `import { ${C} } from "@devigner-ui/icons-solid";\n\n<${C}${v} class="size-6" />`;
58
+ case "angular":
59
+ return `import { DvIcon, ${C} } from "@devigner-ui/icons-angular";\n\n// imports: [DvIcon], and in the class: ${C} = ${C};\n<svg [dvIcon]="${C}"${v} class="size-6"></svg>`;
60
+ case "js":
61
+ return `import { toSvg, ${C} } from "@devigner-ui/icons-js";\n\nel.innerHTML = toSvg(${C}${style === "outline" ? "" : `, { variant: "${style}" }`});`;
62
+ }
63
+ }
64
+
65
+ const text = (value) => ({
66
+ content: [{ type: "text", text: typeof value === "string" ? value : JSON.stringify(value, null, 2) }],
67
+ });
68
+
69
+ /* What a search result carries: enough to choose, not the whole record. */
70
+ const brief = (icon) => ({
71
+ name: icon.name,
72
+ category: icon.category,
73
+ keywords: icon.keywords,
74
+ usage: icon.usage,
75
+ ...(icon.formerly?.length ? { formerly: icon.formerly } : {}),
76
+ });
77
+
78
+ export function createServer() {
79
+ const server = new McpServer({ name: "devigner-icons", version });
80
+
81
+ server.registerTool(
82
+ "search_icons",
83
+ {
84
+ title: "Search icons",
85
+ description:
86
+ "Find Devigner icons by meaning, such as 'add to cart' or 'settings cog'. " +
87
+ "Returns names ranked best first. Old names from before 3.5.0 are matched too.",
88
+ inputSchema: {
89
+ query: z.string().min(1).describe("What the icon should show or mean"),
90
+ limit: z.number().int().min(1).max(50).optional().describe("How many results, default 10"),
91
+ category: z.string().optional().describe("Restrict to one category slug, from list_categories"),
92
+ },
93
+ },
94
+ async ({ query, limit = 10, category }) => {
95
+ const args = ["search", query, "--json", `--limit=${limit}`];
96
+ if (category) args.push(`--category=${category}`);
97
+ return text(JSON.parse(await cli(...args)).map(brief));
98
+ },
99
+ );
100
+
101
+ server.registerTool(
102
+ "get_icon",
103
+ {
104
+ title: "Get an icon",
105
+ description:
106
+ "The code to draw one icon: an import and an element for a framework, or the raw SVG. " +
107
+ "An old name is resolved to the current one.",
108
+ inputSchema: {
109
+ name: z.string().min(1).describe("Icon name, as search_icons returns it, e.g. BagStraps"),
110
+ framework: z.enum(FRAMEWORKS).optional().describe("Default react. 'svg' returns the markup itself"),
111
+ style: z.enum(STYLES).optional().describe("Default outline"),
112
+ },
113
+ },
114
+ async ({ name, framework = "react", style = "outline" }) => {
115
+ const icon = JSON.parse(await cli("info", name, "--json"));
116
+ const code =
117
+ framework === "svg"
118
+ ? (await cli("copy", icon.name, "--format=svg", `--style=${style}`)).trim()
119
+ : snippet(icon.name, framework, style);
120
+ const note = icon.name === name ? "" : `${name} was renamed to ${icon.name}.\n\n`;
121
+ return text(`${note}${code}`);
122
+ },
123
+ );
124
+
125
+ server.registerTool(
126
+ "list_categories",
127
+ {
128
+ title: "List categories",
129
+ description: "Every icon category slug with how many icons it holds, for narrowing search_icons.",
130
+ inputSchema: {},
131
+ },
132
+ async () => text(JSON.parse(await cli("categories", "--json"))),
133
+ );
134
+
135
+ return server;
136
+ }
137
+
package/package.json CHANGED
@@ -1,6 +1,52 @@
1
1
  {
2
2
  "name": "@devigner-ui/icons-mcp",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "3.5.0",
4
+ "description": "MCP server for Devigner Icons: lets AI coding tools search 2,112 icons by meaning and drop them into React, Vue, Svelte, Solid, Angular, React Native or plain SVG.",
5
+ "keywords": [
6
+ "icons",
7
+ "mcp",
8
+ "model-context-protocol",
9
+ "ai",
10
+ "claude",
11
+ "cursor",
12
+ "svg",
13
+ "icon-search"
14
+ ],
15
+ "license": "MIT AND CC-BY-4.0",
16
+ "author": "Devigner",
17
+ "homepage": "https://icons.devigner.cc",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/devigner-ui/icons.git",
21
+ "directory": "packages/icons-mcp"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/devigner-ui/icons/issues"
25
+ },
26
+ "type": "module",
27
+ "files": [
28
+ "bin",
29
+ "lib",
30
+ "ATTRIBUTION.md",
31
+ "CHANGELOG.md"
32
+ ],
33
+ "devDependencies": {},
34
+ "engines": {
35
+ "node": ">=20.0.0"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public",
39
+ "registry": "https://registry.npmjs.org/"
40
+ },
41
+ "bin": {
42
+ "devigner-icons-mcp": "./bin/server.mjs"
43
+ },
44
+ "dependencies": {
45
+ "@modelcontextprotocol/sdk": "^1.17.0",
46
+ "zod": "^3.25.0",
47
+ "@devigner-ui/icons": "^3.5.0"
48
+ },
49
+ "scripts": {
50
+ "test": "node scripts/check.mjs"
51
+ }
6
52
  }