@utilix-tech/mcp 0.50.0 → 0.51.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 +4 -0
- package/README.md +5 -3
- package/dist/index.js +100 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
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.51.0
|
|
6
|
+
- Add `calculate_moving_averages` tool: compute SMA and EMA series from a list of numbers and a window size.
|
|
7
|
+
- Add `calculate_markdown_task_list_progress` tool: parse a Markdown document's checkbox task list and report completion percentage overall and per section.
|
|
8
|
+
|
|
5
9
|
## 0.50.0
|
|
6
10
|
- Add `calculate_cash_rounding` tool: round a cashless total to the nearest payable cash denomination ("Swedish rounding"), with round-nearest, round-up, and round-down modes.
|
|
7
11
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @utilix-tech/mcp
|
|
2
2
|
|
|
3
|
-
MCP server exposing
|
|
3
|
+
MCP server exposing 191 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
|
|
|
@@ -160,7 +160,7 @@ claude mcp add utilix -- npx -y @utilix-tech/mcp
|
|
|
160
160
|
| `convert_timezone` | Convert a date/time between timezones |
|
|
161
161
|
| `convert_iso8601_duration` | Parse an ISO 8601 duration into components and total seconds, or format seconds into a duration string |
|
|
162
162
|
|
|
163
|
-
### Units (
|
|
163
|
+
### Units (31 tools)
|
|
164
164
|
| Tool | Description |
|
|
165
165
|
|------|-------------|
|
|
166
166
|
| `convert_bytes` | Convert between B, KB, MB, GB, TB, KiB, MiB, GiB, TiB |
|
|
@@ -193,6 +193,7 @@ claude mcp add utilix -- npx -y @utilix-tech/mcp
|
|
|
193
193
|
| `calculate_cd_maturity` | Compute a certificate of deposit's maturity value and effective annual yield (APY) from a principal, nominal rate, term, and compounding frequency, plus the net early-withdrawal payout |
|
|
194
194
|
| `calculate_depreciation_schedule` | Build a year-by-year fixed-asset depreciation schedule from cost, salvage value, and useful life, using straight-line, double-declining-balance, or sum-of-years-digits |
|
|
195
195
|
| `calculate_cash_rounding` | Round a cashless total to the nearest payable cash denomination ("Swedish rounding"), with round-nearest, round-up, and round-down modes |
|
|
196
|
+
| `calculate_moving_averages` | Compute simple moving average (SMA) and exponential moving average (EMA) series from a list of numbers and a window size |
|
|
196
197
|
|
|
197
198
|
### API / Network (28 tools)
|
|
198
199
|
| Tool | Description |
|
|
@@ -250,7 +251,7 @@ claude mcp add utilix -- npx -y @utilix-tech/mcp
|
|
|
250
251
|
| `lint_conventional_commit` | Lint a commit message against the Conventional Commits v1.0.0 spec: header format, blank-line separation, footer tokens, and BREAKING CHANGE casing |
|
|
251
252
|
| `test_gitignore_patterns` | Test a list of paths against a .gitignore file's patterns, following git's last-match-wins and negation rules |
|
|
252
253
|
|
|
253
|
-
### Data (
|
|
254
|
+
### Data (12 tools)
|
|
254
255
|
| Tool | Description |
|
|
255
256
|
|------|-------------|
|
|
256
257
|
| `validate_yaml` | Validate YAML syntax |
|
|
@@ -264,6 +265,7 @@ claude mcp add utilix -- npx -y @utilix-tech/mcp
|
|
|
264
265
|
| `generate_markdown_toc` | Scan a Markdown document's ATX headings and build a nested table of contents with GitHub-style anchor slugs |
|
|
265
266
|
| `csv_to_sql_insert` | Convert CSV data with a header row into parameterless SQL INSERT statements, with basic type inference and ANSI/MySQL identifier quoting |
|
|
266
267
|
| `find_csv_duplicate_rows` | Group CSV/TSV rows that share the same value across a chosen set of key columns, or the entire row |
|
|
268
|
+
| `calculate_markdown_task_list_progress` | Parse a Markdown document's checkbox task list and report completion percentage overall and per section, grouped by the nearest preceding heading |
|
|
267
269
|
|
|
268
270
|
### CSS (2 tools)
|
|
269
271
|
| Tool | Description |
|
package/dist/index.js
CHANGED
|
@@ -8340,5 +8340,105 @@ server.tool(
|
|
|
8340
8340
|
return text(JSON.stringify(result, null, 2));
|
|
8341
8341
|
}
|
|
8342
8342
|
);
|
|
8343
|
+
function _calculateMovingAveragesMcp(values, windowSize) {
|
|
8344
|
+
if (!Array.isArray(values) || values.length === 0 || !values.every((v) => typeof v === "number" && Number.isFinite(v))) {
|
|
8345
|
+
return { error: "values must be a non-empty array of finite numbers" };
|
|
8346
|
+
}
|
|
8347
|
+
if (!Number.isInteger(windowSize) || windowSize < 1) {
|
|
8348
|
+
return { error: "windowSize must be a positive integer" };
|
|
8349
|
+
}
|
|
8350
|
+
if (windowSize > values.length) {
|
|
8351
|
+
return { error: "windowSize must be less than or equal to the number of values" };
|
|
8352
|
+
}
|
|
8353
|
+
const round4 = (n) => Math.round(n * 1e4) / 1e4;
|
|
8354
|
+
const multiplier = 2 / (windowSize + 1);
|
|
8355
|
+
const points = [];
|
|
8356
|
+
let emaPrev = null;
|
|
8357
|
+
for (let i = 0; i < values.length; i++) {
|
|
8358
|
+
let sma = null;
|
|
8359
|
+
if (i >= windowSize - 1) {
|
|
8360
|
+
let sum = 0;
|
|
8361
|
+
for (let j = i - windowSize + 1; j <= i; j++) sum += values[j];
|
|
8362
|
+
sma = round4(sum / windowSize);
|
|
8363
|
+
}
|
|
8364
|
+
let ema = null;
|
|
8365
|
+
if (i === windowSize - 1) {
|
|
8366
|
+
ema = sma;
|
|
8367
|
+
emaPrev = ema;
|
|
8368
|
+
} else if (i > windowSize - 1 && emaPrev !== null) {
|
|
8369
|
+
ema = round4(values[i] * multiplier + emaPrev * (1 - multiplier));
|
|
8370
|
+
emaPrev = ema;
|
|
8371
|
+
}
|
|
8372
|
+
points.push({ index: i, value: values[i], sma, ema });
|
|
8373
|
+
}
|
|
8374
|
+
const last = points[points.length - 1];
|
|
8375
|
+
return { windowSize, multiplier: round4(multiplier), points, latestSma: last.sma, latestEma: last.ema };
|
|
8376
|
+
}
|
|
8377
|
+
server.tool(
|
|
8378
|
+
"calculate_moving_averages",
|
|
8379
|
+
"Compute simple moving average (SMA) and exponential moving average (EMA) series from a list of numbers and a window size, a foundational technical-indicator building block for price/volume data. No live market-data feed is involved: this operates only on numbers you supply.",
|
|
8380
|
+
{
|
|
8381
|
+
values: z.array(z.number()).min(1).describe("A non-empty series of finite numbers, e.g. daily closing prices"),
|
|
8382
|
+
windowSize: z.number().int().min(1).describe("The trailing window size for both SMA and EMA, must not exceed values.length")
|
|
8383
|
+
},
|
|
8384
|
+
async ({ values, windowSize }) => {
|
|
8385
|
+
const result = _calculateMovingAveragesMcp(values, windowSize);
|
|
8386
|
+
if ("error" in result) return errText(result);
|
|
8387
|
+
return text(JSON.stringify(result, null, 2));
|
|
8388
|
+
}
|
|
8389
|
+
);
|
|
8390
|
+
function _calculateMarkdownTaskListProgressMcp(markdown) {
|
|
8391
|
+
const round2 = (n) => Math.round(n * 100) / 100;
|
|
8392
|
+
const headingRe = /^(#{1,6})\s+(.*)$/;
|
|
8393
|
+
const itemRe = /^(\s*)[-*+]\s+\[([ xX])\]\s+(.*)$/;
|
|
8394
|
+
let currentSection = "(no heading)";
|
|
8395
|
+
const items = [];
|
|
8396
|
+
for (const line of markdown.replace(/\r\n/g, "\n").split("\n")) {
|
|
8397
|
+
const headingMatch = line.match(headingRe);
|
|
8398
|
+
if (headingMatch) {
|
|
8399
|
+
currentSection = headingMatch[2].trim();
|
|
8400
|
+
continue;
|
|
8401
|
+
}
|
|
8402
|
+
const itemMatch = line.match(itemRe);
|
|
8403
|
+
if (itemMatch) {
|
|
8404
|
+
items.push({
|
|
8405
|
+
text: itemMatch[3].trim(),
|
|
8406
|
+
checked: itemMatch[2].toLowerCase() === "x",
|
|
8407
|
+
indent: itemMatch[1].length,
|
|
8408
|
+
section: currentSection
|
|
8409
|
+
});
|
|
8410
|
+
}
|
|
8411
|
+
}
|
|
8412
|
+
const totalItems = items.length;
|
|
8413
|
+
const completedItems = items.filter((i) => i.checked).length;
|
|
8414
|
+
const percentComplete = totalItems === 0 ? 0 : round2(completedItems / totalItems * 100);
|
|
8415
|
+
const sectionOrder = [];
|
|
8416
|
+
const sectionTotals = /* @__PURE__ */ new Map();
|
|
8417
|
+
for (const item of items) {
|
|
8418
|
+
if (!sectionTotals.has(item.section)) {
|
|
8419
|
+
sectionTotals.set(item.section, { total: 0, completed: 0 });
|
|
8420
|
+
sectionOrder.push(item.section);
|
|
8421
|
+
}
|
|
8422
|
+
const s = sectionTotals.get(item.section);
|
|
8423
|
+
s.total++;
|
|
8424
|
+
if (item.checked) s.completed++;
|
|
8425
|
+
}
|
|
8426
|
+
const sections = sectionOrder.map((section) => {
|
|
8427
|
+
const s = sectionTotals.get(section);
|
|
8428
|
+
return { section, total: s.total, completed: s.completed, percentComplete: s.total === 0 ? 0 : round2(s.completed / s.total * 100) };
|
|
8429
|
+
});
|
|
8430
|
+
return { totalItems, completedItems, percentComplete, sections, items };
|
|
8431
|
+
}
|
|
8432
|
+
server.tool(
|
|
8433
|
+
"calculate_markdown_task_list_progress",
|
|
8434
|
+
"Parse a Markdown document's `- [ ]`/`- [x]` task list checkboxes and report completion percentage overall and per section, where a section is the nearest preceding ATX heading of any level.",
|
|
8435
|
+
{
|
|
8436
|
+
markdown: z.string().describe("The Markdown document to scan for task list checkboxes")
|
|
8437
|
+
},
|
|
8438
|
+
async ({ markdown }) => {
|
|
8439
|
+
const result = _calculateMarkdownTaskListProgressMcp(markdown);
|
|
8440
|
+
return text(JSON.stringify(result, null, 2));
|
|
8441
|
+
}
|
|
8442
|
+
);
|
|
8343
8443
|
var transport = new StdioServerTransport();
|
|
8344
8444
|
await server.connect(transport);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@utilix-tech/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.51.0",
|
|
4
4
|
"description": "MCP server exposing 188 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",
|