it-tools-mcp 4.1.14 → 5.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.
Files changed (2) hide show
  1. package/build/index.js +164 -302
  2. package/package.json +4 -2
package/build/index.js CHANGED
@@ -252,14 +252,21 @@ const server = new McpServer({
252
252
  license: packageInfo.license,
253
253
  }, {
254
254
  capabilities: {
255
- tools: {},
256
- resources: {},
257
- prompts: {},
255
+ tools: {
256
+ listChanged: true
257
+ },
258
+ resources: {
259
+ listChanged: true
260
+ },
261
+ prompts: {
262
+ listChanged: true
263
+ },
258
264
  sampling: {},
259
265
  roots: {
260
266
  listChanged: true
261
267
  },
262
- logging: {}
268
+ logging: {},
269
+ completions: {}
263
270
  }
264
271
  });
265
272
  // MCP Logging Functions
@@ -468,250 +475,6 @@ export function mcpToolHandler(handler, identifier = 'default') {
468
475
  }
469
476
  };
470
477
  }
471
- // Demo tools for MCP utilities
472
- server.registerTool("mcp_utilities_demo", {
473
- description: "Demonstrate MCP utilities: ping, progress tracking, and cancellation support",
474
- inputSchema: {
475
- operation: z.enum(['ping', 'long_task', 'cancellable_task']).describe("The MCP utility operation to demonstrate"),
476
- duration: z.number().optional().describe("Duration in seconds for long-running tasks (default: 10)"),
477
- steps: z.number().optional().describe("Number of progress steps for demonstrating progress tracking (default: 5)")
478
- }
479
- }, async (args) => {
480
- const { operation, duration = 10, steps = 5 } = args;
481
- if (operation === 'ping') {
482
- return {
483
- content: [{
484
- type: "text",
485
- text: JSON.stringify({
486
- operation: 'ping',
487
- status: 'success',
488
- message: 'MCP ping utility is working correctly',
489
- timestamp: new Date().toISOString(),
490
- usage: 'Send a "ping" request to test connection health'
491
- }, null, 2)
492
- }]
493
- };
494
- }
495
- if (operation === 'long_task') {
496
- // Simulate a long-running task with progress updates
497
- const totalMs = duration * 1000;
498
- const stepMs = totalMs / steps;
499
- return {
500
- content: [{
501
- type: "text",
502
- text: JSON.stringify({
503
- operation: 'long_task',
504
- status: 'completed',
505
- message: `Simulated ${duration}s task with ${steps} progress updates`,
506
- note: 'Use _meta.progressToken in your request to receive progress notifications',
507
- example: {
508
- request: {
509
- jsonrpc: "2.0",
510
- id: 1,
511
- method: "tools/call",
512
- params: {
513
- name: "mcp_utilities_demo",
514
- arguments: { operation: "long_task", duration: 5, steps: 3 },
515
- _meta: { progressToken: "demo123" }
516
- }
517
- }
518
- }
519
- }, null, 2)
520
- }]
521
- };
522
- }
523
- if (operation === 'cancellable_task') {
524
- return {
525
- content: [{
526
- type: "text",
527
- text: JSON.stringify({
528
- operation: 'cancellable_task',
529
- status: 'completed',
530
- message: 'Simulated cancellable task',
531
- note: 'Send a notifications/cancelled message to cancel in-progress requests',
532
- example: {
533
- cancel_notification: {
534
- jsonrpc: "2.0",
535
- method: "notifications/cancelled",
536
- params: {
537
- requestId: "your_request_id",
538
- reason: "User requested cancellation"
539
- }
540
- }
541
- }
542
- }, null, 2)
543
- }]
544
- };
545
- }
546
- return {
547
- content: [{
548
- type: "text",
549
- text: JSON.stringify({ error: 'Unknown operation' }, null, 2)
550
- }]
551
- };
552
- });
553
- // Sampling demo tool
554
- server.registerTool("mcp_sampling_demo", {
555
- description: "Demonstrate MCP sampling capabilities and test sampling/createMessage requests",
556
- inputSchema: {
557
- message: z.string().describe("The message to send in the sampling request"),
558
- modelPreference: z.enum(['claude', 'gpt', 'gemini', 'generic']).optional().describe("Preferred model family for demonstration"),
559
- systemPrompt: z.string().optional().describe("System prompt to include in the sampling request"),
560
- maxTokens: z.number().positive().optional().describe("Maximum tokens for the response (default: 100)"),
561
- intelligence: z.number().min(0).max(1).optional().describe("Intelligence priority (0-1, higher = more capable models)"),
562
- speed: z.number().min(0).max(1).optional().describe("Speed priority (0-1, higher = faster models)"),
563
- cost: z.number().min(0).max(1).optional().describe("Cost priority (0-1, higher = cheaper models)")
564
- }
565
- }, async (args) => {
566
- const { message, modelPreference, systemPrompt, maxTokens = 100, intelligence = 0.7, speed = 0.5, cost = 0.3 } = args;
567
- // Build model preferences based on user input
568
- const modelPreferences = {
569
- intelligencePriority: intelligence,
570
- speedPriority: speed,
571
- costPriority: cost
572
- };
573
- // Add model hints based on preference
574
- if (modelPreference) {
575
- const hintMap = {
576
- 'claude': [{ name: 'claude-4-sonnet' }, { name: 'claude' }],
577
- 'gpt': [{ name: 'gpt-4' }, { name: 'gpt' }],
578
- 'gemini': [{ name: 'gemini-1.5-pro' }, { name: 'gemini' }],
579
- 'generic': [{ name: 'general-purpose' }]
580
- };
581
- modelPreferences.hints = hintMap[modelPreference];
582
- }
583
- // Create the sampling request
584
- const samplingRequest = {
585
- method: "sampling/createMessage",
586
- params: {
587
- messages: [
588
- {
589
- role: "user",
590
- content: {
591
- type: "text",
592
- text: message
593
- }
594
- }
595
- ],
596
- modelPreferences,
597
- ...(systemPrompt && { systemPrompt }),
598
- maxTokens
599
- }
600
- };
601
- return {
602
- content: [{
603
- type: "text",
604
- text: JSON.stringify({
605
- demo: 'MCP Sampling Protocol Demonstration',
606
- status: 'request_prepared',
607
- message: 'Here is the sampling request that would be sent to the MCP client',
608
- request: samplingRequest,
609
- explanation: {
610
- protocol: 'MCP 2025-06-18 sampling/createMessage',
611
- purpose: 'This demonstrates how servers can request LLM completions from clients',
612
- modelSelection: modelPreferences.hints ?
613
- `Prefers ${modelPreference} models with intelligence=${intelligence}, speed=${speed}, cost=${cost}` :
614
- `No specific model preference, using priorities: intelligence=${intelligence}, speed=${speed}, cost=${cost}`,
615
- flow: [
616
- '1. Server sends sampling/createMessage request to client',
617
- '2. Client selects appropriate model based on preferences',
618
- '3. Client processes the message through the selected LLM',
619
- '4. Client returns the LLM response to the server',
620
- '5. Server can use the response for its tool operations'
621
- ],
622
- security: 'Clients SHOULD implement user approval controls for sampling requests'
623
- },
624
- nextSteps: 'In production, this request would be sent to the MCP client for actual LLM processing'
625
- }, null, 2)
626
- }]
627
- };
628
- });
629
- // MCP Sampling Implementation - Server-side LLM request handling
630
- server.server.setRequestHandler(z.object({
631
- method: z.literal("sampling/createMessage"),
632
- params: z.object({
633
- messages: z.array(z.object({
634
- role: z.enum(["user", "assistant", "system"]),
635
- content: z.union([
636
- z.object({
637
- type: z.literal("text"),
638
- text: z.string()
639
- }),
640
- z.object({
641
- type: z.literal("image"),
642
- data: z.string(),
643
- mimeType: z.string()
644
- }),
645
- z.object({
646
- type: z.literal("audio"),
647
- data: z.string(),
648
- mimeType: z.string()
649
- })
650
- ])
651
- })),
652
- modelPreferences: z.object({
653
- hints: z.array(z.object({
654
- name: z.string()
655
- })).optional(),
656
- costPriority: z.number().min(0).max(1).optional(),
657
- speedPriority: z.number().min(0).max(1).optional(),
658
- intelligencePriority: z.number().min(0).max(1).optional()
659
- }).optional(),
660
- systemPrompt: z.string().optional(),
661
- maxTokens: z.number().positive().optional(),
662
- temperature: z.number().min(0).max(2).optional(),
663
- stopSequences: z.array(z.string()).optional(),
664
- metadata: z.record(z.any()).optional()
665
- })
666
- }), async (request) => {
667
- const { messages, modelPreferences, systemPrompt, maxTokens, temperature, stopSequences, metadata } = request.params;
668
- mcpLog('info', 'Sampling request received', {
669
- messageCount: messages.length,
670
- modelPreferences: modelPreferences ? Object.keys(modelPreferences) : undefined,
671
- hasSystemPrompt: !!systemPrompt,
672
- maxTokens
673
- });
674
- // In a real implementation, this would:
675
- // 1. Forward the request to the client's LLM service
676
- // 2. Apply model preferences and selection logic
677
- // 3. Handle different content types (text, image, audio)
678
- // 4. Return the LLM response
679
- // For this MCP server implementation, we return a helpful response
680
- // explaining that this is a demonstration of the sampling protocol
681
- // and that the actual LLM processing would be handled by the client
682
- const demoResponse = {
683
- role: "assistant",
684
- content: {
685
- type: "text",
686
- text: `This is a demonstration of MCP sampling protocol support.
687
-
688
- In a production environment, this request would be forwarded to an LLM service based on your model preferences:
689
- ${modelPreferences?.hints?.length ? `- Preferred models: ${modelPreferences.hints.map(h => h.name).join(', ')}` : '- No specific model preferences'}
690
- ${modelPreferences?.intelligencePriority ? `- Intelligence priority: ${modelPreferences.intelligencePriority}` : ''}
691
- ${modelPreferences?.speedPriority ? `- Speed priority: ${modelPreferences.speedPriority}` : ''}
692
- ${modelPreferences?.costPriority ? `- Cost priority: ${modelPreferences.costPriority}` : ''}
693
-
694
- Your message: "${messages[messages.length - 1]?.content?.type === 'text' ? messages[messages.length - 1].content.text : 'Non-text content'}"
695
-
696
- ${systemPrompt ? `System prompt: "${systemPrompt}"` : 'No system prompt provided'}
697
- ${maxTokens ? `Max tokens: ${maxTokens}` : 'No token limit specified'}
698
-
699
- This server supports the full MCP 2025-06-18 sampling specification and is ready for production use with proper LLM integration.`
700
- },
701
- model: "mcp-demo-server",
702
- stopReason: "endTurn",
703
- usage: {
704
- inputTokens: messages.reduce((sum, msg) => sum + (msg.content.type === 'text' ? msg.content.text.length / 4 : 100), 0),
705
- outputTokens: 150
706
- }
707
- };
708
- mcpLog('debug', 'Sampling response generated', {
709
- model: demoResponse.model,
710
- stopReason: demoResponse.stopReason,
711
- outputTokens: demoResponse.usage.outputTokens
712
- });
713
- return demoResponse;
714
- });
715
478
  // VS Code MCP Compliance: Implement Resources
