Skip to main content
Glama

shell_whois

Query WHOIS domain registration information to retrieve ownership details, contact data, and expiration dates for any domain name.

Instructions

Query WHOIS domain registration information

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
argsNoCommand arguments

Implementation Reference

  • Generic handler for all tool calls, including 'shell_whois'. Maps tool name to full command 'shell.whois', validates arguments, executes the 'whois' command via executor, and returns stdout.
    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 }; } });
  • src/index.ts:27-43 (registration)
    Registers the 'shell_whois' tool by transforming 'shell.whois' from allowedCommands, providing name, description, and 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 }; });
  • Defines the schema/configuration for 'shell.whois' (mapped to 'shell_whois' tool), including command executable, description, allowed arguments for validation, and timeout.
    'shell.whois': { command: 'whois', description: 'Query WHOIS domain registration information', allowedArgs: [ '-H', // hide legal disclaimers '*' // allow domain names ], timeout: 5000 },
  • Executes the shell command by spawning the child process for 'whois' with provided arguments, handling streams, timeouts, and errors.
    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 };
  • Validates arguments for the command using allowedArgs from config, ensuring only permitted options like '-H' and domains ('*') for 'whois'.
    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`); } }

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