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.
- package/LICENSE +21 -0
- package/README.dockerhub.md +98 -0
- package/README.md +263 -0
- package/build/index.js +75 -0
- package/build/security.js +201 -0
- package/build/tools/color.js +67 -0
- package/build/tools/crypto.js +445 -0
- package/build/tools/dataFormat.js +517 -0
- package/build/tools/development.js +267 -0
- package/build/tools/encoding.js +240 -0
- package/build/tools/idGenerators.js +176 -0
- package/build/tools/math.js +306 -0
- package/build/tools/network.js +578 -0
- package/build/tools/text.js +678 -0
- package/build/tools/utility.js +407 -0
- package/package.json +94 -0
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
import { createHash, createHmac } from "crypto";
|
|
2
|
+
import bcryptjs from "bcryptjs";
|
|
3
|
+
import * as bip39 from "bip39";
|
|
4
|
+
import speakeasy from "speakeasy";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
export function registerCryptoTools(server) {
|
|
7
|
+
// Hash generation tools
|
|
8
|
+
const hashAlgorithms = ['md5', 'sha1', 'sha256', 'sha512'];
|
|
9
|
+
hashAlgorithms.forEach(algorithm => {
|
|
10
|
+
server.tool(`hash-${algorithm}`, `Generate ${algorithm.toUpperCase()} hash`, {
|
|
11
|
+
text: z.string().describe(`Text to hash with ${algorithm.toUpperCase()}`),
|
|
12
|
+
}, async ({ text }) => {
|
|
13
|
+
const hash = createHash(algorithm);
|
|
14
|
+
hash.update(text);
|
|
15
|
+
const result = hash.digest('hex');
|
|
16
|
+
return {
|
|
17
|
+
content: [
|
|
18
|
+
{
|
|
19
|
+
type: "text",
|
|
20
|
+
text: `${algorithm.toUpperCase()} hash: ${result}`,
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
// HMAC generator tool
|
|
27
|
+
server.tool("hmac-generator", "Generate HMAC (Hash-based Message Authentication Code)", {
|
|
28
|
+
message: z.string().describe("Message to authenticate"),
|
|
29
|
+
key: z.string().describe("Secret key for HMAC"),
|
|
30
|
+
algorithm: z.enum(["sha1", "sha256", "sha512"]).describe("Hash algorithm").optional(),
|
|
31
|
+
}, async ({ message, key, algorithm = "sha256" }) => {
|
|
32
|
+
try {
|
|
33
|
+
const hmac = createHmac(algorithm, key);
|
|
34
|
+
hmac.update(message);
|
|
35
|
+
const result = hmac.digest('hex');
|
|
36
|
+
return {
|
|
37
|
+
content: [
|
|
38
|
+
{
|
|
39
|
+
type: "text",
|
|
40
|
+
text: `HMAC-${algorithm.toUpperCase()}: ${result}
|
|
41
|
+
|
|
42
|
+
Message: ${message}
|
|
43
|
+
Key: ${key}
|
|
44
|
+
Algorithm: ${algorithm.toUpperCase()}`,
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
return {
|
|
51
|
+
content: [
|
|
52
|
+
{
|
|
53
|
+
type: "text",
|
|
54
|
+
text: `Error generating HMAC: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
// JWT decode tool (header and payload only)
|
|
61
|
+
server.tool("jwt-decode", "Decode JWT token (header and payload only)", {
|
|
62
|
+
token: z.string().describe("JWT token to decode"),
|
|
63
|
+
}, async ({ token }) => {
|
|
64
|
+
try {
|
|
65
|
+
const parts = token.split('.');
|
|
66
|
+
if (parts.length !== 3) {
|
|
67
|
+
throw new Error("Invalid JWT format. JWT must have 3 parts separated by dots.");
|
|
68
|
+
}
|
|
69
|
+
const header = JSON.parse(Buffer.from(parts[0], 'base64url').toString());
|
|
70
|
+
const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString());
|
|
71
|
+
return {
|
|
72
|
+
content: [
|
|
73
|
+
{
|
|
74
|
+
type: "text",
|
|
75
|
+
text: `JWT Token Decoded:
|
|
76
|
+
|
|
77
|
+
Header:
|
|
78
|
+
${JSON.stringify(header, null, 2)}
|
|
79
|
+
|
|
80
|
+
Payload:
|
|
81
|
+
${JSON.stringify(payload, null, 2)}
|
|
82
|
+
|
|
83
|
+
Note: Signature verification is not performed. Do not trust this token without proper verification.`,
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
return {
|
|
90
|
+
content: [
|
|
91
|
+
{
|
|
92
|
+
type: "text",
|
|
93
|
+
text: `Error decoding JWT: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
// Basic auth generator tool
|
|
100
|
+
server.tool("basic-auth-generator", "Generate HTTP Basic Authentication header", {
|
|
101
|
+
username: z.string().describe("Username"),
|
|
102
|
+
password: z.string().describe("Password"),
|
|
103
|
+
}, async ({ username, password }) => {
|
|
104
|
+
try {
|
|
105
|
+
const credentials = `${username}:${password}`;
|
|
106
|
+
const encoded = Buffer.from(credentials, 'utf-8').toString('base64');
|
|
107
|
+
const authHeader = `Basic ${encoded}`;
|
|
108
|
+
return {
|
|
109
|
+
content: [
|
|
110
|
+
{
|
|
111
|
+
type: "text",
|
|
112
|
+
text: `HTTP Basic Auth Header:
|
|
113
|
+
Authorization: ${authHeader}
|
|
114
|
+
|
|
115
|
+
Credentials: ${username}:${password}
|
|
116
|
+
Base64 Encoded: ${encoded}
|
|
117
|
+
|
|
118
|
+
Usage in curl:
|
|
119
|
+
curl -H "Authorization: ${authHeader}" https://api.example.com
|
|
120
|
+
|
|
121
|
+
Usage in fetch:
|
|
122
|
+
fetch('https://api.example.com', {
|
|
123
|
+
headers: {
|
|
124
|
+
'Authorization': '${authHeader}'
|
|
125
|
+
}
|
|
126
|
+
})`,
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
return {
|
|
133
|
+
content: [
|
|
134
|
+
{
|
|
135
|
+
type: "text",
|
|
136
|
+
text: `Error generating basic auth: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
// Bcrypt hash tool
|
|
143
|
+
server.tool("bcrypt-hash", "Generate bcrypt hash or verify password against hash", {
|
|
144
|
+
password: z.string().describe("Password to hash or verify"),
|
|
145
|
+
rounds: z.number().describe("Number of salt rounds (4-12, default 10)").optional(),
|
|
146
|
+
hash: z.string().optional().describe("Existing hash to verify against (for verification)"),
|
|
147
|
+
}, async ({ password, rounds = 10, hash }) => {
|
|
148
|
+
try {
|
|
149
|
+
if (rounds < 4 || rounds > 12) {
|
|
150
|
+
return {
|
|
151
|
+
content: [
|
|
152
|
+
{
|
|
153
|
+
type: "text",
|
|
154
|
+
text: "Rounds must be between 4 and 12.",
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
if (hash) {
|
|
160
|
+
// Verification mode
|
|
161
|
+
const isValid = await bcryptjs.compare(password, hash);
|
|
162
|
+
return {
|
|
163
|
+
content: [
|
|
164
|
+
{
|
|
165
|
+
type: "text",
|
|
166
|
+
text: `Password Verification: ${isValid ? 'VALID' : 'INVALID'}
|
|
167
|
+
|
|
168
|
+
Password: ${password}
|
|
169
|
+
Hash: ${hash}`,
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
// Hash generation mode
|
|
176
|
+
const salt = await bcryptjs.genSalt(rounds);
|
|
177
|
+
const hashedPassword = await bcryptjs.hash(password, salt);
|
|
178
|
+
return {
|
|
179
|
+
content: [
|
|
180
|
+
{
|
|
181
|
+
type: "text",
|
|
182
|
+
text: `Bcrypt Hash Generated:
|
|
183
|
+
Hash: ${hashedPassword}
|
|
184
|
+
|
|
185
|
+
Password: ${password}
|
|
186
|
+
Rounds: ${rounds}
|
|
187
|
+
Algorithm: bcrypt
|
|
188
|
+
|
|
189
|
+
This hash can be safely stored in databases and used for password verification.`,
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
return {
|
|
197
|
+
content: [
|
|
198
|
+
{
|
|
199
|
+
type: "text",
|
|
200
|
+
text: `Error with bcrypt operation: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
// BIP39 mnemonic generator
|
|
207
|
+
server.tool("bip39-generate", "Generate BIP39 mnemonic phrases", {
|
|
208
|
+
wordCount: z.enum(["12", "15", "18", "21", "24"]).describe("Number of words in the mnemonic").optional(),
|
|
209
|
+
}, async ({ wordCount = "12" }) => {
|
|
210
|
+
try {
|
|
211
|
+
const count = parseInt(wordCount);
|
|
212
|
+
// Generate entropy based on word count
|
|
213
|
+
// 12 words = 128 bits, 15 words = 160 bits, 18 words = 192 bits, 21 words = 224 bits, 24 words = 256 bits
|
|
214
|
+
const entropyBits = Math.floor((count * 11) / 33) * 32;
|
|
215
|
+
const entropyBytes = entropyBits / 8;
|
|
216
|
+
// Generate cryptographically secure random entropy
|
|
217
|
+
const { randomBytes } = await import('crypto');
|
|
218
|
+
const entropy = randomBytes(entropyBytes);
|
|
219
|
+
// Generate mnemonic using proper BIP39 library
|
|
220
|
+
const mnemonic = bip39.entropyToMnemonic(entropy);
|
|
221
|
+
const words = mnemonic.split(' ');
|
|
222
|
+
// Validate the generated mnemonic
|
|
223
|
+
const isValid = bip39.validateMnemonic(mnemonic);
|
|
224
|
+
return {
|
|
225
|
+
content: [
|
|
226
|
+
{
|
|
227
|
+
type: "text",
|
|
228
|
+
text: `BIP39 Mnemonic Phrase (${words.length} words):
|
|
229
|
+
|
|
230
|
+
${mnemonic}
|
|
231
|
+
|
|
232
|
+
Entropy: ${entropy.toString('hex')}
|
|
233
|
+
Valid: ${isValid ? 'Yes ✅' : 'No ❌'}
|
|
234
|
+
Entropy Bits: ${entropyBits}
|
|
235
|
+
|
|
236
|
+
⚠️ SECURITY WARNING:
|
|
237
|
+
- This uses cryptographically secure random generation
|
|
238
|
+
- Store this mnemonic securely and never share it
|
|
239
|
+
- This can be used to generate cryptocurrency wallet seeds
|
|
240
|
+
- Anyone with this mnemonic can access associated wallets`,
|
|
241
|
+
},
|
|
242
|
+
],
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
return {
|
|
247
|
+
content: [
|
|
248
|
+
{
|
|
249
|
+
type: "text",
|
|
250
|
+
text: `Error generating BIP39 mnemonic: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
// Password generator tool
|
|
257
|
+
server.tool("password-generate", "Generate a secure password", {
|
|
258
|
+
length: z.number().describe("Password length").optional(),
|
|
259
|
+
includeUppercase: z.boolean().describe("Include uppercase letters").optional(),
|
|
260
|
+
includeLowercase: z.boolean().describe("Include lowercase letters").optional(),
|
|
261
|
+
includeNumbers: z.boolean().describe("Include numbers").optional(),
|
|
262
|
+
includeSymbols: z.boolean().describe("Include symbols").optional(),
|
|
263
|
+
}, async ({ length = 16, includeUppercase = true, includeLowercase = true, includeNumbers = true, includeSymbols = true }) => {
|
|
264
|
+
if (length < 4 || length > 128) {
|
|
265
|
+
return {
|
|
266
|
+
content: [
|
|
267
|
+
{
|
|
268
|
+
type: "text",
|
|
269
|
+
text: "Length must be between 4 and 128.",
|
|
270
|
+
},
|
|
271
|
+
],
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
let charset = '';
|
|
275
|
+
if (includeUppercase)
|
|
276
|
+
charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
277
|
+
if (includeLowercase)
|
|
278
|
+
charset += 'abcdefghijklmnopqrstuvwxyz';
|
|
279
|
+
if (includeNumbers)
|
|
280
|
+
charset += '0123456789';
|
|
281
|
+
if (includeSymbols)
|
|
282
|
+
charset += '!@#$%^&*()_+-=[]{}|;:,.<>?';
|
|
283
|
+
if (charset === '') {
|
|
284
|
+
return {
|
|
285
|
+
content: [
|
|
286
|
+
{
|
|
287
|
+
type: "text",
|
|
288
|
+
text: "Error: At least one character type must be selected",
|
|
289
|
+
},
|
|
290
|
+
],
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
let password = '';
|
|
294
|
+
const { randomBytes } = await import('crypto');
|
|
295
|
+
const randomValues = randomBytes(length);
|
|
296
|
+
for (let i = 0; i < length; i++) {
|
|
297
|
+
password += charset.charAt(randomValues[i] % charset.length);
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
content: [
|
|
301
|
+
{
|
|
302
|
+
type: "text",
|
|
303
|
+
text: `Generated password: ${password}`,
|
|
304
|
+
},
|
|
305
|
+
],
|
|
306
|
+
};
|
|
307
|
+
});
|
|
308
|
+
// Token generator tool
|
|
309
|
+
server.tool("token-generator", "Generate secure random tokens", {
|
|
310
|
+
length: z.number().describe("Token length").optional(),
|
|
311
|
+
charset: z.enum(["alphanumeric", "hex", "base64", "custom"]).describe("Character set to use").optional(),
|
|
312
|
+
customChars: z.string().optional().describe("Custom characters (required if charset is 'custom')"),
|
|
313
|
+
}, async ({ length = 32, charset = "alphanumeric", customChars }) => {
|
|
314
|
+
try {
|
|
315
|
+
if (length < 8 || length > 256) {
|
|
316
|
+
return {
|
|
317
|
+
content: [
|
|
318
|
+
{
|
|
319
|
+
type: "text",
|
|
320
|
+
text: "Length must be between 8 and 256.",
|
|
321
|
+
},
|
|
322
|
+
],
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
let chars = '';
|
|
326
|
+
switch (charset) {
|
|
327
|
+
case 'alphanumeric':
|
|
328
|
+
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
329
|
+
break;
|
|
330
|
+
case 'hex':
|
|
331
|
+
chars = '0123456789abcdef';
|
|
332
|
+
break;
|
|
333
|
+
case 'base64':
|
|
334
|
+
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
335
|
+
break;
|
|
336
|
+
case 'custom':
|
|
337
|
+
if (!customChars) {
|
|
338
|
+
return {
|
|
339
|
+
content: [
|
|
340
|
+
{
|
|
341
|
+
type: "text",
|
|
342
|
+
text: "Error: Custom characters required when charset is 'custom'",
|
|
343
|
+
},
|
|
344
|
+
],
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
chars = customChars;
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
let token = '';
|
|
351
|
+
const { randomBytes } = await import('crypto');
|
|
352
|
+
const randomValues = randomBytes(length);
|
|
353
|
+
for (let i = 0; i < length; i++) {
|
|
354
|
+
token += chars.charAt(randomValues[i] % chars.length);
|
|
355
|
+
}
|
|
356
|
+
return {
|
|
357
|
+
content: [
|
|
358
|
+
{
|
|
359
|
+
type: "text",
|
|
360
|
+
text: `Generated Token:
|
|
361
|
+
${token}
|
|
362
|
+
|
|
363
|
+
Length: ${length} characters
|
|
364
|
+
Character set: ${charset}
|
|
365
|
+
${charset === 'custom' ? `Custom chars: ${customChars}` : ''}`,
|
|
366
|
+
},
|
|
367
|
+
],
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
catch (error) {
|
|
371
|
+
return {
|
|
372
|
+
content: [
|
|
373
|
+
{
|
|
374
|
+
type: "text",
|
|
375
|
+
text: `Error generating token: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
376
|
+
},
|
|
377
|
+
],
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
// OTP code generator
|
|
382
|
+
server.tool("otp-code-generator", "Generate Time-based One-Time Password (TOTP) codes", {
|
|
383
|
+
secret: z.string().describe("Base32 encoded secret key"),
|
|
384
|
+
digits: z.number().describe("Number of digits in the code").optional(),
|
|
385
|
+
period: z.number().describe("Time period in seconds").optional(),
|
|
386
|
+
}, async ({ secret, digits = 6, period = 30 }) => {
|
|
387
|
+
try {
|
|
388
|
+
if (digits < 4 || digits > 10) {
|
|
389
|
+
return {
|
|
390
|
+
content: [
|
|
391
|
+
{
|
|
392
|
+
type: "text",
|
|
393
|
+
text: "Digits must be between 4 and 10.",
|
|
394
|
+
},
|
|
395
|
+
],
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
// Generate TOTP code using proper speakeasy library
|
|
399
|
+
const token = speakeasy.totp({
|
|
400
|
+
secret: secret,
|
|
401
|
+
encoding: 'base32',
|
|
402
|
+
digits: digits,
|
|
403
|
+
step: period
|
|
404
|
+
});
|
|
405
|
+
// Calculate remaining time for this token
|
|
406
|
+
const now = Math.floor(Date.now() / 1000);
|
|
407
|
+
const timeRemaining = period - (now % period);
|
|
408
|
+
// Verify the token is valid (for demonstration)
|
|
409
|
+
const verified = speakeasy.totp.verify({
|
|
410
|
+
secret: secret,
|
|
411
|
+
encoding: 'base32',
|
|
412
|
+
token: token,
|
|
413
|
+
step: period,
|
|
414
|
+
window: 1
|
|
415
|
+
});
|
|
416
|
+
return {
|
|
417
|
+
content: [
|
|
418
|
+
{
|
|
419
|
+
type: "text",
|
|
420
|
+
text: `TOTP Code: ${token}
|
|
421
|
+
|
|
422
|
+
Valid for: ${timeRemaining} seconds
|
|
423
|
+
Digits: ${digits}
|
|
424
|
+
Period: ${period} seconds
|
|
425
|
+
Secret: ${secret}
|
|
426
|
+
Verified: ${verified ? 'Yes ✅' : 'No ❌'}
|
|
427
|
+
|
|
428
|
+
This code can be used for two-factor authentication.
|
|
429
|
+
The token changes every ${period} seconds.`,
|
|
430
|
+
},
|
|
431
|
+
],
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
catch (error) {
|
|
435
|
+
return {
|
|
436
|
+
content: [
|
|
437
|
+
{
|
|
438
|
+
type: "text",
|
|
439
|
+
text: `Error generating OTP: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
440
|
+
},
|
|
441
|
+
],
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
}
|