Skip to main content
Glama
secure-bash.jsโ€ข8.62 kB
import { EnhancedSecureCommandExecutor } from './EnhancedSecureCommandExecutor.js'; /** * Enhanced Secure Bash tool with development support * Supports bun, npm, node, and other development tools with privacy protection */ export const secureBashTool = { name: 'secure_bash', description: 'Execute bash commands securely with development tool support, dynamic learning, and privacy protection', inputSchema: { type: 'object', properties: { command: { type: 'string', description: 'The bash command to execute (supports development tools like bun, npm, node)' }, args: { type: 'array', items: { type: 'string' }, description: 'Command arguments (validated and learned over time)', default: [] }, workingDirectory: { type: 'string', description: 'Working directory (must be within workspace)', default: '.' }, securityLevel: { type: 'string', enum: ['STRICT', 'BALANCED', 'DEVELOPMENT', 'PERMISSIVE'], description: 'Security level - DEVELOPMENT recommended for coding', default: 'DEVELOPMENT' }, confirmed: { type: 'boolean', description: 'Explicit confirmation for new or sensitive operations', default: false }, timeout: { type: 'number', description: 'Timeout in milliseconds (max 120000 for builds)', minimum: 1000, maximum: 120000, default: 60000 }, enableLearning: { type: 'boolean', description: 'Enable learning new commands with user consent', default: true }, keepPrivate: { type: 'boolean', description: 'Enhanced privacy mode - sanitize all output', default: true } }, required: ['command'] } }; export async function handleSecureBash(args) { const { command, args: commandArgs = [], workingDirectory = '.', securityLevel = 'DEVELOPMENT', confirmed = false, timeout = 60000, enableLearning = true, keepPrivate = true } = args.params || args; try { // Initialize enhanced executor const executor = new EnhancedSecureCommandExecutor(workingDirectory, { securityLevel, timeoutMs: timeout, enableLearning, enableAuditing: true, enableContentFiltering: keepPrivate, outputSanitization: keepPrivate }); // Execute command const result = await executor.execute(command, commandArgs); // Check if user consent is required if (result.requiresConsent && !confirmed) { return formatConsentResponse(result, command, commandArgs); } // Grant consent if confirmed if (confirmed && result.requiresConsent) { executor.grantConsent(command, commandArgs); // Re-execute with consent const retryResult = await executor.execute(command, commandArgs); return formatSuccessResponse(retryResult); } return formatSuccessResponse(result); } catch (error) { return formatErrorResponse(error, command, commandArgs); } } /** * Format consent request with enhanced information */ function formatConsentResponse(result, command, args) { const commandCategory = result.commandCategory || 'UNKNOWN'; const isLearned = result.isLearned || false; return { content: [ { type: 'text', text: `๐Ÿ” Enhanced Security Review **Command**: \`${command} ${args.join(' ')}\` **Category**: ${commandCategory} **Status**: ${isLearned ? '๐ŸŽ“ Previously learned' : '๐Ÿ†• New command'} **Security Level**: ${result.securityLevel} ${result.message} **What this means**: - ๐Ÿ”’ **New commands** need your approval for security - ๐ŸŽ“ **Learned commands** are remembered for future use - ๐Ÿ›ก๏ธ **Privacy protection** is always active - ๐Ÿ“Š **Audit logging** tracks all operations **Development Tools Supported**: - ๐Ÿ“ฆ **Package Managers**: bun, npm, yarn, pnpm - ๐Ÿš€ **Runtimes**: node, bun, python, deno - ๐Ÿงช **Testing**: jest, vitest, mocha, playwright - ๐Ÿ” **Linting**: eslint, prettier, tsc, ruff - ๐Ÿ”จ **Build Tools**: webpack, vite, rollup To proceed, run the command again with \`confirmed: true\`: \`\`\`json { "command": "${command}", "args": ${JSON.stringify(args)}, "confirmed": true } \`\`\` โœ… **Privacy Features**: - All output is sanitized to remove sensitive data - Absolute paths are converted to relative paths - API keys and tokens are automatically redacted - Personal information is filtered out ๐ŸŽฏ **Learning System**: - Approved commands are remembered - Builds a personalized whitelist over time - Consent expires after 24 hours for security - Reset learning anytime with \`resetLearning: true\` ` } ] }; } /** * Format successful execution with enhanced details */ function formatSuccessResponse(result) { const outputPreview = result.output.length > 3000 ? result.output.substring(0, 3000) + '\n\n... (output truncated for display)' : result.output; return { content: [ { type: 'text', text: `โœ… Command Executed Successfully **Command**: \`${result.command} ${result.args.join(' ')}\` **Security Level**: ${result.securityLevel} **Category**: ${result.commandCategory || 'FILESYSTEM'} **Files Processed**: ${result.paths.length} **Output Size**: ${result.output.length} bytes **Timestamp**: ${result.timestamp} ๐Ÿ“‹ **Output**: \`\`\` ${outputPreview} \`\`\` ๐Ÿ”’ **Privacy Protection**: - โœ… Content filtering: ${result.contentFiltered ? 'Active' : 'Disabled'} - โœ… Output sanitization: ${result.outputSanitized ? 'Active' : 'Disabled'} - โœ… Path normalization: Absolute paths converted to relative - โœ… Sensitive data redaction: API keys, tokens, credentials filtered ๐Ÿ›ก๏ธ **Security Status**: - โœ… Command validated and approved - โœ… Workspace restrictions enforced - โœ… Execution logged for audit trail - โœ… Privacy controls active ${result.paths.length > 0 ? `๐Ÿ“ **Files Accessed**: ${result.paths.join(', ')}` : ''} ๐Ÿ’ก **Tip**: This command will be remembered for faster future execution! ` } ] }; } /** * Format error response with helpful guidance */ function formatErrorResponse(error, command, args) { const isCommandNotFound = error.message.includes('not allowed') || error.message.includes('Command not found'); const isArgError = error.message.includes('Argument') && error.message.includes('not allowed'); return { content: [ { type: 'text', text: `โŒ Enhanced Secure Bash Failed **Command**: \`${command} ${args.join(' ')}\` **Error**: ${error.message} ๐Ÿ›ก๏ธ **Enhanced Security Protection Active** ${isCommandNotFound ? ` ๐Ÿ†• **New Command Detected** The command '${command}' is not in the current whitelist. This is normal for development! **To use this command**: 1. Run again with \`confirmed: true\` to approve it 2. The command will be learned and remembered 3. Future uses won't require confirmation **Supported Command Categories**: - ๐Ÿ“ฆ **PACKAGE_MANAGERS**: npm, bun, yarn, pnpm, deno - ๐Ÿš€ **RUNTIMES**: node, bun, python, python3 - ๐Ÿงช **TESTING**: jest, vitest, mocha, tap, cypress, playwright - ๐Ÿ” **LINTING**: eslint, prettier, tsc, ruff, black, flake8 - ๐Ÿ”จ **BUILD_TOOLS**: webpack, vite, rollup, esbuild - ๐Ÿ“ **FILESYSTEM**: grep, find, ls, cat, head, tail, wc - ๐Ÿ”ง **UTILITIES**: echo, pwd, which, date, du, df - ๐ŸŒฟ **GIT**: git (with safe operations) - ๐Ÿณ **DOCKER**: docker, docker-compose, docker-machine ` : ''} ${isArgError ? ` โš ๏ธ **Argument Not Allowed** The argument is not in the current whitelist for this command. **To fix this**: 1. Check if the argument is correct 2. Run with \`confirmed: true\` to approve new arguments 3. The argument will be learned for future use ` : ''} **Security Levels**: - ๐Ÿ”’ **STRICT**: Minimal commands, requires consent - โš–๏ธ **BALANCED**: Standard commands, automatic filtering - ๐Ÿ”ง **DEVELOPMENT**: Full dev tools, privacy-first (recommended) - ๐ŸŒ **PERMISSIVE**: Extended commands, minimal restrictions **Privacy Features**: - ๐Ÿ”’ All output is sanitized by default - ๐Ÿ” Sensitive data is automatically redacted - ๐Ÿ“ Absolute paths are converted to relative - ๐Ÿ›ก๏ธ Personal information is filtered out **Example Usage**: \`\`\`json { "command": "bun", "args": ["test"], "securityLevel": "DEVELOPMENT", "confirmed": true } \`\`\` ๐Ÿ’ก **Tip**: Use \`securityLevel: "DEVELOPMENT"\` for the best coding experience! ` } ] }; } export default { secureBashTool, handleSecureBash };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/moikas-code/moidvk'

If you have feedback or need assistance with the MCP directory API, please join our Discord server