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.
Files changed (127) hide show
  1. package/README.dockerhub.md +22 -16
  2. package/README.md +73 -32
  3. package/build/index.js +47 -15
  4. package/build/tools/ansible/ansible-inventory-generator/index.js +212 -0
  5. package/build/tools/ansible/ansible-playbook-validator/index.js +128 -0
  6. package/build/tools/ansible/ansible-reference/index.js +393 -0
  7. package/build/tools/ansible/ansible-vault-decrypt/index.js +137 -0
  8. package/build/tools/ansible/ansible-vault-encrypt/index.js +79 -0
  9. package/build/tools/color/color-hex-to-rgb/index.js +29 -0
  10. package/build/tools/{color.js → color/color-rgb-to-hex/index.js} +1 -27
  11. package/build/tools/crypto/basic-auth-generator/index.js +45 -0
  12. package/build/tools/crypto/bcrypt-hash/index.js +67 -0
  13. package/build/tools/crypto/bip39-generate/index.js +53 -0
  14. package/build/tools/crypto/hash-md5/index.js +19 -0
  15. package/build/tools/crypto/hash-sha1/index.js +19 -0
  16. package/build/tools/crypto/hash-sha256/index.js +19 -0
  17. package/build/tools/crypto/hash-sha512/index.js +19 -0
  18. package/build/tools/crypto/hmac-generator/index.js +37 -0
  19. package/build/tools/crypto/jwt-decode/index.js +41 -0
  20. package/build/tools/crypto/otp-code-generator/index.js +67 -0
  21. package/build/tools/crypto/password-generate/index.js +54 -0
  22. package/build/tools/crypto/token-generator/index.js +75 -0
  23. package/build/tools/dataFormat/html-to-markdown/index.js +34 -0
  24. package/build/tools/dataFormat/json-diff/index.js +94 -0
  25. package/build/tools/dataFormat/json-format/index.js +100 -0
  26. package/build/tools/dataFormat/json-minify/index.js +29 -0
  27. package/build/tools/dataFormat/json-to-csv/index.js +34 -0
  28. package/build/tools/dataFormat/json-to-toml/index.js +30 -0
  29. package/build/tools/dataFormat/markdown-to-html/index.js +32 -0
  30. package/build/tools/dataFormat/phone-format/index.js +35 -0
  31. package/build/tools/dataFormat/sql-format/index.js +37 -0
  32. package/build/tools/dataFormat/toml-to-json/index.js +29 -0
  33. package/build/tools/dataFormat/xml-format/index.js +44 -0
  34. package/build/tools/dataFormat/yaml-format/index.js +58 -0
  35. package/build/tools/{development.js → development/crontab-generate/index.js} +1 -129
  36. package/build/tools/development/html-prettifier/index.js +47 -0
  37. package/build/tools/development/javascript-prettifier/index.js +74 -0
  38. package/build/tools/development/list-converter/index.js +62 -0
  39. package/build/tools/development/markdown-toc-generator/index.js +53 -0
  40. package/build/tools/development/regex-tester/index.js +69 -0
  41. package/build/tools/docker/docker-compose-to-docker-run/index.js +138 -0
  42. package/build/tools/docker/docker-compose-validator/index.js +125 -0
  43. package/build/tools/docker/docker-reference/index.js +188 -0
  44. package/build/tools/docker/docker-run-to-docker-compose/index.js +117 -0
  45. package/build/tools/docker/traefik-compose-generator/index.js +98 -0
  46. package/build/tools/encoding/base64-decode/index.js +28 -0
  47. package/build/tools/encoding/base64-encode/index.js +16 -0
  48. package/build/tools/encoding/html-decode/index.js +21 -0
  49. package/build/tools/encoding/html-encode/index.js +21 -0
  50. package/build/tools/encoding/html-entities-extended/index.js +72 -0
  51. package/build/tools/encoding/text-to-binary/index.js +51 -0
  52. package/build/tools/encoding/url-decode/index.js +28 -0
  53. package/build/tools/encoding/url-encode/index.js +16 -0
  54. package/build/tools/forensic/file-type-identifier/index.js +90 -0
  55. package/build/tools/forensic/safelink-decoder/index.js +54 -0
  56. package/build/tools/forensic/url-fanger/index.js +52 -0
  57. package/build/tools/idGenerators/qr-generate/index.js +76 -0
  58. package/build/tools/idGenerators/svg-placeholder-generator/index.js +59 -0
  59. package/build/tools/idGenerators/ulid-generate/index.js +34 -0
  60. package/build/tools/idGenerators/uuid-generate/index.js +14 -0
  61. package/build/tools/math/math-evaluate/index.js +33 -0
  62. package/build/tools/math/number-base-converter/index.js +46 -0
  63. package/build/tools/math/percentage-calculator/index.js +50 -0
  64. package/build/tools/math/roman-numeral-converter/index.js +76 -0
  65. package/build/tools/math/temperature-converter/index.js +59 -0
  66. package/build/tools/math/unix-timestamp-converter/index.js +55 -0
  67. package/build/tools/network/cat/index.js +15 -0
  68. package/build/tools/network/cidr-to-ip-range/index.js +108 -0
  69. package/build/tools/network/curl/index.js +35 -0
  70. package/build/tools/network/dig/index.js +19 -0
  71. package/build/tools/network/grep/index.js +18 -0
  72. package/build/tools/network/head/index.js +17 -0
  73. package/build/tools/network/iban-validate/index.js +83 -0
  74. package/build/tools/network/ip-range-to-cidr/index.js +88 -0
  75. package/build/tools/network/ip-subnet-calculator/index.js +102 -0
  76. package/build/tools/network/ipv4-subnet-calc/index.js +112 -0
  77. package/build/tools/network/ipv6-subnet-calculator/index.js +104 -0
  78. package/build/tools/network/ipv6-ula-generator/index.js +65 -0
  79. package/build/tools/network/mac-address-generate/index.js +68 -0
  80. package/build/tools/network/nslookup/index.js +18 -0
  81. package/build/tools/network/ping/index.js +20 -0
  82. package/build/tools/network/ps/index.js +22 -0
  83. package/build/tools/network/random-port/index.js +53 -0
  84. package/build/tools/network/scp/index.js +134 -0
  85. package/build/tools/network/ssh/index.js +83 -0
  86. package/build/tools/network/tail/index.js +16 -0
  87. package/build/tools/network/telnet/index.js +45 -0
  88. package/build/tools/network/top/index.js +14 -0
  89. package/build/tools/network/url-parse/index.js +52 -0
  90. package/build/tools/physics/angle-converter/index.js +73 -0
  91. package/build/tools/physics/energy-converter/index.js +72 -0
  92. package/build/tools/physics/power-converter/index.js +71 -0
  93. package/build/tools/text/ascii-art-text/index.js +112 -0
  94. package/build/tools/text/distinct-words/index.js +30 -0
  95. package/build/tools/text/emoji-search/index.js +76 -0
  96. package/build/tools/text/lorem-ipsum-generator/index.js +87 -0
  97. package/build/tools/text/numeronym-generator/index.js +37 -0
  98. package/build/tools/text/slugify-string/index.js +44 -0
  99. package/build/tools/text/string-obfuscator/index.js +49 -0
  100. package/build/tools/text/text-camelcase/index.js +20 -0
  101. package/build/tools/text/text-capitalize/index.js +16 -0
  102. package/build/tools/text/text-diff/index.js +72 -0
  103. package/build/tools/text/text-kebabcase/index.js +20 -0
  104. package/build/tools/text/text-lowercase/index.js +15 -0
  105. package/build/tools/text/text-pascalcase/index.js +18 -0
  106. package/build/tools/text/text-snakecase/index.js +20 -0
  107. package/build/tools/text/text-stats/index.js +29 -0
  108. package/build/tools/text/text-to-nato-alphabet/index.js +57 -0
  109. package/build/tools/text/text-to-unicode/index.js +50 -0
  110. package/build/tools/text/text-to-unicode-names/index.js +34 -0
  111. package/build/tools/text/text-uppercase/index.js +15 -0
  112. package/build/tools/utility/css-prettifier/index.js +70 -0
  113. package/build/tools/utility/device-info/index.js +44 -0
  114. package/build/tools/utility/email-normalizer/index.js +73 -0
  115. package/build/tools/utility/http-status-codes/index.js +173 -0
  116. package/build/tools/utility/mime-types/index.js +121 -0
  117. package/build/tools/utility/port-numbers/index.js +106 -0
  118. package/build/tools/utility/rem-px-converter/index.js +63 -0
  119. package/package.json +3 -3
  120. package/build/tools/crypto.js +0 -445
  121. package/build/tools/dataFormat.js +0 -535
  122. package/build/tools/encoding.js +0 -240
  123. package/build/tools/idGenerators.js +0 -180
  124. package/build/tools/math.js +0 -310
  125. package/build/tools/network.js +0 -939
  126. package/build/tools/text.js +0 -678
  127. package/build/tools/utility.js +0 -407
