Skip to main content
Glama

shell_dig

Perform DNS lookups programmatically by executing specified command arguments, enabling quick domain and IP resolution while adhering to secure, controlled execution environments.

Instructions

DNS lookup utility

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
argsNoCommand arguments

Implementation Reference

  • Generic MCP tool call handler that executes shell_dig by mapping 'shell_dig' to 'shell.dig', retrieving its config from allowedCommands, validating arguments, and executing the 'dig' command via executor.
    server.setRequestHandler(CallToolRequestSchema, async (request) => { try { const command = String(request.params?.name || ''); const fullCommand = `shell.${command.replace('shell_', '')}`; // Replace shell_ back to shell. if (!(fullCommand in allowedCommands)) { return { content: [{ type: "text", text: `Unknown command: ${command}` }], isError: true }; } const actualCommand = allowedCommands[fullCommand].command; const args = Array.isArray(request.params?.arguments?.args) ? request.params.arguments.args.map(String) : []; validator.validateCommand(actualCommand, args); const stream = await executor.execute(actualCommand, args); return { content: [{ type: "text", text: await new Promise((resolve, reject) => { const chunks: Buffer[] = []; stream.stdout.on('data', (chunk: Buffer) => chunks.push(chunk)); stream.stdout.on('end', () => resolve(Buffer.concat(chunks).toString())); stream.stdout.on('error', reject); }) }] }; } catch (error) { return { content: [{ type: "text", text: `Command execution failed: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } });
  • Specific schema/configuration for shell.dig tool: maps to 'dig' command, provides description, allowed arguments for validation, and timeout.
    'shell.dig': { command: 'dig', description: 'DNS lookup utility', allowedArgs: [ '+short', // short form '+trace', // trace query '+dnssec', // show DNSSEC info '@*', // nameserver '*' // domain names ], timeout: 5000 },
  • src/index.ts:27-43 (registration)
    Tool registration via ListToolsRequestSchema handler. Dynamically generates list of tools from allowedCommands, transforming 'shell.dig' to 'shell_dig' with input schema.
    server.setRequestHandler(ListToolsRequestSchema, async () => { const tools = Object.entries(allowedCommands).map(([name, config]) => ({ name: name.replace('shell.', 'shell_'), // Replace shell. with shell_ description: config.description, inputSchema: { type: "object", properties: { args: { type: "array", items: { type: "string" }, description: "Command arguments" } } } })); return { tools }; });
  • Helper function validateCommand used to validate arguments for shell.dig against its allowedArgs from config, checks paths, etc.
    validateCommand( command: string, args: string[] = [], options: CommandOptions = {} ): void { console.log('Validating command:', { command, args, baseCommand: command.replace('shell.', ''), fullCommand: `shell.${command.replace('shell.', '')}`, config: allowedCommands[`shell.${command.replace('shell.', '')}`] }); const baseCommand = command.replace('shell.', ''); if (!(`shell.${baseCommand}` in allowedCommands)) { throw new Error(`Command not allowed: ${command}`); } const config = allowedCommands[`shell.${baseCommand}`]; const allowedArgs = config.allowedArgs || []; console.log('Checking args:', { allowedArgs, hasWildcard: allowedArgs.includes('*') }); args.forEach(arg => { if (arg.startsWith('-')) { if (!allowedArgs.includes(arg)) { console.log('Invalid option:', arg); throw new Error(`Invalid argument: ${arg}`); } } else if (!allowedArgs.includes('*')) { console.log('Path not allowed:', arg); throw new Error(`Invalid argument: ${arg}`); } else { // 檢查路徑參數 this.validatePath(arg); } }); // 檢查超時設定 if (options.timeout && options.timeout > securityConfig.defaultTimeout) { throw new Error(`Timeout exceeds maximum allowed value`); } }
  • Helper function that spawns the actual 'dig' process (passed as command='dig') with arguments, handles streaming output, caching, security, timeouts.
    async execute( command: string, args: string[] = [], options: ExecuteOptions = {} ): Promise<{ stdout: Readable }> { const commandKey = `${command} ${args.join(' ')}`; try { // Check security await this.securityChecker.validateCommand(command, args, options); // Check cache const cached = this.cache.get(commandKey); if (cached) { this.logger.debug('Using cached command result', { command, args }); return this.createStreamFromCache(cached); } // Remove 'shell.' prefix for execution const baseCommand = command.replace('shell.', ''); // Execute command this.logger.debug('Starting command execution', { command, args, options }); const childProcess = spawn(baseCommand, args, { stdio: ['ignore', 'pipe', 'pipe'], timeout: options.timeout, cwd: options.cwd, env: { ...process.env, ...options.env }, signal: options.signal }); this.currentProcess = childProcess; // Error handling childProcess.on('error', (error: Error) => { this.logger.error('Command execution error', { command, args, error: error.message }); throw new ToolError( 'PROCESS_ERROR', 'Command execution error', { command, args, error: error.message } ); }); // Timeout handling if (options.timeout) { setTimeout(() => { if (childProcess.exitCode === null) { this.logger.warn('Command execution timeout', { command, args, timeout: options.timeout }); childProcess.kill(); throw new ToolError( 'TIMEOUT', 'Command execution timeout', { command, args, timeout: options.timeout } ); } }, options.timeout); } if (!childProcess.stdout) { throw new ToolError( 'STREAM_ERROR', 'Unable to get command output stream', { command, args } ); } // Monitor process status childProcess.on('exit', (code, signal) => { this.logger.debug('Command execution completed', { command, args, exitCode: code, signal }); }); return { stdout: childProcess.stdout };

Other Tools

Related Tools

Latest Blog Posts

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/kevinwatt/shell-mcp'

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