read
Read file contents with safety checks and optional line range selection to access specific portions of documents efficiently.
Instructions
Read file contents with safety checks and optional line range
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path to read | |
| startLine | No | Start line number (1-based, default: 1) | |
| endLine | No | End line number (1-based, optional) | |
| maxLines | No | Maximum number of lines to read (default: 20) |
Implementation Reference
- servers/file-mcp/tools/read.ts:43-118 (handler)Core handler function implementing the 'read' tool: input validation, safe file reading with line ranges, content formatting, truncation handling, and error management.
async execute(args: any): Promise<any> { try { // Validate and parse input using Zod schema const validatedArgs = ReadToolInputSchema.parse(args); const { path: filePath, startLine, endLine, maxLines } = validatedArgs; // Use FileUtils for safe file reading with line range support const options: any = { startLine, maxLines, }; if (endLine !== undefined) { options.endLine = endLine; } const { content: selectedContent, totalLines } = await FileUtils.readFileLines( filePath, options ); // Calculate actual range (for display purposes) const actualStartLine = Math.max(1, startLine); const actualEndLine = endLine ? Math.min(endLine, totalLines) : Math.min(actualStartLine + maxLines - 1, totalLines); // Check character limit for selected content only const isRangeSpecified = args.startLine !== undefined || args.endLine !== undefined || args.maxLines !== undefined; const hasRangeLimit = isRangeSpecified || actualEndLine < totalLines; if (hasRangeLimit && selectedContent.length > 20000) { throw ToolError.createValidationError( "contentSize", selectedContent.length, "Selected range is too large. Maximum allowed: 20,000 characters. Please reduce range" ); } // Format output (plain text, no line numbers by default) let formattedLines = selectedContent; const messages = []; if (actualStartLine > 1) { messages.push(`... above (${actualStartLine - 1} lines)`); } if (actualEndLine < totalLines) { const remainingLines = totalLines - actualEndLine; const nextStart = actualEndLine + 1; messages.push(`below (${remainingLines} lines) ...`); // Add helpful suggestions const suggestions = []; suggestions.push(`startLine=${nextStart}`); suggestions.push(`maxLines=<more>`); messages.push(`To read more: ${suggestions.join(" or ")}`); } if (messages.length > 0) { formattedLines = `${formattedLines}\n\n[${messages.join(" | ")}]`; } // Mark file as read for Edit Tool and Write Tool safety fileReadTracker.markFileAsRead(filePath); return ResultFormatter.createResponse(formattedLines); } catch (error) { // Handle Zod validation errors if (error instanceof Error && error.name === "ZodError") { throw ToolError.createValidationError("input", args, `Invalid input: ${error.message}`); } throw ToolError.wrapError("Read operation", error); } } - Zod input schema for the 'read' tool, validating path, line ranges, and maxLines with constraints.
export const ReadToolInputSchema = z .object({ path: FilePathSchema, startLine: LineNumberSchema.default(1), endLine: OptionalLineNumberSchema, maxLines: z.number().int().min(1).default(20), }) .refine((data) => !data.endLine || data.startLine <= data.endLine, { message: "Start line cannot be greater than end line", path: ["startLine"], }); - servers/file-mcp/index.ts:90-99 (registration)Registration of the 'read' tool by including its definition in the server's tool list.
protected getTools(): Tool[] { return [ this.readTool.getDefinition(), this.findTool.getDefinition(), this.grepTool.getDefinition(), this.writeTool.getDefinition(), this.editTool.getDefinition(), this.moveTool.getDefinition(), this.copyTool.getDefinition(), ]; - servers/file-mcp/index.ts:110-112 (registration)Dispatch to the 'read' tool handler in the main tool call switch statement.
case "read": return await this.readTool.execute(args); case "find": - servers/file-mcp/tools/read.ts:12-40 (schema)JSON schema definition for the 'read' tool input, provided for MCP protocol compliance.
getDefinition(): Tool { return { name: "read", description: "Read file contents with safety checks and optional line range", inputSchema: { type: "object", properties: { path: { type: "string", description: "File path to read", }, startLine: { type: "number", default: 1, description: "Start line number (1-based, default: 1)", }, endLine: { type: "number", description: "End line number (1-based, optional)", }, maxLines: { type: "number", default: 20, description: "Maximum number of lines to read (default: 20)", }, }, required: ["path"], }, };