/** * SSH File Tools * Tools for working with files on remote server */ import { CallToolRequest, Tool } from '@modelcontextprotocol/sdk/types.js'; import { type ToolResult } from '../utils/tool-result.js'; /** * File Tools */ export declare class FileTools { private executor; constructor(); /** * Get tool descriptions for MCP */ getTools(): Tool[]; /** * Handle tool call */ handleCall(request: CallToolRequest, signal?: AbortSignal): Promise; /** * Handle ssh_file_read */ private handleFileRead; /** * Handle ssh_file_write */ private handleFileWrite; /** Size of what the caller asked to write: base64 is counted after decoding */ private contentBytes; /** * Write a file to the server. * * One path handles any content: data lands on a staging path next to the * target and takes its place via the installer. Only how the staging path * gets filled differs — small content streams into the `cat` command's * stdin, large and binary content goes to the transport. * * Content never appears inside the command string. A heredoc glues it into * the command text, and on live servers that corrupts the write: an * apostrophe turns into five characters, the string `SSHEOF` inside the * text cuts the file short, and the remainder executes as commands. */ private writeFileRouted; /** * Fill the staging path via a stdin stream. * * The content travels as bytes over the channel, not as command text, so * the shell never parses it: quotes, line boundaries and the null byte all * mean nothing to it. Holds on both BusyBox and dash, on both backends. */ private stageByStdin; /** Fill the staging path via the transport: for large and binary content */ private stageByTransport; /** * Fetch the whole file and return base64. * Needed when binary=true: `cat` through a PTY corrupts bytes outside utf8. */ private readFileBinary; /** * Handle ssh_file_list */ private handleFileList; /** * File read command. * * The path arrives here already expanded and travels in single quotes — * the same way as for a write. */ private buildReadCommand; }