it-tools-mcp 3.2.10 → 3.2.12
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 +2 -2
- package/README.md +14 -7
- package/build/index.js +190 -13
- package/package.json +1 -1
package/README.dockerhub.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
[](https://hub.docker.com/r/wrenchpilot/it-tools-mcp)
|
|
12
12
|
[](https://github.com/wrenchpilot/it-tools-mcp/stargazers)
|
|
13
13
|
|
|
14
|
-
A comprehensive Model Context Protocol (MCP) server that provides access to **
|
|
14
|
+
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.
|
|
15
15
|
|
|
16
16
|
## Using with VS Code
|
|
17
17
|
|
|
@@ -62,7 +62,7 @@ Add to your VS Code `settings.json`:
|
|
|
62
62
|
}
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
See the complete list of
|
|
65
|
+
See the complete list of tools with detailed parameters on [GitHub](https://github.com/wrenchpilot/it-tools-mcp#available-tools)
|
|
66
66
|
|
|
67
67
|
## 📸 Examples in Action
|
|
68
68
|
|
package/README.md
CHANGED
|
@@ -14,17 +14,24 @@
|
|
|
14
14
|
|
|
15
15
|
> **📝 Note**: A condensed version of this README is automatically synced to [Docker Hub](https://hub.docker.com/r/wrenchpilot/it-tools-mcp) due to character limits.
|
|
16
16
|
|
|
17
|
-
A comprehensive Model Context Protocol (MCP) server that provides access to
|
|
17
|
+
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.
|
|
18
18
|
|
|
19
19
|
## 📦 Installation & Setup
|
|
20
20
|
|
|
21
21
|
### Using with VS Code
|
|
22
22
|
|
|
23
|
-
**
|
|
23
|
+
**Quick Install:**
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
[](https://insiders.vscode.dev/redirect/mcp/install?name=it-tools&config=%7B%22command%22%3A%20%22npx%22%2C%22args%22%3A%20%5B%22it-tools-mcp%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=it-tools&config=%7B%22command%22%3A%20%22npx%22%2C%22args%22%3A%20%5B%22it-tools-mcp%22%5D%7D&quality=insiders)
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
**Install:**
|
|
28
|
+
|
|
29
|
+
1. Open VS Code
|
|
30
|
+
2. Press `Ctrl+Shift+P` (or `Cmd+Shift+P` on Mac)
|
|
31
|
+
3. Type "MCP" and select "MCP: Add Server"
|
|
32
|
+
4. Choose "NPM Package" and enter: `it-tools-mcp`
|
|
33
|
+
|
|
34
|
+
**Or manually add to your VS Code `settings.json`:**
|
|
28
35
|
|
|
29
36
|
#### Node
|
|
30
37
|
|
|
@@ -89,7 +96,7 @@ echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"base64-enc
|
|
|
89
96
|
|
|
90
97
|
## 🛠️ Tool Categories
|
|
91
98
|
|
|
92
|
-
This MCP server provides **
|
|
99
|
+
This MCP server provides over **100 tools** across **14 categories**:
|
|
93
100
|
|
|
94
101
|
- **� Ansible Tools** (5 tools): Vault encryption/decryption, inventory parser, playbook validator, reference
|
|
95
102
|
- **🎨 Color Tools** (2 tools): Hex ↔ RGB conversion
|
|
@@ -258,14 +265,14 @@ Built with **TypeScript**, **Zod** validation, and **MCP SDK** for robust, type-
|
|
|
258
265
|
This project was developed using **VS Code**, **Copilot Chat Agent**, **Playwright MCP**, and the **Claude Sonnet 4 Model**, demonstrating the power of AI-assisted software development:
|
|
259
266
|
|
|
260
267
|
- **Intelligent Code Generation**: Claude Sonnet analyzed requirements and generated comprehensive tool implementations
|
|
261
|
-
- **Schema Validation**: Automatically identified and resolved JSON schema validation issues across
|
|
268
|
+
- **Schema Validation**: Automatically identified and resolved JSON schema validation issues across tools
|
|
262
269
|
- **Docker Optimization**: Created production-ready Docker workflows and multi-stage builds
|
|
263
270
|
- **Documentation**: Generated comprehensive README with examples and tool reference tables
|
|
264
271
|
- **Testing**: Implemented robust error handling and validation throughout the codebase
|
|
265
272
|
|
|
266
273
|
**Key AI Contributions:**
|
|
267
274
|
|
|
268
|
-
- 🔧 **Tool Implementation**: All
|
|
275
|
+
- 🔧 **Tool Implementation**: All tools designed and implemented with AI assistance
|
|
269
276
|
- 📦 **Docker Setup**: Complete containerization with GitHub Actions CI/CD pipeline
|
|
270
277
|
- 🔍 **Schema Cleanup**: Systematic removal of unsupported Zod keywords from all tool definitions
|
|
271
278
|
- 📚 **Documentation**: Comprehensive README with usage examples and tool catalogs
|
package/build/index.js
CHANGED
|
@@ -208,17 +208,27 @@ export const SECURITY_HEADERS = {
|
|
|
208
208
|
'Referrer-Policy': 'strict-origin-when-cross-origin',
|
|
209
209
|
};
|
|
210
210
|
// Helper to read version from package.json at runtime (ESM compatible)
|
|
211
|
-
|
|
212
|
-
|
|
211
|
+
// Get package metadata for enhanced server info
|
|
212
|
+
function getPackageMetadata() {
|
|
213
213
|
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
214
214
|
const pkgPath = path.resolve(__dirname, '../package.json');
|
|
215
215
|
const pkgRaw = fs.readFileSync(pkgPath, 'utf-8');
|
|
216
|
-
|
|
216
|
+
const pkg = JSON.parse(pkgRaw);
|
|
217
|
+
return {
|
|
218
|
+
name: pkg.name,
|
|
219
|
+
version: pkg.version,
|
|
220
|
+
description: pkg.description,
|
|
221
|
+
keywords: pkg.keywords,
|
|
222
|
+
author: pkg.author,
|
|
223
|
+
repository: pkg.repository,
|
|
224
|
+
homepage: pkg.homepage
|
|
225
|
+
};
|
|
217
226
|
}
|
|
218
|
-
// Create server instance
|
|
227
|
+
// Create server instance with enhanced metadata
|
|
228
|
+
const packageInfo = getPackageMetadata();
|
|
219
229
|
const server = new McpServer({
|
|
220
230
|
name: "it-tools-mcp",
|
|
221
|
-
version:
|
|
231
|
+
version: packageInfo.version,
|
|
222
232
|
capabilities: {
|
|
223
233
|
resources: {},
|
|
224
234
|
tools: {},
|
|
@@ -257,14 +267,181 @@ async function loadModularTools(server, category) {
|
|
|
257
267
|
}
|
|
258
268
|
}
|
|
259
269
|
}
|
|
260
|
-
//
|
|
270
|
+
// Dynamic tool discovery and metadata generation
|
|
271
|
+
async function discoverTools() {
|
|
272
|
+
const toolsBaseDir = path.join(__dirname, 'tools');
|
|
273
|
+
if (!fs.existsSync(toolsBaseDir)) {
|
|
274
|
+
return { toolCategories: {}, totalToolCount: 0 };
|
|
275
|
+
}
|
|
276
|
+
// Discover categories dynamically from the filesystem
|
|
277
|
+
const categories = fs.readdirSync(toolsBaseDir, { withFileTypes: true })
|
|
278
|
+
.filter(dirent => dirent.isDirectory())
|
|
279
|
+
.map(dirent => dirent.name)
|
|
280
|
+
.sort(); // Sort for consistent ordering
|
|
281
|
+
const toolCategories = {};
|
|
282
|
+
let totalToolCount = 0;
|
|
283
|
+
for (const category of categories) {
|
|
284
|
+
const toolsDir = path.join(toolsBaseDir, category);
|
|
285
|
+
const toolDirs = fs.readdirSync(toolsDir, { withFileTypes: true })
|
|
286
|
+
.filter(dirent => dirent.isDirectory())
|
|
287
|
+
.map(dirent => dirent.name)
|
|
288
|
+
.sort(); // Sort tools within category
|
|
289
|
+
if (toolDirs.length > 0) {
|
|
290
|
+
toolCategories[category] = {
|
|
291
|
+
description: await getCategoryDescription(category, toolDirs),
|
|
292
|
+
tools: toolDirs
|
|
293
|
+
};
|
|
294
|
+
totalToolCount += toolDirs.length;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return { toolCategories, totalToolCount };
|
|
298
|
+
}
|
|
299
|
+
// Generate category description by examining actual tool metadata
|
|
300
|
+
async function getCategoryDescription(category, toolNames) {
|
|
301
|
+
const toolsDir = path.join(__dirname, 'tools', category);
|
|
302
|
+
const toolDescriptions = [];
|
|
303
|
+
// Try to extract descriptions from a few sample tools in the category
|
|
304
|
+
const samplesToCheck = Math.min(3, toolNames.length); // Check up to 3 tools for description
|
|
305
|
+
for (let i = 0; i < samplesToCheck; i++) {
|
|
306
|
+
const toolDir = toolNames[i];
|
|
307
|
+
const toolPath = path.join(toolsDir, toolDir, 'index.js');
|
|
308
|
+
if (fs.existsSync(toolPath)) {
|
|
309
|
+
try {
|
|
310
|
+
const toolModule = await import(`./${path.relative(__dirname, toolPath).replace(/\\/g, '/')}`);
|
|
311
|
+
// Look for description in the tool registration
|
|
312
|
+
const registerFunction = Object.values(toolModule).find((fn) => typeof fn === 'function' && fn.name.startsWith('register'));
|
|
313
|
+
if (registerFunction) {
|
|
314
|
+
// Create a mock server to capture the tool registration
|
|
315
|
+
const mockServer = {
|
|
316
|
+
registerTool: (name, config) => {
|
|
317
|
+
if (config.description && typeof config.description === 'string') {
|
|
318
|
+
toolDescriptions.push(config.description);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
try {
|
|
323
|
+
registerFunction(mockServer);
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
// Ignore errors in mock registration
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
// Continue if we can't load a tool
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// Generate category description based on collected tool descriptions
|
|
336
|
+
if (toolDescriptions.length > 0) {
|
|
337
|
+
// Create a summary from the actual tool descriptions
|
|
338
|
+
const uniqueDescriptions = [...new Set(toolDescriptions)];
|
|
339
|
+
if (uniqueDescriptions.length === 1) {
|
|
340
|
+
// If all tools have the same description, use it directly
|
|
341
|
+
return uniqueDescriptions[0];
|
|
342
|
+
}
|
|
343
|
+
else if (uniqueDescriptions.length <= 3) {
|
|
344
|
+
// If we have 2-3 unique descriptions, combine them
|
|
345
|
+
return `${category.charAt(0).toUpperCase() + category.slice(1)} tools: ${uniqueDescriptions.join(', ')}`;
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
// If we have many descriptions, provide a generic summary
|
|
349
|
+
return `${category.charAt(0).toUpperCase() + category.slice(1)} category with ${toolNames.length} tools including: ${uniqueDescriptions.slice(0, 2).join(', ')} and more`;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
// Fallback: generate description from category name and tool count
|
|
353
|
+
const categoryTitle = category.charAt(0).toUpperCase() + category.slice(1);
|
|
354
|
+
return `${categoryTitle} tools and utilities (${toolNames.length} tools available)`;
|
|
355
|
+
}
|
|
356
|
+
// Register server info tool with dynamic metadata
|
|
357
|
+
server.registerTool("server-info", {
|
|
358
|
+
description: "Get comprehensive information about the IT Tools MCP server, including available tool categories, version, and capabilities",
|
|
359
|
+
inputSchema: {
|
|
360
|
+
include_tools: z.boolean().optional().describe("Include detailed information about all available tools"),
|
|
361
|
+
category: z.string().optional().describe("Get information about a specific category (dynamically discovered)")
|
|
362
|
+
}
|
|
363
|
+
}, async (args) => {
|
|
364
|
+
const { include_tools = false, category } = args;
|
|
365
|
+
// Discover tools dynamically
|
|
366
|
+
const { toolCategories, totalToolCount } = await discoverTools();
|
|
367
|
+
// Get system info
|
|
368
|
+
const systemInfo = {
|
|
369
|
+
timestamp: new Date().toISOString(),
|
|
370
|
+
platform: process.platform,
|
|
371
|
+
nodeVersion: process.version,
|
|
372
|
+
memoryUsage: process.memoryUsage(),
|
|
373
|
+
uptime: process.uptime()
|
|
374
|
+
};
|
|
375
|
+
// Server metadata from package.json
|
|
376
|
+
const serverMetadata = {
|
|
377
|
+
name: "IT Tools MCP Server",
|
|
378
|
+
version: packageInfo.version,
|
|
379
|
+
description: packageInfo.description,
|
|
380
|
+
author: packageInfo.author,
|
|
381
|
+
repository: packageInfo.repository?.url,
|
|
382
|
+
homepage: packageInfo.homepage,
|
|
383
|
+
keywords: packageInfo.keywords,
|
|
384
|
+
protocol: "Model Context Protocol (MCP)",
|
|
385
|
+
transport: "stdio"
|
|
386
|
+
};
|
|
387
|
+
const baseResult = {
|
|
388
|
+
server: serverMetadata,
|
|
389
|
+
system: systemInfo,
|
|
390
|
+
categories: Object.keys(toolCategories).length,
|
|
391
|
+
totalTools: totalToolCount,
|
|
392
|
+
installation: {
|
|
393
|
+
vscode: "Use VS Code install button in README or manual configuration",
|
|
394
|
+
claude: "Add to claude_desktop_config.json",
|
|
395
|
+
npm: `npm install -g ${packageInfo.name}`
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
let result = baseResult;
|
|
399
|
+
// Add category-specific information
|
|
400
|
+
if (category && toolCategories[category]) {
|
|
401
|
+
result = {
|
|
402
|
+
...result,
|
|
403
|
+
categoryDetails: {
|
|
404
|
+
name: category,
|
|
405
|
+
...toolCategories[category]
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
else if (!category) {
|
|
410
|
+
result = {
|
|
411
|
+
...result,
|
|
412
|
+
availableCategories: toolCategories
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
// Include detailed tool information if requested
|
|
416
|
+
if (include_tools) {
|
|
417
|
+
result = {
|
|
418
|
+
...result,
|
|
419
|
+
toolsBreakdown: Object.entries(toolCategories).map(([cat, info]) => ({
|
|
420
|
+
category: cat,
|
|
421
|
+
count: info.tools.length,
|
|
422
|
+
tools: info.tools
|
|
423
|
+
}))
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
return {
|
|
427
|
+
content: [{
|
|
428
|
+
type: "text",
|
|
429
|
+
text: JSON.stringify(result, null, 2)
|
|
430
|
+
}]
|
|
431
|
+
};
|
|
432
|
+
});
|
|
433
|
+
// Register all tools dynamically by discovering categories from filesystem
|
|
261
434
|
async function registerAllTools(server) {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
'
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
435
|
+
const toolsBaseDir = path.join(__dirname, 'tools');
|
|
436
|
+
if (!fs.existsSync(toolsBaseDir)) {
|
|
437
|
+
console.warn('Tools directory does not exist:', toolsBaseDir);
|
|
438
|
+
return;
|
|
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
|
|
268
445
|
for (const category of categories) {
|
|
269
446
|
await loadModularTools(server, category);
|
|
270
447
|
}
|
|
@@ -278,7 +455,7 @@ server.tool("system-info", "Get system resource usage and server information", {
|
|
|
278
455
|
type: "text",
|
|
279
456
|
text: JSON.stringify({
|
|
280
457
|
server: "IT Tools MCP Server",
|
|
281
|
-
version:
|
|
458
|
+
version: packageInfo.version,
|
|
282
459
|
uptime: `${Math.floor(usage.uptimeSeconds)} seconds`,
|
|
283
460
|
memory: usage.memory,
|
|
284
461
|
timestamp: new Date().toISOString(),
|