@@ -0,0 +1,102 @@
1
+ import { z } from "zod";
2
+ export function registerIpSubnetCalculator(server) {
3
+ server.tool("ip-subnet-calculator", "Calculate subnet information for IPv4", {
4
+ ip: z.string().describe("IPv4 address (e.g., 192.168.1.1)"),
5
+ cidr: z.number().describe("CIDR notation (e.g., 24)"),
6
+ }, async ({ ip, cidr }) => {
7
+ try {
8
+ if (cidr < 1 || cidr > 32) {
9
+ return {
10
+ content: [
11
+ {
12
+ type: "text",
13
+ text: "CIDR must be between 1 and 32.",
14
+ },
15
+ ],
16
+ };
17
+ }
18
+ const ipParts = ip.split('.').map(part => {
19
+ const num = parseInt(part);
20
+ if (isNaN(num) || num < 0 || num > 255) {
21
+ throw new Error(`Invalid IP address part: ${part}`);
22
+ }
23
+ return num;
24
+ });
25
+ if (ipParts.length !== 4) {
26
+ throw new Error("Invalid IP address format");
27
+ }
28
+ // Calculate subnet mask
29
+ const mask = (0xFFFFFFFF << (32 - cidr)) >>> 0;
30
+ const maskParts = [
31
+ (mask >>> 24) & 0xFF,
32
+ (mask >>> 16) & 0xFF,
33
+ (mask >>> 8) & 0xFF,
34
+ mask & 0xFF
35
+ ];
36
+ // Calculate network address
37
+ const ipNum = (ipParts[0] << 24) | (ipParts[1] << 16) | (ipParts[2] << 8) | ipParts[3];
38
+ const networkNum = (ipNum & mask) >>> 0;
39
+ const networkParts = [
40
+ (networkNum >>> 24) & 0xFF,
41
+ (networkNum >>> 16) & 0xFF,
42
+ (networkNum >>> 8) & 0xFF,
43
+ networkNum & 0xFF
44
+ ];
45
+ // Calculate broadcast address
46
+ const broadcastNum = (networkNum | (0xFFFFFFFF >>> cidr)) >>> 0;
47
+ const broadcastParts = [
48
+ (broadcastNum >>> 24) & 0xFF,
49
+ (broadcastNum >>> 16) & 0xFF,
50
+ (broadcastNum >>> 8) & 0xFF,
51
+ broadcastNum & 0xFF
52
+ ];
53
+ // Calculate first and last usable addresses
54
+ const firstUsableNum = networkNum + 1;
55
+ const lastUsableNum = broadcastNum - 1;
56
+ const firstUsableParts = [
57
+ (firstUsableNum >>> 24) & 0xFF,
58
+ (firstUsableNum >>> 16) & 0xFF,
59
+ (firstUsableNum >>> 8) & 0xFF,
60
+ firstUsableNum & 0xFF
61
+ ];
62
+ const lastUsableParts = [
63
+ (lastUsableNum >>> 24) & 0xFF,
64
+ (lastUsableNum >>> 16) & 0xFF,
65
+ (lastUsableNum >>> 8) & 0xFF,
66
+ lastUsableNum & 0xFF
67
+ ];
68
+ const totalHosts = Math.pow(2, 32 - cidr);
69
+ const usableHosts = totalHosts - 2;
70
+ return {
71
+ content: [
72
+ {
73
+ type: "text",
74
+ text: `IPv4 Subnet Information:
75
+
76
+ Input: ${ip}/${cidr}
77
+
78
+ Network Address: ${networkParts.join('.')}
79
+ Subnet Mask: ${maskParts.join('.')}
80
+ Broadcast Address: ${broadcastParts.join('.')}
81
+ First Usable: ${firstUsableParts.join('.')}
82
+ Last Usable: ${lastUsableParts.join('.')}
83
+
84
+ Total Addresses: ${totalHosts}
85
+ Usable Addresses: ${usableHosts}
86
+ CIDR: /${cidr}`,
87
+ },
88
+ ],
89
+ };
90
+ }
91
+ catch (error) {
92
+ return {
93
+ content: [
94
+ {
95
+ type: "text",
96
+ text: `Error calculating subnet: ${error instanceof Error ? error.message : 'Unknown error'}`,
97
+ },
98
+ ],
99
+ };
100
+ }
101
+ });
102
+ }
@@ -0,0 +1,112 @@
1
+ import { z } from "zod";
2
+ export function registerIpv4SubnetCalc(server) {
3
+ server.tool("ipv4-subnet-calc", "Calculate IPv4 subnet information", {
4
+ cidr: z.string().describe("IPv4 CIDR notation (e.g., 192.168.1.0/24)"),
5
+ }, async ({ cidr }) => {
6
+ try {
7
+ const [ip, prefixLength] = cidr.split('/');
8
+ const prefix = parseInt(prefixLength);
9
+ if (isNaN(prefix) || prefix < 0 || prefix > 32) {
10
+ throw new Error("Invalid CIDR prefix length");
11
+ }
12
+ const ipParts = ip.split('.').map(part => {
13
+ const num = parseInt(part);
14
+ if (isNaN(num) || num < 0 || num > 255) {
15
+ throw new Error(`Invalid IP address part: ${part}`);
16
+ }
17
+ return num;
18
+ });
19
+ if (ipParts.length !== 4) {
20
+ throw new Error("Invalid IP address format");
21
+ }
22
+ // Calculate all subnet information
23
+ const mask = (0xFFFFFFFF << (32 - prefix)) >>> 0;
24
+ const inverseMask = (0xFFFFFFFF >>> prefix);
25
+ const maskOctets = [
26
+ (mask >>> 24) & 0xFF,
27
+ (mask >>> 16) & 0xFF,
28
+ (mask >>> 8) & 0xFF,
29
+ mask & 0xFF
30
+ ];
31
+ const wildcardOctets = [
32
+ inverseMask >>> 24,
33
+ (inverseMask >>> 16) & 0xFF,
34
+ (inverseMask >>> 8) & 0xFF,
35
+ inverseMask & 0xFF
36
+ ];
37
+ const ipNum = (ipParts[0] << 24) | (ipParts[1] << 16) | (ipParts[2] << 8) | ipParts[3];
38
+ const networkNum = (ipNum & mask) >>> 0;
39
+ const broadcastNum = (networkNum | inverseMask) >>> 0;
40
+ const networkOctets = [
41
+ (networkNum >>> 24) & 0xFF,
42
+ (networkNum >>> 16) & 0xFF,
43
+ (networkNum >>> 8) & 0xFF,
44
+ networkNum & 0xFF
45
+ ];
46
+ const broadcastOctets = [
47
+ (broadcastNum >>> 24) & 0xFF,
48
+ (broadcastNum >>> 16) & 0xFF,
49
+ (broadcastNum >>> 8) & 0xFF,
50
+ broadcastNum & 0xFF
51
+ ];
52
+ const totalAddresses = Math.pow(2, 32 - prefix);
53
+ const usableAddresses = Math.max(0, totalAddresses - 2);
54
+ // Determine network class
55
+ let networkClass = 'Unknown';
56
+ const firstOctet = networkOctets[0];
57
+ if (firstOctet >= 1 && firstOctet <= 126)
58
+ networkClass = 'A';
59
+ else if (firstOctet >= 128 && firstOctet <= 191)
60
+ networkClass = 'B';
61
+ else if (firstOctet >= 192 && firstOctet <= 223)
62
+ networkClass = 'C';
63
+ else if (firstOctet >= 224 && firstOctet <= 239)
64
+ networkClass = 'D (Multicast)';
65
+ else if (firstOctet >= 240 && firstOctet <= 255)
66
+ networkClass = 'E (Reserved)';
67
+ // Check if private
68
+ const isPrivate = (firstOctet === 10) ||
69
+ (firstOctet === 172 && networkOctets[1] >= 16 && networkOctets[1] <= 31) ||
70
+ (firstOctet === 192 && networkOctets[1] === 168);
71
+ return {
72
+ content: [
73
+ {
74
+ type: "text",
75
+ text: `Enhanced IPv4 Subnet Calculation:
76
+
77
+ Input CIDR: ${cidr}
78
+
79
+ Network Information:
80
+ Network Address: ${networkOctets.join('.')}
81
+ Broadcast Address: ${broadcastOctets.join('.')}
82
+ Subnet Mask: ${maskOctets.join('.')}
83
+ Wildcard Mask: ${wildcardOctets.join('.')}
84
+
85
+ Address Range:
86
+ First Host: ${networkOctets[0]}.${networkOctets[1]}.${networkOctets[2]}.${networkOctets[3] + 1}
87
+ Last Host: ${broadcastOctets[0]}.${broadcastOctets[1]}.${broadcastOctets[2]}.${broadcastOctets[3] - 1}
88
+
89
+ Capacity:
90
+ Total Addresses: ${totalAddresses.toLocaleString()}
91
+ Usable Host Addresses: ${usableAddresses.toLocaleString()}
92
+
93
+ Network Properties:
94
+ Class: ${networkClass}
95
+ Type: ${isPrivate ? 'Private' : 'Public'}
96
+ CIDR Prefix: /${prefix}`,
97
+ },
98
+ ],
99
+ };
100
+ }
101
+ catch (error) {
102
+ return {
103
+ content: [
104
+ {
105
+ type: "text",
106
+ text: `Error calculating IPv4 subnet: ${error instanceof Error ? error.message : 'Unknown error'}`,
107
+ },
108
+ ],
109
+ };
110
+ }
111
+ });
112
+ }
@@ -0,0 +1,104 @@
1
+ import { z } from "zod";
2
+ export function registerIpv6SubnetCalculator(server) {
3
+ server.tool("ipv6-subnet-calculator", "Calculate IPv6 subnet information", {
4
+ ipv6: z.string().describe("IPv6 address and prefix (e.g., 2001:db8::/32)"),
5
+ newPrefix: z.number().optional().describe("New prefix length for subnetting")
6
+ }, async ({ ipv6, newPrefix }) => {
7
+ try {
8
+ const [address, prefixStr] = ipv6.split('/');
9
+ if (!address || !prefixStr) {
10
+ throw new Error("Invalid IPv6 format. Use format: address/prefix");
11
+ }
12
+ const prefix = parseInt(prefixStr);
13
+ if (prefix < 0 || prefix > 128) {
14
+ throw new Error("Prefix length must be between 0 and 128");
15
+ }
16
+ // Expand IPv6 address to full form
17
+ const expandIPv6 = (addr) => {
18
+ // Handle :: notation
19
+ const parts = addr.split('::');
20
+ if (parts.length === 2) {
21
+ const left = parts[0] ? parts[0].split(':') : [];
22
+ const right = parts[1] ? parts[1].split(':') : [];
23
+ const missing = 8 - left.length - right.length;
24
+ const middle = Array(missing).fill('0000');
25
+ return [...left, ...middle, ...right].map(part => part.padStart(4, '0')).join(':');
26
+ }
27
+ else {
28
+ return addr.split(':').map(part => part.padStart(4, '0')).join(':');
29
+ }
30
+ };
31
+ const fullAddress = expandIPv6(address);
32
+ const parts = fullAddress.split(':');
33
+ if (parts.length !== 8) {
34
+ throw new Error("Invalid IPv6 address format");
35
+ }
36
+ // Calculate network portion
37
+ const networkBits = prefix;
38
+ const hostBits = 128 - prefix;
39
+ // Create network address
40
+ const networkParts = [...parts];
41
+ const bytesToClear = Math.floor((128 - prefix) / 16);
42
+ const partialBits = (128 - prefix) % 16;
43
+ // Clear host portion
44
+ for (let i = 8 - bytesToClear; i < 8; i++) {
45
+ networkParts[i] = '0000';
46
+ }
47
+ if (partialBits > 0) {
48
+ const partIndex = 8 - bytesToClear - 1;
49
+ const mask = (0xFFFF << partialBits) & 0xFFFF;
50
+ const value = parseInt(networkParts[partIndex], 16) & mask;
51
+ networkParts[partIndex] = value.toString(16).padStart(4, '0');
52
+ }
53
+ const networkAddr = networkParts.join(':');
54
+ // Calculate some common subnet sizes if newPrefix is provided
55
+ let subnetInfo = '';
56
+ if (newPrefix && newPrefix > prefix) {
57
+ const subnetBits = newPrefix - prefix;
58
+ const numSubnets = Math.pow(2, subnetBits);
59
+ const hostsPerSubnet = Math.pow(2, 128 - newPrefix);
60
+ subnetInfo = `\nSubnetting to /${newPrefix}:
61
+ • Subnet bits borrowed: ${subnetBits}
62
+ • Number of subnets: ${numSubnets.toLocaleString()}
63
+ • Hosts per subnet: ${hostsPerSubnet.toExponential(2)}`;
64
+ }
65
+ const totalHosts = Math.pow(2, hostBits);
66
+ return {
67
+ content: [{
68
+ type: "text",
69
+ text: `IPv6 Subnet Calculator Results:
70
+
71
+ Input: ${ipv6}
72
+ Full Address: ${fullAddress}
73
+
74
+ Network Information:
75
+ • Network Address: ${networkAddr}/${prefix}
76
+ • Prefix Length: /${prefix}
77
+ • Network Bits: ${networkBits}
78
+ • Host Bits: ${hostBits}
79
+ • Total Addresses: 2^${hostBits} (${totalHosts.toExponential(2)})
80
+
81
+ Address Format:
82
+ • Compressed: ${networkAddr.replace(/(:0000)+/g, '::').replace(/^0+|:0+/g, ':').replace(/^:/, '').replace(/:$/, '') || '::'}/${prefix}
83
+ • Full: ${networkAddr}/${prefix}
84
+
85
+ ${subnetInfo}
86
+
87
+ IPv6 Address Types:
88
+ • Global Unicast: 2000::/3
89
+ • Link-Local: fe80::/10
90
+ • Unique Local: fc00::/7
91
+ • Multicast: ff00::/8`
92
+ }]
93
+ };
94
+ }
95
+ catch (error) {
96
+ return {
97
+ content: [{
98
+ type: "text",
99
+ text: `Error calculating IPv6 subnet: ${error instanceof Error ? error.message : 'Unknown error'}`
100
+ }]
101
+ };
102
+ }
103
+ });
104
+ }
@@ -0,0 +1,65 @@
1
+ import { z } from "zod";
2
+ export function registerIpv6UlaGenerator(server) {
3
+ server.tool("ipv6-ula-generator", "Generate IPv6 Unique Local Address (ULA) prefix", {
4
+ globalId: z.string().optional().describe("Global ID (40 bits in hex, auto-generated if not provided)"),
5
+ }, async ({ globalId }) => {
6
+ try {
7
+ // Generate random 40-bit Global ID if not provided
8
+ let gid = globalId;
9
+ if (!gid) {
10
+ const randomBytes = [];
11
+ for (let i = 0; i < 5; i++) {
12
+ randomBytes.push(Math.floor(Math.random() * 256).toString(16).padStart(2, '0'));
13
+ }
14
+ gid = randomBytes.join('');
15
+ }
16
+ // Validate Global ID
17
+ if (!/^[0-9a-fA-F]{10}$/.test(gid)) {
18
+ throw new Error("Global ID must be exactly 10 hexadecimal characters (40 bits)");
19
+ }
20
+ // Format the ULA prefix
21
+ const prefix = `fd${gid.substring(0, 2)}:${gid.substring(2, 6)}:${gid.substring(6, 10)}`;
22
+ const fullPrefix = `${prefix}::/48`;
23
+ // Generate some example subnets
24
+ const subnets = [];
25
+ for (let i = 0; i < 5; i++) {
26
+ const subnetId = Math.floor(Math.random() * 65536).toString(16).padStart(4, '0');
27
+ subnets.push(`${prefix}:${subnetId}::/64`);
28
+ }
29
+ return {
30
+ content: [
31
+ {
32
+ type: "text",
33
+ text: `IPv6 ULA (Unique Local Address) Generated:
34
+
35
+ ULA Prefix: ${fullPrefix}
36
+ Global ID: ${gid}
37
+
38
+ Example Subnets:
39
+ ${subnets.map((subnet, i) => `${i + 1}. ${subnet}`).join('\n')}
40
+
41
+ Properties:
42
+ - Scope: Local (not routed on the internet)
43
+ - Prefix: fd00::/8 (ULA)
44
+ - Global ID: ${gid} (40 bits)
45
+ - Subnet ID: 16 bits available
46
+ - Interface ID: 64 bits available
47
+
48
+ Note: ULAs are designed for local communications within a site.
49
+ They are not expected to be routable on the global Internet.`,
50
+ },
51
+ ],
52
+ };
53
+ }
54
+ catch (error) {
55
+ return {
56
+ content: [
57
+ {
58
+ type: "text",
59
+ text: `Error generating IPv6 ULA: ${error instanceof Error ? error.message : 'Unknown error'}`,
60
+ },
61
+ ],
62
+ };
63
+ }
64
+ });
65
+ }
@@ -0,0 +1,68 @@
1
+ import { z } from "zod";
2
+ export function registerMacAddressGenerate(server) {
3
+ server.tool("mac-address-generate", "Generate random MAC address", {
4
+ prefix: z.string().optional().describe("MAC address prefix (e.g., '00:1B:44')"),
5
+ separator: z.enum([":", "-"]).describe("Separator character").optional(),
6
+ }, async ({ prefix, separator = ":" }) => {
7
+ try {
8
+ let macParts = [];
9
+ if (prefix) {
10
+ // Validate and use provided prefix
11
+ const prefixParts = prefix.split(/[:-]/);
12
+ if (prefixParts.length > 6) {
13
+ throw new Error("Prefix cannot have more than 6 parts");
14
+ }
15
+ for (const part of prefixParts) {
16
+ if (!/^[0-9-A-Fa-f]{2}$/.test(part)) {
17
+ throw new Error(`Invalid MAC address part: ${part}`);
18
+ }
19
+ macParts.push(part.toUpperCase());
20
+ }
21
+ }
22
+ // Generate remaining parts
23
+ while (macParts.length < 6) {
24
+ const randomByte = Math.floor(Math.random() * 256).toString(16).padStart(2, '0').toUpperCase();
25
+ macParts.push(randomByte);
26
+ }
27
+ // Ensure first octet indicates locally administered unicast
28
+ if (!prefix) {
29
+ const firstOctet = parseInt(macParts[0], 16);
30
+ // Set locally administered bit (bit 1) and clear multicast bit (bit 0)
31
+ macParts[0] = ((firstOctet | 0x02) & 0xFE).toString(16).padStart(2, '0').toUpperCase();
32
+ }
33
+ const macAddress = macParts.join(separator);
34
+ // Analyze the MAC address
35
+ const firstOctet = parseInt(macParts[0], 16);
36
+ const isMulticast = (firstOctet & 0x01) !== 0;
37
+ const isLocallyAdministered = (firstOctet & 0x02) !== 0;
38
+ return {
39
+ content: [
40
+ {
41
+ type: "text",
42
+ text: `Generated MAC Address: ${macAddress}
43
+
44
+ Properties:
45
+ Type: ${isMulticast ? 'Multicast' : 'Unicast'}
46
+ Administration: ${isLocallyAdministered ? 'Locally Administered' : 'Universally Administered'}
47
+ Format: ${separator === ':' ? 'Colon notation' : 'Hyphen notation'}
48
+
49
+ Binary representation:
50
+ ${macParts.map(part => parseInt(part, 16).toString(2).padStart(8, '0')).join(' ')}
51
+
52
+ ${prefix ? `Used prefix: ${prefix}` : 'Randomly generated'}`,
53
+ },
54
+ ],
55
+ };
56
+ }
57
+ catch (error) {
58
+ return {
59
+ content: [
60
+ {
61
+ type: "text",
62
+ text: `Error generating MAC address: ${error instanceof Error ? error.message : 'Unknown error'}`,
63
+ },
64
+ ],
65
+ };
66
+ }
67
+ });
68
+ }
@@ -0,0 +1,18 @@
1
+ import { z } from "zod";
2
+ import dns from "dns";
3
+ export function registerNslookup(server) {
4
+ server.tool("nslookup", "Perform DNS lookup on a hostname or IP address", {
5
+ target: z.string().describe("Hostname or IP address")
6
+ }, async ({ target }) => {
7
+ return new Promise((resolve) => {
8
+ dns.lookup(target, (err, address, family) => {
9
+ if (err) {
10
+ resolve({ content: [{ type: "text", text: `nslookup failed: ${err.message}` }] });
11
+ }
12
+ else {
13
+ resolve({ content: [{ type: "text", text: `Address: ${address}\nFamily: IPv${family}` }] });
14
+ }
15
+ });
16
+ });
17
+ });
18
+ }
@@ -0,0 +1,20 @@
1
+ import { z } from "zod";
2
+ import ping from "ping";
3
+ export function registerPing(server) {
4
+ server.tool("ping", "Ping a host to check connectivity", {
5
+ target: z.string().describe("Host to ping"),
6
+ count: z.number().default(4).describe("Number of ping attempts")
7
+ }, async ({ target, count }) => {
8
+ try {
9
+ const res = await ping.promise.probe(target, { min_reply: count });
10
+ return {
11
+ content: [
12
+ { type: "text", text: `Ping to ${target}:\nAlive: ${res.alive}\nTime: ${res.time} ms\nOutput: ${res.output}` }
13
+ ]
14
+ };
15
+ }
16
+ catch (error) {
17
+ return { content: [{ type: "text", text: `Ping failed: ${error instanceof Error ? error.message : error}` }] };
18
+ }
19
+ });
20
+ }
@@ -0,0 +1,22 @@
1
+ import psList from "ps-list";
2
+ export function registerPs(server) {
3
+ server.tool("ps", "List running processes", {}, async () => {
4
+ try {
5
+ const processes = await psList();
6
+ // Defensive: handle missing properties and filter out bad entries
7
+ const output = processes
8
+ .map(p => {
9
+ const pid = p.pid ?? 'N/A';
10
+ const name = p.name ?? 'N/A';
11
+ return `${pid}\t${name}`;
12
+ })
13
+ .join("\n");
14
+ return { content: [{ type: "text", text: output || 'No processes found.' }] };
15
+ }
16
+ catch (error) {
17
+ // Log error for debugging
18
+ console.error('ps error:', error);
19
+ return { content: [{ type: "text", text: `ps failed: ${error instanceof Error ? error.message : error}` }] };
20
+ }
21
+ });
22
+ }
@@ -0,0 +1,53 @@
1
+ import { z } from "zod";
2
+ export function registerRandomPort(server) {
3
+ server.tool("random-port", "Generate random port numbers", {
4
+ count: z.number().describe("Number of ports to generate").optional(),
5
+ min: z.number().describe("Minimum port number").optional(),
6
+ max: z.number().describe("Maximum port number").optional(),
7
+ exclude: z.array(z.number()).optional().describe("Ports to exclude"),
8
+ }, async ({ count = 1, min = 1024, max = 65535, exclude = [] }) => {
9
+ try {
10
+ const ports = [];
11
+ const excludeSet = new Set(exclude);
12
+ // Well-known ports to avoid by default
13
+ const wellKnownPorts = [22, 23, 25, 53, 80, 110, 143, 443, 993, 995];
14
+ wellKnownPorts.forEach(port => excludeSet.add(port));
15
+ for (let i = 0; i < count; i++) {
16
+ let port;
17
+ let attempts = 0;
18
+ do {
19
+ port = Math.floor(Math.random() * (max - min + 1)) + min;
20
+ attempts++;
21
+ if (attempts > 1000) {
22
+ throw new Error("Could not generate unique port after 1000 attempts");
23
+ }
24
+ } while (excludeSet.has(port) || ports.includes(port));
25
+ ports.push(port);
26
+ }
27
+ return {
28
+ content: [
29
+ {
30
+ type: "text",
31
+ text: `Random Ports Generated:
32
+
33
+ ${ports.map((port, i) => `${i + 1}. ${port}`).join('\n')}
34
+
35
+ Range: ${min} - ${max}
36
+ Excluded well-known ports: ${wellKnownPorts.join(', ')}
37
+ ${exclude.length > 0 ? `Custom excluded: ${exclude.join(', ')}` : ''}`,
38
+ },
39
+ ],
40
+ };
41
+ }
42
+ catch (error) {
43
+ return {
44
+ content: [
45
+ {
46
+ type: "text",
47
+ text: `Error generating random ports: ${error instanceof Error ? error.message : 'Unknown error'}`,
48
+ },
49
+ ],
50
+ };
51
+ }
52
+ });
53
+ }