read_log_paginated
Read specific line ranges from large log files for debugging and troubleshooting. This tool enables paginated access to log content, allowing you to retrieve manageable portions of extensive log data.
Instructions
Reads a paginated portion of a log file. Useful for large log files. Returns specific line ranges.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes | Name of the log file to read | |
| start_line | No | Starting line number (1-based, default: 1) | |
| num_lines | No | Number of lines to read (default: 100, max: 1000) |
Implementation Reference
- log_mcp/server.py:323-399 (handler)The handler function for the 'read_log_paginated' tool. It processes the tool call by validating parameters (filename, start_line, num_lines), resolving the log file path, reading the specified range of lines, formatting them with line numbers, and returning the content as TextContent. Handles errors like invalid params, file not found, permissions.elif name == "read_log_paginated": filename = arguments.get("filename") start_line = arguments.get("start_line", 1) num_lines = arguments.get("num_lines", 100) if not filename: return [TextContent( type="text", text="Error: filename parameter is required" )] # Validate parameters if start_line < 1: return [TextContent( type="text", text="Error: start_line must be >= 1" )] if num_lines < 1 or num_lines > 1000: return [TextContent( type="text", text="Error: num_lines must be between 1 and 1000" )] try: log_dir, log_file = resolve_log_file(filename) except ValueError as e: return [TextContent( type="text", text=f"Error: {e}" )] if not log_file.exists(): return [TextContent( type="text", text=f"Log file does not exist: {log_file}" )] if not log_file.is_file(): return [TextContent( type="text", text=f"Path exists but is not a file: {log_file}" )] try: with open(log_file, 'r') as f: # Read all lines to count total all_lines = f.readlines() total_lines = len(all_lines) # Calculate the slice end_line = min(start_line - 1 + num_lines, total_lines) lines = all_lines[start_line - 1:end_line] result = f"File: {log_file}\n" result += f"Total lines: {total_lines}\n" result += f"Showing lines {start_line}-{start_line - 1 + len(lines)}\n" result += f"\n{'=' * 60}\n\n" for i, line in enumerate(lines, start=start_line): result += f"{i:6d} | {line}" if end_line < total_lines: result += f"\n\n... {total_lines - end_line} more lines available ..." return [TextContent(type="text", text=result)] except PermissionError: return [TextContent( type="text", text=f"Permission denied reading: {log_file}" )] except Exception as e: return [TextContent( type="text", text=f"Error reading file: {e}" )]
- log_mcp/server.py:165-188 (schema)The schema definition and registration of the 'read_log_paginated' tool within the list_tools() function. Defines the input schema with properties for filename (required), start_line, and num_lines, including types, descriptions, and defaults.Tool( name="read_log_paginated", description="Reads a paginated portion of a log file. Useful for large log files. Returns specific line ranges.", inputSchema={ "type": "object", "properties": { "filename": { "type": "string", "description": "Name of the log file to read" }, "start_line": { "type": "integer", "description": "Starting line number (1-based, default: 1)", "default": 1 }, "num_lines": { "type": "integer", "description": "Number of lines to read (default: 100, max: 1000)", "default": 100 } }, "required": ["filename"] } ),
- log_mcp/server.py:138-227 (registration)The list_tools decorator function where the 'read_log_paginated' tool is registered by including its Tool object in the returned list.@app.list_tools() async def list_tools() -> list[Tool]: """List available tools.""" return [ Tool( name="list_log_files", description="Lists all log files in $XDG_RUNTIME_DIR/log. Use this FIRST when user reports errors or problems to see what logs are available for inspection.", inputSchema={ "type": "object", "properties": {}, "required": [] } ), Tool( name="get_log_content", description="Returns the content of a specific log file from $XDG_RUNTIME_DIR/log. Use this to inspect runtime logs when debugging errors or investigating problems. For large files, use read_log_paginated instead.", inputSchema={ "type": "object", "properties": { "filename": { "type": "string", "description": "Name of the log file to read" } }, "required": ["filename"] } ), Tool( name="read_log_paginated", description="Reads a paginated portion of a log file. Useful for large log files. Returns specific line ranges.", inputSchema={ "type": "object", "properties": { "filename": { "type": "string", "description": "Name of the log file to read" }, "start_line": { "type": "integer", "description": "Starting line number (1-based, default: 1)", "default": 1 }, "num_lines": { "type": "integer", "description": "Number of lines to read (default: 100, max: 1000)", "default": 100 } }, "required": ["filename"] } ), Tool( name="search_log_file", description="Searches a log file using regex pattern and returns matching lines with surrounding context. Supports pagination of results.", inputSchema={ "type": "object", "properties": { "filename": { "type": "string", "description": "Name of the log file to search" }, "pattern": { "type": "string", "description": "Regex pattern to search for" }, "context_lines": { "type": "integer", "description": "Number of lines to show before and after each match (default: 2, max: 10)", "default": 2 }, "case_sensitive": { "type": "boolean", "description": "Whether the search should be case-sensitive (default: false)", "default": False }, "max_matches": { "type": "integer", "description": "Maximum number of matches to return (default: 50, max: 500)", "default": 50 }, "skip_matches": { "type": "integer", "description": "Number of matches to skip (for pagination, default: 0)", "default": 0 } }, "required": ["filename", "pattern"] } ) ]