read_file
Retrieve the entire content of a specified file as UTF-8 text using relative or absolute paths. Relative paths resolve against a session default for efficient file access.
Instructions
Reads the entire content of a specified file as UTF-8 text. Accepts relative or absolute paths. Relative paths are resolved against the session default set by set_filesystem_default.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | The path to the file to read. Can be relative or absolute. If relative, it resolves against the path set by `set_filesystem_default`. If absolute, it is used directly. If relative and no default is set, an error occurs. |
Implementation Reference
- Core handler function that resolves the file path using serverState.resolvePath and reads the file content with comprehensive error handling for not found, directories, and I/O errors.export const readFileLogic = async (input: ReadFileInput, context: RequestContext): Promise<ReadFileOutput> => { const { path: requestedPath } = input; // Resolve the path using serverState (handles relative/absolute logic and sanitization) // This will throw McpError if a relative path is given without a default set. const absolutePath = serverState.resolvePath(requestedPath, context); try { // Read the file content using the resolved absolute path const content = await fs.readFile(absolutePath, 'utf8'); return { content }; } catch (error: any) { // Handle specific file system errors // Handle specific file system errors using the resolved absolutePath in messages if (error.code === 'ENOENT') { // Use NOT_FOUND error code throw new McpError(BaseErrorCode.NOT_FOUND, `File not found at resolved path: ${absolutePath}`, { ...context, requestedPath, resolvedPath: absolutePath, originalError: error }); } if (error.code === 'EISDIR') { // Use VALIDATION_ERROR throw new McpError(BaseErrorCode.VALIDATION_ERROR, `Resolved path is a directory, not a file: ${absolutePath}`, { ...context, requestedPath, resolvedPath: absolutePath, originalError: error }); } // Handle other potential I/O errors using INTERNAL_ERROR throw new McpError(BaseErrorCode.INTERNAL_ERROR, `Failed to read file: ${error.message || 'Unknown I/O error'}`, { ...context, originalError: error }); } };
- Zod input schema for read_file tool parameters, TypeScript input/output types.export const ReadFileInputSchema = z.object({ path: z.string().min(1, 'Path cannot be empty') .describe('The path to the file to read. Can be relative or absolute. If relative, it resolves against the path set by `set_filesystem_default`. If absolute, it is used directly. If relative and no default is set, an error occurs.'), }); // Define the TypeScript type for the input export type ReadFileInput = z.infer<typeof ReadFileInputSchema>; // Define the TypeScript type for the output export interface ReadFileOutput { content: string; }
- src/mcp-server/tools/readFile/registration.ts:22-52 (registration)Registers the 'read_file' MCP tool with description, input schema shape, and async handler function that invokes readFileLogic and formats the MCP response.server.tool( 'read_file', // Tool name 'Reads the entire content of a specified file as UTF-8 text. Accepts relative or absolute paths. Relative paths are resolved against the session default set by `set_filesystem_default`.', // Updated Description ReadFileInputSchema.shape, // Pass the schema shape, not the object instance async (params, extra) => { // Correct handler signature: params and extra // Cast params to the correct type within the handler for type safety const typedParams = params as ReadFileInput; // Create a new context for this specific tool execution // We might potentially use `extra.requestId` if available and needed for tracing, but let's keep it simple for now. const callContext = requestContextService.createRequestContext({ operation: 'ReadFileToolExecution', parentId: registrationContext.requestId }); logger.info(`Executing 'read_file' tool for path: ${typedParams.path}`, callContext); // ErrorHandler will catch McpErrors thrown by readFileLogic and format them const result = await ErrorHandler.tryCatch( () => readFileLogic(typedParams, callContext), // Use typedParams { operation: 'readFileLogic', context: callContext, input: typedParams, // Input is automatically sanitized by ErrorHandler for logging errorCode: BaseErrorCode.INTERNAL_ERROR // Default error if unexpected failure } ); logger.info(`Successfully read file: ${typedParams.path}`, callContext); // Use typedParams // Format the successful response return { content: [{ type: 'text', text: result.content }], }; } );
- src/mcp-server/server.ts:81-92 (registration)Calls registerReadFileTool(server) as part of the Promise.all for registering all filesystem tools during server initialization.const registrationPromises = [ registerReadFileTool(server), registerSetFilesystemDefaultTool(server), registerWriteFileTool(server), registerUpdateFileTool(server), registerListFilesTool(server), registerDeleteFileTool(server), registerDeleteDirectoryTool(server), registerCreateDirectoryTool(server), registerMovePathTool(server), registerCopyPathTool(server) ];