Skip to main content
Glama

search_output

Search recent terminal output for specific patterns or error messages to quickly identify issues without manual scanning.

Instructions

Search through recent terminal output for a specific pattern or error message.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
patternYesText pattern to search for (case-insensitive)
countNoNumber of recent commands to search through

Implementation Reference

  • Handler function that implements the search_output tool: parses recent terminal history, searches for the given pattern in commands and outputs, and returns matching entries with highlighted lines.
    async ({ pattern, count = 10 }) => {
      const entries = parseLogFile();
      
      if (entries.length === 0) {
        return {
          content: [{
            type: 'text',
            text: 'No terminal history found.',
          }],
        };
      }
    
      const recent = entries.slice(-count);
      const regex = new RegExp(pattern, 'gi');
      const matches = [];
    
      for (const entry of recent) {
        const fullText = `${entry.command}\n${entry.output}`;
        if (regex.test(fullText)) {
          // Find matching lines
          const lines = fullText.split('\n');
          const matchingLines = lines.filter(line => new RegExp(pattern, 'i').test(line));
          
          matches.push({
            command: entry.command,
            exitCode: entry.exitCode,
            matchingLines,
          });
        }
      }
    
      if (matches.length === 0) {
        return {
          content: [{
            type: 'text',
            text: `No matches found for "${pattern}" in the last ${count} commands.`,
          }],
        };
      }
    
      const formatted = matches.map(m => {
        const status = m.exitCode === 0 ? '✓' : `✗ (${m.exitCode})`;
        return `${status} $ ${m.command}\nMatching lines:\n${m.matchingLines.map(l => `  > ${l}`).join('\n')}`;
      }).join('\n\n');
      
      return {
        content: [{
          type: 'text',
          text: `Found ${matches.length} command(s) matching "${pattern}":\n\n${formatted}`,
        }],
      };
    }
  • Input schema definition for the search_output tool using Zod for validation: requires a pattern string and optional count of recent commands.
    {
      title: 'Search Terminal Output',
      description: 'Search through recent terminal output for a specific pattern or error message.',
      inputSchema: {
        pattern: z.string().describe('Text pattern to search for (case-insensitive)'),
        count: z.number().min(1).max(50).default(10).describe('Number of recent commands to search through'),
      },
  • index.js:188-250 (registration)
    Registers the search_output tool with the MCP server, including name, schema, and handler reference.
    server.registerTool(
      'search_output',
      {
        title: 'Search Terminal Output',
        description: 'Search through recent terminal output for a specific pattern or error message.',
        inputSchema: {
          pattern: z.string().describe('Text pattern to search for (case-insensitive)'),
          count: z.number().min(1).max(50).default(10).describe('Number of recent commands to search through'),
        },
      },
      async ({ pattern, count = 10 }) => {
        const entries = parseLogFile();
        
        if (entries.length === 0) {
          return {
            content: [{
              type: 'text',
              text: 'No terminal history found.',
            }],
          };
        }
    
        const recent = entries.slice(-count);
        const regex = new RegExp(pattern, 'gi');
        const matches = [];
    
        for (const entry of recent) {
          const fullText = `${entry.command}\n${entry.output}`;
          if (regex.test(fullText)) {
            // Find matching lines
            const lines = fullText.split('\n');
            const matchingLines = lines.filter(line => new RegExp(pattern, 'i').test(line));
            
            matches.push({
              command: entry.command,
              exitCode: entry.exitCode,
              matchingLines,
            });
          }
        }
    
        if (matches.length === 0) {
          return {
            content: [{
              type: 'text',
              text: `No matches found for "${pattern}" in the last ${count} commands.`,
            }],
          };
        }
    
        const formatted = matches.map(m => {
          const status = m.exitCode === 0 ? '✓' : `✗ (${m.exitCode})`;
          return `${status} $ ${m.command}\nMatching lines:\n${m.matchingLines.map(l => `  > ${l}`).join('\n')}`;
        }).join('\n\n');
        
        return {
          content: [{
            type: 'text',
            text: `Found ${matches.length} command(s) matching "${pattern}":\n\n${formatted}`,
          }],
        };
      }
    );
  • Helper function to parse the terminal log file into structured command entries, used by search_output to access history.
    function parseLogFile() {
      if (!existsSync(LOG_FILE)) {
        return [];
      }
    
      const content = readFileSync(LOG_FILE, 'utf8');
      const entries = [];
      const blocks = content.split('---CMD---').filter(block => block.trim());
    
      for (const block of blocks) {
        const entry = {
          command: '',
          output: '',
          exitCode: null,
          timestamp: null,
        };
    
        // Extract command (line starting with $)
        const cmdMatch = block.match(/^\s*\$\s*(.+?)(?:\n|---)/m);
        if (cmdMatch) {
          entry.command = cmdMatch[1].trim();
        }
    
        // Extract output
        const outputMatch = block.match(/---OUTPUT---\n([\s\S]*?)(?:---EXIT|---END|$)/);
        if (outputMatch) {
          entry.output = outputMatch[1].trim();
        }
    
        // Extract exit code
        const exitMatch = block.match(/---EXIT:(\d+)---/);
        if (exitMatch) {
          entry.exitCode = parseInt(exitMatch[1], 10);
        }
    
        // Extract timestamp if present
        const timestampMatch = block.match(/---TIMESTAMP:(.+?)---/);
        if (timestampMatch) {
          entry.timestamp = timestampMatch[1];
        }
    
        if (entry.command) {
          entries.push(entry);
        }
      }
    
      return entries;
    }

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/chrisvin-jabamani/terminal-reader-mcp'

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