it-tools-mcp 3.2.12 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.dockerhub.md +1 -1
- package/README.md +105 -104
- package/build/index.js +464 -70
- package/build/tools/ansible/{ansible-vault-decrypt → decrypt_ansible_vault}/index.js +13 -4
- package/build/tools/ansible/{ansible-vault-encrypt → encrypt_ansible_vault}/index.js +14 -5
- package/build/tools/ansible/generate_ansible_inventory/index.js +221 -0
- package/build/tools/ansible/{ansible-inventory-generator → parse_ansible_inventory}/index.js +11 -2
- package/build/tools/ansible/{ansible-reference → show_ansible_reference}/index.js +11 -2
- package/build/tools/ansible/{ansible-playbook-validator → validate_ansible_playbook}/index.js +12 -3
- package/build/tools/color/{color-hex-to-rgb → convert_hex_to_rgb}/index.js +12 -3
- package/build/tools/color/{color-rgb-to-hex → convert_rgb_to_hex}/index.js +14 -5
- package/build/tools/crypto/{jwt-decode → decode_jwt}/index.js +12 -3
- package/build/tools/crypto/{basic-auth-generator → generate_basic_auth}/index.js +13 -4
- package/build/tools/crypto/{bip39-generate → generate_bip39}/index.js +12 -3
- package/build/tools/crypto/{hmac-generator → generate_hmac}/index.js +14 -5
- package/build/tools/crypto/{otp-code-generator → generate_otp}/index.js +14 -5
- package/build/tools/crypto/{password-generate → generate_password}/index.js +16 -7
- package/build/tools/crypto/{token-generator → generate_token}/index.js +14 -5
- package/build/tools/crypto/{bcrypt-hash → hash_bcrypt}/index.js +14 -5
- package/build/tools/crypto/{hash-md5 → hash_md5}/index.js +11 -2
- package/build/tools/crypto/{hash-sha1 → hash_sha1}/index.js +11 -2
- package/build/tools/crypto/{hash-sha256 → hash_sha256}/index.js +11 -2
- package/build/tools/crypto/{hash-sha512 → hash_sha512}/index.js +11 -2
- package/build/tools/{dataFormat/json-diff → data_format/compare_json}/index.js +13 -4
- package/build/tools/{dataFormat/html-to-markdown → data_format/convert_html_to_markdown}/index.js +12 -3
- package/build/tools/{dataFormat/json-to-csv → data_format/convert_json_to_csv}/index.js +13 -4
- package/build/tools/{dataFormat/json-to-toml → data_format/convert_json_to_toml}/index.js +12 -3
- package/build/tools/{dataFormat/markdown-to-html → data_format/convert_markdown_to_html}/index.js +12 -3
- package/build/tools/{dataFormat/toml-to-json → data_format/convert_toml_to_json}/index.js +12 -3
- package/build/tools/{dataFormat/json-format → data_format/format_json}/index.js +14 -4
- package/build/tools/{dataFormat/phone-format → data_format/format_phone}/index.js +13 -4
- package/build/tools/{dataFormat/sql-format → data_format/format_sql}/index.js +13 -4
- package/build/tools/{dataFormat/xml-format → data_format/format_xml}/index.js +13 -4
- package/build/tools/{dataFormat/yaml-format → data_format/format_yaml}/index.js +12 -3
- package/build/tools/{dataFormat/json-minify → data_format/minify_json}/index.js +12 -3
- package/build/tools/development/{list-converter → convert_list}/index.js +15 -6
- package/build/tools/development/{html-prettifier → format_html}/index.js +13 -4
- package/build/tools/development/{javascript-prettifier → format_javascript}/index.js +14 -5
- package/build/tools/development/{crontab-generate → generate_crontab}/index.js +16 -7
- package/build/tools/development/{markdown-toc-generator → generate_markdown_toc}/index.js +14 -5
- package/build/tools/development/{regex-tester → test_regex}/index.js +14 -5
- package/build/tools/docker/{docker-compose-to-docker-run → convert_docker_compose_to_run}/index.js +11 -2
- package/build/tools/docker/{docker-run-to-docker-compose → convert_docker_run_to_compose}/index.js +11 -2
- package/build/tools/docker/{traefik-compose-generator → generate_traefik_compose}/index.js +16 -7
- package/build/tools/docker/{docker-reference → show_docker_reference}/index.js +11 -2
- package/build/tools/docker/{docker-compose-validator → validate_docker_compose}/index.js +12 -3
- package/build/tools/encoding/{text-to-binary → convert_text_to_binary}/index.js +13 -4
- package/build/tools/encoding/{base64-decode → decode_base64}/index.js +13 -3
- package/build/tools/encoding/{html-decode → decode_html}/index.js +12 -3
- package/build/tools/encoding/{url-decode → decode_url}/index.js +12 -3
- package/build/tools/encoding/encode_base64/index.js +38 -0
- package/build/tools/encoding/{html-encode → encode_html}/index.js +12 -3
- package/build/tools/encoding/{html-entities-extended → encode_html_entities}/index.js +13 -4
- package/build/tools/encoding/encode_url/index.js +25 -0
- package/build/tools/forensic/{safelink-decoder → decode_safelink}/index.js +12 -3
- package/build/tools/forensic/{url-fanger → fang_url}/index.js +13 -4
- package/build/tools/forensic/{file-type-identifier → identify_file_type}/index.js +13 -4
- package/build/tools/{idGenerators/qr-generate → id_generators/generate_qr_code}/index.js +13 -4
- package/build/tools/{idGenerators/svg-placeholder-generator → id_generators/generate_svg_placeholder}/index.js +16 -7
- package/build/tools/{idGenerators/ulid-generate → id_generators/generate_ulid}/index.js +11 -2
- package/build/tools/id_generators/generate_uuid/index.js +23 -0
- package/build/tools/math/{percentage-calculator → calculate_percentage}/index.js +14 -5
- package/build/tools/math/{number-base-converter → convert_number_base}/index.js +14 -5
- package/build/tools/math/{roman-numeral-converter → convert_roman_numerals}/index.js +12 -3
- package/build/tools/math/{temperature-converter → convert_temperature}/index.js +14 -5
- package/build/tools/math/{unix-timestamp-converter → convert_unix_timestamp}/index.js +11 -2
- package/build/tools/math/{math-evaluate → evaluate_math}/index.js +12 -3
- package/build/tools/network/{ip-subnet-calculator → calculate_ip_subnet}/index.js +12 -3
- package/build/tools/network/{ipv4-subnet-calc → calculate_ipv4_subnet}/index.js +11 -2
- package/build/tools/network/{ipv6-subnet-calculator → calculate_ipv6_subnet}/index.js +12 -3
- package/build/tools/network/cat/index.js +11 -2
- package/build/tools/network/{cidr-to-ip-range → convert_cidr_to_ip_range}/index.js +11 -2
- package/build/tools/network/{ip-range-to-cidr → convert_ip_range_to_cidr}/index.js +12 -3
- package/build/tools/network/curl/index.js +17 -6
- package/build/tools/network/dig/index.js +12 -3
- package/build/tools/network/{ipv6-ula-generator → generate_ipv6_ula}/index.js +11 -2
- package/build/tools/network/{mac-address-generate → generate_mac_address}/index.js +12 -3
- package/build/tools/network/{random-port → generate_random_port}/index.js +14 -5
- package/build/tools/network/grep/index.js +12 -3
- package/build/tools/network/head/index.js +12 -3
- package/build/tools/network/nslookup/index.js +11 -2
- package/build/tools/network/{url-parse → parse_url}/index.js +11 -2
- package/build/tools/network/ping/index.js +15 -4
- package/build/tools/network/ps/index.js +10 -1
- package/build/tools/network/scp/index.js +16 -7
- package/build/tools/network/ssh/index.js +14 -5
- package/build/tools/network/tail/index.js +12 -3
- package/build/tools/network/telnet/index.js +12 -3
- package/build/tools/network/top/index.js +10 -1
- package/build/tools/network/{iban-validate → validate_iban}/index.js +11 -2
- package/build/tools/physics/{angle-converter → convert_angle}/index.js +17 -8
- package/build/tools/physics/{energy-converter → convert_energy}/index.js +19 -10
- package/build/tools/physics/{power-converter → convert_power}/index.js +19 -10
- package/build/tools/text/{distinct-words → analyze_distinct_words}/index.js +11 -2
- package/build/tools/text/{text-stats → analyze_text_stats}/index.js +11 -2
- package/build/tools/text/capitalize_text/index.js +25 -0
- package/build/tools/text/{text-diff → compare_text}/index.js +12 -3
- package/build/tools/text/convert_text_to_camelcase/index.js +29 -0
- package/build/tools/text/{text-kebabcase → convert_text_to_kebabcase}/index.js +11 -2
- package/build/tools/text/convert_text_to_lowercase/index.js +24 -0
- package/build/tools/text/{text-to-nato-alphabet → convert_text_to_nato}/index.js +12 -3
- package/build/tools/text/{text-pascalcase → convert_text_to_pascalcase}/index.js +11 -2
- package/build/tools/text/{text-to-unicode → convert_text_to_unicode}/index.js +12 -3
- package/build/tools/text/convert_text_to_uppercase/index.js +24 -0
- package/build/tools/text/{ascii-art-text → generate_ascii_art}/index.js +12 -3
- package/build/tools/text/{lorem-ipsum-generator → generate_lorem_ipsum}/index.js +12 -3
- package/build/tools/text/{numeronym-generator → generate_numeronym}/index.js +11 -2
- package/build/tools/text/{string-obfuscator → obfuscate_string}/index.js +12 -3
- package/build/tools/text/{emoji-search → search_emoji}/index.js +11 -2
- package/build/tools/text/{text-to-unicode-names → show_unicode_names}/index.js +11 -2
- package/build/tools/text/{slugify-string → slugify_text}/index.js +13 -4
- package/build/tools/text/text_snakecase/index.js +1 -0
- package/build/tools/utility/{rem-px-converter → convert_rem_px}/index.js +14 -4
- package/build/tools/utility/{css-prettifier → format_css}/index.js +12 -3
- package/build/tools/utility/{http-status-codes → lookup_http_status}/index.js +11 -2
- package/build/tools/utility/{mime-types → lookup_mime_types}/index.js +12 -3
- package/build/tools/utility/{port-numbers → lookup_port_numbers}/index.js +11 -2
- package/build/tools/utility/{email-normalizer → normalize_email}/index.js +11 -2
- package/build/tools/utility/{device-info → show_device_info}/index.js +10 -1
- package/package.json +50 -6
- package/build/tools/encoding/base64-encode/index.js +0 -16
- package/build/tools/encoding/url-encode/index.js +0 -16
- package/build/tools/idGenerators/uuid-generate/index.js +0 -14
- package/build/tools/text/text-camelcase/index.js +0 -20
- package/build/tools/text/text-capitalize/index.js +0 -16
- package/build/tools/text/text-lowercase/index.js +0 -15
- package/build/tools/text/text-snakecase/index.js +0 -20
- package/build/tools/text/text-uppercase/index.js +0 -15
package/build/index.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { completable } from "@modelcontextprotocol/sdk/server/completable.js";
|
|
4
5
|
import { z } from "zod";
|
|
5
6
|
import fs from 'fs';
|
|
6
7
|
import path from 'path';
|
|
7
8
|
import { fileURLToPath } from 'url';
|
|
9
|
+
import { exec } from 'child_process';
|
|
10
|
+
import { promisify } from 'util';
|
|
8
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
12
|
const __dirname = path.dirname(__filename);
|
|
10
13
|
/**
|
|
@@ -199,15 +202,8 @@ export function getResourceUsage() {
|
|
|
199
202
|
};
|
|
200
203
|
}
|
|
201
204
|
/**
|
|
202
|
-
*
|
|
205
|
+
* Input validation and security utilities
|
|
203
206
|
*/
|
|
204
|
-
export const SECURITY_HEADERS = {
|
|
205
|
-
'X-Content-Type-Options': 'nosniff',
|
|
206
|
-
'X-Frame-Options': 'DENY',
|
|
207
|
-
'X-XSS-Protection': '1; mode=block',
|
|
208
|
-
'Referrer-Policy': 'strict-origin-when-cross-origin',
|
|
209
|
-
};
|
|
210
|
-
// Helper to read version from package.json at runtime (ESM compatible)
|
|
211
207
|
// Get package metadata for enhanced server info
|
|
212
208
|
function getPackageMetadata() {
|
|
213
209
|
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
@@ -221,19 +217,268 @@ function getPackageMetadata() {
|
|
|
221
217
|
keywords: pkg.keywords,
|
|
222
218
|
author: pkg.author,
|
|
223
219
|
repository: pkg.repository,
|
|
224
|
-
homepage: pkg.homepage
|
|
220
|
+
homepage: pkg.homepage,
|
|
221
|
+
license: pkg.license
|
|
225
222
|
};
|
|
226
223
|
}
|
|
227
|
-
// Create server instance with enhanced metadata
|
|
224
|
+
// Create server instance with enhanced metadata and VS Code compliance features
|
|
228
225
|
const packageInfo = getPackageMetadata();
|
|
226
|
+
const execAsync = promisify(exec);
|
|
227
|
+
// Environment detection
|
|
228
|
+
const isDevelopment = process.env.NODE_ENV === 'development' || process.env.MCP_DEV_MODE === 'true';
|
|
229
|
+
const isTest = process.env.NODE_ENV === 'test';
|
|
229
230
|
const server = new McpServer({
|
|
230
231
|
name: "it-tools-mcp",
|
|
231
232
|
version: packageInfo.version,
|
|
233
|
+
description: "A comprehensive Model Context Protocol (MCP) server that provides access to over 100 IT tools and utilities commonly used by developers, system administrators, and IT professionals. This server exposes a complete set of tools for encoding/decoding, text manipulation, hashing, network utilities, and many other common development and IT tasks.",
|
|
234
|
+
author: packageInfo.author,
|
|
235
|
+
homepage: packageInfo.homepage,
|
|
236
|
+
repository: packageInfo.repository,
|
|
237
|
+
license: packageInfo.license,
|
|
238
|
+
}, {
|
|
232
239
|
capabilities: {
|
|
233
|
-
resources: {},
|
|
234
240
|
tools: {},
|
|
241
|
+
resources: {},
|
|
242
|
+
prompts: {},
|
|
243
|
+
sampling: {},
|
|
244
|
+
roots: {
|
|
245
|
+
listChanged: true
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
// VS Code MCP Compliance: Implement Resources
|
|
250
|
+
server.registerResource("server-manifest", new ResourceTemplate("manifest://{type}", {
|
|
251
|
+
list: async () => ({
|
|
252
|
+
resources: [
|
|
253
|
+
{ name: "manifest://info", description: "Server information and capabilities", uri: "manifest://info" },
|
|
254
|
+
{ name: "manifest://tools", description: "Complete list of available tools", uri: "manifest://tools" },
|
|
255
|
+
{ name: "manifest://categories", description: "Tool categories and descriptions", uri: "manifest://categories" }
|
|
256
|
+
]
|
|
257
|
+
})
|
|
258
|
+
}), {
|
|
259
|
+
title: "Server Manifest",
|
|
260
|
+
description: "Comprehensive server information, capabilities, and tool catalog",
|
|
261
|
+
mimeType: "application/json"
|
|
262
|
+
}, async (uri, params) => {
|
|
263
|
+
const type = params.type;
|
|
264
|
+
const manifestContent = await getManifestContent(type);
|
|
265
|
+
return {
|
|
266
|
+
contents: [{
|
|
267
|
+
uri: uri.href,
|
|
268
|
+
text: JSON.stringify(manifestContent, null, 2),
|
|
269
|
+
mimeType: "application/json"
|
|
270
|
+
}]
|
|
271
|
+
};
|
|
272
|
+
});
|
|
273
|
+
server.registerResource("system-logs", new ResourceTemplate("logs://{type}", {
|
|
274
|
+
list: async () => ({
|
|
275
|
+
resources: [
|
|
276
|
+
{ name: "logs://system", description: "System log entries", uri: "logs://system" },
|
|
277
|
+
{ name: "logs://error", description: "Error log entries", uri: "logs://error" },
|
|
278
|
+
{ name: "logs://debug", description: "Debug information", uri: "logs://debug" }
|
|
279
|
+
]
|
|
280
|
+
})
|
|
281
|
+
}), {
|
|
282
|
+
title: "System Logs",
|
|
283
|
+
description: "Access to system and application logs",
|
|
284
|
+
mimeType: "text/plain"
|
|
285
|
+
}, async (uri, params) => {
|
|
286
|
+
const type = params.type;
|
|
287
|
+
const logContent = await getLogContent(type);
|
|
288
|
+
return {
|
|
289
|
+
contents: [{
|
|
290
|
+
uri: uri.href,
|
|
291
|
+
text: logContent,
|
|
292
|
+
mimeType: "text/plain"
|
|
293
|
+
}]
|
|
294
|
+
};
|
|
295
|
+
});
|
|
296
|
+
server.registerResource("tool-documentation", new ResourceTemplate("docs://{category}/{tool?}", {
|
|
297
|
+
list: async () => {
|
|
298
|
+
const { toolCategories } = await discoverTools();
|
|
299
|
+
const resources = Object.keys(toolCategories).map(category => ({
|
|
300
|
+
name: `docs://${category}`,
|
|
301
|
+
description: `Documentation for ${category} tools`,
|
|
302
|
+
uri: `docs://${category}`
|
|
303
|
+
}));
|
|
304
|
+
return { resources };
|
|
235
305
|
},
|
|
306
|
+
complete: {
|
|
307
|
+
category: (value) => {
|
|
308
|
+
const categories = ["crypto", "encoding", "network", "text", "utility", "data_format", "id_generators"];
|
|
309
|
+
return categories.filter(c => c.startsWith(value));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}), {
|
|
313
|
+
title: "Tool Documentation",
|
|
314
|
+
description: "Documentation for available tools by category"
|
|
315
|
+
}, async (uri, params) => {
|
|
316
|
+
const category = params.category;
|
|
317
|
+
const tool = params.tool;
|
|
318
|
+
const docs = await getToolDocumentation(category, tool);
|
|
319
|
+
return {
|
|
320
|
+
contents: [{
|
|
321
|
+
uri: uri.href,
|
|
322
|
+
text: docs,
|
|
323
|
+
mimeType: "text/markdown"
|
|
324
|
+
}]
|
|
325
|
+
};
|
|
326
|
+
});
|
|
327
|
+
server.registerResource("workspace-config", "config://workspace", {
|
|
328
|
+
title: "Workspace Configuration",
|
|
329
|
+
description: "Current workspace configuration and environment settings"
|
|
330
|
+
}, async (uri) => {
|
|
331
|
+
const config = {
|
|
332
|
+
environment: isDevelopment ? "development" : "production",
|
|
333
|
+
nodeVersion: process.version,
|
|
334
|
+
platform: process.platform,
|
|
335
|
+
arch: process.arch,
|
|
336
|
+
workingDirectory: process.cwd(),
|
|
337
|
+
timestamp: new Date().toISOString()
|
|
338
|
+
};
|
|
339
|
+
return {
|
|
340
|
+
contents: [{
|
|
341
|
+
uri: uri.href,
|
|
342
|
+
text: JSON.stringify(config, null, 2),
|
|
343
|
+
mimeType: "application/json"
|
|
344
|
+
}]
|
|
345
|
+
};
|
|
236
346
|
});
|
|
347
|
+
// VS Code MCP Compliance: Implement Prompts
|
|
348
|
+
server.registerPrompt("it-workflow", {
|
|
349
|
+
title: "IT Workflow Assistant",
|
|
350
|
+
description: "Guided workflow for common IT tasks using available tools",
|
|
351
|
+
argsSchema: {
|
|
352
|
+
task_type: completable(z.string(), (value) => {
|
|
353
|
+
const tasks = ["encode", "decode", "hash", "encrypt", "format", "validate", "generate", "convert"];
|
|
354
|
+
return tasks.filter(t => t.startsWith(value));
|
|
355
|
+
}),
|
|
356
|
+
context: z.string().optional().describe("Additional context about the task")
|
|
357
|
+
}
|
|
358
|
+
}, ({ task_type, context = "" }) => {
|
|
359
|
+
const workflow = generateWorkflowPrompt(task_type, context);
|
|
360
|
+
return {
|
|
361
|
+
messages: [{
|
|
362
|
+
role: "user",
|
|
363
|
+
content: {
|
|
364
|
+
type: "text",
|
|
365
|
+
text: workflow
|
|
366
|
+
}
|
|
367
|
+
}]
|
|
368
|
+
};
|
|
369
|
+
});
|
|
370
|
+
server.registerPrompt("security-check", {
|
|
371
|
+
title: "Security Analysis",
|
|
372
|
+
description: "Analyze data for security concerns before processing",
|
|
373
|
+
argsSchema: {
|
|
374
|
+
data_type: completable(z.string(), (value) => {
|
|
375
|
+
const types = ["text", "json", "xml", "html", "sql", "script"];
|
|
376
|
+
return types.filter(t => t.startsWith(value));
|
|
377
|
+
}),
|
|
378
|
+
data: z.string().describe("Data to analyze for security issues")
|
|
379
|
+
}
|
|
380
|
+
}, ({ data_type, data }) => ({
|
|
381
|
+
messages: [{
|
|
382
|
+
role: "user",
|
|
383
|
+
content: {
|
|
384
|
+
type: "text",
|
|
385
|
+
text: `Please analyze this ${data_type} data for potential security issues:\n\n${data}\n\nCheck for: injection attempts, malicious patterns, suspicious content, and provide recommendations.`
|
|
386
|
+
}
|
|
387
|
+
}]
|
|
388
|
+
}));
|
|
389
|
+
// VS Code MCP Compliance: Sampling and Roots are declared in capabilities
|
|
390
|
+
// The MCP SDK handles these automatically when capabilities are declared
|
|
391
|
+
// Helper functions for VS Code MCP compliance features
|
|
392
|
+
async function getLogContent(type) {
|
|
393
|
+
const logs = {
|
|
394
|
+
system: `System log entries for IT Tools MCP Server\nTimestamp: ${new Date().toISOString()}\nStatus: Running\nMemory: ${JSON.stringify(getResourceUsage().memory, null, 2)}`,
|
|
395
|
+
error: `Error log entries\nNo recent errors recorded\nServer startup: successful\nTool loading: complete`,
|
|
396
|
+
debug: `Debug information\nEnvironment: ${isDevelopment ? 'development' : 'production'}\nNode version: ${process.version}\nPlatform: ${process.platform}`
|
|
397
|
+
};
|
|
398
|
+
return logs[type] || "Log type not found";
|
|
399
|
+
}
|
|
400
|
+
async function getManifestContent(type) {
|
|
401
|
+
const { toolCategories } = await discoverTools();
|
|
402
|
+
const toolCount = Object.keys(toolCategories).reduce((total, category) => {
|
|
403
|
+
return total + toolCategories[category].tools.length;
|
|
404
|
+
}, 0);
|
|
405
|
+
const manifests = {
|
|
406
|
+
info: {
|
|
407
|
+
name: packageInfo.name,
|
|
408
|
+
displayName: "IT Tools MCP Server",
|
|
409
|
+
description: packageInfo.description,
|
|
410
|
+
version: packageInfo.version,
|
|
411
|
+
author: packageInfo.author,
|
|
412
|
+
license: packageInfo.license,
|
|
413
|
+
homepage: packageInfo.homepage,
|
|
414
|
+
repository: packageInfo.repository,
|
|
415
|
+
capabilities: {
|
|
416
|
+
tools: toolCount,
|
|
417
|
+
categories: Object.keys(toolCategories).length,
|
|
418
|
+
resources: true,
|
|
419
|
+
prompts: true
|
|
420
|
+
},
|
|
421
|
+
features: [
|
|
422
|
+
`${toolCount}+ IT tools and utilities`,
|
|
423
|
+
`${Object.keys(toolCategories).length} tool categories`,
|
|
424
|
+
"Encoding/Decoding tools",
|
|
425
|
+
"Cryptographic functions",
|
|
426
|
+
"Network utilities",
|
|
427
|
+
"Text processing tools",
|
|
428
|
+
"JSON/XML/YAML formatting",
|
|
429
|
+
"Docker integration",
|
|
430
|
+
"Security focused design",
|
|
431
|
+
"Type-safe implementation"
|
|
432
|
+
],
|
|
433
|
+
installation: {
|
|
434
|
+
npm: "npx it-tools-mcp",
|
|
435
|
+
docker: "docker run -i --rm wrenchpilot/it-tools-mcp:latest"
|
|
436
|
+
}
|
|
437
|
+
},
|
|
438
|
+
tools: Object.keys(toolCategories).reduce((acc, category) => {
|
|
439
|
+
acc[category] = {
|
|
440
|
+
description: toolCategories[category].description,
|
|
441
|
+
tools: toolCategories[category].tools
|
|
442
|
+
};
|
|
443
|
+
return acc;
|
|
444
|
+
}, {}),
|
|
445
|
+
categories: Object.keys(toolCategories).map(category => ({
|
|
446
|
+
name: category,
|
|
447
|
+
description: toolCategories[category].description,
|
|
448
|
+
toolCount: toolCategories[category].tools.length,
|
|
449
|
+
tools: toolCategories[category].tools
|
|
450
|
+
}))
|
|
451
|
+
};
|
|
452
|
+
return manifests[type] || { error: "Manifest type not found" };
|
|
453
|
+
}
|
|
454
|
+
async function getToolDocumentation(category, tool) {
|
|
455
|
+
if (tool) {
|
|
456
|
+
return `# ${tool} Documentation\n\nCategory: ${category}\n\nThis tool provides ${category} functionality.\n\nUsage: See tool description for specific parameters and examples.`;
|
|
457
|
+
}
|
|
458
|
+
const { toolCategories } = await discoverTools();
|
|
459
|
+
const categoryInfo = toolCategories[category];
|
|
460
|
+
if (!categoryInfo) {
|
|
461
|
+
return `# Category Not Found\n\nThe category '${category}' was not found.`;
|
|
462
|
+
}
|
|
463
|
+
return `# ${category} Category Documentation\n\n${categoryInfo.description}\n\n## Available Tools\n\n${categoryInfo.tools.map(t => `- ${t}`).join('\n')}`;
|
|
464
|
+
}
|
|
465
|
+
function generateWorkflowPrompt(taskType, context) {
|
|
466
|
+
const workflows = {
|
|
467
|
+
encode: `I need to encode data. Context: ${context}\n\nRecommended workflow:\n1. Identify the type of encoding needed (base64, URL, HTML)\n2. Use the appropriate encoding tool\n3. Verify the result`,
|
|
468
|
+
hash: `I need to hash data. Context: ${context}\n\nRecommended workflow:\n1. Choose appropriate hash algorithm (MD5, SHA256, etc.)\n2. Use the corresponding hash tool\n3. Store or compare the hash securely`,
|
|
469
|
+
format: `I need to format data. Context: ${context}\n\nRecommended workflow:\n1. Identify the data format (JSON, XML, HTML, SQL)\n2. Use the appropriate formatter tool\n3. Validate the formatted output`
|
|
470
|
+
};
|
|
471
|
+
return workflows[taskType] || `Generic IT workflow for: ${taskType}\nContext: ${context}\n\nPlease describe your specific requirements for customized guidance.`;
|
|
472
|
+
}
|
|
473
|
+
function getAnalysisPrompt(analysisType, content) {
|
|
474
|
+
const prompts = {
|
|
475
|
+
summarize: `Please provide a concise summary of the following content:\n\n${content}`,
|
|
476
|
+
security: `Please analyze the following content for security concerns, potential vulnerabilities, or suspicious patterns:\n\n${content}`,
|
|
477
|
+
optimization: `Please analyze the following content and suggest optimizations or improvements:\n\n${content}`,
|
|
478
|
+
documentation: `Please analyze the following content and generate appropriate documentation:\n\n${content}`
|
|
479
|
+
};
|
|
480
|
+
return prompts[analysisType] || `Please analyze the following content:\n\n${content}`;
|
|
481
|
+
}
|
|
237
482
|
// Helper function to dynamically load modular tools from a category directory
|
|
238
483
|
async function loadModularTools(server, category) {
|
|
239
484
|
const toolsDir = path.join(__dirname, 'tools', category);
|
|
@@ -253,13 +498,14 @@ async function loadModularTools(server, category) {
|
|
|
253
498
|
const registerFunction = Object.values(toolModule).find((fn) => typeof fn === 'function' && fn.name.startsWith('register'));
|
|
254
499
|
if (registerFunction) {
|
|
255
500
|
registerFunction(server);
|
|
501
|
+
console.error(`Loaded tool: ${category}/${toolDir}`);
|
|
256
502
|
}
|
|
257
503
|
else {
|
|
258
504
|
console.warn(`No register function found in ${toolPath}`);
|
|
259
505
|
}
|
|
260
506
|
}
|
|
261
507
|
catch (error) {
|
|
262
|
-
console.error(`Failed to load tool ${category}/${toolDir}:`, error);
|
|
508
|
+
console.error(`Failed to load tool ${category}/${toolDir}:`, error instanceof Error ? error.message : 'Unknown error');
|
|
263
509
|
}
|
|
264
510
|
}
|
|
265
511
|
else {
|
|
@@ -353,24 +599,48 @@ async function getCategoryDescription(category, toolNames) {
|
|
|
353
599
|
const categoryTitle = category.charAt(0).toUpperCase() + category.slice(1);
|
|
354
600
|
return `${categoryTitle} tools and utilities (${toolNames.length} tools available)`;
|
|
355
601
|
}
|
|
356
|
-
// Register
|
|
357
|
-
|
|
358
|
-
|
|
602
|
+
// Register all tools dynamically by discovering categories from filesystem
|
|
603
|
+
async function registerAllTools(server) {
|
|
604
|
+
const toolsBaseDir = path.join(__dirname, 'tools');
|
|
605
|
+
if (!fs.existsSync(toolsBaseDir)) {
|
|
606
|
+
console.warn('Tools directory does not exist:', toolsBaseDir);
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
// Discover categories dynamically from the filesystem
|
|
610
|
+
const categories = fs.readdirSync(toolsBaseDir, { withFileTypes: true })
|
|
611
|
+
.filter(dirent => dirent.isDirectory())
|
|
612
|
+
.map(dirent => dirent.name)
|
|
613
|
+
.sort(); // Sort for consistent ordering
|
|
614
|
+
for (const category of categories) {
|
|
615
|
+
await loadModularTools(server, category);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
// Add comprehensive system and server information tool with VS Code compliance annotations
|
|
619
|
+
server.registerTool("system_info", {
|
|
620
|
+
description: "Get comprehensive system information, server details, available tool categories, and resource usage. Example: system information, tool categories, installation guide",
|
|
359
621
|
inputSchema: {
|
|
360
622
|
include_tools: z.boolean().optional().describe("Include detailed information about all available tools"),
|
|
361
623
|
category: z.string().optional().describe("Get information about a specific category (dynamically discovered)")
|
|
624
|
+
},
|
|
625
|
+
// VS Code compliance annotations
|
|
626
|
+
annotations: {
|
|
627
|
+
title: "System Information",
|
|
628
|
+
description: "Comprehensive system and server information including tool categories and resource usage",
|
|
629
|
+
readOnlyHint: true
|
|
362
630
|
}
|
|
363
631
|
}, async (args) => {
|
|
364
632
|
const { include_tools = false, category } = args;
|
|
365
633
|
// Discover tools dynamically
|
|
366
634
|
const { toolCategories, totalToolCount } = await discoverTools();
|
|
367
|
-
// Get system info
|
|
635
|
+
// Get comprehensive system info
|
|
636
|
+
const usage = getResourceUsage();
|
|
368
637
|
const systemInfo = {
|
|
369
638
|
timestamp: new Date().toISOString(),
|
|
370
639
|
platform: process.platform,
|
|
371
640
|
nodeVersion: process.version,
|
|
372
641
|
memoryUsage: process.memoryUsage(),
|
|
373
|
-
uptime: process.uptime()
|
|
642
|
+
uptime: process.uptime(),
|
|
643
|
+
resourceUsage: usage
|
|
374
644
|
};
|
|
375
645
|
// Server metadata from package.json
|
|
376
646
|
const serverMetadata = {
|
|
@@ -430,65 +700,189 @@ server.registerTool("server-info", {
|
|
|
430
700
|
}]
|
|
431
701
|
};
|
|
432
702
|
});
|
|
433
|
-
//
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
// Discover categories dynamically from the filesystem
|
|
441
|
-
const categories = fs.readdirSync(toolsBaseDir, { withFileTypes: true })
|
|
442
|
-
.filter(dirent => dirent.isDirectory())
|
|
443
|
-
.map(dirent => dirent.name)
|
|
444
|
-
.sort(); // Sort for consistent ordering
|
|
445
|
-
for (const category of categories) {
|
|
446
|
-
await loadModularTools(server, category);
|
|
703
|
+
// VS Code MCP Compliance: Implement Prompts
|
|
704
|
+
server.registerPrompt("it-tools-workflow", {
|
|
705
|
+
description: "Guided workflow for common IT tasks using available tools",
|
|
706
|
+
argsSchema: {
|
|
707
|
+
task_type: z.string().describe("Type of IT task to perform"),
|
|
708
|
+
context: z.string().optional().describe("Additional context about the task")
|
|
447
709
|
}
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
710
|
+
}, async (args) => {
|
|
711
|
+
const { task_type, context = "" } = args;
|
|
712
|
+
const workflows = {
|
|
713
|
+
security: `Security Workflow for IT Tools MCP:
|
|
714
|
+
1. Generate secure password: use generate_password tool
|
|
715
|
+
2. Hash password: use bcrypt_hash tool
|
|
716
|
+
3. Generate JWT token: use jwt_decode tool
|
|
717
|
+
4. Generate TOTP: use otp_code_generator tool
|
|
718
|
+
5. Create basic auth: use basic_auth_generator tool
|
|
719
|
+
${context ? `Context: ${context}` : ''}`,
|
|
720
|
+
encoding: `Encoding/Decoding Workflow:
|
|
721
|
+
1. Base64 encode: use base64_encode tool
|
|
722
|
+
2. URL encode: use url_encode tool
|
|
723
|
+
3. HTML encode: use html_encode tool
|
|
724
|
+
4. Convert text to binary: use text_to_binary tool
|
|
725
|
+
${context ? `Context: ${context}` : ''}`,
|
|
726
|
+
network: `Network Analysis Workflow:
|
|
727
|
+
1. Check connectivity: use ping tool
|
|
728
|
+
2. DNS lookup: use dig tool
|
|
729
|
+
3. Make HTTP request: use curl tool
|
|
730
|
+
4. Generate QR code: use qr_generate tool
|
|
731
|
+
${context ? `Context: ${context}` : ''}`,
|
|
732
|
+
development: `Development Workflow:
|
|
733
|
+
1. Format JSON: use json_format tool
|
|
734
|
+
2. Generate regex: use regex_tester tool
|
|
735
|
+
3. Create cron job: use crontab_generate tool
|
|
736
|
+
4. Prettify code: use javascript_prettifier tool
|
|
737
|
+
${context ? `Context: ${context}` : ''}`
|
|
738
|
+
};
|
|
739
|
+
const workflow = workflows[task_type] ||
|
|
740
|
+
`General IT Tools Workflow:
|
|
741
|
+
1. Use system_info to explore available tools
|
|
742
|
+
2. Select appropriate tools from 14+ categories
|
|
743
|
+
3. Execute tasks with proper input validation
|
|
744
|
+
${context ? `Context: ${context}` : ''}`;
|
|
452
745
|
return {
|
|
453
|
-
|
|
746
|
+
description: `Workflow guidance for ${task_type} tasks`,
|
|
747
|
+
messages: [
|
|
454
748
|
{
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
749
|
+
role: "user",
|
|
750
|
+
content: {
|
|
751
|
+
type: "text",
|
|
752
|
+
text: workflow
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
]
|
|
756
|
+
};
|
|
757
|
+
});
|
|
758
|
+
// Add a README resource for VS Code
|
|
759
|
+
server.registerResource("readme", new ResourceTemplate("readme://{section}", {
|
|
760
|
+
list: async () => ({
|
|
761
|
+
resources: [
|
|
762
|
+
{ name: "readme://full", description: "Complete README documentation", uri: "readme://full" },
|
|
763
|
+
{ name: "readme://installation", description: "Installation instructions", uri: "readme://installation" },
|
|
764
|
+
{ name: "readme://tools", description: "Available tools overview", uri: "readme://tools" },
|
|
765
|
+
{ name: "readme://examples", description: "Usage examples", uri: "readme://examples" }
|
|
766
|
+
]
|
|
767
|
+
})
|
|
768
|
+
}), {
|
|
769
|
+
title: "Documentation",
|
|
770
|
+
description: "Server documentation and usage guide",
|
|
771
|
+
mimeType: "text/markdown"
|
|
772
|
+
}, async (uri, params) => {
|
|
773
|
+
const section = params.section;
|
|
774
|
+
const readmeContent = await getReadmeContent(section);
|
|
775
|
+
return {
|
|
776
|
+
contents: [{
|
|
777
|
+
uri: uri.href,
|
|
778
|
+
text: readmeContent,
|
|
779
|
+
mimeType: "text/markdown"
|
|
780
|
+
}]
|
|
465
781
|
};
|
|
466
782
|
});
|
|
467
783
|
// Run the server
|
|
468
784
|
async function main() {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
//
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
785
|
+
try {
|
|
786
|
+
// VS Code MCP Compliance: Dev Mode Support
|
|
787
|
+
const isDevelopment = process.env.NODE_ENV === 'development' || process.env.MCP_DEV_MODE === 'true';
|
|
788
|
+
const isTest = process.env.NODE_ENV === 'test' && process.env.MCP_TEST_MODE === 'true';
|
|
789
|
+
if (isDevelopment) {
|
|
790
|
+
console.error("🔧 IT Tools MCP Server starting in DEVELOPMENT mode");
|
|
791
|
+
console.error(" - Enhanced logging enabled");
|
|
792
|
+
console.error(" - Hot reload capabilities active");
|
|
793
|
+
console.error(" - Debug information available");
|
|
794
|
+
}
|
|
795
|
+
await registerAllTools(server);
|
|
796
|
+
const transport = new StdioServerTransport();
|
|
797
|
+
await server.connect(transport);
|
|
798
|
+
// Log startup information based on environment
|
|
799
|
+
if (isTest) {
|
|
800
|
+
console.error("IT Tools MCP Server running on stdio");
|
|
801
|
+
// Exit after stdin closes (for test automation)
|
|
802
|
+
process.stdin.on('end', () => {
|
|
803
|
+
setTimeout(() => process.exit(0), 100);
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
else if (isDevelopment) {
|
|
807
|
+
console.error("🚀 IT Tools MCP Server connected successfully");
|
|
808
|
+
console.error(`📊 Loaded ${await getToolCount()} tools across ${await getCategoryCount()} categories`);
|
|
809
|
+
console.error(`🔗 Protocol: Model Context Protocol (MCP) via stdio`);
|
|
810
|
+
console.error(`📦 Version: ${packageInfo.version}`);
|
|
811
|
+
}
|
|
812
|
+
// Enhanced monitoring in development mode
|
|
813
|
+
if (isDevelopment && !isTest) {
|
|
814
|
+
// More frequent monitoring in dev mode (every minute)
|
|
815
|
+
setInterval(() => {
|
|
816
|
+
const usage = getResourceUsage();
|
|
817
|
+
if (usage.memory.heapUsedBytes > 200 * 1024 * 1024) {
|
|
818
|
+
console.error("⚠️ High memory usage detected:", usage.memory);
|
|
819
|
+
}
|
|
820
|
+
// Log periodic status in dev mode
|
|
821
|
+
console.error(`📈 Status: Memory ${usage.memory.heapUsed}, CPU ${usage.cpu.user}ms user, ${usage.cpu.system}ms system`);
|
|
822
|
+
}, 60 * 1000); // Every minute in dev mode
|
|
823
|
+
}
|
|
824
|
+
else if (!isTest) {
|
|
825
|
+
// Production monitoring (every 5 minutes)
|
|
826
|
+
setInterval(() => {
|
|
827
|
+
const usage = getResourceUsage();
|
|
828
|
+
if (usage.memory.heapUsedBytes > 200 * 1024 * 1024) {
|
|
829
|
+
console.error("High memory usage detected:", usage.memory);
|
|
830
|
+
}
|
|
831
|
+
}, 5 * 60 * 1000);
|
|
832
|
+
}
|
|
833
|
+
// Handle graceful shutdown
|
|
834
|
+
const shutdown = () => {
|
|
835
|
+
if (isDevelopment) {
|
|
836
|
+
console.error("🛑 Shutting down IT Tools MCP Server (Development Mode)...");
|
|
487
837
|
}
|
|
488
|
-
|
|
838
|
+
else {
|
|
839
|
+
console.error("Shutting down IT Tools MCP Server...");
|
|
840
|
+
}
|
|
841
|
+
process.exit(0);
|
|
842
|
+
};
|
|
843
|
+
process.on('SIGINT', shutdown);
|
|
844
|
+
process.on('SIGTERM', shutdown);
|
|
845
|
+
}
|
|
846
|
+
catch (error) {
|
|
847
|
+
console.error("Failed to start MCP server:", error);
|
|
848
|
+
process.exit(1);
|
|
489
849
|
}
|
|
490
850
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
851
|
+
// Helper functions for development mode
|
|
852
|
+
async function getToolCount() {
|
|
853
|
+
const { totalToolCount } = await discoverTools();
|
|
854
|
+
return totalToolCount;
|
|
855
|
+
}
|
|
856
|
+
async function getCategoryCount() {
|
|
857
|
+
const { toolCategories } = await discoverTools();
|
|
858
|
+
return Object.keys(toolCategories).length;
|
|
859
|
+
}
|
|
860
|
+
async function getReadmeContent(section) {
|
|
861
|
+
const readmePath = path.resolve(__dirname, '../README.md');
|
|
862
|
+
try {
|
|
863
|
+
const fullReadme = fs.readFileSync(readmePath, 'utf-8');
|
|
864
|
+
const sections = {
|
|
865
|
+
full: fullReadme,
|
|
866
|
+
installation: extractReadmeSection(fullReadme, '## 📦 Installation & Setup'),
|
|
867
|
+
tools: extractReadmeSection(fullReadme, '## Available Tools'),
|
|
868
|
+
examples: extractReadmeSection(fullReadme, '## 📸 Screenshot Examples')
|
|
869
|
+
};
|
|
870
|
+
return sections[section] || `# ${section}\n\nSection not found in README.`;
|
|
871
|
+
}
|
|
872
|
+
catch (error) {
|
|
873
|
+
return `# Error\n\nCould not read README.md: ${error}`;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
function extractReadmeSection(content, heading) {
|
|
877
|
+
const lines = content.split('\n');
|
|
878
|
+
const startIndex = lines.findIndex(line => line.startsWith(heading));
|
|
879
|
+
if (startIndex === -1) {
|
|
880
|
+
return `# Section Not Found\n\nThe section "${heading}" was not found in the README.`;
|
|
881
|
+
}
|
|
882
|
+
const endIndex = lines.findIndex((line, index) => index > startIndex && line.startsWith('## ') && !line.startsWith(heading));
|
|
883
|
+
const sectionLines = endIndex === -1
|
|
884
|
+
? lines.slice(startIndex)
|
|
885
|
+
: lines.slice(startIndex, endIndex);
|
|
886
|
+
return sectionLines.join('\n');
|
|
887
|
+
}
|
|
888
|
+
// ...existing code...
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { pbkdf2Sync } from "crypto";
|
|
3
|
-
export function
|
|
4
|
-
server.
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
export function registerDecryptAnsibleVault(server) {
|
|
4
|
+
server.registerTool("decrypt_ansible_vault", {
|
|
5
|
+
description: "Decrypt Ansible Vault encrypted text",
|
|
6
|
+
inputSchema: {
|
|
7
|
+
encryptedText: z.string().describe("Ansible Vault encrypted text to decrypt"),
|
|
8
|
+
password: z.string().describe("Password for decryption"),
|
|
9
|
+
},
|
|
10
|
+
// VS Code compliance annotations
|
|
11
|
+
annotations: {
|
|
12
|
+
title: "Decrypt Ansible Vault",
|
|
13
|
+
description: "Decrypt Ansible Vault encrypted text",
|
|
14
|
+
readOnlyHint: false
|
|
15
|
+
}
|
|
7
16
|
}, async ({ encryptedText, password }) => {
|
|
8
17
|
if (!encryptedText?.trim()) {
|
|
9
18
|
return {
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { pbkdf2Sync, randomBytes } from "crypto";
|
|
3
|
-
export function
|
|
4
|
-
server.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
export function registerEncryptAnsibleVault(server) {
|
|
4
|
+
server.registerTool("encrypt_ansible_vault", {
|
|
5
|
+
description: "Encrypt text using Ansible Vault format",
|
|
6
|
+
inputSchema: {
|
|
7
|
+
text: z.string().describe("Text to encrypt"),
|
|
8
|
+
password: z.string().describe("Password for encryption"),
|
|
9
|
+
vaultId: z.string().optional().describe("Vault ID for the encrypted content (optional)"),
|
|
10
|
+
},
|
|
11
|
+
// VS Code compliance annotations
|
|
12
|
+
annotations: {
|
|
13
|
+
title: "Encrypt Ansible Vault",
|
|
14
|
+
description: "Encrypt text using Ansible Vault format",
|
|
15
|
+
readOnlyHint: false
|
|
16
|
+
}
|
|
8
17
|
}, async ({ text, password, vaultId }) => {
|
|
9
18
|
if (!text?.trim()) {
|
|
10
19
|
return {
|