@utilix-tech/mcp 0.1.0 → 0.2.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @utilix-tech/mcp
2
2
 
3
- MCP server exposing 51 developer utility tools to Claude, Cursor, VS Code Copilot, and any [Model Context Protocol](https://modelcontextprotocol.io) compatible AI assistant.
3
+ MCP server exposing 70 developer utility tools to Claude, Cursor, VS Code Copilot, and any [Model Context Protocol](https://modelcontextprotocol.io) compatible AI assistant.
4
4
 
5
5
  No API key required. All tools run locally.
6
6
 
@@ -91,14 +91,16 @@ Add to `.vscode/mcp.json`:
91
91
  | `bcrypt_hash` | Hash a password using bcrypt |
92
92
  | `bcrypt_verify` | Verify a password against a bcrypt hash |
93
93
 
94
- ### Generators (3 tools)
94
+ ### Generators (5 tools)
95
95
  | Tool | Description |
96
96
  |------|-------------|
97
97
  | `generate_uuid` | Generate UUID v4 or v7 |
98
98
  | `generate_ulid` | Generate a ULID |
99
99
  | `generate_password` | Generate a secure random password |
100
+ | `generate_qr` | Generate a QR code as an SVG string |
101
+ | `generate_random_data` | Generate random mock data: names, emails, UUIDs, IPs, etc. |
100
102
 
101
- ### Text (8 tools)
103
+ ### Text (9 tools)
102
104
  | Tool | Description |
103
105
  |------|-------------|
104
106
  | `convert_case` | Convert text case: camelCase, snake_case, PascalCase, etc. |
@@ -107,8 +109,11 @@ Add to `.vscode/mcp.json`:
107
109
  | `escape_string` | Escape characters for JSON, JavaScript, HTML, URL, or CSV |
108
110
  | `unescape_string` | Unescape JSON, JavaScript, HTML, URL, or CSV strings |
109
111
  | `lorem_ipsum` | Generate Lorem Ipsum placeholder text |
112
+ | `text_diff` | Diff two text blocks line-by-line |
113
+ | `html_to_markdown` | Convert HTML to Markdown |
114
+ | `line_operations` | Sort, deduplicate, reverse, shuffle, trim, or number lines |
110
115
 
111
- ### Time (4 tools)
116
+ ### Time (5 tools)
112
117
  | Tool | Description |
113
118
  |------|-------------|
114
119
  | `unix_timestamp` | Convert a Unix timestamp to human-readable date |
@@ -123,31 +128,53 @@ Add to `.vscode/mcp.json`:
123
128
  | `convert_bytes` | Convert between B, KB, MB, GB, TB, KiB, MiB, GiB, TiB |
124
129
  | `px_to_units` | Convert pixels to rem, em, pt, and vw |
125
130
 
126
- ### API / Network (3 tools)
131
+ ### API / Network (4 tools)
127
132
  | Tool | Description |
128
133
  |------|-------------|
129
134
  | `decode_jwt` | Decode a JWT — header, payload, and expiry |
130
135
  | `build_curl` | Build a cURL command from method, URL, headers, and body |
131
136
  | `curl_to_code` | Convert a cURL command to fetch, axios, Python, Go, PHP, or Ruby |
137
+ | `cors_headers` | Generate CORS response headers for a configuration |
132
138
 
133
- ### Color (1 tool)
139
+ ### Color (4 tools)
134
140
  | Tool | Description |
135
141
  |------|-------------|
136
142
  | `convert_color` | Convert a color between HEX, RGB, HSL, and HSV |
143
+ | `check_contrast` | Check WCAG contrast ratio between two colors |
144
+ | `color_palette` | Generate a color palette from a base color |
145
+ | `color_shades` | Generate shades or tints from a base color |
137
146
 
138
- ### Code (3 tools)
147
+ ### Code (7 tools)
139
148
  | Tool | Description |
140
149
  |------|-------------|
141
150
  | `format_sql` | Format a SQL query with proper indentation |
142
151
  | `format_html` | Format and indent HTML markup |
143
152
  | `test_regex` | Test a regular expression and return all matches |
153
+ | `minify_js` | Minify JavaScript by removing whitespace and comments |
154
+ | `format_graphql` | Format or minify a GraphQL query or schema |
155
+ | `parse_env` | Parse a .env file and return all key-value pairs |
156
+ | `parse_docker_image` | Parse a Docker image reference into its components |
144
157
 
145
- ### Data (3 tools)
158
+ ### Data (4 tools)
146
159
  | Tool | Description |
147
160
  |------|-------------|
148
161
  | `validate_yaml` | Validate YAML syntax |
149
162
  | `toml_to_json` | Convert TOML to JSON |
150
163
  | `xml_to_json` | Convert XML to JSON |
164
+ | `parse_csv` | Parse a CSV string and return the data as JSON |
165
+
166
+ ### CSS (2 tools)
167
+ | Tool | Description |
168
+ |------|-------------|
169
+ | `minify_css` | Minify CSS by removing whitespace and comments |
170
+ | `css_gradient` | Generate a CSS gradient from color stops |
171
+
172
+ ### Misc (3 tools)
173
+ | Tool | Description |
174
+ |------|-------------|
175
+ | `number_to_words` | Convert a number to English words, Roman numerals, or ordinal |
176
+ | `unicode_inspect` | Inspect Unicode code points of a string |
177
+ | `optimize_svg` | Optimize and minify an SVG string |
151
178
 
152
179
  ## Requirements
153
180
 
package/dist/index.js CHANGED
@@ -38,7 +38,9 @@ import {
38
38
  import {
39
39
  generateUuid,
40
40
  generatePassword,
41
- generateUlid
41
+ generateUlid,
42
+ generateData,
43
+ generateQrSvg
42
44
  } from "@utilix-tech/sdk/generators";
43
45
  import {
44
46
  countWords,
@@ -46,7 +48,10 @@ import {
46
48
  slugify,
47
49
  generate as loremGenerate,
48
50
  escapeString,
49
- unescapeString
51
+ unescapeString,
52
+ diffLines,
53
+ htmlToMarkdown,
54
+ applyOps
50
55
  } from "@utilix-tech/sdk/text";
51
56
  import {
52
57
  fromUnix,
@@ -60,11 +65,15 @@ import {
60
65
  decodeJwt,
61
66
  buildCurl,
62
67
  parseCurlCommand,
63
- convertToCode
68
+ convertToCode,
69
+ generateCors,
70
+ DEFAULT_CORS_CONFIG
64
71
  } from "@utilix-tech/sdk/api";
65
- import { parseColor } from "@utilix-tech/sdk/color";
66
- import { formatSql, formatHtml, testRegex } from "@utilix-tech/sdk/code";
67
- import { validateYaml, tomlToJson, xmlToJson } from "@utilix-tech/sdk/data";
72
+ import { parseColor, checkContrast, generatePalette, generateShades } from "@utilix-tech/sdk/color";
73
+ import { formatSql, formatHtml, testRegex, minifyJs, formatGql, parseDockerImage, parseEnv as parseEnvFile } from "@utilix-tech/sdk/code";
74
+ import { validateYaml, tomlToJson, xmlToJson, parseCsv } from "@utilix-tech/sdk/data";
75
+ import { generateGradient, minifyCss } from "@utilix-tech/sdk/css";
76
+ import { optimizeSvg, charToCodePoint, numberToWords } from "@utilix-tech/sdk/misc";
68
77
  var CRON_DAY_MAP = {
69
78
  SUN: "0",
70
79
  MON: "1",
@@ -739,5 +748,284 @@ server.tool(
739
748
  return text(result);
740
749
  }
741
750
  );
751
+ server.tool(
752
+ "text_diff",
753
+ "Diff two text blocks line-by-line and show added, removed, and unchanged lines.",
754
+ {
755
+ left: z.string().describe("Original text"),
756
+ right: z.string().describe("New/modified text")
757
+ },
758
+ async ({ left, right }) => {
759
+ const r = diffLines(left, right);
760
+ const lines = r.lines.map((l) => {
761
+ const prefix = l.type === "added" ? "+ " : l.type === "removed" ? "- " : " ";
762
+ return `${prefix}${l.text}`;
763
+ });
764
+ return text(`${r.addedCount} added, ${r.removedCount} removed, ${r.unchangedCount} unchanged
765
+
766
+ ${lines.join("\n")}`);
767
+ }
768
+ );
769
+ server.tool(
770
+ "html_to_markdown",
771
+ "Convert HTML to Markdown.",
772
+ { input: z.string().describe("HTML string to convert") },
773
+ async ({ input }) => text(htmlToMarkdown(input))
774
+ );
775
+ server.tool(
776
+ "line_operations",
777
+ "Sort, deduplicate, reverse, shuffle, trim, or number lines of text.",
778
+ {
779
+ input: z.string().describe("Multi-line text"),
780
+ operation: z.enum(["sort-asc", "sort-desc", "sort-natural", "reverse", "dedupe", "dedupe-ci", "shuffle", "trim", "remove-empty", "number-lines"]).describe("Operation to apply")
781
+ },
782
+ async ({ input, operation }) => text(applyOps(input, [operation]))
783
+ );
784
+ server.tool(
785
+ "number_to_words",
786
+ "Convert a number to its English words representation, Roman numerals, or ordinal form.",
787
+ {
788
+ number: z.number().describe("Number to convert"),
789
+ format: z.enum(["words", "roman", "ordinal"]).default("words").describe("Output format")
790
+ },
791
+ async ({ number: n, format }) => {
792
+ if (format === "roman") {
793
+ const { numberToRoman } = await import("@utilix-tech/sdk/misc");
794
+ const r = numberToRoman(n);
795
+ return typeof r === "string" ? text(r) : text(`Error: ${r}`);
796
+ }
797
+ if (format === "ordinal") {
798
+ const { numberToOrdinal } = await import("@utilix-tech/sdk/misc");
799
+ return text(numberToOrdinal(n));
800
+ }
801
+ return text(numberToWords(n));
802
+ }
803
+ );
804
+ server.tool(
805
+ "unicode_inspect",
806
+ "Inspect the Unicode code point(s) of a character or string.",
807
+ { input: z.string().min(1).describe("Character or string to inspect") },
808
+ async ({ input }) => {
809
+ const chars = [...input].slice(0, 50);
810
+ const lines = chars.map((c) => {
811
+ const cp = charToCodePoint(c);
812
+ const hex = cp.toString(16).toUpperCase().padStart(4, "0");
813
+ return `U+${hex} ${JSON.stringify(c)} (decimal ${cp})`;
814
+ });
815
+ return text(lines.join("\n"));
816
+ }
817
+ );
818
+ server.tool(
819
+ "minify_css",
820
+ "Minify CSS by removing whitespace and comments.",
821
+ { input: z.string().describe("CSS to minify") },
822
+ async ({ input }) => {
823
+ const r = minifyCss(input);
824
+ return text(`${r.output}
825
+
826
+ (${r.originalSize}B \u2192 ${r.outputSize}B, saved ${r.savingsPercent}%)`);
827
+ }
828
+ );
829
+ server.tool(
830
+ "css_gradient",
831
+ "Generate a CSS gradient from stops.",
832
+ {
833
+ type: z.enum(["linear", "radial", "conic"]).default("linear").describe("Gradient type"),
834
+ angle: z.number().default(90).describe("Angle in degrees (linear only)"),
835
+ stops: z.array(z.object({
836
+ color: z.string().describe("CSS color value"),
837
+ position: z.number().min(0).max(100).describe("Position 0\u2013100")
838
+ })).min(2).describe("Color stops")
839
+ },
840
+ async ({ type, angle, stops }) => {
841
+ const css = generateGradient({ type, angle, stops });
842
+ return text(css);
843
+ }
844
+ );
845
+ server.tool(
846
+ "check_contrast",
847
+ "Check WCAG contrast ratio between two colors.",
848
+ {
849
+ foreground: z.string().describe("Foreground color (HEX, RGB, or named)"),
850
+ background: z.string().describe("Background color (HEX, RGB, or named)")
851
+ },
852
+ async ({ foreground, background }) => {
853
+ const r = checkContrast(foreground, background);
854
+ return text(
855
+ `Ratio: ${r.ratioString}
856
+ Level: ${r.level}
857
+ AA normal: ${r.aa.normal ? "\u2713" : "\u2717"} AA large: ${r.aa.large ? "\u2713" : "\u2717"} AA UI: ${r.aa.ui ? "\u2713" : "\u2717"}
858
+ AAA normal: ${r.aaa.normal ? "\u2713" : "\u2717"} AAA large: ${r.aaa.large ? "\u2713" : "\u2717"}`
859
+ );
860
+ }
861
+ );
862
+ server.tool(
863
+ "color_palette",
864
+ "Generate a color palette (analogous, complementary, triadic, etc.) from a base color.",
865
+ {
866
+ color: z.string().describe("Base color in HEX format"),
867
+ type: z.enum(["analogous", "complementary", "triadic", "tetradic", "split-complementary"]).default("analogous")
868
+ },
869
+ async ({ color, type }) => {
870
+ const r = generatePalette(color, type);
871
+ const colors = r.colors;
872
+ return text(colors.map((c) => `${c.hex} ${c.label}`).join("\n"));
873
+ }
874
+ );
875
+ server.tool(
876
+ "color_shades",
877
+ "Generate a scale of shades (darker) or tints (lighter) from a base color.",
878
+ {
879
+ color: z.string().describe("Base color in HEX format"),
880
+ count: z.number().int().min(2).max(20).default(5).describe("Number of shades to generate")
881
+ },
882
+ async ({ color, count }) => {
883
+ const shades = generateShades(color, count);
884
+ return text(shades.join("\n"));
885
+ }
886
+ );
887
+ server.tool(
888
+ "cors_headers",
889
+ "Generate CORS response headers for a given configuration.",
890
+ {
891
+ origins: z.array(z.string()).default(["*"]).describe("Allowed origins"),
892
+ methods: z.array(z.string()).default(["GET", "POST", "PUT", "DELETE", "OPTIONS"]).describe("Allowed HTTP methods"),
893
+ headers: z.array(z.string()).default(["Content-Type", "Authorization"]).describe("Allowed request headers"),
894
+ credentials: z.boolean().default(false).describe("Allow credentials"),
895
+ max_age: z.number().int().default(86400).describe("Preflight cache duration in seconds")
896
+ },
897
+ async ({ origins, methods, headers: hdrs, credentials, max_age }) => {
898
+ const r = generateCors({
899
+ ...DEFAULT_CORS_CONFIG,
900
+ allowedOrigins: origins,
901
+ allowedMethods: methods,
902
+ allowedHeaders: hdrs,
903
+ allowCredentials: credentials,
904
+ maxAge: max_age
905
+ });
906
+ const headerLines = Object.entries(r.headers).map(([k, v]) => `${k}: ${v}`).join("\n");
907
+ return text(`Headers:
908
+ ${headerLines}
909
+
910
+ Express:
911
+ ${r.expressCode}`);
912
+ }
913
+ );
914
+ server.tool(
915
+ "minify_js",
916
+ "Minify JavaScript by removing whitespace and comments.",
917
+ { input: z.string().describe("JavaScript code to minify") },
918
+ async ({ input }) => {
919
+ const r = minifyJs(input);
920
+ return text(`${r.minified}
921
+
922
+ (${r.originalSize}B \u2192 ${r.minifiedSize}B, saved ${r.savedBytes}B)`);
923
+ }
924
+ );
925
+ server.tool(
926
+ "format_graphql",
927
+ "Format or minify a GraphQL query or schema.",
928
+ {
929
+ input: z.string().describe("GraphQL query or schema string"),
930
+ minify: z.boolean().default(false).describe("Minify instead of format")
931
+ },
932
+ async ({ input, minify }) => {
933
+ if (minify) {
934
+ const { minifyGql } = await import("@utilix-tech/sdk/code");
935
+ const r2 = minifyGql(input);
936
+ if (!r2.valid) return text("Error: invalid GraphQL");
937
+ return text(r2.output);
938
+ }
939
+ const r = formatGql(input);
940
+ if (!r.valid) return text("Error: invalid GraphQL");
941
+ return text(r.output);
942
+ }
943
+ );
944
+ server.tool(
945
+ "parse_env",
946
+ "Parse a .env file and return all key-value pairs with validation.",
947
+ { input: z.string().describe(".env file contents") },
948
+ async ({ input }) => {
949
+ const r = parseEnvFile(input);
950
+ if (r.errors.length) {
951
+ return text(`Errors:
952
+ ${r.errors.map((e) => ` Line ${e.line}: ${e.message}`).join("\n")}
953
+
954
+ Parsed ${r.entries.length} entries.`);
955
+ }
956
+ const lines = r.entries.map((e) => `${e.key}=${e.value}`);
957
+ return text(`${lines.join("\n")}
958
+
959
+ (${r.entries.length} entries, ${r.comments.length} comments)`);
960
+ }
961
+ );
962
+ server.tool(
963
+ "parse_docker_image",
964
+ "Parse a Docker image reference into registry, namespace, repository, tag, and digest.",
965
+ { input: z.string().describe('Docker image reference e.g. "nginx:1.21-alpine"') },
966
+ async ({ input }) => {
967
+ const r = parseDockerImage(input);
968
+ return text(
969
+ `Registry: ${r.registry}
970
+ Namespace: ${r.namespace}
971
+ Repository: ${r.repository}
972
+ Tag: ${r.tag || "latest"}
973
+ Digest: ${r.digest || "none"}
974
+ Official: ${r.isOfficial}`
975
+ );
976
+ }
977
+ );
978
+ server.tool(
979
+ "generate_qr",
980
+ "Generate a QR code as an SVG string.",
981
+ {
982
+ input: z.string().describe("Text or URL to encode"),
983
+ size: z.number().int().min(100).max(1e3).default(300).describe("SVG size in px")
984
+ },
985
+ async ({ input, size }) => {
986
+ const svg = await generateQrSvg(input, { size });
987
+ return text(svg);
988
+ }
989
+ );
990
+ server.tool(
991
+ "generate_random_data",
992
+ "Generate random mock data: names, emails, UUIDs, phone numbers, dates, colors, IPs, etc.",
993
+ {
994
+ type: z.enum(["name", "email", "uuid", "phone", "date", "number", "boolean", "color", "url", "ipv4", "sentence", "paragraph"]).describe("Data type to generate"),
995
+ count: z.number().int().min(1).max(50).default(5).describe("Number of items")
996
+ },
997
+ async ({ type, count }) => {
998
+ const items = generateData({ type, count });
999
+ const valid = items.filter(Boolean);
1000
+ if (!valid.length) return text("Error: could not generate data for this type");
1001
+ return text(valid.join("\n"));
1002
+ }
1003
+ );
1004
+ server.tool(
1005
+ "parse_csv",
1006
+ "Parse a CSV string and return the data as JSON.",
1007
+ {
1008
+ input: z.string().describe("CSV content"),
1009
+ delimiter: z.string().default(",").describe("Field delimiter")
1010
+ },
1011
+ async ({ input, delimiter }) => {
1012
+ const r = parseCsv(input, { delimiter });
1013
+ return text(JSON.stringify({ headers: r.headers, rows: r.rows, totalRows: r.totalRows }, null, 2));
1014
+ }
1015
+ );
1016
+ server.tool(
1017
+ "optimize_svg",
1018
+ "Optimize and minify an SVG string.",
1019
+ { input: z.string().describe("SVG content to optimize") },
1020
+ async ({ input }) => {
1021
+ const result = optimizeSvg(input);
1022
+ const original = new TextEncoder().encode(input).length;
1023
+ const optimized = new TextEncoder().encode(result).length;
1024
+ const saved = Math.round((1 - optimized / original) * 100);
1025
+ return text(`${result}
1026
+
1027
+ (${original}B \u2192 ${optimized}B, saved ${saved}%)`);
1028
+ }
1029
+ );
742
1030
  var transport = new StdioServerTransport();
743
1031
  await server.connect(transport);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@utilix-tech/mcp",
3
- "version": "0.1.0",
4
- "description": "MCP server exposing 107 Utilix developer tools to Claude, Cursor, VS Code Copilot, and any MCP-compatible AI assistant.",
3
+ "version": "0.2.0",
4
+ "description": "MCP server exposing 70 Utilix developer tools to Claude, Cursor, VS Code Copilot, and any MCP-compatible AI assistant.",
5
5
  "author": "Utilix <hello@utilix.tech>",
6
6
  "license": "MIT",
7
7
  "homepage": "https://utilix.tech/docs",
package/smithery.yaml CHANGED
@@ -1,5 +1,5 @@
1
1
  name: utilix
2
- description: 107 developer utility tools — JSON, hashing, encoding, JWT, UUID, cron, color, SQL, regex and more. All run locally, no API key required.
2
+ description: 70 developer utility tools — JSON, hashing, encoding, JWT, UUID, cron, color, SQL, regex, CSS, QR codes and more. All run locally, no API key required.
3
3
  homepage: https://utilix.tech
4
4
  license: MIT
5
5
 
@@ -61,3 +61,22 @@ tools:
61
61
  - validate_yaml
62
62
  - toml_to_json
63
63
  - xml_to_json
64
+ - text_diff
65
+ - html_to_markdown
66
+ - line_operations
67
+ - number_to_words
68
+ - unicode_inspect
69
+ - minify_css
70
+ - css_gradient
71
+ - check_contrast
72
+ - color_palette
73
+ - color_shades
74
+ - cors_headers
75
+ - minify_js
76
+ - format_graphql
77
+ - parse_env
78
+ - parse_docker_image
79
+ - generate_qr
80
+ - generate_random_data
81
+ - parse_csv
82
+ - optimize_svg