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