@utilix-tech/mcp 0.16.0 → 0.17.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/CHANGELOG.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  Full release notes for all Utilix surfaces (browser tools, REST API, SDKs, MCP server) live at [utilix.tech/changelog](https://utilix.tech/changelog). This file tracks just this package.
4
4
 
5
+ ## 0.17.0
6
+ - Added Simple Interest Calculator (`calculate_simple_interest`) and Base58 / Base62 Encoder (`base58_encode`, `base58_decode`, `base62_encode`, `base62_decode`).
7
+
5
8
  ## 0.16.0
6
9
  - Added MIME Type Lookup (`lookup_mime`) and Tip / Bill Split Calculator (`calculate_tip_split`).
7
10
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @utilix-tech/mcp
2
2
 
3
- MCP server exposing 118 developer utility tools to Claude, Cursor, VS Code Copilot, and any [Model Context Protocol](https://modelcontextprotocol.io) compatible AI assistant.
3
+ MCP server exposing 123 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. Requires Node.js 18 or later.
6
6
 
@@ -92,7 +92,7 @@ claude mcp add utilix -- npx -y @utilix-tech/mcp
92
92
  | `json_to_python` | Generate Python dataclasses from JSON |
93
93
  | `json_to_zod` | Generate a Zod schema from JSON |
94
94
 
95
- ### Encoding (8 tools)
95
+ ### Encoding (12 tools)
96
96
  | Tool | Description |
97
97
  |------|-------------|
98
98
  | `base64_encode` | Encode a string to Base64 |
@@ -103,6 +103,10 @@ claude mcp add utilix -- npx -y @utilix-tech/mcp
103
103
  | `html_entities_decode` | Decode HTML entities |
104
104
  | `base32_encode` | Encode a string to Base32 |
105
105
  | `base32_decode` | Decode a Base32 string |
106
+ | `base58_encode` | Encode text as Base58 (Bitcoin-address style, no ambiguous 0/O/I/l characters) |
107
+ | `base58_decode` | Decode a Base58 string back to text |
108
+ | `base62_encode` | Encode text as Base62 (alphanumeric, URL-safe) |
109
+ | `base62_decode` | Decode a Base62 string back to text |
106
110
 
107
111
  ### Hashing (4 tools)
108
112
  | Tool | Description |
@@ -145,7 +149,7 @@ claude mcp add utilix -- npx -y @utilix-tech/mcp
145
149
  | `date_diff` | Calculate the difference between two dates |
146
150
  | `convert_timezone` | Convert a date/time between timezones |
147
151
 
148
- ### Units (10 tools)
152
+ ### Units (11 tools)
149
153
  | Tool | Description |
150
154
  |------|-------------|
151
155
  | `convert_bytes` | Convert between B, KB, MB, GB, TB, KiB, MiB, GiB, TiB |
@@ -158,6 +162,7 @@ claude mcp add utilix -- npx -y @utilix-tech/mcp
158
162
  | `calculate_compound_interest` | Compute the future value of a principal plus an optional recurring contribution under compound interest |
159
163
  | `validate_isbn` | Validate an ISBN-10 or ISBN-13 checksum and convert it to the other format where possible |
160
164
  | `calculate_tip_split` | Compute a tip on a bill amount and split the bill, tip, and total evenly across N people |
165
+ | `calculate_simple_interest` | Compute simple (non-compounding) interest as principal x rate x time, plus the total payoff |
161
166
 
162
167
  ### API / Network (8 tools)
163
168
  | Tool | Description |
package/dist/index.js CHANGED
@@ -2267,6 +2267,114 @@ server.tool(
2267
2267
  return text(JSON.stringify(result, null, 2));
2268
2268
  }
2269
2269
  );
2270
+ function _calculateSimpleInterestMcp(principal, annualRatePercent, years) {
2271
+ if (!Number.isFinite(principal) || principal < 0) return { error: "Principal must be zero or a positive number" };
2272
+ if (!Number.isFinite(annualRatePercent) || annualRatePercent < 0) return { error: "Annual interest rate must be zero or a positive number" };
2273
+ if (!Number.isFinite(years) || years <= 0) return { error: "Years must be a positive number" };
2274
+ const round2 = (n) => Math.round(n * 100) / 100;
2275
+ const interest = round2(principal * (annualRatePercent / 100) * years);
2276
+ return {
2277
+ principal: round2(principal),
2278
+ annualRatePercent,
2279
+ years,
2280
+ interest,
2281
+ totalPayoff: round2(principal + interest)
2282
+ };
2283
+ }
2284
+ server.tool(
2285
+ "calculate_simple_interest",
2286
+ "Compute simple (non-compounding) interest as principal x rate x time, plus the total payoff. Distinct from calculate_compound_interest, which reinvests interest each period.",
2287
+ {
2288
+ principal: z.number().describe("Starting principal amount"),
2289
+ annualRatePercent: z.number().describe("Annual interest rate as a percent, e.g. 5"),
2290
+ years: z.number().describe("Term in years, may be fractional")
2291
+ },
2292
+ async ({ principal, annualRatePercent, years }) => {
2293
+ const result = _calculateSimpleInterestMcp(principal, annualRatePercent, years);
2294
+ if ("error" in result) return errText(result);
2295
+ return text(JSON.stringify(result, null, 2));
2296
+ }
2297
+ );
2298
+ var _BASE58_ALPHABET_MCP = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
2299
+ var _BASE62_ALPHABET_MCP = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2300
+ function _encodeBytesToBaseMcp(bytes, alphabet) {
2301
+ const base = BigInt(alphabet.length);
2302
+ let num = 0n;
2303
+ for (const byte of bytes) num = num << 8n | BigInt(byte);
2304
+ let out = "";
2305
+ while (num > 0n) {
2306
+ out = alphabet[Number(num % base)] + out;
2307
+ num = num / base;
2308
+ }
2309
+ let leadingZeros = 0;
2310
+ for (const byte of bytes) {
2311
+ if (byte === 0) leadingZeros++;
2312
+ else break;
2313
+ }
2314
+ return alphabet[0].repeat(leadingZeros) + out;
2315
+ }
2316
+ function _decodeBaseToBytesMcp(input, alphabet) {
2317
+ const base = BigInt(alphabet.length);
2318
+ let num = 0n;
2319
+ for (const char of input) {
2320
+ const idx = alphabet.indexOf(char);
2321
+ if (idx === -1) return { error: `Invalid character '${char}' for this alphabet` };
2322
+ num = num * base + BigInt(idx);
2323
+ }
2324
+ const bytes = [];
2325
+ while (num > 0n) {
2326
+ bytes.unshift(Number(num % 256n));
2327
+ num = num / 256n;
2328
+ }
2329
+ let leadingZeros = 0;
2330
+ for (const char of input) {
2331
+ if (char === alphabet[0]) leadingZeros++;
2332
+ else break;
2333
+ }
2334
+ return new Uint8Array([...new Array(leadingZeros).fill(0), ...bytes]);
2335
+ }
2336
+ server.tool(
2337
+ "base58_encode",
2338
+ "Encode text as Base58 (Bitcoin-address style, no ambiguous 0/O/I/l characters).",
2339
+ { input: z.string().describe("The text to encode") },
2340
+ async ({ input }) => text(_encodeBytesToBaseMcp(new TextEncoder().encode(input), _BASE58_ALPHABET_MCP))
2341
+ );
2342
+ server.tool(
2343
+ "base58_decode",
2344
+ "Decode a Base58 string back to text.",
2345
+ { input: z.string().describe("The Base58 string to decode") },
2346
+ async ({ input }) => {
2347
+ if (!input) return errText({ error: "No input provided" });
2348
+ const result = _decodeBaseToBytesMcp(input, _BASE58_ALPHABET_MCP);
2349
+ if (!(result instanceof Uint8Array)) return errText(result);
2350
+ try {
2351
+ return text(new TextDecoder("utf-8", { fatal: true }).decode(result));
2352
+ } catch {
2353
+ return errText({ error: "Decoded bytes are not valid UTF-8 text" });
2354
+ }
2355
+ }
2356
+ );
2357
+ server.tool(
2358
+ "base62_encode",
2359
+ "Encode text as Base62 (alphanumeric, URL-safe, no punctuation).",
2360
+ { input: z.string().describe("The text to encode") },
2361
+ async ({ input }) => text(_encodeBytesToBaseMcp(new TextEncoder().encode(input), _BASE62_ALPHABET_MCP))
2362
+ );
2363
+ server.tool(
2364
+ "base62_decode",
2365
+ "Decode a Base62 string back to text.",
2366
+ { input: z.string().describe("The Base62 string to decode") },
2367
+ async ({ input }) => {
2368
+ if (!input) return errText({ error: "No input provided" });
2369
+ const result = _decodeBaseToBytesMcp(input, _BASE62_ALPHABET_MCP);
2370
+ if (!(result instanceof Uint8Array)) return errText(result);
2371
+ try {
2372
+ return text(new TextDecoder("utf-8", { fatal: true }).decode(result));
2373
+ } catch {
2374
+ return errText({ error: "Decoded bytes are not valid UTF-8 text" });
2375
+ }
2376
+ }
2377
+ );
2270
2378
  server.tool(
2271
2379
  "format_ndjson",
2272
2380
  "Validate newline-delimited JSON (NDJSON/JSON Lines), report per-line errors, and pretty-print each valid line.",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@utilix-tech/mcp",
3
- "version": "0.16.0",
4
- "description": "MCP server exposing 116 Utilix developer tools to Claude, Cursor, VS Code Copilot, and any MCP-compatible AI assistant.",
3
+ "version": "0.17.0",
4
+ "description": "MCP server exposing 123 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/mcp",