@utilix-tech/mcp 0.23.0 → 0.24.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 +3 -0
- package/README.md +3 -2
- package/dist/index.js +66 -0
- package/package.json +1 -1
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.24.0
|
|
6
|
+
- Add `calculate_margin_markup` tool: given exactly two of cost, price, margin percent, and markup percent, solve for the other two plus the gross profit.
|
|
7
|
+
|
|
5
8
|
## 0.23.0
|
|
6
9
|
- Add `convert_apr_apy` tool: convert between a nominal APR and effective APY for a given compounding frequency, in both directions.
|
|
7
10
|
- Add `convert_iso8601_duration` tool: parse an ISO 8601 duration into components and total seconds, or format seconds into a canonical duration string.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @utilix-tech/mcp
|
|
2
2
|
|
|
3
|
-
MCP server exposing
|
|
3
|
+
MCP server exposing 135 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
|
|
|
@@ -152,7 +152,7 @@ claude mcp add utilix -- npx -y @utilix-tech/mcp
|
|
|
152
152
|
| `convert_timezone` | Convert a date/time between timezones |
|
|
153
153
|
| `convert_iso8601_duration` | Parse an ISO 8601 duration into components and total seconds, or format seconds into a duration string |
|
|
154
154
|
|
|
155
|
-
### Units (
|
|
155
|
+
### Units (15 tools)
|
|
156
156
|
| Tool | Description |
|
|
157
157
|
|------|-------------|
|
|
158
158
|
| `convert_bytes` | Convert between B, KB, MB, GB, TB, KiB, MiB, GiB, TiB |
|
|
@@ -169,6 +169,7 @@ claude mcp add utilix -- npx -y @utilix-tech/mcp
|
|
|
169
169
|
| `calculate_time_value` | Convert between present and future value (time value of money) in either direction |
|
|
170
170
|
| `calculate_percentage_change` | Compute the percentage change between two numbers, with absolute change, direction, and multiplier |
|
|
171
171
|
| `convert_apr_apy` | Convert between a nominal APR and effective APY for a given compounding frequency, in both directions |
|
|
172
|
+
| `calculate_margin_markup` | Given any two of cost, price, margin percent, and markup percent, solve for the other two plus gross profit |
|
|
172
173
|
|
|
173
174
|
### API / Network (10 tools)
|
|
174
175
|
| Tool | Description |
|
package/dist/index.js
CHANGED
|
@@ -4058,5 +4058,71 @@ server.tool(
|
|
|
4058
4058
|
return text(JSON.stringify(result, null, 2));
|
|
4059
4059
|
}
|
|
4060
4060
|
);
|
|
4061
|
+
var _MARGIN_FIELDS_MCP = ["cost", "price", "marginPercent", "markupPercent"];
|
|
4062
|
+
function _calculateMarginMarkupMcp(input) {
|
|
4063
|
+
const provided = (v) => typeof v === "number" && Number.isFinite(v);
|
|
4064
|
+
const given = _MARGIN_FIELDS_MCP.filter((f) => provided(input[f]));
|
|
4065
|
+
if (given.length !== 2) {
|
|
4066
|
+
return { error: `Provide exactly two of cost, price, marginPercent, markupPercent (got ${given.length})` };
|
|
4067
|
+
}
|
|
4068
|
+
const has = (f) => given.includes(f);
|
|
4069
|
+
const cost0 = input.cost;
|
|
4070
|
+
const price0 = input.price;
|
|
4071
|
+
const margin0 = input.marginPercent;
|
|
4072
|
+
const markup0 = input.markupPercent;
|
|
4073
|
+
if (has("cost") && cost0 <= 0) return { error: "Cost must be greater than zero" };
|
|
4074
|
+
if (has("price") && price0 <= 0) return { error: "Price must be greater than zero" };
|
|
4075
|
+
if (has("marginPercent") && margin0 >= 100) return { error: "Margin percent must be below 100 (a 100% margin implies a zero cost)" };
|
|
4076
|
+
if (has("markupPercent") && markup0 <= -100) return { error: "Markup percent must be greater than -100" };
|
|
4077
|
+
let cost;
|
|
4078
|
+
let price;
|
|
4079
|
+
if (has("cost") && has("price")) {
|
|
4080
|
+
cost = cost0;
|
|
4081
|
+
price = price0;
|
|
4082
|
+
} else if (has("cost") && has("marginPercent")) {
|
|
4083
|
+
cost = cost0;
|
|
4084
|
+
price = cost0 / (1 - margin0 / 100);
|
|
4085
|
+
} else if (has("cost") && has("markupPercent")) {
|
|
4086
|
+
cost = cost0;
|
|
4087
|
+
price = cost0 * (1 + markup0 / 100);
|
|
4088
|
+
} else if (has("price") && has("marginPercent")) {
|
|
4089
|
+
price = price0;
|
|
4090
|
+
cost = price0 * (1 - margin0 / 100);
|
|
4091
|
+
} else if (has("price") && has("markupPercent")) {
|
|
4092
|
+
price = price0;
|
|
4093
|
+
cost = price0 / (1 + markup0 / 100);
|
|
4094
|
+
} else {
|
|
4095
|
+
return { error: "Margin and markup alone cannot be solved: also provide a cost or a price" };
|
|
4096
|
+
}
|
|
4097
|
+
if (!Number.isFinite(cost) || !Number.isFinite(price)) return { error: "Inputs produce a non-finite result" };
|
|
4098
|
+
if (cost <= 0) return { error: "Those inputs imply a cost of zero or less" };
|
|
4099
|
+
if (price <= 0) return { error: "Those inputs imply a price of zero or less" };
|
|
4100
|
+
const round4 = (n) => Math.round(n * 1e4) / 1e4;
|
|
4101
|
+
const profit = price - cost;
|
|
4102
|
+
return {
|
|
4103
|
+
cost: round4(cost),
|
|
4104
|
+
price: round4(price),
|
|
4105
|
+
profit: round4(profit),
|
|
4106
|
+
marginPercent: round4(profit / price * 100),
|
|
4107
|
+
markupPercent: round4(profit / cost * 100),
|
|
4108
|
+
given,
|
|
4109
|
+
solvedFor: _MARGIN_FIELDS_MCP.filter((f) => !given.includes(f))
|
|
4110
|
+
};
|
|
4111
|
+
}
|
|
4112
|
+
server.tool(
|
|
4113
|
+
"calculate_margin_markup",
|
|
4114
|
+
"Solve a pricing triangle: given exactly two of cost, price, gross margin percent, and markup percent, derive the other two plus the gross profit. Margin is profit as a share of the selling price (profit / price) while markup is profit as a share of the cost (profit / cost), so a 20% margin equals a 25% markup. Margin plus markup alone cannot be solved, since neither carries an absolute amount.",
|
|
4115
|
+
{
|
|
4116
|
+
cost: z.number().optional().describe("Unit cost (what you pay). Provide exactly two of the four fields."),
|
|
4117
|
+
price: z.number().optional().describe("Selling price (what the customer pays). Provide exactly two of the four fields."),
|
|
4118
|
+
marginPercent: z.number().optional().describe("Gross margin as a percent of the selling price (must be below 100)"),
|
|
4119
|
+
markupPercent: z.number().optional().describe("Markup as a percent of the cost (must be greater than -100)")
|
|
4120
|
+
},
|
|
4121
|
+
async ({ cost, price, marginPercent, markupPercent }) => {
|
|
4122
|
+
const result = _calculateMarginMarkupMcp({ cost, price, marginPercent, markupPercent });
|
|
4123
|
+
if ("error" in result) return errText(result);
|
|
4124
|
+
return text(JSON.stringify(result, null, 2));
|
|
4125
|
+
}
|
|
4126
|
+
);
|
|
4061
4127
|
var transport = new StdioServerTransport();
|
|
4062
4128
|
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.24.0",
|
|
4
4
|
"description": "MCP server exposing 125 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",
|