Skip to main content
Glama

shell_lspci

List PCI devices on a system by executing the lspci command through Shell-MCP, enabling structured device discovery for integration with MCP-compatible LLMs and systems.

Instructions

List PCI devices

Input Schema

NameRequiredDescriptionDefault
argsNoCommand arguments

Input Schema (JSON Schema)

{ "properties": { "args": { "description": "Command arguments", "items": { "type": "string" }, "type": "array" } }, "type": "object" }

Implementation Reference

  • Core handler that spawns the 'lspci' process (after stripping shell. prefix), handles caching, security validation, timeouts, streaming stdout, and error handling.
    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 }; } catch (error) { this.logger.error('Command execution failed', { command, args, error: error instanceof Error ? error.message : String(error) }); throw new ToolError( 'EXECUTION_ERROR', 'Command execution failed', { command, args, error: error instanceof Error ? error.message : String(error) } ); } }
  • MCP CallToolRequestSchema handler specific to shell_lspci: maps tool name 'shell_lspci' back to config key 'shell.lspci', extracts command 'lspci', validates args, executes via executor, collects and returns output.
    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 }; } });
  • Schema/configuration defining the shell.lspci tool: command to execute ('lspci'), description, allowed arguments for validation, and timeout.
    'shell.lspci': { command: 'lspci', description: 'List PCI devices', allowedArgs: [ '-v', // verbose '-k', // kernel drivers '-mm', // machine readable '-nn', // show vendor/device codes '--help' ], timeout: 2000 },
  • src/index.ts:27-43 (registration)
    Registers all shell tools including 'shell_lspci' (transforms 'shell.lspci' to 'shell_lspci') in the MCP tools list with input schema for args array.
    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 }; });
  • Validates command and arguments for shell tools like lspci against allowedArgs from config, checks paths, timeouts, and sanitizes input.
    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