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,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
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
function getStatusCategory(code) {
|
|
3
|
+
if (code >= 100 && code < 200)
|
|
4
|
+
return '1xx Informational';
|
|
5
|
+
if (code >= 200 && code < 300)
|
|
6
|
+
return '2xx Success';
|
|
7
|
+
if (code >= 300 && code < 400)
|
|
8
|
+
return '3xx Redirection';
|
|
9
|
+
if (code >= 400 && code < 500)
|
|
10
|
+
return '4xx Client Error';
|
|
11
|
+
if (code >= 500 && code < 600)
|
|
12
|
+
return '5xx Server Error';
|
|
13
|
+
return 'Unknown Category';
|
|
14
|
+
}
|
|
15
|
+
function getUsageHint(code) {
|
|
16
|
+
if (code >= 100 && code < 200)
|
|
17
|
+
return 'the request is being processed';
|
|
18
|
+
if (code >= 200 && code < 300)
|
|
19
|
+
return 'the request was successful';
|
|
20
|
+
if (code >= 300 && code < 400)
|
|
21
|
+
return 'the client needs to take additional action';
|
|
22
|
+
if (code >= 400 && code < 500)
|
|
23
|
+
return 'there was an error with the client request';
|
|
24
|
+
if (code >= 500 && code < 600)
|
|
25
|
+
return 'there was an error on the server side';
|
|
26
|
+
return 'an unknown status';
|
|
27
|
+
}
|
|
28
|
+
export function registerHttpStatusCodes(server) {
|
|
29
|
+
server.tool("http-status-codes", "Get information about HTTP status codes", {
|
|
30
|
+
code: z.number().optional().describe("HTTP status code to look up (optional)"),
|
|
31
|
+
}, async ({ code }) => {
|
|
32
|
+
try {
|
|
33
|
+
const statusCodes = {
|
|
34
|
+
// 1xx Informational
|
|
35
|
+
100: "Continue",
|
|
36
|
+
101: "Switching Protocols",
|
|
37
|
+
102: "Processing",
|
|
38
|
+
// 2xx Success
|
|
39
|
+
200: "OK",
|
|
40
|
+
201: "Created",
|
|
41
|
+
202: "Accepted",
|
|
42
|
+
204: "No Content",
|
|
43
|
+
206: "Partial Content",
|
|
44
|
+
// 3xx Redirection
|
|
45
|
+
300: "Multiple Choices",
|
|
46
|
+
301: "Moved Permanently",
|
|
47
|
+
302: "Found",
|
|
48
|
+
304: "Not Modified",
|
|
49
|
+
307: "Temporary Redirect",
|
|
50
|
+
308: "Permanent Redirect",
|
|
51
|
+
// 4xx Client Error
|
|
52
|
+
400: "Bad Request",
|
|
53
|
+
401: "Unauthorized",
|
|
54
|
+
403: "Forbidden",
|
|
55
|
+
404: "Not Found",
|
|
56
|
+
405: "Method Not Allowed",
|
|
57
|
+
409: "Conflict",
|
|
58
|
+
410: "Gone",
|
|
59
|
+
422: "Unprocessable Entity",
|
|
60
|
+
429: "Too Many Requests",
|
|
61
|
+
// 5xx Server Error
|
|
62
|
+
500: "Internal Server Error",
|
|
63
|
+
501: "Not Implemented",
|
|
64
|
+
502: "Bad Gateway",
|
|
65
|
+
503: "Service Unavailable",
|
|
66
|
+
504: "Gateway Timeout",
|
|
67
|
+
505: "HTTP Version Not Supported"
|
|
68
|
+
};
|
|
69
|
+
const descriptions = {
|
|
70
|
+
100: "The server has received the request headers and the client should proceed to send the request body.",
|
|
71
|
+
101: "The requester has asked the server to switch protocols and the server has agreed to do so.",
|
|
72
|
+
102: "The server has received and is processing the request, but no response is available yet.",
|
|
73
|
+
200: "The request has succeeded.",
|
|
74
|
+
201: "The request has been fulfilled and resulted in a new resource being created.",
|
|
75
|
+
202: "The request has been accepted for processing, but the processing has not been completed.",
|
|
76
|
+
204: "The server successfully processed the request and is not returning any content.",
|
|
77
|
+
206: "The server is delivering only part of the resource due to a range header sent by the client.",
|
|
78
|
+
300: "The request has more than one possible response.",
|
|
79
|
+
301: "The URL of the requested resource has been changed permanently.",
|
|
80
|
+
302: "The resource is temporarily located at a different URL.",
|
|
81
|
+
304: "The response has not been modified since the last request.",
|
|
82
|
+
307: "The request should be repeated with another URI, but future requests should still use the original URI.",
|
|
83
|
+
308: "The request and all future requests should be repeated using another URI.",
|
|
84
|
+
400: "The server could not understand the request due to invalid syntax.",
|
|
85
|
+
401: "The client must authenticate itself to get the requested response.",
|
|
86
|
+
403: "The client does not have access rights to the content.",
|
|
87
|
+
404: "The server can not find the requested resource.",
|
|
88
|
+
405: "The request method is known by the server but is not supported by the target resource.",
|
|
89
|
+
409: "The request conflicts with the current state of the server.",
|
|
90
|
+
410: "The content has been permanently deleted from server.",
|
|
91
|
+
422: "The request was well-formed but was unable to be followed due to semantic errors.",
|
|
92
|
+
429: "The user has sent too many requests in a given amount of time.",
|
|
93
|
+
500: "The server has encountered a situation it doesn't know how to handle.",
|
|
94
|
+
501: "The request method is not supported by the server and cannot be handled.",
|
|
95
|
+
502: "The server got an invalid response while working as a gateway.",
|
|
96
|
+
503: "The server is not ready to handle the request.",
|
|
97
|
+
504: "The server is acting as a gateway and cannot get a response in time.",
|
|
98
|
+
505: "The HTTP version used in the request is not supported by the server."
|
|
99
|
+
};
|
|
100
|
+
if (code !== undefined) {
|
|
101
|
+
const message = statusCodes[code];
|
|
102
|
+
const description = descriptions[code];
|
|
103
|
+
if (!message) {
|
|
104
|
+
return {
|
|
105
|
+
content: [
|
|
106
|
+
{
|
|
107
|
+
type: "text",
|
|
108
|
+
text: `HTTP Status Code: ${code}
|
|
109
|
+
|
|
110
|
+
Status: Unknown/Custom status code
|
|
111
|
+
|
|
112
|
+
Common status codes:
|
|
113
|
+
${Object.entries(statusCodes).slice(0, 10).map(([c, m]) => `• ${c}: ${m}`).join('\n')}`,
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const category = getStatusCategory(code);
|
|
119
|
+
return {
|
|
120
|
+
content: [
|
|
121
|
+
{
|
|
122
|
+
type: "text",
|
|
123
|
+
text: `HTTP Status Code: ${code}
|
|
124
|
+
|
|
125
|
+
Message: ${message}
|
|
126
|
+
Category: ${category}
|
|
127
|
+
|
|
128
|
+
Description: ${description || 'No detailed description available.'}
|
|
129
|
+
|
|
130
|
+
Usage: This status code indicates ${getUsageHint(code)}.`,
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
// Return overview of all status codes
|
|
137
|
+
const byCategory = {
|
|
138
|
+
'1xx (Informational)': Object.entries(statusCodes).filter(([c]) => c.startsWith('1')),
|
|
139
|
+
'2xx (Success)': Object.entries(statusCodes).filter(([c]) => c.startsWith('2')),
|
|
140
|
+
'3xx (Redirection)': Object.entries(statusCodes).filter(([c]) => c.startsWith('3')),
|
|
141
|
+
'4xx (Client Error)': Object.entries(statusCodes).filter(([c]) => c.startsWith('4')),
|
|
142
|
+
'5xx (Server Error)': Object.entries(statusCodes).filter(([c]) => c.startsWith('5'))
|
|
143
|
+
};
|
|
144
|
+
let result = 'HTTP Status Codes Reference:\n\n';
|
|
145
|
+
for (const [category, codes] of Object.entries(byCategory)) {
|
|
146
|
+
result += `${category}:\n`;
|
|
147
|
+
for (const [code, message] of codes) {
|
|
148
|
+
result += `• ${code}: ${message}\n`;
|
|
149
|
+
}
|
|
150
|
+
result += '\n';
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
content: [
|
|
154
|
+
{
|
|
155
|
+
type: "text",
|
|
156
|
+
text: result.trim(),
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
return {
|
|
164
|
+
content: [
|
|
165
|
+
{
|
|
166
|
+
type: "text",
|
|
167
|
+
text: `Error looking up HTTP status code: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import mimeTypes from 'mime-types';
|
|
3
|
+
function getMimeCategory(mimeType) {
|
|
4
|
+
if (mimeType.startsWith('text/'))
|
|
5
|
+
return 'Text';
|
|
6
|
+
if (mimeType.startsWith('image/'))
|
|
7
|
+
return 'Image';
|
|
8
|
+
if (mimeType.startsWith('audio/'))
|
|
9
|
+
return 'Audio';
|
|
10
|
+
if (mimeType.startsWith('video/'))
|
|
11
|
+
return 'Video';
|
|
12
|
+
if (mimeType.startsWith('application/'))
|
|
13
|
+
return 'Application';
|
|
14
|
+
if (mimeType.startsWith('font/'))
|
|
15
|
+
return 'Font';
|
|
16
|
+
return 'Other';
|
|
17
|
+
}
|
|
18
|
+
function getMimeDescription(mimeType) {
|
|
19
|
+
const descriptions = {
|
|
20
|
+
'text/plain': 'Plain text file',
|
|
21
|
+
'text/html': 'HTML document',
|
|
22
|
+
'text/css': 'Cascading Style Sheets',
|
|
23
|
+
'text/javascript': 'JavaScript code',
|
|
24
|
+
'application/json': 'JSON data',
|
|
25
|
+
'image/jpeg': 'JPEG image',
|
|
26
|
+
'image/png': 'PNG image',
|
|
27
|
+
'image/gif': 'GIF image',
|
|
28
|
+
'application/pdf': 'PDF document',
|
|
29
|
+
'application/zip': 'ZIP archive',
|
|
30
|
+
'audio/mpeg': 'MP3 audio file',
|
|
31
|
+
'video/mp4': 'MP4 video file'
|
|
32
|
+
};
|
|
33
|
+
return descriptions[mimeType] || 'No description available';
|
|
34
|
+
}
|
|
35
|
+
export function registerMimeTypes(server) {
|
|
36
|
+
server.tool("mime-types", "Look up MIME types for file extensions", {
|
|
37
|
+
input: z.string().describe("File extension (e.g., 'txt') or MIME type (e.g., 'text/plain')"),
|
|
38
|
+
lookupType: z.enum(["extension-to-mime", "mime-to-extension"]).describe("Lookup direction").optional(),
|
|
39
|
+
}, async ({ input, lookupType = "extension-to-mime" }) => {
|
|
40
|
+
try {
|
|
41
|
+
if (lookupType === "extension-to-mime") {
|
|
42
|
+
const ext = input.toLowerCase().replace(/^\./, ''); // Remove leading dot if present
|
|
43
|
+
const mimeType = mimeTypes.lookup(ext);
|
|
44
|
+
if (!mimeType) {
|
|
45
|
+
return {
|
|
46
|
+
content: [
|
|
47
|
+
{
|
|
48
|
+
type: "text",
|
|
49
|
+
text: `MIME Type Lookup:
|
|
50
|
+
|
|
51
|
+
Extension: .${ext}
|
|
52
|
+
Result: Not found
|
|
53
|
+
|
|
54
|
+
Note: This extension is not recognized in the MIME types database.`,
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
content: [
|
|
61
|
+
{
|
|
62
|
+
type: "text",
|
|
63
|
+
text: `MIME Type Lookup:
|
|
64
|
+
|
|
65
|
+
Extension: .${ext}
|
|
66
|
+
MIME Type: ${mimeType}
|
|
67
|
+
|
|
68
|
+
Category: ${getMimeCategory(mimeType)}
|
|
69
|
+
Description: ${getMimeDescription(mimeType)}`,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
// mime-to-extension
|
|
76
|
+
const mimeType = input.toLowerCase();
|
|
77
|
+
const extension = mimeTypes.extension(mimeType);
|
|
78
|
+
if (!extension) {
|
|
79
|
+
return {
|
|
80
|
+
content: [
|
|
81
|
+
{
|
|
82
|
+
type: "text",
|
|
83
|
+
text: `Extension Lookup:
|
|
84
|
+
|
|
85
|
+
MIME Type: ${input}
|
|
86
|
+
Result: Not found
|
|
87
|
+
|
|
88
|
+
Note: This MIME type is not recognized or has no standard extension.`,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
content: [
|
|
95
|
+
{
|
|
96
|
+
type: "text",
|
|
97
|
+
text: `Extension Lookup:
|
|
98
|
+
|
|
99
|
+
MIME Type: ${mimeType}
|
|
100
|
+
Extension: .${extension}
|
|
101
|
+
Primary: .${extension}
|
|
102
|
+
|
|
103
|
+
Category: ${getMimeCategory(mimeType)}
|
|
104
|
+
Description: ${getMimeDescription(mimeType)}`,
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
return {
|
|
112
|
+
content: [
|
|
113
|
+
{
|
|
114
|
+
type: "text",
|
|
115
|
+
text: `Error looking up MIME type: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerPortNumbers(server) {
|
|
3
|
+
server.tool("port-numbers", "Look up common TCP/UDP port numbers and their services", {
|
|
4
|
+
query: z.string().describe("Port number or service name to look up")
|
|
5
|
+
}, async ({ query }) => {
|
|
6
|
+
try {
|
|
7
|
+
const ports = {
|
|
8
|
+
// Well-known ports (0-1023)
|
|
9
|
+
"21": "FTP (File Transfer Protocol)",
|
|
10
|
+
"22": "SSH (Secure Shell)",
|
|
11
|
+
"23": "Telnet",
|
|
12
|
+
"25": "SMTP (Simple Mail Transfer Protocol)",
|
|
13
|
+
"53": "DNS (Domain Name System)",
|
|
14
|
+
"80": "HTTP (Hypertext Transfer Protocol)",
|
|
15
|
+
"110": "POP3 (Post Office Protocol v3)",
|
|
16
|
+
"143": "IMAP (Internet Message Access Protocol)",
|
|
17
|
+
"443": "HTTPS (HTTP Secure)",
|
|
18
|
+
"993": "IMAPS (IMAP Secure)",
|
|
19
|
+
"995": "POP3S (POP3 Secure)",
|
|
20
|
+
// Registered ports (1024-49151)
|
|
21
|
+
"1433": "Microsoft SQL Server",
|
|
22
|
+
"1521": "Oracle Database",
|
|
23
|
+
"3306": "MySQL",
|
|
24
|
+
"3389": "RDP (Remote Desktop Protocol)",
|
|
25
|
+
"5432": "PostgreSQL",
|
|
26
|
+
"5672": "AMQP (Advanced Message Queuing Protocol)",
|
|
27
|
+
"5984": "CouchDB",
|
|
28
|
+
"6379": "Redis",
|
|
29
|
+
"8080": "HTTP Alternate",
|
|
30
|
+
"8443": "HTTPS Alternate",
|
|
31
|
+
"9200": "Elasticsearch",
|
|
32
|
+
"27017": "MongoDB",
|
|
33
|
+
// Development ports
|
|
34
|
+
"3000": "Node.js Development Server",
|
|
35
|
+
"3001": "React Development Server",
|
|
36
|
+
"4200": "Angular Development Server",
|
|
37
|
+
"5173": "Vite Development Server",
|
|
38
|
+
"8000": "Python HTTP Server",
|
|
39
|
+
"8888": "Jupyter Notebook"
|
|
40
|
+
};
|
|
41
|
+
const isNumber = /^\d+$/.test(query);
|
|
42
|
+
let results = [];
|
|
43
|
+
if (isNumber) {
|
|
44
|
+
// Look up by port number
|
|
45
|
+
const port = query;
|
|
46
|
+
if (ports[port]) {
|
|
47
|
+
results.push(`Port ${port}: ${ports[port]}`);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
results.push(`Port ${port}: No standard service found`);
|
|
51
|
+
}
|
|
52
|
+
// Add range information
|
|
53
|
+
const portNum = parseInt(port);
|
|
54
|
+
if (portNum <= 1023) {
|
|
55
|
+
results.push("Range: Well-known ports (0-1023) - requires root privileges");
|
|
56
|
+
}
|
|
57
|
+
else if (portNum <= 49151) {
|
|
58
|
+
results.push("Range: Registered ports (1024-49151) - assigned by IANA");
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
results.push("Range: Dynamic/Private ports (49152-65535) - available for applications");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// Search by service name
|
|
66
|
+
const searchTerm = query.toLowerCase();
|
|
67
|
+
for (const [port, service] of Object.entries(ports)) {
|
|
68
|
+
if (service.toLowerCase().includes(searchTerm)) {
|
|
69
|
+
results.push(`Port ${port}: ${service}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (results.length === 0) {
|
|
73
|
+
results.push(`No ports found matching "${query}"`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
content: [{
|
|
78
|
+
type: "text",
|
|
79
|
+
text: `Port Number Lookup Results:
|
|
80
|
+
|
|
81
|
+
Query: "${query}"
|
|
82
|
+
|
|
83
|
+
${results.join('\n')}
|
|
84
|
+
|
|
85
|
+
Common Port Ranges:
|
|
86
|
+
• 0-1023: Well-known ports (system/root required)
|
|
87
|
+
• 1024-49151: Registered ports (IANA assigned)
|
|
88
|
+
• 49152-65535: Dynamic/Private ports (ephemeral)
|
|
89
|
+
|
|
90
|
+
Security Notes:
|
|
91
|
+
• Always check firewall rules before opening ports
|
|
92
|
+
• Use non-standard ports for additional security
|
|
93
|
+
• Monitor open ports with netstat/ss commands`
|
|
94
|
+
}]
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
return {
|
|
99
|
+
content: [{
|
|
100
|
+
type: "text",
|
|
101
|
+
text: `Error looking up port: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
102
|
+
}]
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|