/** * SSH Log Tools * Tools for working with logs on remote server */ import { CallToolRequest, Tool } from '@modelcontextprotocol/sdk/types.js'; import { type ToolResult } from '../utils/tool-result.js'; /** * Log Tools */ export declare class LogTools { private executor; constructor(); /** * Get tool descriptions for MCP */ getTools(): Tool[]; /** * Handle tool call */ handleCall(request: CallToolRequest, signal?: AbortSignal): Promise; /** * Handle ssh_log_tail */ private handleLogTail; /** * Handle ssh_log_search */ private handleLogSearch; /** * Which files the call is about: the ones named, or the one a container writes to. * * The two are alternatives, not a pair — a call carrying both names two * different sources and gets neither, rather than a silent choice between them. */ private resolveSources; /** * The server's own date, asked rather than assumed. * * "Today" belongs to the machine holding the logs: it may sit in another * timezone, and a day taken from here would search the wrong one. */ private serverToday; /** * Of the given files, the ones written to inside the window — and the ones * whose time could not be read at all. * * The two are kept apart on purpose. A file find could not look at is not * an old file: dropping it here would send it out as "not touched within * the window", and a closed directory would read as a quiet log. Whatever * could not be checked stays in the search, where an unreadable file is * named for what it is. */ private changedWithin; /** Of the given files, the ones whose lines carry a date at all */ private filesWithTimestamps; /** * Files named by a pattern. * * `find` expands it by name rather than the server's shell: the path * travels in quotes, otherwise a space, `$(…)` and a newline in the name * would come alive along with the asterisk. The directory is checked * against profile rules here, each matched name through the normal path at * its call site. * * A path that exists under its own name does not count as a pattern: a * bracket in a file name is a legal character, not a pattern marker. */ private expandPatterns; /** Notes about expanding a pattern go under the answer, not instead of it */ private withGlobNotes; /** * Log path for the command. * * `~` is expanded on our side from the passport's home directory and * travels in single quotes — the same way as for writing and reading files. * * Profile rules are checked right here, after expansion. Checking a raw * path instead would have the validator judge a made-up `/home/user/secret` * for `~/secret`, and a rule forbidding `/root` would never fire for root — * the forbidden file's content would come back regardless. */ private buildSafePath; }