Skip to main content
Glama
modelcontextprotocol

Filesystem MCP Server

Official

Read File (Deprecated)

read_file
Read-only

Read the complete contents of a file as text, with options to return only the first or last N lines.

Instructions

Read the complete contents of a file as text. DEPRECATED: Use read_text_file instead.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathYes
tailNoIf provided, returns only the last N lines of the file
headNoIf provided, returns only the first N lines of the file

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
contentYes

Implementation Reference

  • The handler function for the 'read_file' tool. Calls validatePath for security, then reads the file via readFileContent, tailFile, or headFile based on optional args.
    const readTextFileHandler = async (args: z.infer<typeof ReadTextFileArgsSchema>) => {
      const validPath = await validatePath(args.path);
    
      if (args.head && args.tail) {
        throw new Error("Cannot specify both head and tail parameters simultaneously");
      }
    
      let content: string;
      if (args.tail) {
        content = await tailFile(validPath, args.tail);
      } else if (args.head) {
        content = await headFile(validPath, args.head);
      } else {
        content = await readFileContent(validPath);
      }
    
      return {
        content: [{ type: "text" as const, text: content }],
        structuredContent: { content }
      };
    };
  • Registration of the 'read_file' tool (deprecated) on the MCP server with inputSchema, outputSchema, annotations, and the readTextFileHandler.
    server.registerTool(
      "read_file",
      {
        title: "Read File (Deprecated)",
        description: "Read the complete contents of a file as text. DEPRECATED: Use read_text_file instead.",
        inputSchema: ReadTextFileArgsSchema.shape,
        outputSchema: { content: z.string() },
        annotations: { readOnlyHint: true }
      },
      readTextFileHandler
    );
  • Zod schema for the read_file tool's arguments (path, optional tail, optional head).
    const ReadTextFileArgsSchema = z.object({
      path: z.string(),
      tail: z.number().optional().describe('If provided, returns only the last N lines of the file'),
      head: z.number().optional().describe('If provided, returns only the first N lines of the file')
    });
  • Core helper function readFileContent that reads a file from disk using fs.readFile with configurable encoding (default utf-8).
    export async function readFileContent(filePath: string, encoding: string = 'utf-8'): Promise<string> {
      return await fs.readFile(filePath, encoding as BufferEncoding);
    }
  • Helper function tailFile that reads the last N lines of a file efficiently by reading chunks from the end.
    export async function tailFile(filePath: string, numLines: number): Promise<string> {
      const CHUNK_SIZE = 1024; // Read 1KB at a time
      const stats = await fs.stat(filePath);
      const fileSize = stats.size;
      
      if (fileSize === 0) return '';
      
      // Open file for reading
      const fileHandle = await fs.open(filePath, 'r');
      try {
        const lines: string[] = [];
        let position = fileSize;
        let chunk = Buffer.alloc(CHUNK_SIZE);
        let linesFound = 0;
        let remainingText = '';
        
        // Read chunks from the end of the file until we have enough lines
        while (position > 0 && linesFound < numLines) {
          const size = Math.min(CHUNK_SIZE, position);
          position -= size;
          
          const { bytesRead } = await fileHandle.read(chunk, 0, size, position);
          if (!bytesRead) break;
          
          // Get the chunk as a string and prepend any remaining text from previous iteration
          const readData = chunk.slice(0, bytesRead).toString('utf-8');
          const chunkText = readData + remainingText;
          
          // Split by newlines and count
          const chunkLines = normalizeLineEndings(chunkText).split('\n');
          
          // If this isn't the end of the file, the first line is likely incomplete
          // Save it to prepend to the next chunk
          if (position > 0) {
            remainingText = chunkLines[0];
            chunkLines.shift(); // Remove the first (incomplete) line
          }
          
          // Add lines to our result (up to the number we need)
          for (let i = chunkLines.length - 1; i >= 0 && linesFound < numLines; i--) {
            lines.unshift(chunkLines[i]);
            linesFound++;
          }
        }
        
        return lines.join('\n');
      } finally {
        await fileHandle.close();
      }
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint=true, so the description adds only the deprecation status and that it reads text. It does not elaborate on return format, handling of line-based reads, or other behavioral details. With annotations, the bar is lower, and the deprecation is useful, but the description misses an opportunity to clarify that head/tail allow partial reads, which might contradict 'complete contents'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise: two sentences front-loaded with purpose and deprecation warning. Every sentence serves a clear function with zero waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool is deprecated and has a direct alternative, the description covers the necessary information. It doesn't need to explain return values since an output schema exists. However, it could mention that the tool still works but is discouraged, and could briefly note the partial read capabilities to avoid confusion.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67% (path lacks description), but the description adds no parameter details. It says 'complete contents' but parameters tail/head enable partial reading, creating a mismatch. The description fails to clarify the path format or resolve the ambiguity between 'complete' and partial reads.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reads a file's complete contents as text and marks it as deprecated with a specific alternative (read_text_file). However, the phrase 'complete contents' is slightly misleading because the tool supports partial reads via head/tail parameters, which are not mentioned in the description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states 'DEPRECATED: Use read_text_file instead,' providing a direct directive to avoid this tool and use a specific alternative. This offers clear when-not-to-use guidance and a named alternative, which is excellent for decision-making.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/modelcontextprotocol/filesystem'

If you have feedback or need assistance with the MCP directory API, please join our Discord server