write
Create new files or overwrite existing files by writing complete content to specified paths, with optional parent directory creation.
Instructions
Write complete file contents (create new files or overwrite existing files)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path to write | |
| content | Yes | Complete file content to write | |
| createParentDir | No | Create parent directories if they don't exist (default: false) |
Implementation Reference
- servers/file-mcp/tools/write.ts:39-94 (handler)Core handler function that validates input, checks safety conditions, ensures parent directories, writes the file content, and formats the response.
async execute(args: any): Promise<any> { try { // Validate and parse input using Zod schema const validatedArgs = WriteToolInputSchema.parse(args); const { path: filePath, content, createParentDir } = validatedArgs; const resolvedPath = resolve(filePath); // Security validation await ToolValidation.validateFileAccess(resolvedPath); // Check if file exists and enforce read requirement for existing files let fileExists = false; try { await access(resolvedPath); fileExists = true; } catch { // File doesn't exist, which is fine for write operations } if (fileExists && !fileReadTracker.isFileRead(resolvedPath)) { throw ToolError.createValidationError( "filePath", filePath, `File must be read first. Use read(path="${filePath}") before overwriting to ensure safety` ); } ToolValidation.validateContentSize(content, "write operation"); // Ensure parent directory exists if needed await this.ensureParentDirectory(resolvedPath, createParentDir); // Write the file await writeFile(resolvedPath, content, "utf-8"); // Mark file as read after writing (for subsequent edits) fileReadTracker.markFileAsRead(resolvedPath); // Generate result display const resultDisplay = await ResultFormatter.generateFilePreview( filePath, `Successfully wrote ${content.length} characters to ${filePath}`, undefined, content.length ); return ResultFormatter.createResponse(resultDisplay); } catch (error: any) { // Handle Zod validation errors if (error instanceof Error && error.name === "ZodError") { throw ToolError.createValidationError("input", args, `Invalid input: ${error.message}`); } throw ToolError.wrapError("Write operation", error); } } - Zod input schema for the write tool used for validation in the execute method.
// Write tool input schema export const WriteToolInputSchema = z.object({ path: FilePathSchema, content: FileContentSchema, createParentDir: BooleanFlagSchema, }); - servers/file-mcp/index.ts:90-100 (registration)Registration of the write tool's definition in the server's list of available tools via getTools().
protected getTools(): Tool[] { return [ this.readTool.getDefinition(), this.findTool.getDefinition(), this.grepTool.getDefinition(), this.writeTool.getDefinition(), this.editTool.getDefinition(), this.moveTool.getDefinition(), this.copyTool.getDefinition(), ]; } - servers/file-mcp/index.ts:116-117 (registration)Dispatch logic in handleToolCall that routes 'write' tool calls to the WriteTool.execute method.
case "write": return await this.writeTool.execute(args); - Helper method to ensure the parent directory exists before writing the file, creating it if createParentDir is true.
private async ensureParentDirectory(filePath: string, createParentDir: boolean): Promise<void> { const parentDir = dirname(filePath); try { await access(parentDir); } catch { if (createParentDir) { await mkdir(parentDir, { recursive: true }); } else { throw ToolError.createValidationError( "parentDir", parentDir, "Parent directory does not exist.\nTo create parent directories automatically, re-run with: createParentDir=true" ); } } }