it-tools-mcp 3.0.24 → 3.1.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/README.dockerhub.md +22 -16
- package/README.md +73 -32
- package/build/index.js +47 -15
- package/build/tools/ansible/ansible-inventory-generator/index.js +212 -0
- package/build/tools/ansible/ansible-playbook-validator/index.js +128 -0
- package/build/tools/ansible/ansible-reference/index.js +393 -0
- package/build/tools/ansible/ansible-vault-decrypt/index.js +137 -0
- package/build/tools/ansible/ansible-vault-encrypt/index.js +79 -0
- package/build/tools/color/color-hex-to-rgb/index.js +29 -0
- package/build/tools/{color.js → color/color-rgb-to-hex/index.js} +1 -27
- package/build/tools/crypto/basic-auth-generator/index.js +45 -0
- package/build/tools/crypto/bcrypt-hash/index.js +67 -0
- package/build/tools/crypto/bip39-generate/index.js +53 -0
- package/build/tools/crypto/hash-md5/index.js +19 -0
- package/build/tools/crypto/hash-sha1/index.js +19 -0
- package/build/tools/crypto/hash-sha256/index.js +19 -0
- package/build/tools/crypto/hash-sha512/index.js +19 -0
- package/build/tools/crypto/hmac-generator/index.js +37 -0
- package/build/tools/crypto/jwt-decode/index.js +41 -0
- package/build/tools/crypto/otp-code-generator/index.js +67 -0
- package/build/tools/crypto/password-generate/index.js +54 -0
- package/build/tools/crypto/token-generator/index.js +75 -0
- package/build/tools/dataFormat/html-to-markdown/index.js +34 -0
- package/build/tools/dataFormat/json-diff/index.js +94 -0
- package/build/tools/dataFormat/json-format/index.js +100 -0
- package/build/tools/dataFormat/json-minify/index.js +29 -0
- package/build/tools/dataFormat/json-to-csv/index.js +34 -0
- package/build/tools/dataFormat/json-to-toml/index.js +30 -0
- package/build/tools/dataFormat/markdown-to-html/index.js +32 -0
- package/build/tools/dataFormat/phone-format/index.js +35 -0
- package/build/tools/dataFormat/sql-format/index.js +37 -0
- package/build/tools/dataFormat/toml-to-json/index.js +29 -0
- package/build/tools/dataFormat/xml-format/index.js +44 -0
- package/build/tools/dataFormat/yaml-format/index.js +58 -0
- package/build/tools/{development.js → development/crontab-generate/index.js} +1 -129
- package/build/tools/development/html-prettifier/index.js +47 -0
- package/build/tools/development/javascript-prettifier/index.js +74 -0
- package/build/tools/development/list-converter/index.js +62 -0
- package/build/tools/development/markdown-toc-generator/index.js +53 -0
- package/build/tools/development/regex-tester/index.js +69 -0
- package/build/tools/docker/docker-compose-to-docker-run/index.js +138 -0
- package/build/tools/docker/docker-compose-validator/index.js +125 -0
- package/build/tools/docker/docker-reference/index.js +188 -0
- package/build/tools/docker/docker-run-to-docker-compose/index.js +117 -0
- package/build/tools/docker/traefik-compose-generator/index.js +98 -0
- package/build/tools/encoding/base64-decode/index.js +28 -0
- package/build/tools/encoding/base64-encode/index.js +16 -0
- package/build/tools/encoding/html-decode/index.js +21 -0
- package/build/tools/encoding/html-encode/index.js +21 -0
- package/build/tools/encoding/html-entities-extended/index.js +72 -0
- package/build/tools/encoding/text-to-binary/index.js +51 -0
- package/build/tools/encoding/url-decode/index.js +28 -0
- package/build/tools/encoding/url-encode/index.js +16 -0
- package/build/tools/forensic/file-type-identifier/index.js +90 -0
- package/build/tools/forensic/safelink-decoder/index.js +54 -0
- package/build/tools/forensic/url-fanger/index.js +52 -0
- package/build/tools/idGenerators/qr-generate/index.js +76 -0
- package/build/tools/idGenerators/svg-placeholder-generator/index.js +59 -0
- package/build/tools/idGenerators/ulid-generate/index.js +34 -0
- package/build/tools/idGenerators/uuid-generate/index.js +14 -0
- package/build/tools/math/math-evaluate/index.js +33 -0
- package/build/tools/math/number-base-converter/index.js +46 -0
- package/build/tools/math/percentage-calculator/index.js +50 -0
- package/build/tools/math/roman-numeral-converter/index.js +76 -0
- package/build/tools/math/temperature-converter/index.js +59 -0
- package/build/tools/math/unix-timestamp-converter/index.js +55 -0
- package/build/tools/network/cat/index.js +15 -0
- package/build/tools/network/cidr-to-ip-range/index.js +108 -0
- package/build/tools/network/curl/index.js +35 -0
- package/build/tools/network/dig/index.js +19 -0
- package/build/tools/network/grep/index.js +18 -0
- package/build/tools/network/head/index.js +17 -0
- package/build/tools/network/iban-validate/index.js +83 -0
- package/build/tools/network/ip-range-to-cidr/index.js +88 -0
- package/build/tools/network/ip-subnet-calculator/index.js +102 -0
- package/build/tools/network/ipv4-subnet-calc/index.js +112 -0
- package/build/tools/network/ipv6-subnet-calculator/index.js +104 -0
- package/build/tools/network/ipv6-ula-generator/index.js +65 -0
- package/build/tools/network/mac-address-generate/index.js +68 -0
- package/build/tools/network/nslookup/index.js +18 -0
- package/build/tools/network/ping/index.js +20 -0
- package/build/tools/network/ps/index.js +22 -0
- package/build/tools/network/random-port/index.js +53 -0
- package/build/tools/network/scp/index.js +134 -0
- package/build/tools/network/ssh/index.js +83 -0
- package/build/tools/network/tail/index.js +16 -0
- package/build/tools/network/telnet/index.js +45 -0
- package/build/tools/network/top/index.js +14 -0
- package/build/tools/network/url-parse/index.js +52 -0
- package/build/tools/physics/angle-converter/index.js +73 -0
- package/build/tools/physics/energy-converter/index.js +72 -0
- package/build/tools/physics/power-converter/index.js +71 -0
- package/build/tools/text/ascii-art-text/index.js +112 -0
- package/build/tools/text/distinct-words/index.js +30 -0
- package/build/tools/text/emoji-search/index.js +76 -0
- package/build/tools/text/lorem-ipsum-generator/index.js +87 -0
- package/build/tools/text/numeronym-generator/index.js +37 -0
- package/build/tools/text/slugify-string/index.js +44 -0
- package/build/tools/text/string-obfuscator/index.js +49 -0
- package/build/tools/text/text-camelcase/index.js +20 -0
- package/build/tools/text/text-capitalize/index.js +16 -0
- package/build/tools/text/text-diff/index.js +72 -0
- package/build/tools/text/text-kebabcase/index.js +20 -0
- package/build/tools/text/text-lowercase/index.js +15 -0
- package/build/tools/text/text-pascalcase/index.js +18 -0
- package/build/tools/text/text-snakecase/index.js +20 -0
- package/build/tools/text/text-stats/index.js +29 -0
- package/build/tools/text/text-to-nato-alphabet/index.js +57 -0
- package/build/tools/text/text-to-unicode/index.js +50 -0
- package/build/tools/text/text-to-unicode-names/index.js +34 -0
- package/build/tools/text/text-uppercase/index.js +15 -0
- package/build/tools/utility/css-prettifier/index.js +70 -0
- package/build/tools/utility/device-info/index.js +44 -0
- package/build/tools/utility/email-normalizer/index.js +73 -0
- package/build/tools/utility/http-status-codes/index.js +173 -0
- package/build/tools/utility/mime-types/index.js +121 -0
- package/build/tools/utility/port-numbers/index.js +106 -0
- package/build/tools/utility/rem-px-converter/index.js +63 -0
- package/package.json +3 -3
- package/build/tools/crypto.js +0 -445
- package/build/tools/dataFormat.js +0 -535
- package/build/tools/encoding.js +0 -240
- package/build/tools/idGenerators.js +0 -180
- package/build/tools/math.js +0 -310
- package/build/tools/network.js +0 -939
- package/build/tools/text.js +0 -678
- package/build/tools/utility.js +0 -407
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { pbkdf2Sync, randomBytes } from "crypto";
|
|
3
|
+
export function registerAnsibleVaultEncrypt(server) {
|
|
4
|
+
server.tool("ansible-vault-encrypt", "Encrypt text using Ansible Vault format", {
|
|
5
|
+
text: z.string().describe("Text to encrypt"),
|
|
6
|
+
password: z.string().describe("Password for encryption"),
|
|
7
|
+
vaultId: z.string().optional().describe("Vault ID for the encrypted content (optional)"),
|
|
8
|
+
}, async ({ text, password, vaultId }) => {
|
|
9
|
+
if (!text?.trim()) {
|
|
10
|
+
return {
|
|
11
|
+
content: [
|
|
12
|
+
{
|
|
13
|
+
type: "text",
|
|
14
|
+
text: "Please provide text to encrypt",
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
if (!password?.trim()) {
|
|
20
|
+
return {
|
|
21
|
+
content: [
|
|
22
|
+
{
|
|
23
|
+
type: "text",
|
|
24
|
+
text: "Please provide a password for encryption",
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
// Generate salt and key using PBKDF2
|
|
31
|
+
const salt = randomBytes(32);
|
|
32
|
+
const key = pbkdf2Sync(password, salt, 10000, 32, 'sha256');
|
|
33
|
+
// Generate IV
|
|
34
|
+
const iv = randomBytes(16);
|
|
35
|
+
// Encrypt using AES-256-CTR
|
|
36
|
+
const crypto = await import('crypto');
|
|
37
|
+
const cipher = crypto.createCipheriv('aes-256-ctr', key, iv);
|
|
38
|
+
let encrypted = cipher.update(text, 'utf8', 'hex');
|
|
39
|
+
encrypted += cipher.final('hex');
|
|
40
|
+
// Create HMAC for integrity check
|
|
41
|
+
const hmac = crypto.createHmac('sha256', key);
|
|
42
|
+
hmac.update(salt);
|
|
43
|
+
hmac.update(iv);
|
|
44
|
+
hmac.update(Buffer.from(encrypted, 'hex'));
|
|
45
|
+
const mac = hmac.digest();
|
|
46
|
+
// Combine salt + iv + encrypted data + mac
|
|
47
|
+
const combined = Buffer.concat([salt, iv, Buffer.from(encrypted, 'hex'), mac]);
|
|
48
|
+
const b64encoded = combined.toString('base64');
|
|
49
|
+
// Format as Ansible Vault
|
|
50
|
+
const vaultHeader = vaultId
|
|
51
|
+
? `$ANSIBLE_VAULT;1.1;AES256;${vaultId}`
|
|
52
|
+
: '$ANSIBLE_VAULT;1.1;AES256';
|
|
53
|
+
// Split base64 into 80-character lines
|
|
54
|
+
const lines = [];
|
|
55
|
+
for (let i = 0; i < b64encoded.length; i += 80) {
|
|
56
|
+
lines.push(b64encoded.substring(i, i + 80));
|
|
57
|
+
}
|
|
58
|
+
const result = vaultHeader + '\n' + lines.join('\n');
|
|
59
|
+
return {
|
|
60
|
+
content: [
|
|
61
|
+
{
|
|
62
|
+
type: "text",
|
|
63
|
+
text: result,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
return {
|
|
70
|
+
content: [
|
|
71
|
+
{
|
|
72
|
+
type: "text",
|
|
73
|
+
text: `Error encrypting text: ${error.message}`,
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import Color from "color";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export function registerColorHexToRgb(server) {
|
|
4
|
+
server.tool("color-hex-to-rgb", "Convert HEX color to RGB", {
|
|
5
|
+
hex: z.string().describe("HEX color code (e.g., #FF5733 or FF5733)"),
|
|
6
|
+
}, async ({ hex }) => {
|
|
7
|
+
try {
|
|
8
|
+
const rgb = Color(hex).rgb().array();
|
|
9
|
+
return {
|
|
10
|
+
content: [
|
|
11
|
+
{
|
|
12
|
+
type: "text",
|
|
13
|
+
text: `${hex} = RGB(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`,
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
return {
|
|
20
|
+
content: [
|
|
21
|
+
{
|
|
22
|
+
type: "text",
|
|
23
|
+
text: `Error converting HEX to RGB: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -1,32 +1,6 @@
|
|
|
1
1
|
import Color from "color";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
export function
|
|
4
|
-
// Color conversion tools
|
|
5
|
-
server.tool("color-hex-to-rgb", "Convert HEX color to RGB", {
|
|
6
|
-
hex: z.string().describe("HEX color code (e.g., #FF5733 or FF5733)"),
|
|
7
|
-
}, async ({ hex }) => {
|
|
8
|
-
try {
|
|
9
|
-
const rgb = Color(hex).rgb().array();
|
|
10
|
-
return {
|
|
11
|
-
content: [
|
|
12
|
-
{
|
|
13
|
-
type: "text",
|
|
14
|
-
text: `${hex} = RGB(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`,
|
|
15
|
-
},
|
|
16
|
-
],
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
catch (error) {
|
|
20
|
-
return {
|
|
21
|
-
content: [
|
|
22
|
-
{
|
|
23
|
-
type: "text",
|
|
24
|
-
text: `Error converting HEX to RGB: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
});
|
|
3
|
+
export function registerColorRgbToHex(server) {
|
|
30
4
|
server.tool("color-rgb-to-hex", "Convert RGB color to HEX", {
|
|
31
5
|
r: z.number().describe("Red value (0-255)"),
|
|
32
6
|
g: z.number().describe("Green value (0-255)"),
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerBasicAuthGenerator(server) {
|
|
3
|
+
server.tool("basic-auth-generator", "Generate HTTP Basic Authentication header", {
|
|
4
|
+
username: z.string().describe("Username"),
|
|
5
|
+
password: z.string().describe("Password"),
|
|
6
|
+
}, async ({ username, password }) => {
|
|
7
|
+
try {
|
|
8
|
+
const credentials = `${username}:${password}`;
|
|
9
|
+
const encoded = Buffer.from(credentials, 'utf-8').toString('base64');
|
|
10
|
+
const authHeader = `Basic ${encoded}`;
|
|
11
|
+
return {
|
|
12
|
+
content: [
|
|
13
|
+
{
|
|
14
|
+
type: "text",
|
|
15
|
+
text: `HTTP Basic Auth Header:
|
|
16
|
+
Authorization: ${authHeader}
|
|
17
|
+
|
|
18
|
+
Credentials: ${username}:${password}
|
|
19
|
+
Base64 Encoded: ${encoded}
|
|
20
|
+
|
|
21
|
+
Usage in curl:
|
|
22
|
+
curl -H "Authorization: ${authHeader}" https://api.example.com
|
|
23
|
+
|
|
24
|
+
Usage in fetch:
|
|
25
|
+
fetch('https://api.example.com', {
|
|
26
|
+
headers: {
|
|
27
|
+
'Authorization': '${authHeader}'
|
|
28
|
+
}
|
|
29
|
+
})`,
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
return {
|
|
36
|
+
content: [
|
|
37
|
+
{
|
|
38
|
+
type: "text",
|
|
39
|
+
text: `Error generating basic auth: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import bcryptjs from "bcryptjs";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export function registerBcryptHash(server) {
|
|
4
|
+
server.tool("bcrypt-hash", "Generate bcrypt hash or verify password against hash", {
|
|
5
|
+
password: z.string().describe("Password to hash or verify"),
|
|
6
|
+
rounds: z.number().describe("Number of salt rounds (4-12, default 10)").optional(),
|
|
7
|
+
hash: z.string().optional().describe("Existing hash to verify against (for verification)"),
|
|
8
|
+
}, async ({ password, rounds = 10, hash }) => {
|
|
9
|
+
try {
|
|
10
|
+
if (rounds < 4 || rounds > 12) {
|
|
11
|
+
return {
|
|
12
|
+
content: [
|
|
13
|
+
{
|
|
14
|
+
type: "text",
|
|
15
|
+
text: "Rounds must be between 4 and 12.",
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
if (hash) {
|
|
21
|
+
// Verification mode
|
|
22
|
+
const isValid = await bcryptjs.compare(password, hash);
|
|
23
|
+
return {
|
|
24
|
+
content: [
|
|
25
|
+
{
|
|
26
|
+
type: "text",
|
|
27
|
+
text: `Password Verification: ${isValid ? 'VALID' : 'INVALID'}
|
|
28
|
+
|
|
29
|
+
Password: ${password}
|
|
30
|
+
Hash: ${hash}`,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// Hash generation mode
|
|
37
|
+
const salt = await bcryptjs.genSalt(rounds);
|
|
38
|
+
const hashedPassword = await bcryptjs.hash(password, salt);
|
|
39
|
+
return {
|
|
40
|
+
content: [
|
|
41
|
+
{
|
|
42
|
+
type: "text",
|
|
43
|
+
text: `Bcrypt Hash Generated:
|
|
44
|
+
Hash: ${hashedPassword}
|
|
45
|
+
|
|
46
|
+
Password: ${password}
|
|
47
|
+
Rounds: ${rounds}
|
|
48
|
+
Algorithm: bcrypt
|
|
49
|
+
|
|
50
|
+
This hash can be safely stored in databases and used for password verification.`,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
return {
|
|
58
|
+
content: [
|
|
59
|
+
{
|
|
60
|
+
type: "text",
|
|
61
|
+
text: `Error with bcrypt operation: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as bip39 from "bip39";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export function registerBip39Generate(server) {
|
|
4
|
+
server.tool("bip39-generate", "Generate BIP39 mnemonic phrases", {
|
|
5
|
+
wordCount: z.enum(["12", "15", "18", "21", "24"]).describe("Number of words in the mnemonic").optional(),
|
|
6
|
+
}, async ({ wordCount = "12" }) => {
|
|
7
|
+
try {
|
|
8
|
+
const count = parseInt(wordCount);
|
|
9
|
+
// Generate entropy based on word count
|
|
10
|
+
// 12 words = 128 bits, 15 words = 160 bits, 18 words = 192 bits, 21 words = 224 bits, 24 words = 256 bits
|
|
11
|
+
const entropyBits = Math.floor((count * 11) / 33) * 32;
|
|
12
|
+
const entropyBytes = entropyBits / 8;
|
|
13
|
+
// Generate cryptographically secure random entropy
|
|
14
|
+
const { randomBytes } = await import('crypto');
|
|
15
|
+
const entropy = randomBytes(entropyBytes);
|
|
16
|
+
// Generate mnemonic using proper BIP39 library
|
|
17
|
+
const mnemonic = bip39.entropyToMnemonic(entropy);
|
|
18
|
+
const words = mnemonic.split(' ');
|
|
19
|
+
// Validate the generated mnemonic
|
|
20
|
+
const isValid = bip39.validateMnemonic(mnemonic);
|
|
21
|
+
return {
|
|
22
|
+
content: [
|
|
23
|
+
{
|
|
24
|
+
type: "text",
|
|
25
|
+
text: `BIP39 Mnemonic Phrase (${words.length} words):
|
|
26
|
+
|
|
27
|
+
${mnemonic}
|
|
28
|
+
|
|
29
|
+
Entropy: ${entropy.toString('hex')}
|
|
30
|
+
Valid: ${isValid ? 'Yes ✅' : 'No ❌'}
|
|
31
|
+
Entropy Bits: ${entropyBits}
|
|
32
|
+
|
|
33
|
+
⚠️ SECURITY WARNING:
|
|
34
|
+
- This uses cryptographically secure random generation
|
|
35
|
+
- Store this mnemonic securely and never share it
|
|
36
|
+
- This can be used to generate cryptocurrency wallet seeds
|
|
37
|
+
- Anyone with this mnemonic can access associated wallets`,
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
return {
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: "text",
|
|
47
|
+
text: `Error generating BIP39 mnemonic: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createHash } from "crypto";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export function registerHashMd5(server) {
|
|
4
|
+
server.tool("hash-md5", "Generate MD5 hash", {
|
|
5
|
+
text: z.string().describe("Text to hash with MD5"),
|
|
6
|
+
}, async ({ text }) => {
|
|
7
|
+
const hash = createHash('md5');
|
|
8
|
+
hash.update(text);
|
|
9
|
+
const result = hash.digest('hex');
|
|
10
|
+
return {
|
|
11
|
+
content: [
|
|
12
|
+
{
|
|
13
|
+
type: "text",
|
|
14
|
+
text: `MD5 hash: ${result}`,
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createHash } from "crypto";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export function registerHashSha1(server) {
|
|
4
|
+
server.tool("hash-sha1", "Generate SHA1 hash", {
|
|
5
|
+
text: z.string().describe("Text to hash with SHA1"),
|
|
6
|
+
}, async ({ text }) => {
|
|
7
|
+
const hash = createHash('sha1');
|
|
8
|
+
hash.update(text);
|
|
9
|
+
const result = hash.digest('hex');
|
|
10
|
+
return {
|
|
11
|
+
content: [
|
|
12
|
+
{
|
|
13
|
+
type: "text",
|
|
14
|
+
text: `SHA1 hash: ${result}`,
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createHash } from "crypto";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export function registerHashSha256(server) {
|
|
4
|
+
server.tool("hash-sha256", "Generate SHA256 hash", {
|
|
5
|
+
text: z.string().describe("Text to hash with SHA256"),
|
|
6
|
+
}, async ({ text }) => {
|
|
7
|
+
const hash = createHash('sha256');
|
|
8
|
+
hash.update(text);
|
|
9
|
+
const result = hash.digest('hex');
|
|
10
|
+
return {
|
|
11
|
+
content: [
|
|
12
|
+
{
|
|
13
|
+
type: "text",
|
|
14
|
+
text: `SHA256 hash: ${result}`,
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createHash } from "crypto";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export function registerHashSha512(server) {
|
|
4
|
+
server.tool("hash-sha512", "Generate SHA512 hash", {
|
|
5
|
+
text: z.string().describe("Text to hash with SHA512"),
|
|
6
|
+
}, async ({ text }) => {
|
|
7
|
+
const hash = createHash('sha512');
|
|
8
|
+
hash.update(text);
|
|
9
|
+
const result = hash.digest('hex');
|
|
10
|
+
return {
|
|
11
|
+
content: [
|
|
12
|
+
{
|
|
13
|
+
type: "text",
|
|
14
|
+
text: `SHA512 hash: ${result}`,
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createHmac } from "crypto";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export function registerHmacGenerator(server) {
|
|
4
|
+
server.tool("hmac-generator", "Generate HMAC (Hash-based Message Authentication Code)", {
|
|
5
|
+
message: z.string().describe("Message to authenticate"),
|
|
6
|
+
key: z.string().describe("Secret key for HMAC"),
|
|
7
|
+
algorithm: z.enum(["sha1", "sha256", "sha512"]).describe("Hash algorithm").optional(),
|
|
8
|
+
}, async ({ message, key, algorithm = "sha256" }) => {
|
|
9
|
+
try {
|
|
10
|
+
const hmac = createHmac(algorithm, key);
|
|
11
|
+
hmac.update(message);
|
|
12
|
+
const result = hmac.digest('hex');
|
|
13
|
+
return {
|
|
14
|
+
content: [
|
|
15
|
+
{
|
|
16
|
+
type: "text",
|
|
17
|
+
text: `HMAC-${algorithm.toUpperCase()}: ${result}
|
|
18
|
+
|
|
19
|
+
Message: ${message}
|
|
20
|
+
Key: ${key}
|
|
21
|
+
Algorithm: ${algorithm.toUpperCase()}`,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
return {
|
|
28
|
+
content: [
|
|
29
|
+
{
|
|
30
|
+
type: "text",
|
|
31
|
+
text: `Error generating HMAC: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerJwtDecode(server) {
|
|
3
|
+
server.tool("jwt-decode", "Decode JWT token (header and payload only)", {
|
|
4
|
+
token: z.string().describe("JWT token to decode"),
|
|
5
|
+
}, async ({ token }) => {
|
|
6
|
+
try {
|
|
7
|
+
const parts = token.split('.');
|
|
8
|
+
if (parts.length !== 3) {
|
|
9
|
+
throw new Error("Invalid JWT format. JWT must have 3 parts separated by dots.");
|
|
10
|
+
}
|
|
11
|
+
const header = JSON.parse(Buffer.from(parts[0], 'base64url').toString());
|
|
12
|
+
const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString());
|
|
13
|
+
return {
|
|
14
|
+
content: [
|
|
15
|
+
{
|
|
16
|
+
type: "text",
|
|
17
|
+
text: `JWT Token Decoded:
|
|
18
|
+
|
|
19
|
+
Header:
|
|
20
|
+
${JSON.stringify(header, null, 2)}
|
|
21
|
+
|
|
22
|
+
Payload:
|
|
23
|
+
${JSON.stringify(payload, null, 2)}
|
|
24
|
+
|
|
25
|
+
Note: Signature verification is not performed. Do not trust this token without proper verification.`,
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
return {
|
|
32
|
+
content: [
|
|
33
|
+
{
|
|
34
|
+
type: "text",
|
|
35
|
+
text: `Error decoding JWT: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import speakeasy from "speakeasy";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export function registerOtpCodeGenerator(server) {
|
|
4
|
+
server.tool("otp-code-generator", "Generate Time-based One-Time Password (TOTP) codes", {
|
|
5
|
+
secret: z.string().describe("Base32 encoded secret key"),
|
|
6
|
+
digits: z.number().describe("Number of digits in the code").optional(),
|
|
7
|
+
period: z.number().describe("Time period in seconds").optional(),
|
|
8
|
+
}, async ({ secret, digits = 6, period = 30 }) => {
|
|
9
|
+
try {
|
|
10
|
+
if (digits < 4 || digits > 10) {
|
|
11
|
+
return {
|
|
12
|
+
content: [
|
|
13
|
+
{
|
|
14
|
+
type: "text",
|
|
15
|
+
text: "Digits must be between 4 and 10.",
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
// Generate TOTP code using proper speakeasy library
|
|
21
|
+
const token = speakeasy.totp({
|
|
22
|
+
secret: secret,
|
|
23
|
+
encoding: 'base32',
|
|
24
|
+
digits: digits,
|
|
25
|
+
step: period
|
|
26
|
+
});
|
|
27
|
+
// Calculate remaining time for this token
|
|
28
|
+
const now = Math.floor(Date.now() / 1000);
|
|
29
|
+
const timeRemaining = period - (now % period);
|
|
30
|
+
// Verify the token is valid (for demonstration)
|
|
31
|
+
const verified = speakeasy.totp.verify({
|
|
32
|
+
secret: secret,
|
|
33
|
+
encoding: 'base32',
|
|
34
|
+
token: token,
|
|
35
|
+
step: period,
|
|
36
|
+
window: 1
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
content: [
|
|
40
|
+
{
|
|
41
|
+
type: "text",
|
|
42
|
+
text: `TOTP Code: ${token}
|
|
43
|
+
|
|
44
|
+
Valid for: ${timeRemaining} seconds
|
|
45
|
+
Digits: ${digits}
|
|
46
|
+
Period: ${period} seconds
|
|
47
|
+
Secret: ${secret}
|
|
48
|
+
Verified: ${verified ? 'Yes ✅' : 'No ❌'}
|
|
49
|
+
|
|
50
|
+
This code can be used for two-factor authentication.
|
|
51
|
+
The token changes every ${period} seconds.`,
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
return {
|
|
58
|
+
content: [
|
|
59
|
+
{
|
|
60
|
+
type: "text",
|
|
61
|
+
text: `Error generating OTP: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerPasswordGenerate(server) {
|
|
3
|
+
server.tool("password-generate", "Generate a secure password", {
|
|
4
|
+
length: z.number().describe("Password length").optional(),
|
|
5
|
+
includeUppercase: z.boolean().describe("Include uppercase letters").optional(),
|
|
6
|
+
includeLowercase: z.boolean().describe("Include lowercase letters").optional(),
|
|
7
|
+
includeNumbers: z.boolean().describe("Include numbers").optional(),
|
|
8
|
+
includeSymbols: z.boolean().describe("Include symbols").optional(),
|
|
9
|
+
}, async ({ length = 16, includeUppercase = true, includeLowercase = true, includeNumbers = true, includeSymbols = true }) => {
|
|
10
|
+
if (length < 4 || length > 128) {
|
|
11
|
+
return {
|
|
12
|
+
content: [
|
|
13
|
+
{
|
|
14
|
+
type: "text",
|
|
15
|
+
text: "Length must be between 4 and 128.",
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
let charset = '';
|
|
21
|
+
if (includeUppercase)
|
|
22
|
+
charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
23
|
+
if (includeLowercase)
|
|
24
|
+
charset += 'abcdefghijklmnopqrstuvwxyz';
|
|
25
|
+
if (includeNumbers)
|
|
26
|
+
charset += '0123456789';
|
|
27
|
+
if (includeSymbols)
|
|
28
|
+
charset += '!@#$%^&*()_+-=[]{}|;:,.<>?';
|
|
29
|
+
if (charset === '') {
|
|
30
|
+
return {
|
|
31
|
+
content: [
|
|
32
|
+
{
|
|
33
|
+
type: "text",
|
|
34
|
+
text: "Error: At least one character type must be selected",
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
let password = '';
|
|
40
|
+
const { randomBytes } = await import('crypto');
|
|
41
|
+
const randomValues = randomBytes(length);
|
|
42
|
+
for (let i = 0; i < length; i++) {
|
|
43
|
+
password += charset.charAt(randomValues[i] % charset.length);
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
content: [
|
|
47
|
+
{
|
|
48
|
+
type: "text",
|
|
49
|
+
text: `Generated password: ${password}`,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerTokenGenerator(server) {
|
|
3
|
+
server.tool("token-generator", "Generate secure random tokens", {
|
|
4
|
+
length: z.number().describe("Token length").optional(),
|
|
5
|
+
charset: z.enum(["alphanumeric", "hex", "base64", "custom"]).describe("Character set to use").optional(),
|
|
6
|
+
customChars: z.string().optional().describe("Custom characters (required if charset is 'custom')"),
|
|
7
|
+
}, async ({ length = 32, charset = "alphanumeric", customChars }) => {
|
|
8
|
+
try {
|
|
9
|
+
if (length < 8 || length > 256) {
|
|
10
|
+
return {
|
|
11
|
+
content: [
|
|
12
|
+
{
|
|
13
|
+
type: "text",
|
|
14
|
+
text: "Length must be between 8 and 256.",
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
let chars = '';
|
|
20
|
+
switch (charset) {
|
|
21
|
+
case 'alphanumeric':
|
|
22
|
+
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
23
|
+
break;
|
|
24
|
+
case 'hex':
|
|
25
|
+
chars = '0123456789abcdef';
|
|
26
|
+
break;
|
|
27
|
+
case 'base64':
|
|
28
|
+
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
29
|
+
break;
|
|
30
|
+
case 'custom':
|
|
31
|
+
if (!customChars) {
|
|
32
|
+
return {
|
|
33
|
+
content: [
|
|
34
|
+
{
|
|
35
|
+
type: "text",
|
|
36
|
+
text: "Error: Custom characters required when charset is 'custom'",
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
chars = customChars;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
let token = '';
|
|
45
|
+
const { randomBytes } = await import('crypto');
|
|
46
|
+
const randomValues = randomBytes(length);
|
|
47
|
+
for (let i = 0; i < length; i++) {
|
|
48
|
+
token += chars.charAt(randomValues[i] % chars.length);
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
content: [
|
|
52
|
+
{
|
|
53
|
+
type: "text",
|
|
54
|
+
text: `Generated Token:
|
|
55
|
+
${token}
|
|
56
|
+
|
|
57
|
+
Length: ${length} characters
|
|
58
|
+
Character set: ${charset}
|
|
59
|
+
${charset === 'custom' ? `Custom chars: ${customChars}` : ''}`,
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
return {
|
|
66
|
+
content: [
|
|
67
|
+
{
|
|
68
|
+
type: "text",
|
|
69
|
+
text: `Error generating token: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|