safe-commander-mcp
Version:
A secure MCP server for executing whitelisted development commands with comprehensive security controls and resource limits
114 lines (113 loc) • 5.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.setupRequestHandlers = setupRequestHandlers;
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
const command_executor_1 = require("../commands/command-executor");
const command_categorizer_1 = require("../commands/command-categorizer");
const config_loader_1 = require("../config/config-loader");
const logger_1 = require("../utils/logger");
/**
* Setup MCP tool request handlers
*
* @param server - The MCP server instance to configure
*/
function setupRequestHandlers(server) {
// Enhanced tool handler with comprehensive security and monitoring
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (name === "run_command") {
const commandRequest = args;
const result = await (0, command_executor_1.executeCommand)(commandRequest);
return {
content: [{
type: "text",
text: result.output,
}],
};
}
if (name === "list_available_commands") {
try {
// Get categorized commands and descriptions
const categorized = (0, command_categorizer_1.categorizeCommands)(config_loader_1.CONFIG.ALLOWED_COMMANDS);
const descriptions = (0, command_categorizer_1.getCommandDescriptions)(config_loader_1.CONFIG.ALLOWED_COMMANDS);
const summary = (0, command_categorizer_1.getCommandSummary)(config_loader_1.CONFIG.ALLOWED_COMMANDS);
// Get validation info for debugging (only log if there are issues)
const validation = (0, command_categorizer_1.validateCommandCategories)(config_loader_1.CONFIG.ALLOWED_COMMANDS);
if (!validation.valid) {
(0, logger_1.log)('debug', 'Command categorization validation', {
missingCategories: validation.missingCategories,
missingDescriptions: validation.missingDescriptions
});
}
// Build comprehensive response
const response = {
workingDirectory: config_loader_1.CONFIG.ALLOWED_PATH,
totalCommands: config_loader_1.CONFIG.ALLOWED_COMMANDS.length,
categories: categorized,
commandDescriptions: descriptions,
summary: {
topCategories: summary.topCategories.slice(0, 5), // Top 5 categories
categoryCounts: summary.categoryCounts
},
configuration: {
maxCommandLength: config_loader_1.CONFIG.MAX_COMMAND_LENGTH,
commandTimeout: `${config_loader_1.CONFIG.COMMAND_TIMEOUT}ms`,
maxConcurrentCommands: config_loader_1.CONFIG.MAX_CONCURRENT_COMMANDS,
maxOutputSize: `${Math.round(config_loader_1.CONFIG.MAX_OUTPUT_SIZE / 1024)}KB`
}
};
(0, logger_1.log)('info', 'Command list requested', {
totalCommands: config_loader_1.CONFIG.ALLOWED_COMMANDS.length,
requestedBy: 'Claude'
});
return {
content: [{
type: "text",
text: JSON.stringify(response, null, 2)
}]
};
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
(0, logger_1.log)('error', 'Failed to list available commands', { error: errorMessage });
return {
content: [{
type: "text",
text: `Error retrieving command list: ${errorMessage}`
}]
};
}
}
throw new Error(`Unknown tool: ${name}`);
});
// Enhanced tool listing with better descriptions and command enumeration
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
tools: [
{
name: "run_command",
description: "Execute secure development commands with comprehensive validation and monitoring. Commands are categorized by type (package management, version control, file operations, etc.) and executed within a controlled environment.",
inputSchema: {
type: "object",
properties: {
command: {
type: "string",
description: `Command to execute from the available command set. Must be one of the allowed commands and cannot contain dangerous characters. Use 'list_available_commands' to see all available options.`,
enum: config_loader_1.CONFIG.ALLOWED_COMMANDS, // CRITICAL: This enables Claude's intelligence
maxLength: config_loader_1.CONFIG.MAX_COMMAND_LENGTH
},
},
required: ["command"],
},
},
{
name: "list_available_commands",
description: "Get comprehensive information about all available commands including categories, descriptions, working directory, and system configuration. This helps understand what operations are possible before attempting to execute commands.",
inputSchema: {
type: "object",
properties: {},
additionalProperties: false
},
},
],
}));
}