716
479
  server.registerResource("server-manifest", new ResourceTemplate("manifest://{type}", {
717
480
  list: async () => ({
@@ -759,7 +522,7 @@ server.registerResource("system-logs", new ResourceTemplate("logs://{type}", {
759
522
  }]
760
523
  };
761
524
  });
762
- server.registerResource("tool-documentation", new ResourceTemplate("docs://{category}/{tool?}", {
525
+ server.registerResource("tool-documentation", new ResourceTemplate("docs://{category}", {
763
526
  list: async () => {
764
527
  const { toolCategories } = await discoverTools();
765
528
  const resources = Object.keys(toolCategories).map(category => ({
@@ -780,8 +543,8 @@ server.registerResource("tool-documentation", new ResourceTemplate("docs://{cate
780
543
  description: "Documentation for available tools by category"
781
544
  }, async (uri, params) => {
782
545
  const category = params.category;
783
- const tool = params.tool;
784
- const docs = await getToolDocumentation(category, tool);
546
+ // For this simpler template, we only handle category-level documentation
547
+ const docs = await getToolDocumentation(category);
785
548
  return {
786
549
  contents: [{
787
550
  uri: uri.href,
@@ -917,16 +680,125 @@ async function getManifestContent(type) {
917
680
  };
918
681
  return manifests[type] || { error: "Manifest type not found" };
919
682
  }
683
+ // Helper function to extract tool documentation from the main README table
684
+ function extractToolFromReadme(readmeContent, toolName) {
685
+ // Look for the tool in the Available Tools table
686
+ const lines = readmeContent.split('\n');
687
+ const toolRegex = new RegExp(`\\|\s*\`${toolName}\`\\s*\\|`, 'i');
688
+ for (let i = 0; i < lines.length; i++) {
689
+ const line = lines[i];
690
+ if (toolRegex.test(line)) {
691
+ // Found the tool, extract the row
692
+ const parts = line.split('|').map(part => part.trim()).filter(part => part.length > 0);
693
+ if (parts.length >= 2) {
694
+ const cleanToolName = parts[0].replace(/`/g, ''); // Remove backticks from tool name
695
+ const descCell = parts[1]; // Description cell
696
+ const paramsCell = parts.length > 2 ? parts[2] : ''; // Parameters cell
697
+ return `# ${cleanToolName} Documentation\n\n**Description:** ${descCell}\n\n${paramsCell ? `**Parameters:** ${paramsCell}\n\n` : ''}**Usage:** ${descCell}`;
698
+ }
699
+ }
700
+ }
701
+ return null;
702
+ }
703
+ // Helper function to extract category section from the main README
704
+ function extractCategoryFromReadme(readmeContent, category) {
705
+ // Map category names to README section names
706
+ const categoryMappings = {
707
+ 'ansible': 'Ansible Tools',
708
+ 'color': 'Color Tools',
709
+ 'data_format': 'Data Format',
710
+ 'development': 'Development Tools',
711
+ 'docker': 'Docker Tools',
712
+ 'encoding': 'Encoding & Decoding',
713
+ 'forensic': 'Forensic Tools',
714
+ 'id_generators': 'ID & Code Generators',
715
+ 'math': 'Math & Calculations',
716
+ 'network': 'Network & System',
717
+ 'physics': 'Physics',
718
+ 'crypto': 'Security & Crypto',
719
+ 'text': 'Text Processing',
720
+ 'utility': 'Utility Tools'
721
+ };
722
+ const sectionName = categoryMappings[category];
723
+ if (!sectionName) {
724
+ return null;
725
+ }
726
+ // Find the section in the README table
727
+ const lines = readmeContent.split('\n');
728
+ let inTargetSection = false;
729
+ let tableRows = [];
730
+ for (let i = 0; i < lines.length; i++) {
731
+ const line = lines[i];
732
+ // Check if we're entering the target section
733
+ if (line.includes(`**${sectionName}**`)) {
734
+ inTargetSection = true;
735
+ continue;
736
+ }
737
+ // Check if we're entering a new section (exit current)
738
+ if (inTargetSection && line.includes('**') && line.includes('**') && !line.includes(sectionName)) {
739
+ break;
740
+ }
741
+ // Collect table rows while in target section
742
+ if (inTargetSection && line.includes('|') && !line.includes('---')) {
743
+ tableRows.push(line);
744
+ }
745
+ }
746
+ if (tableRows.length === 0) {
747
+ return null;
748
+ }
749
+ // Parse and clean up the table
750
+ const cleanedContent = [`# ${sectionName} Documentation\n`];
751
+ for (const row of tableRows) {
752
+ const cells = row.split('|').map(cell => cell.trim()).filter(cell => cell.length > 0);
753
+ if (cells.length >= 2) {
754
+ const toolName = cells[0].replace(/`/g, ''); // Remove backticks
755
+ const description = cells[1];
756
+ const parameters = cells.length > 2 ? cells[2] : '';
757
+ cleanedContent.push(`## ${toolName}`);
758
+ cleanedContent.push(`**Description:** ${description}`);
759
+ if (parameters) {
760
+ cleanedContent.push(`**Parameters:** ${parameters}`);
761
+ }
762
+ cleanedContent.push(''); // Add empty line for spacing
763
+ }
764
+ }
765
+ return cleanedContent.join('\n');
766
+ }
920
767
  async function getToolDocumentation(category, tool) {
768
+ // When compiled, __dirname will be the build/ directory, so we need to go up one level
769
+ const readmePath = path.join(__dirname, '../README.md');
921
770
  if (tool) {
771
+ // For specific tools, try to find them in the README table
772
+ try {
773
+ const readmeContent = fs.readFileSync(readmePath, 'utf-8');
774
+ const toolSection = extractToolFromReadme(readmeContent, tool);
775
+ if (toolSection) {
776
+ return toolSection;
777
+ }
778
+ }
779
+ catch (error) {
780
+ mcpLog('warning', `Failed to read README for tool documentation: ${readmePath}`, error instanceof Error ? error.message : 'Unknown error');
781
+ }
922
782
  return `# ${tool} Documentation\n\nCategory: ${category}\n\nThis tool provides ${category} functionality.\n\nUsage: See tool description for specific parameters and examples.`;
923
783
  }
784
+ // Try to read category documentation from README
785
+ try {
786
+ const readmeContent = fs.readFileSync(readmePath, 'utf-8');
787
+ const categorySection = extractCategoryFromReadme(readmeContent, category);
788
+ if (categorySection) {
789
+ return categorySection;
790
+ }
791
+ }
792
+ catch (error) {
793
+ mcpLog('warning', `Failed to read README for category documentation: ${readmePath}`, error instanceof Error ? error.message : 'Unknown error');
794
+ }
795
+ // Fallback to dynamic generation
924
796
  const { toolCategories } = await discoverTools();
925
797
  const categoryInfo = toolCategories[category];
926
798
  if (!categoryInfo) {
927
- return `# Category Not Found\n\nThe category '${category}' was not found.`;
799
+ return `# Category Not Found\n\nThe category '${category}' was not found.\n\nAvailable categories: ${Object.keys(toolCategories).join(', ')}`;
928
800
  }
929
- return `# ${category} Category Documentation\n\n${categoryInfo.description}\n\n## Available Tools\n\n${categoryInfo.tools.map(t => `- ${t}`).join('\n')}`;
801
+ return `# ${category} Category Documentation\n\n${categoryInfo.description}\n\n## Available Tools\n\n${categoryInfo.tools.map(t => `- ${t}`).join('\n')}\n\n*This documentation was generated automatically. For detailed documentation, see the main README.md file.*`;
930
802
  }
931
803
  function generateWorkflowPrompt(taskType, context) {
932
804
  const workflows = {
@@ -1271,79 +1143,71 @@ async function main() {
1271
1143
  try {
1272
1144
  // VS Code MCP Compliance: Dev Mode Support
1273
1145
  const isTest = process.env.NODE_ENV === 'test' && process.env.MCP_TEST_MODE === 'true';
1274
- if (isDevelopment) {
1275
- mcpLog('info', "🔧 IT Tools MCP Server starting in DEVELOPMENT mode");
1276
- mcpLog('debug', " - Enhanced logging enabled");
1277
- mcpLog('debug', " - Hot reload capabilities active");
1278
- mcpLog('debug', " - Debug information available");
1279
- }
1146
+ mcpLog('info', 'Starting IT Tools MCP Server', {
1147
+ version: packageInfo.version,
1148
+ environment: isDevelopment ? 'development' : 'production',
1149
+ nodeVersion: process.version
1150
+ });
1280
1151
  // Add error handling for unhandled rejections
1281
1152
  process.on('unhandledRejection', (reason, promise) => {
1282
- mcpLog('error', 'Unhandled Rejection', { promise: promise.toString(), reason });
1153
+ // Only log to stderr in development or for critical errors
1154
+ if (isDevelopment) {
1155
+ mcpLog('error', 'Unhandled Rejection', { promise: promise.toString(), reason });
1156
+ }
1283
1157
  });
1284
1158
  process.on('uncaughtException', (error) => {
1285
1159
  mcpLog('critical', 'Uncaught Exception', error.message);
1286
1160
  process.exit(1);
1287
1161
  });
1162
+ // Register tools and connect
1163
+ mcpLog('debug', 'Registering tools...');
1164
+ const startTime = Date.now();
1288
1165
  await registerAllTools(server);
1166
+ const toolLoadTime = Date.now() - startTime;
1167
+ const { totalToolCount, toolCategories } = await discoverTools();
1168
+ mcpLog('info', 'Tools registered successfully', {
1169
+ totalTools: totalToolCount,
1170
+ categories: Object.keys(toolCategories).length,
1171
+ loadTimeMs: toolLoadTime
1172
+ });
1173
+ mcpLog('debug', 'Connecting to MCP transport...');
1289
1174
  const transport = new StdioServerTransport();
1290
1175
  await server.connect(transport);
1291
1176
  // Mark MCP transport as ready for logging
1292
1177
  mcpTransportReady = true;
1293
- // Log startup information based on environment
1178
+ mcpLog('info', 'MCP Server started successfully', {
1179
+ transport: 'stdio',
1180
+ ready: true
1181
+ });
1182
+ // Exit handler for test automation
1294
1183
  if (isTest) {
1295
- mcpLog('info', "IT Tools MCP Server running on stdio");
1296
- // Exit after stdin closes (for test automation)
1184
+ mcpLog('debug', 'Test mode: Setting up exit handler');
1297
1185
  process.stdin.on('end', () => {
1186
+ mcpLog('debug', 'Test mode: stdin ended, exiting...');
1298
1187
  setTimeout(() => process.exit(0), 100);
1299
1188
  });
1300
1189
  }
1301
- else if (isDevelopment) {
1302
- mcpLog('info', "🚀 IT Tools MCP Server connected successfully");
1303
- mcpLog('info', `📊 Loaded ${await getToolCount()} tools across ${await getCategoryCount()} categories`);
1304
- mcpLog('info', `🔗 Protocol: Model Context Protocol (MCP) via stdio`);
1305
- mcpLog('info', `📦 Version: ${packageInfo.version}`);
1306
- }
1307
- else {
1308
- // Production mode - simple ready message
1309
- mcpLog('info', `IT Tools MCP Server v${packageInfo.version} ready - ${await getToolCount()} tools loaded`);
1310
- }
1311
- // Enhanced monitoring in development mode
1312
- if (isDevelopment && !isTest) {
1313
- // More frequent monitoring in dev mode (every minute)
1190
+ // Production monitoring (every 5 minutes) - no logging unless critical
1191
+ if (!isTest) {
1192
+ mcpLog('debug', 'Setting up production monitoring');
1314
1193
  setInterval(() => {
1315
1194
  const usage = getResourceUsage();
1316
1195
  if (usage.memory.heapUsedBytes > 200 * 1024 * 1024) {
1317
- mcpLog('warning', "⚠️ High memory usage detected", usage.memory);
1318
- }
1319
- // Log periodic status in dev mode
1320
- mcpLog('debug', `📈 Status: Memory ${usage.memory.heapUsed}, CPU ${usage.cpu.user}ms user, ${usage.cpu.system}ms system`);
1321
- }, 60 * 1000); // Every minute in dev mode
1322
- }
1323
- else if (!isTest) {
1324
- // Production monitoring (every 5 minutes)
1325
- setInterval(() => {
1326
- const usage = getResourceUsage();
1327
- if (usage.memory.heapUsedBytes > 200 * 1024 * 1024) {
1328
- mcpLog('warning', "High memory usage detected", usage.memory);
1196
+ // Critical memory issues
1197
+ mcpLog('critical', 'High memory usage detected', usage.memory);
1329
1198
  }
1330
1199
  }, 5 * 60 * 1000);
1331
1200
  }
1332
1201
  // Handle graceful shutdown
1333
1202
  const shutdown = () => {
1334
- if (isDevelopment) {
1335
- mcpLog('info', "🛑 Shutting down IT Tools MCP Server (Development Mode)...");
1336
- }
1337
- else {
1338
- mcpLog('info', "Shutting down IT Tools MCP Server...");
1339
- }
1203
+ mcpLog('info', 'Graceful shutdown initiated');
1340
1204
  process.exit(0);
1341
1205
  };
1342
1206
  process.on('SIGINT', shutdown);
1343
1207
  process.on('SIGTERM', shutdown);
1344
1208
  }
1345
1209
  catch (error) {
1346
- mcpLog('critical', "Failed to start MCP server", error instanceof Error ? error.message : 'Unknown error');
1210
+ mcpLog('emergency', 'Fatal error starting MCP server', error instanceof Error ? error.message : 'Unknown error');
1347
1211
  process.exit(1);
1348
1212
  }
1349
1213
  }
@@ -1384,10 +1248,8 @@ function extractReadmeSection(content, heading) {
1384
1248
  : lines.slice(startIndex, endIndex);
1385
1249
  return sectionLines.join('\n');
1386
1250
  }
1387
- // Start the server if this file is executed directly
1388
- if (import.meta.url === `file://${process.argv[1]}`) {
1389
- main().catch((error) => {
1390
- mcpLog('emergency', "Fatal error starting MCP server", error instanceof Error ? error.message : 'Unknown error');
1391
- process.exit(1);
1392
- });
1393
- }
1251
+ // Start the server
1252
+ main().catch((error) => {
1253
+ console.error("Fatal error in main():", error);
1254
+ process.exit(1);
1255
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "it-tools-mcp",
3
- "version": "4.1.14",
3
+ "version": "5.0.0",
4
4
  "description": "Full MCP 2025-06-18 compliant server with 121+ IT tools, logging, ping, progress tracking, cancellation, and sampling utilities",
5
5
  "type": "module",
6
6
  "main": "./build/index.js",
@@ -72,8 +72,10 @@
72
72
  "tools",
73
73
  "resources",
74
74
  "prompts",
75
+ "completions",
75
76
  "sampling",
76
- "roots"
77
+ "roots",
78
+ "logging"
77
79
  ],
78
80
  "toolCount": 116,
79
81
  "categories": [