it-tools-mcp 3.0.24 → 3.1.1
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 +23 -18
- package/README.md +77 -34
- package/build/index.js +51 -24
- 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,49 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerStringObfuscator(server) {
|
|
3
|
+
server.tool("string-obfuscator", "Obfuscate text by replacing characters with their HTML entities or other representations", {
|
|
4
|
+
text: z.string().describe("Text to obfuscate"),
|
|
5
|
+
method: z.enum(["html-entities", "unicode", "base64"]).describe("Obfuscation method").optional(),
|
|
6
|
+
}, async ({ text, method = "html-entities" }) => {
|
|
7
|
+
try {
|
|
8
|
+
let result = '';
|
|
9
|
+
switch (method) {
|
|
10
|
+
case 'html-entities':
|
|
11
|
+
result = text
|
|
12
|
+
.split('')
|
|
13
|
+
.map(char => `&#${char.charCodeAt(0)};`)
|
|
14
|
+
.join('');
|
|
15
|
+
break;
|
|
16
|
+
case 'unicode':
|
|
17
|
+
result = text
|
|
18
|
+
.split('')
|
|
19
|
+
.map(char => `\\u${char.charCodeAt(0).toString(16).padStart(4, '0')}`)
|
|
20
|
+
.join('');
|
|
21
|
+
break;
|
|
22
|
+
case 'base64':
|
|
23
|
+
result = Buffer.from(text, 'utf-8').toString('base64');
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
content: [
|
|
28
|
+
{
|
|
29
|
+
type: "text",
|
|
30
|
+
text: `Obfuscated Text (${method}):
|
|
31
|
+
|
|
32
|
+
Original: ${text}
|
|
33
|
+
Obfuscated: ${result}`,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
return {
|
|
40
|
+
content: [
|
|
41
|
+
{
|
|
42
|
+
type: "text",
|
|
43
|
+
text: `Error obfuscating text: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerTextCamelcase(server) {
|
|
3
|
+
server.tool("text-camelcase", "Convert text to camelCase", {
|
|
4
|
+
text: z.string().describe("Text to convert to camelCase"),
|
|
5
|
+
}, async ({ text }) => {
|
|
6
|
+
const camelCase = text
|
|
7
|
+
.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
|
|
8
|
+
return index === 0 ? word.toLowerCase() : word.toUpperCase();
|
|
9
|
+
})
|
|
10
|
+
.replace(/\s+/g, '');
|
|
11
|
+
return {
|
|
12
|
+
content: [
|
|
13
|
+
{
|
|
14
|
+
type: "text",
|
|
15
|
+
text: `camelCase: ${camelCase}`,
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerTextCapitalize(server) {
|
|
3
|
+
server.tool("text-capitalize", "Capitalize first letter of each word", {
|
|
4
|
+
text: z.string().describe("Text to capitalize"),
|
|
5
|
+
}, async ({ text }) => {
|
|
6
|
+
const capitalized = text.replace(/\b\w/g, l => l.toUpperCase());
|
|
7
|
+
return {
|
|
8
|
+
content: [
|
|
9
|
+
{
|
|
10
|
+
type: "text",
|
|
11
|
+
text: `Capitalized: ${capitalized}`,
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
};
|
|
15
|
+
});
|
|
16
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerTextDiff(server) {
|
|
3
|
+
server.tool("text-diff", "Compare two texts and show differences", {
|
|
4
|
+
text1: z.string().describe("First text to compare"),
|
|
5
|
+
text2: z.string().describe("Second text to compare"),
|
|
6
|
+
}, async ({ text1, text2 }) => {
|
|
7
|
+
try {
|
|
8
|
+
// Simple diff implementation
|
|
9
|
+
const lines1 = text1.split('\n');
|
|
10
|
+
const lines2 = text2.split('\n');
|
|
11
|
+
const maxLines = Math.max(lines1.length, lines2.length);
|
|
12
|
+
let differences = [];
|
|
13
|
+
let same = true;
|
|
14
|
+
for (let i = 0; i < maxLines; i++) {
|
|
15
|
+
const line1 = lines1[i] || '';
|
|
16
|
+
const line2 = lines2[i] || '';
|
|
17
|
+
if (line1 !== line2) {
|
|
18
|
+
same = false;
|
|
19
|
+
if (line1 && line2) {
|
|
20
|
+
differences.push(`Line ${i + 1}: Changed`);
|
|
21
|
+
differences.push(` - ${line1}`);
|
|
22
|
+
differences.push(` + ${line2}`);
|
|
23
|
+
}
|
|
24
|
+
else if (line1) {
|
|
25
|
+
differences.push(`Line ${i + 1}: Removed`);
|
|
26
|
+
differences.push(` - ${line1}`);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
differences.push(`Line ${i + 1}: Added`);
|
|
30
|
+
differences.push(` + ${line2}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (same) {
|
|
35
|
+
return {
|
|
36
|
+
content: [
|
|
37
|
+
{
|
|
38
|
+
type: "text",
|
|
39
|
+
text: "✅ Texts are identical - no differences found.",
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
return {
|
|
46
|
+
content: [
|
|
47
|
+
{
|
|
48
|
+
type: "text",
|
|
49
|
+
text: `❌ Found differences:
|
|
50
|
+
|
|
51
|
+
${differences.join('\n')}
|
|
52
|
+
|
|
53
|
+
Summary:
|
|
54
|
+
Lines in text 1: ${lines1.length}
|
|
55
|
+
Lines in text 2: ${lines2.length}`,
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
return {
|
|
63
|
+
content: [
|
|
64
|
+
{
|
|
65
|
+
type: "text",
|
|
66
|
+
text: `Error comparing texts: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerTextKebabcase(server) {
|
|
3
|
+
server.tool("text-kebabcase", "Convert text to kebab-case", {
|
|
4
|
+
text: z.string().describe("Text to convert to kebab-case"),
|
|
5
|
+
}, async ({ text }) => {
|
|
6
|
+
const kebabCase = text
|
|
7
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
8
|
+
.replace(/[^a-zA-Z0-9]+/g, '-')
|
|
9
|
+
.toLowerCase()
|
|
10
|
+
.replace(/^-+|-+$/g, '');
|
|
11
|
+
return {
|
|
12
|
+
content: [
|
|
13
|
+
{
|
|
14
|
+
type: "text",
|
|
15
|
+
text: `kebab-case: ${kebabCase}`,
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerTextLowercase(server) {
|
|
3
|
+
server.tool("text-lowercase", "Convert text to lowercase", {
|
|
4
|
+
text: z.string().describe("Text to convert to lowercase"),
|
|
5
|
+
}, async ({ text }) => {
|
|
6
|
+
return {
|
|
7
|
+
content: [
|
|
8
|
+
{
|
|
9
|
+
type: "text",
|
|
10
|
+
text: `Lowercase: ${text.toLowerCase()}`,
|
|
11
|
+
},
|
|
12
|
+
],
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerTextPascalcase(server) {
|
|
3
|
+
server.tool("text-pascalcase", "Convert text to PascalCase", {
|
|
4
|
+
text: z.string().describe("Text to convert to PascalCase"),
|
|
5
|
+
}, async ({ text }) => {
|
|
6
|
+
const pascalCase = text
|
|
7
|
+
.replace(/(?:^\w|[A-Z]|\b\w)/g, word => word.toUpperCase())
|
|
8
|
+
.replace(/\s+/g, '');
|
|
9
|
+
return {
|
|
10
|
+
content: [
|
|
11
|
+
{
|
|
12
|
+
type: "text",
|
|
13
|
+
text: `PascalCase: ${pascalCase}`,
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerTextSnakecase(server) {
|
|
3
|
+
server.tool("text-snakecase", "Convert text to snake_case", {
|
|
4
|
+
text: z.string().describe("Text to convert to snake_case"),
|
|
5
|
+
}, async ({ text }) => {
|
|
6
|
+
const snakeCase = text
|
|
7
|
+
.replace(/([a-z])([A-Z])/g, '$1_$2')
|
|
8
|
+
.replace(/[^a-zA-Z0-9]+/g, '_')
|
|
9
|
+
.toLowerCase()
|
|
10
|
+
.replace(/^_+|_+$/g, '');
|
|
11
|
+
return {
|
|
12
|
+
content: [
|
|
13
|
+
{
|
|
14
|
+
type: "text",
|
|
15
|
+
text: `snake_case: ${snakeCase}`,
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerTextStats(server) {
|
|
3
|
+
server.tool("text-stats", "Get statistics about text (character count, word count, etc.)", {
|
|
4
|
+
text: z.string().describe("Text to analyze"),
|
|
5
|
+
}, async ({ text }) => {
|
|
6
|
+
const lines = text.split('\n');
|
|
7
|
+
const words = text.trim().split(/\s+/).filter(word => word.length > 0);
|
|
8
|
+
const characters = text.length;
|
|
9
|
+
const charactersNoSpaces = text.replace(/\s/g, '').length;
|
|
10
|
+
const paragraphs = text.split(/\n\s*\n/).filter(para => para.trim().length > 0);
|
|
11
|
+
return {
|
|
12
|
+
content: [
|
|
13
|
+
{
|
|
14
|
+
type: "text",
|
|
15
|
+
text: `Text Statistics:
|
|
16
|
+
|
|
17
|
+
Characters: ${characters}
|
|
18
|
+
Characters (no spaces): ${charactersNoSpaces}
|
|
19
|
+
Words: ${words.length}
|
|
20
|
+
Lines: ${lines.length}
|
|
21
|
+
Paragraphs: ${paragraphs.length}
|
|
22
|
+
|
|
23
|
+
Reading time: ~${Math.ceil(words.length / 200)} minutes (200 WPM)
|
|
24
|
+
Speaking time: ~${Math.ceil(words.length / 150)} minutes (150 WPM)`,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerTextToNatoAlphabet(server) {
|
|
3
|
+
server.tool("text-to-nato-alphabet", "Convert text to NATO phonetic alphabet", {
|
|
4
|
+
text: z.string().describe("Text to convert to NATO phonetic alphabet"),
|
|
5
|
+
language: z.string().optional().default("International").describe("Language/country variant (International, France, Germany, etc.)")
|
|
6
|
+
}, async ({ text, language }) => {
|
|
7
|
+
// NATO phonetic alphabet mappings
|
|
8
|
+
const natoAlphabets = {
|
|
9
|
+
International: {
|
|
10
|
+
'A': 'ALFA', 'B': 'BRAVO', 'C': 'CHARLIE', 'D': 'DELTA', 'E': 'ECHO', 'F': 'FOXTROT',
|
|
11
|
+
'G': 'GOLF', 'H': 'HOTEL', 'I': 'INDIA', 'J': 'JULIET', 'K': 'KILO', 'L': 'LIMA',
|
|
12
|
+
'M': 'MIKE', 'N': 'NOVEMBER', 'O': 'OSCAR', 'P': 'PAPA', 'Q': 'QUEBEC', 'R': 'ROMEO',
|
|
13
|
+
'S': 'SIERRA', 'T': 'TANGO', 'U': 'UNIFORM', 'V': 'VICTOR', 'W': 'WHISKEY', 'X': 'XRAY',
|
|
14
|
+
'Y': 'YANKEE', 'Z': 'ZULU'
|
|
15
|
+
},
|
|
16
|
+
France: {
|
|
17
|
+
'A': 'ANATOLE', 'B': 'BERTHE', 'C': 'CELESTIN', 'D': 'DESIRE', 'E': 'EUGENE', 'F': 'FRANCOIS',
|
|
18
|
+
'G': 'GASTON', 'H': 'HENRI', 'I': 'IRMA', 'J': 'JOSEPH', 'K': 'KLEBER', 'L': 'LOUIS',
|
|
19
|
+
'M': 'MARCEL', 'N': 'NICOLAS', 'O': 'OSCAR', 'P': 'PIERRE', 'Q': 'QUINTAL', 'R': 'RAOUL',
|
|
20
|
+
'S': 'SUZANNE', 'T': 'THERESE', 'U': 'URSULE', 'V': 'VICTOR', 'W': 'WILLIAM', 'X': 'XAVIER',
|
|
21
|
+
'Y': 'YVONNE', 'Z': 'ZOE'
|
|
22
|
+
},
|
|
23
|
+
Germany: {
|
|
24
|
+
'A': 'ANTON', 'B': 'BERTA', 'C': 'CÄSAR', 'D': 'DORA', 'E': 'EMIL', 'F': 'FRIEDRICH',
|
|
25
|
+
'G': 'GUSTAV', 'H': 'HEINRICH', 'I': 'IDA', 'J': 'JULIUS', 'K': 'KAUFMANN', 'L': 'LUDWIG',
|
|
26
|
+
'M': 'MARTHA', 'N': 'NORDPOL', 'O': 'OTTO', 'P': 'PAULA', 'Q': 'QUELLE', 'R': 'RICHARD',
|
|
27
|
+
'S': 'SIEGFRIED', 'T': 'THEODOR', 'U': 'ULRICH', 'V': 'VIKTOR', 'W': 'WILHELM', 'X': 'XANTHIPPE',
|
|
28
|
+
'Y': 'YPSILON', 'Z': 'ZACHARIAS'
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const selectedAlphabet = natoAlphabets[language] || natoAlphabets.International;
|
|
32
|
+
const result = text.toUpperCase().split('').map(char => {
|
|
33
|
+
if (selectedAlphabet[char]) {
|
|
34
|
+
return selectedAlphabet[char];
|
|
35
|
+
}
|
|
36
|
+
else if (/[0-9]/.test(char)) {
|
|
37
|
+
return `(digit ${char})`;
|
|
38
|
+
}
|
|
39
|
+
else if (char === ' ') {
|
|
40
|
+
return '(SPACE)';
|
|
41
|
+
}
|
|
42
|
+
else if (/[!@#$%^&*(),.?":{}|<>]/.test(char)) {
|
|
43
|
+
return `(punctuation ${char})`;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
return `(${char})`;
|
|
47
|
+
}
|
|
48
|
+
}).join(' ');
|
|
49
|
+
return {
|
|
50
|
+
content: [{
|
|
51
|
+
type: "text",
|
|
52
|
+
text: `NATO Phonetic Alphabet (${language}):
|
|
53
|
+
${result}`
|
|
54
|
+
}]
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerTextToUnicode(server) {
|
|
3
|
+
server.tool("text-to-unicode", "Convert text to Unicode code points and vice versa", {
|
|
4
|
+
input: z.string().describe("Text to convert to Unicode or Unicode to convert to text"),
|
|
5
|
+
operation: z.enum(["encode", "decode"]).describe("Operation: encode text to Unicode or decode Unicode to text"),
|
|
6
|
+
}, async ({ input, operation }) => {
|
|
7
|
+
try {
|
|
8
|
+
if (operation === "encode") {
|
|
9
|
+
const unicode = input
|
|
10
|
+
.split('')
|
|
11
|
+
.map(char => `U+${char.charCodeAt(0).toString(16).toUpperCase().padStart(4, '0')}`)
|
|
12
|
+
.join(' ');
|
|
13
|
+
return {
|
|
14
|
+
content: [
|
|
15
|
+
{
|
|
16
|
+
type: "text",
|
|
17
|
+
text: `Text: ${input}\nUnicode: ${unicode}`,
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
// Decode Unicode to text
|
|
24
|
+
const unicodePattern = /U\+([0-9A-Fa-f]{4,6})/g;
|
|
25
|
+
const text = input.replace(unicodePattern, (match, hex) => {
|
|
26
|
+
const decimal = parseInt(hex, 16);
|
|
27
|
+
return String.fromCharCode(decimal);
|
|
28
|
+
});
|
|
29
|
+
return {
|
|
30
|
+
content: [
|
|
31
|
+
{
|
|
32
|
+
type: "text",
|
|
33
|
+
text: `Unicode: ${input}\nText: ${text}`,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return {
|
|
41
|
+
content: [
|
|
42
|
+
{
|
|
43
|
+
type: "text",
|
|
44
|
+
text: `Error converting text/Unicode: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerTextToUnicodeNames(server) {
|
|
3
|
+
server.tool("text-to-unicode-names", "Convert text to Unicode character names", {
|
|
4
|
+
text: z.string().describe("Text to convert to Unicode names")
|
|
5
|
+
}, async ({ text }) => {
|
|
6
|
+
const unicodeNames = [...text].map(char => {
|
|
7
|
+
const codePoint = char.codePointAt(0);
|
|
8
|
+
if (!codePoint)
|
|
9
|
+
return char;
|
|
10
|
+
const hex = codePoint.toString(16).toUpperCase().padStart(4, '0');
|
|
11
|
+
// Basic Unicode character name mapping for common characters
|
|
12
|
+
const basicNames = {
|
|
13
|
+
32: 'SPACE',
|
|
14
|
+
33: 'EXCLAMATION MARK',
|
|
15
|
+
63: 'QUESTION MARK',
|
|
16
|
+
64: 'COMMERCIAL AT',
|
|
17
|
+
65: 'LATIN CAPITAL LETTER A',
|
|
18
|
+
66: 'LATIN CAPITAL LETTER B',
|
|
19
|
+
97: 'LATIN SMALL LETTER A',
|
|
20
|
+
98: 'LATIN SMALL LETTER B',
|
|
21
|
+
// Add more as needed
|
|
22
|
+
};
|
|
23
|
+
const name = basicNames[codePoint] || 'UNKNOWN CHARACTER';
|
|
24
|
+
return `${char} (U+${hex}: ${name})`;
|
|
25
|
+
}).join('\n');
|
|
26
|
+
return {
|
|
27
|
+
content: [{
|
|
28
|
+
type: "text",
|
|
29
|
+
text: `Unicode Character Names:
|
|
30
|
+
${unicodeNames}`
|
|
31
|
+
}]
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerTextUppercase(server) {
|
|
3
|
+
server.tool("text-uppercase", "Convert text to uppercase", {
|
|
4
|
+
text: z.string().describe("Text to convert to uppercase"),
|
|
5
|
+
}, async ({ text }) => {
|
|
6
|
+
return {
|
|
7
|
+
content: [
|
|
8
|
+
{
|
|
9
|
+
type: "text",
|
|
10
|
+
text: `Uppercase: ${text.toUpperCase()}`,
|
|
11
|
+
},
|
|
12
|
+
],
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerCssPrettifier(server) {
|
|
3
|
+
server.tool("css-prettifier", "Format and prettify CSS code", {
|
|
4
|
+
css: z.string().describe("CSS code to format"),
|
|
5
|
+
indentSize: z.number().optional().describe("Number of spaces for indentation (default: 2)")
|
|
6
|
+
}, async ({ css, indentSize = 2 }) => {
|
|
7
|
+
try {
|
|
8
|
+
// Basic CSS prettifier implementation
|
|
9
|
+
let formatted = css
|
|
10
|
+
// Remove extra whitespace
|
|
11
|
+
.replace(/\s+/g, ' ')
|
|
12
|
+
.trim()
|
|
13
|
+
// Add newlines and indentation
|
|
14
|
+
.replace(/\{/g, ' {\n' + ' '.repeat(indentSize))
|
|
15
|
+
.replace(/\}/g, '\n}\n')
|
|
16
|
+
.replace(/;/g, ';\n' + ' '.repeat(indentSize))
|
|
17
|
+
.replace(/,/g, ',\n')
|
|
18
|
+
// Clean up extra newlines
|
|
19
|
+
.replace(/\n\s*\n/g, '\n')
|
|
20
|
+
.replace(/\n\s*\}/g, '\n}')
|
|
21
|
+
// Fix selectors
|
|
22
|
+
.replace(/\n([^{]+)\{/g, '\n\n$1 {')
|
|
23
|
+
.trim();
|
|
24
|
+
// Add some basic formatting rules
|
|
25
|
+
formatted = formatted
|
|
26
|
+
.replace(/:\s*/g, ': ')
|
|
27
|
+
.replace(/,\s*/g, ', ')
|
|
28
|
+
.replace(/\s*{\s*/g, ' {\n' + ' '.repeat(indentSize))
|
|
29
|
+
.replace(/;\s*}/g, ';\n}');
|
|
30
|
+
// Count some metrics
|
|
31
|
+
const selectors = (css.match(/[^{}]+(?=\s*\{)/g) || []).length;
|
|
32
|
+
const properties = (css.match(/[^{}:;]+\s*:\s*[^{}:;]+/g) || []).length;
|
|
33
|
+
const lines = formatted.split('\n').length;
|
|
34
|
+
const originalLines = css.split('\n').length;
|
|
35
|
+
return {
|
|
36
|
+
content: [{
|
|
37
|
+
type: "text",
|
|
38
|
+
text: `CSS Prettifier Results:
|
|
39
|
+
|
|
40
|
+
Original CSS (${css.length} characters, ${originalLines} lines):
|
|
41
|
+
${css}
|
|
42
|
+
|
|
43
|
+
Formatted CSS (${formatted.length} characters, ${lines} lines):
|
|
44
|
+
${formatted}
|
|
45
|
+
|
|
46
|
+
Statistics:
|
|
47
|
+
• Selectors: ${selectors}
|
|
48
|
+
• Properties: ${properties}
|
|
49
|
+
• Size change: ${css.length} → ${formatted.length} characters
|
|
50
|
+
• Lines: ${originalLines} → ${lines}
|
|
51
|
+
• Indentation: ${indentSize} spaces
|
|
52
|
+
|
|
53
|
+
Formatting Applied:
|
|
54
|
+
• Proper indentation and spacing
|
|
55
|
+
• Consistent selector formatting
|
|
56
|
+
• Property alignment
|
|
57
|
+
• Clean line breaks`
|
|
58
|
+
}]
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
return {
|
|
63
|
+
content: [{
|
|
64
|
+
type: "text",
|
|
65
|
+
text: `Error prettifying CSS: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
66
|
+
}]
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export function registerDeviceInfo(server) {
|
|
2
|
+
server.tool("device-info", "Get basic device/system information", {}, async () => {
|
|
3
|
+
try {
|
|
4
|
+
const info = {
|
|
5
|
+
platform: process.platform,
|
|
6
|
+
arch: process.arch,
|
|
7
|
+
nodeVersion: process.version,
|
|
8
|
+
userAgent: 'IT Tools MCP Server',
|
|
9
|
+
timestamp: new Date().toISOString(),
|
|
10
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
11
|
+
language: 'en-US' // Default for server environment
|
|
12
|
+
};
|
|
13
|
+
return {
|
|
14
|
+
content: [
|
|
15
|
+
{
|
|
16
|
+
type: "text",
|
|
17
|
+
text: `Device Information:
|
|
18
|
+
|
|
19
|
+
Platform: ${info.platform}
|
|
20
|
+
Architecture: ${info.arch}
|
|
21
|
+
Node.js Version: ${info.nodeVersion}
|
|
22
|
+
User Agent: ${info.userAgent}
|
|
23
|
+
Current Time: ${info.timestamp}
|
|
24
|
+
Timezone: ${info.timezone}
|
|
25
|
+
Language: ${info.language}
|
|
26
|
+
|
|
27
|
+
Note: This is basic server environment information.
|
|
28
|
+
For detailed client device info, use a browser-based tool.`,
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
return {
|
|
35
|
+
content: [
|
|
36
|
+
{
|
|
37
|
+
type: "text",
|
|
38
|
+
text: `Error getting device info: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerEmailNormalizer(server) {
|
|
3
|
+
server.tool("email-normalizer", "Normalize email addresses (remove dots, plus aliases, etc.)", {
|
|
4
|
+
email: z.string().describe("Email address to normalize"),
|
|
5
|
+
}, async ({ email }) => {
|
|
6
|
+
try {
|
|
7
|
+
// Basic email validation
|
|
8
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
9
|
+
if (!emailRegex.test(email)) {
|
|
10
|
+
throw new Error("Invalid email format");
|
|
11
|
+
}
|
|
12
|
+
const [localPart, domain] = email.toLowerCase().split('@');
|
|
13
|
+
let normalizedLocal = localPart;
|
|
14
|
+
let notes = [];
|
|
15
|
+
// Handle Gmail-specific rules
|
|
16
|
+
if (domain === 'gmail.com' || domain === 'googlemail.com') {
|
|
17
|
+
// Remove dots from Gmail addresses
|
|
18
|
+
const withoutDots = normalizedLocal.replace(/\./g, '');
|
|
19
|
+
if (withoutDots !== normalizedLocal) {
|
|
20
|
+
notes.push(`Removed dots: ${normalizedLocal} → ${withoutDots}`);
|
|
21
|
+
normalizedLocal = withoutDots;
|
|
22
|
+
}
|
|
23
|
+
// Remove everything after + (alias)
|
|
24
|
+
const plusIndex = normalizedLocal.indexOf('+');
|
|
25
|
+
if (plusIndex !== -1) {
|
|
26
|
+
const withoutAlias = normalizedLocal.substring(0, plusIndex);
|
|
27
|
+
notes.push(`Removed alias: ${normalizedLocal} → ${withoutAlias}`);
|
|
28
|
+
normalizedLocal = withoutAlias;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Handle other common plus aliasing
|
|
32
|
+
const plusIndex = normalizedLocal.indexOf('+');
|
|
33
|
+
if (plusIndex !== -1 && domain !== 'gmail.com' && domain !== 'googlemail.com') {
|
|
34
|
+
const withoutAlias = normalizedLocal.substring(0, plusIndex);
|
|
35
|
+
notes.push(`Removed plus alias: ${normalizedLocal} → ${withoutAlias}`);
|
|
36
|
+
normalizedLocal = withoutAlias;
|
|
37
|
+
}
|
|
38
|
+
const normalizedEmail = `${normalizedLocal}@${domain}`;
|
|
39
|
+
const isChanged = normalizedEmail !== email.toLowerCase();
|
|
40
|
+
return {
|
|
41
|
+
content: [
|
|
42
|
+
{
|
|
43
|
+
type: "text",
|
|
44
|
+
text: `Email Normalization:
|
|
45
|
+
|
|
46
|
+
Original: ${email}
|
|
47
|
+
Normalized: ${normalizedEmail}
|
|
48
|
+
Changed: ${isChanged ? 'Yes' : 'No'}
|
|
49
|
+
|
|
50
|
+
${notes.length > 0 ? `Transformations applied:
|
|
51
|
+
${notes.map(note => `• ${note}`).join('\n')}` : 'No transformations needed'}
|
|
52
|
+
|
|
53
|
+
Domain: ${domain}
|
|
54
|
+
Local part: ${normalizedLocal}
|
|
55
|
+
|
|
56
|
+
Note: This normalization helps identify duplicate email addresses
|
|
57
|
+
that would be delivered to the same inbox.`,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
return {
|
|
64
|
+
content: [
|
|
65
|
+
{
|
|
66
|
+
type: "text",
|
|
67
|
+
text: `Error normalizing email: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|