write_file
Write content to a specific file path. Provide the file path and content to create or overwrite a file on the local system.
Instructions
Write content to a file
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Path to the file to write | |
| content | Yes | Content to write to the file |
Implementation Reference
- src/index.ts:560-569 (handler)The handler function for the 'write_file' tool. It validates the path using validatePath(), writes the file content to disk using fsPromises.writeFile() with UTF-8 encoding, and returns a success result.
case "write_file": { const validPath = await validatePath(args.path); await fsPromises.writeFile(validPath, args.content, "utf-8"); return { toolResult: { success: true, content: [{ type: "text", text: `File written successfully to: ${args.path}` }], message: `File saved to: ${args.path}` } }; - src/index.ts:315-330 (registration)Registration of the 'write_file' tool in the ListToolsRequestSchema handler. Defines the tool name, description, and inputSchema with 'path' and 'content' string properties, both required.
name: "write_file", description: "Write content to a file", inputSchema: { type: "object", properties: { path: { type: "string", description: "Path to the file to write" }, content: { type: "string", description: "Content to write to the file" } }, required: ["path", "content"] } - src/index.ts:91-129 (helper)The validatePath() async function used by the write_file handler to ensure the requested path is within allowed directories and handles symlink security.
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(dir)); if (!isAllowed) { throw new Error(`Access denied - path outside allowed directories: ${absolute} not in ${allowedDirectories.join(', ')}`); } // Handle symlinks by checking their real path try { const realPath = await fsPromises.realpath(absolute); const normalizedReal = normalizePath(realPath); const isRealPathAllowed = allowedDirectories.some(dir => normalizedReal.startsWith(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 fsPromises.realpath(parentDir); const normalizedParent = normalizePath(realParentPath); const isParentAllowed = allowedDirectories.some(dir => normalizedParent.startsWith(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}`); } } } - src/index.ts:560-569 (schema)The input schema for write_file is defined at lines 317-330 as part of the tool registration — it requires 'path' (string) and 'content' (string). The handler case at line 560-569 is the execution logic.
case "write_file": { const validPath = await validatePath(args.path); await fsPromises.writeFile(validPath, args.content, "utf-8"); return { toolResult: { success: true, content: [{ type: "text", text: `File written successfully to: ${args.path}` }], message: `File saved to: ${args.path}` } };