vibe-coder-mcp
Version:
Production-ready MCP server with complete agent integration, multi-transport support, and comprehensive development automation tools for AI-assisted workflows.
52 lines (51 loc) • 2.56 kB
JavaScript
import fs from 'fs-extra';
import path from 'path';
import logger from '../logger.js';
import { AppError } from './errors.js';
const BASE_WORKING_DIR = process.cwd();
export async function readFileContent(relativeFilePath) {
const normalizedRelativePath = path.normalize(relativeFilePath);
if (path.isAbsolute(normalizedRelativePath)) {
logger.error(`Attempted to read absolute path: ${normalizedRelativePath}`);
throw new AppError(`Invalid path: Absolute paths are not allowed.`);
}
const absolutePath = path.resolve(BASE_WORKING_DIR, normalizedRelativePath);
const relativeCheck = path.relative(BASE_WORKING_DIR, absolutePath);
if (relativeCheck.startsWith('..') || path.isAbsolute(relativeCheck)) {
logger.error(`Attempted directory traversal: ${normalizedRelativePath} resolved outside base directory (${BASE_WORKING_DIR}). Resolved to: ${absolutePath}`);
throw new AppError(`Invalid path: Directory traversal is not allowed.`);
}
logger.debug(`Attempting to read file: ${absolutePath}`);
try {
const stats = await fs.stat(absolutePath);
if (!stats.isFile()) {
throw new AppError(`Invalid path: Not a file ('${relativeFilePath}').`);
}
const content = await fs.readFile(absolutePath, 'utf-8');
logger.info(`Successfully read file: ${relativeFilePath}`);
return content;
}
catch (error) {
let errorMessage = `Failed to read file: '${relativeFilePath}'.`;
if (error && typeof error === 'object' && 'code' in error) {
const fsError = error;
if (fsError.code === 'ENOENT') {
logger.warn(`File not found: ${absolutePath}`);
errorMessage = `File not found: '${relativeFilePath}'.`;
}
else if (fsError.code === 'EACCES') {
logger.error(`Permission denied for file: ${absolutePath}`);
errorMessage = `Permission denied for file: '${relativeFilePath}'.`;
}
}
else if (error instanceof AppError) {
throw error;
}
else {
const errMsg = error instanceof Error ? error.message : String(error);
logger.error({ err: error }, `Unexpected error reading file: ${absolutePath}`);
errorMessage = `Could not read file '${relativeFilePath}'. Reason: ${errMsg || 'Unknown error'}`;
}
throw new AppError(errorMessage, { filePath: relativeFilePath }, error instanceof Error ? error : undefined);
}
}