Skip to main content
Glama
StrawHatAI

Claude Desktop Commander MCP

by StrawHatAI

read_file

Retrieve and read the entire contents of a file from the file system, supporting multiple text encodings. Provides detailed error messages for unreadable files and operates within specified allowed directories.

Instructions

Read the complete contents of a file from the file system. Handles various text encodings and provides detailed error messages if the file cannot be read. Only works within allowed directories.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathYes

Implementation Reference

  • Core handler function that validates the file path security and reads the file content using fs.promises.readFile.
    export async function readFile(filePath: string): Promise<string> { const validPath = await validatePath(filePath); return fs.readFile(validPath, "utf-8"); }
  • Zod input schema for the read_file tool, requiring a 'path' string parameter.
    export const ReadFileArgsSchema = z.object({ path: z.string(), });
  • src/server.ts:125-132 (registration)
    Tool registration in the MCP ListTools handler, defining name, description, and input schema.
    { name: "read_file", description: "Read the complete contents of a file from the file system. " + "Handles various text encodings and provides detailed error messages " + "if the file cannot be read. Only works within allowed directories.", inputSchema: zodToJsonSchema(ReadFileArgsSchema), },
  • MCP CallTool dispatch handler for read_file, which parses arguments, calls the readFile function, and formats the response.
    case "read_file": { const parsed = ReadFileArgsSchema.parse(args); const content = await readFile(parsed.path); return { content: [{ type: "text", text: content }], }; }
  • Security helper function used by readFile to validate paths are within allowed directories and resolve symlinks.
    export async function validatePath(requestedPath: string): Promise<string> { const expandedPath = expandHome(requestedPath); const absolute = path.isAbsolute(expandedPath) ? path.resolve(expandedPath) : path.resolve(process.cwd(), expandedPath); const normalizedRequested = normalizePath(absolute); // Check if path is within allowed directories const isAllowed = allowedDirectories.some(dir => normalizedRequested.startsWith(normalizePath(dir))); if (!isAllowed) { throw new Error(`Access denied - path outside allowed directories: ${absolute}`); } // Handle symlinks by checking their real path try { const realPath = await fs.realpath(absolute); const normalizedReal = normalizePath(realPath); const isRealPathAllowed = allowedDirectories.some(dir => normalizedReal.startsWith(normalizePath(dir))); if (!isRealPathAllowed) { throw new Error("Access denied - symlink target outside allowed directories"); } return realPath; } catch (error) { // For new files that don't exist yet, verify parent directory const parentDir = path.dirname(absolute); try { const realParentPath = await fs.realpath(parentDir); const normalizedParent = normalizePath(realParentPath); const isParentAllowed = allowedDirectories.some(dir => normalizedParent.startsWith(normalizePath(dir))); if (!isParentAllowed) { throw new Error("Access denied - parent directory outside allowed directories"); } return absolute; } catch { throw new Error(`Parent directory does not exist: ${parentDir}`); } } }

Other Tools

Related 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/StrawHatAI/claude-dev-tools'

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