read_file
Retrieve the contents of a specified file within secure, restricted directories. Use to access file data safely on the Simple MCP Server, ensuring controlled and secure file handling.
Instructions
指定されたファイルの内容を読み込みます(許可されたディレクトリのみ)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filepath | Yes | 読み込むファイルのパス |
Implementation Reference
- src/index.ts:314-340 (handler)The main execution logic for the 'read_file' tool. Validates the filepath using PathValidator for security restrictions, reads the file content using fs.readFile, and returns a CallToolResult with the content.private async readFile(filepath: string): Promise<CallToolResult> { try { const pathValidation = this.pathValidator.validatePath(filepath); if (!pathValidation.isValid) { throw new Error(pathValidation.error); } const extValidation = this.pathValidator.validateFileExtension(pathValidation.normalizedPath); if (!extValidation.isValid) { throw new Error(extValidation.error); } console.error(`Reading file: ${pathValidation.normalizedPath}`); const content = await fs.readFile(pathValidation.normalizedPath, "utf-8"); return { content: [ { type: "text", text: `ファイル "${pathValidation.normalizedPath}" の内容:\n\n${content}`, }, ], isError: false, }; } catch (error) { throw new Error(`ファイルの読み込みに失敗: ${error}`); } }
- src/index.ts:115-128 (schema)The tool schema definition including name, description, and inputSchema for 'read_file' as part of the static TOOLS array.{ name: "read_file", description: "指定されたファイルの内容を読み込みます(許可されたディレクトリのみ)", inputSchema: { type: "object", properties: { filepath: { type: "string", description: "読み込むファイルのパス", }, }, required: ["filepath"], }, },
- src/index.ts:275-276 (registration)The dispatch case in the CallToolRequestSchema handler that routes 'read_file' calls to the readFile method.case "read_file": return await this.readFile(args.filepath as string);
- src/index.ts:249-254 (registration)The ListToolsRequestSchema handler that registers and provides the list of tools, including 'read_file', via the static TOOLS array.this.server.setRequestHandler(ListToolsRequestSchema, async () => { console.error("ListTools request received"); return { tools: TOOLS, }; });
- src/index.ts:17-111 (helper)The PathValidator class used by read_file for path normalization, blocking forbidden paths, allowing only specific directories and file extensions.class PathValidator { private allowedPaths: string[]; private blockedPaths: string[]; private allowedExtensions: string[]; constructor() { // 許可されるディレクトリ(絶対パスに正規化) this.allowedPaths = [ //path.resolve(process.cwd()), // 現在のワーキングディレクトリ //path.resolve(os.homedir(), 'Documents'), // ドキュメントフォルダ path.resolve(os.homedir(), 'Documents/00_AI_Area'), // 専用フォルダ //path.resolve(os.homedir(), 'Desktop'), // デスクトップ //path.resolve(os.tmpdir()), // 一時ディレクトリ ]; // 明示的にブロックするパス this.blockedPaths = [ '/etc', '/bin', '/sbin', '/usr/bin', '/usr/sbin', '/System', '/Windows', '/Program Files', '/Program Files (x86)', path.resolve(os.homedir(), '.ssh'), path.resolve(os.homedir(), '.aws'), path.resolve(os.homedir(), '.config'), ]; // 許可されるファイル拡張子 this.allowedExtensions = [ '.txt', '.md', '.json', '.js', '.ts', '.html', '.css', '.py', '.java', '.cpp', '.c', '.h', '.xml', '.yaml', '.yml', '.log', '.csv', '.tsv', '.sql', '.sh', '.bat', '.ps1' ]; } validatePath(inputPath: string): { isValid: boolean; normalizedPath: string; error?: string } { try { // パスを正規化 const normalizedPath = path.resolve(inputPath); // ブロックされたパスのチェック for (const blockedPath of this.blockedPaths) { if (normalizedPath.startsWith(path.resolve(blockedPath))) { return { isValid: false, normalizedPath, error: `アクセスが禁止されているディレクトリです: ${blockedPath}` }; } } // 許可されたパスのチェック const isAllowed = this.allowedPaths.some(allowedPath => normalizedPath.startsWith(allowedPath) ); if (!isAllowed) { return { isValid: false, normalizedPath, error: `許可されていないパスです。アクセス可能なパス: ${this.allowedPaths.join(', ')}` }; } return { isValid: true, normalizedPath }; } catch (error) { return { isValid: false, normalizedPath: inputPath, error: `無効なパスです: ${error}` }; } } validateFileExtension(filepath: string): { isValid: boolean; error?: string } { const ext = path.extname(filepath).toLowerCase(); if (ext && !this.allowedExtensions.includes(ext)) { return { isValid: false, error: `許可されていないファイル拡張子です: ${ext}。許可されている拡張子: ${this.allowedExtensions.join(', ')}` }; } return { isValid: true }; } getAllowedPaths(): string[] { return [...this.allowedPaths]; } }