it-tools-mcp 3.0.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.
@@ -0,0 +1,306 @@
1
+ import { evaluate } from "mathjs";
2
+ import { z } from "zod";
3
+ export function registerMathTools(server) {
4
+ // Math expression evaluator
5
+ server.tool("math-evaluate", "Safely evaluate mathematical expressions", {
6
+ expression: z.string().describe("Mathematical expression to evaluate (e.g., '2 + 3 * 4')")
7
+ }, async ({ expression }) => {
8
+ try {
9
+ const result = evaluate(expression);
10
+ return {
11
+ content: [
12
+ {
13
+ type: "text",
14
+ text: `Expression: ${expression}\nResult: ${result}`
15
+ }
16
+ ]
17
+ };
18
+ }
19
+ catch (error) {
20
+ return {
21
+ content: [
22
+ {
23
+ type: "text",
24
+ text: `Error evaluating expression: ${error instanceof Error ? error.message : 'Unknown error'}`
25
+ }
26
+ ]
27
+ };
28
+ }
29
+ });
30
+ // Number base converter
31
+ server.tool("number-base-converter", "Convert numbers between different bases (binary, octal, decimal, hexadecimal)", {
32
+ number: z.string().describe("Number to convert"),
33
+ fromBase: z.number().describe("Source base (2-36)"),
34
+ toBase: z.number().describe("Target base (2-36)")
35
+ }, async ({ number, fromBase, toBase }) => {
36
+ try {
37
+ if (fromBase < 2 || fromBase > 36 || toBase < 2 || toBase > 36) {
38
+ return {
39
+ content: [
40
+ {
41
+ type: "text",
42
+ text: "Base must be between 2 and 36.",
43
+ },
44
+ ],
45
+ };
46
+ }
47
+ // Parse number from source base to decimal
48
+ const decimal = parseInt(number, fromBase);
49
+ if (isNaN(decimal)) {
50
+ throw new Error("Invalid number for the specified base");
51
+ }
52
+ // Convert decimal to target base
53
+ const result = decimal.toString(toBase);
54
+ return {
55
+ content: [
56
+ {
57
+ type: "text",
58
+ text: `${number} (base ${fromBase}) = ${result} (base ${toBase})\nDecimal equivalent: ${decimal}`
59
+ }
60
+ ]
61
+ };
62
+ }
63
+ catch (error) {
64
+ return {
65
+ content: [
66
+ {
67
+ type: "text",
68
+ text: `Error converting number: ${error instanceof Error ? error.message : 'Unknown error'}`
69
+ }
70
+ ]
71
+ };
72
+ }
73
+ });
74
+ // Roman numeral converter
75
+ server.tool("roman-numeral-converter", "Convert between Arabic numbers and Roman numerals", {
76
+ input: z.string().describe("Number to convert (Arabic number 1-3999 or Roman numeral)")
77
+ }, async ({ input }) => {
78
+ try {
79
+ // Auto-detect if input is a number or Roman numeral
80
+ const isNumber = /^\d+$/.test(input.trim());
81
+ if (isNumber) {
82
+ // Convert number to Roman numeral
83
+ const num = parseInt(input);
84
+ if (isNaN(num) || num < 1 || num > 3999) {
85
+ throw new Error("Number must be between 1 and 3999");
86
+ }
87
+ const values = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
88
+ const symbols = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"];
89
+ let result = "";
90
+ let remaining = num;
91
+ for (let i = 0; i < values.length; i++) {
92
+ while (remaining >= values[i]) {
93
+ result += symbols[i];
94
+ remaining -= values[i];
95
+ }
96
+ }
97
+ return {
98
+ content: [
99
+ {
100
+ type: "text",
101
+ text: `${num} = ${result} in Roman numerals`
102
+ }
103
+ ]
104
+ };
105
+ }
106
+ else {
107
+ // Convert Roman numeral to number
108
+ const roman = input.toUpperCase();
109
+ const romanMap = {
110
+ I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000
111
+ };
112
+ let result = 0;
113
+ let prev = 0;
114
+ for (let i = roman.length - 1; i >= 0; i--) {
115
+ const current = romanMap[roman[i]];
116
+ if (!current) {
117
+ throw new Error(`Invalid Roman numeral character: ${roman[i]}`);
118
+ }
119
+ if (current < prev) {
120
+ result -= current;
121
+ }
122
+ else {
123
+ result += current;
124
+ }
125
+ prev = current;
126
+ }
127
+ return {
128
+ content: [
129
+ {
130
+ type: "text",
131
+ text: `${roman} = ${result} in decimal`
132
+ }
133
+ ]
134
+ };
135
+ }
136
+ }
137
+ catch (error) {
138
+ return {
139
+ content: [
140
+ {
141
+ type: "text",
142
+ text: `Error converting Roman numeral: ${error instanceof Error ? error.message : 'Unknown error'}`
143
+ }
144
+ ]
145
+ };
146
+ }
147
+ });
148
+ // Temperature converter
149
+ server.tool("temperature-converter", "Convert temperatures between Celsius, Fahrenheit, and Kelvin", {
150
+ temperature: z.number().describe("Temperature value to convert"),
151
+ from: z.enum(["celsius", "fahrenheit", "kelvin"]).describe("Source temperature unit"),
152
+ to: z.enum(["celsius", "fahrenheit", "kelvin"]).describe("Target temperature unit")
153
+ }, async ({ temperature, from, to }) => {
154
+ try {
155
+ // Convert to Celsius first
156
+ let celsius;
157
+ switch (from) {
158
+ case "celsius":
159
+ celsius = temperature;
160
+ break;
161
+ case "fahrenheit":
162
+ celsius = (temperature - 32) * 5 / 9;
163
+ break;
164
+ case "kelvin":
165
+ celsius = temperature - 273.15;
166
+ break;
167
+ default:
168
+ throw new Error("Invalid source unit");
169
+ }
170
+ // Convert from Celsius to target unit
171
+ let result;
172
+ switch (to) {
173
+ case "celsius":
174
+ result = celsius;
175
+ break;
176
+ case "fahrenheit":
177
+ result = celsius * 9 / 5 + 32;
178
+ break;
179
+ case "kelvin":
180
+ result = celsius + 273.15;
181
+ break;
182
+ default:
183
+ throw new Error("Invalid target unit");
184
+ }
185
+ return {
186
+ content: [
187
+ {
188
+ type: "text",
189
+ text: `${temperature}° ${from} = ${result.toFixed(2)}° ${to}`
190
+ }
191
+ ]
192
+ };
193
+ }
194
+ catch (error) {
195
+ return {
196
+ content: [
197
+ {
198
+ type: "text",
199
+ text: `Error converting temperature: ${error instanceof Error ? error.message : 'Unknown error'}`
200
+ }
201
+ ]
202
+ };
203
+ }
204
+ });
205
+ // Percentage calculator
206
+ server.tool("percentage-calculator", "Calculate percentages, percentage of a number, or percentage change", {
207
+ operation: z.enum(["percentage-of", "what-percentage", "percentage-change"]).describe("Type of percentage calculation"),
208
+ value1: z.number().describe("First value"),
209
+ value2: z.number().describe("Second value")
210
+ }, async ({ operation, value1, value2 }) => {
211
+ try {
212
+ let result;
213
+ let explanation;
214
+ switch (operation) {
215
+ case "percentage-of":
216
+ // value1% of value2
217
+ result = (value1 / 100) * value2;
218
+ explanation = `${value1}% of ${value2} = ${result}`;
219
+ break;
220
+ case "what-percentage":
221
+ // value1 is what percentage of value2
222
+ result = (value1 / value2) * 100;
223
+ explanation = `${value1} is ${result.toFixed(2)}% of ${value2}`;
224
+ break;
225
+ case "percentage-change":
226
+ // percentage change from value1 to value2
227
+ result = ((value2 - value1) / value1) * 100;
228
+ explanation = `Percentage change from ${value1} to ${value2} = ${result.toFixed(2)}%`;
229
+ break;
230
+ default:
231
+ throw new Error("Invalid operation");
232
+ }
233
+ return {
234
+ content: [
235
+ {
236
+ type: "text",
237
+ text: explanation
238
+ }
239
+ ]
240
+ };
241
+ }
242
+ catch (error) {
243
+ return {
244
+ content: [
245
+ {
246
+ type: "text",
247
+ text: `Error calculating percentage: ${error instanceof Error ? error.message : 'Unknown error'}`
248
+ }
249
+ ]
250
+ };
251
+ }
252
+ });
253
+ // Unix timestamp converter
254
+ server.tool("unix-timestamp-converter", "Convert between Unix timestamps and human-readable dates", {
255
+ input: z.string().describe("Unix timestamp (seconds) or ISO date string")
256
+ }, async ({ input }) => {
257
+ try {
258
+ // Auto-detect if input is a timestamp or date string
259
+ const isTimestamp = /^\d+$/.test(input.trim());
260
+ if (isTimestamp) {
261
+ // Convert timestamp to date
262
+ const timestamp = parseInt(input);
263
+ if (isNaN(timestamp)) {
264
+ throw new Error("Invalid timestamp");
265
+ }
266
+ const date = new Date(timestamp * 1000);
267
+ const iso = date.toISOString();
268
+ const local = date.toLocaleString();
269
+ return {
270
+ content: [
271
+ {
272
+ type: "text",
273
+ text: `Timestamp: ${timestamp}\nISO Date: ${iso}\nLocal Date: ${local}`
274
+ }
275
+ ]
276
+ };
277
+ }
278
+ else {
279
+ // Convert date string to timestamp
280
+ const date = new Date(input);
281
+ if (isNaN(date.getTime())) {
282
+ throw new Error("Invalid date string");
283
+ }
284
+ const timestamp = Math.floor(date.getTime() / 1000);
285
+ return {
286
+ content: [
287
+ {
288
+ type: "text",
289
+ text: `Date: ${input}\nUnix Timestamp: ${timestamp}`
290
+ }
291
+ ]
292
+ };
293
+ }
294
+ }
295
+ catch (error) {
296
+ return {
297
+ content: [
298
+ {
299
+ type: "text",
300
+ text: `Error converting timestamp: ${error instanceof Error ? error.message : 'Unknown error'}`
301
+ }
302
+ ]
303
+ };
304
+ }
305
+ });
306
+ }