Skip to main content
Glama

write_file

Write content to a specified file on the Filesystem MCP Server. Creates or overwrites the file and necessary directories based on provided relative or absolute paths.

Instructions

Writes content to a specified file. Creates the file (and necessary directories) if it doesn't exist, or overwrites it if it does. Accepts relative or absolute paths (resolved like readFile).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
contentYesThe content to write to the file. If the file exists, it will be overwritten.
pathYesThe path to the file to write. Can be relative or absolute. If relative, it resolves against the path set by `set_filesystem_default`. If absolute, it is used directly. Missing directories will be created.

Implementation Reference

  • Core handler function that executes the write_file tool logic: resolves the input path using serverState.resolvePath, checks if it's not a directory, creates parent directories if needed, writes the content using fs.promises.writeFile, logs progress, handles errors with McpError, and returns success details including bytes written.
    export const writeFileLogic = async (input: WriteFileInput, context: RequestContext): Promise<WriteFileOutput> => { const { path: requestedPath, content } = input; logger.debug(`writeFileLogic: Received request for path "${requestedPath}"`, context); // Resolve the path using serverState (handles relative/absolute logic and sanitization) const absolutePath = serverState.resolvePath(requestedPath, context); logger.debug(`writeFileLogic: Resolved path to "${absolutePath}"`, { ...context, requestedPath }); try { // Ensure the target path is not a directory before attempting to write try { const stats = await fs.stat(absolutePath); if (stats.isDirectory()) { logger.warning(`writeFileLogic: Attempted to write to a directory path "${absolutePath}"`, { ...context, requestedPath }); throw new McpError(BaseErrorCode.VALIDATION_ERROR, `Cannot write file. Path exists and is a directory: ${absolutePath}`, { ...context, requestedPath, resolvedPath: absolutePath }); } } catch (statError: any) { // ENOENT (file/dir doesn't exist) is expected and okay, we'll create it. // Other errors during stat (like permission issues) should be thrown. if (statError.code !== 'ENOENT') { throw statError; // Re-throw other stat errors } // If ENOENT, proceed to create directory and file logger.debug(`writeFileLogic: Path "${absolutePath}" does not exist, will create.`, { ...context, requestedPath }); } // Ensure the directory exists before writing the file const dirName = path.dirname(absolutePath); logger.debug(`writeFileLogic: Ensuring directory "${dirName}" exists`, { ...context, requestedPath, resolvedPath: absolutePath }); await fs.mkdir(dirName, { recursive: true }); logger.debug(`writeFileLogic: Directory "${dirName}" confirmed/created`, { ...context, requestedPath, resolvedPath: absolutePath }); // Write the file content logger.debug(`writeFileLogic: Writing content to "${absolutePath}"`, { ...context, requestedPath }); await fs.writeFile(absolutePath, content, 'utf8'); const bytesWritten = Buffer.byteLength(content, 'utf8'); logger.info(`writeFileLogic: Successfully wrote ${bytesWritten} bytes to "${absolutePath}"`, { ...context, requestedPath }); return { message: `Successfully wrote content to ${absolutePath}`, writtenPath: absolutePath, bytesWritten: bytesWritten, }; } catch (error: any) { logger.error(`writeFileLogic: Error writing file to "${absolutePath}"`, { ...context, requestedPath, error: error.message, code: error.code }); // Handle specific file system errors if (error instanceof McpError) { throw error; // Re-throw McpErrors (like the directory check) } // Handle potential I/O errors during mkdir or writeFile throw new McpError(BaseErrorCode.INTERNAL_ERROR, `Failed to write file: ${error.message || 'Unknown I/O error'}`, { ...context, requestedPath, resolvedPath: absolutePath, originalError: error }); } };
  • Zod schema defining the input parameters for the write_file tool: 'path' (string, required) and 'content' (string).
    export const WriteFileInputSchema = z.object({ path: z.string().min(1, 'Path cannot be empty') .describe('The path to the file to write. Can be relative or absolute. If relative, it resolves against the path set by `set_filesystem_default`. If absolute, it is used directly. Missing directories will be created.'), content: z.string() // Allow empty content .describe('The content to write to the file. If the file exists, it will be overwritten.'), });
  • Function that registers the 'write_file' tool with the MCP server using server.tool(), providing tool name, description, input schema, and an inline handler that calls the core writeFileLogic function, handles logging and error wrapping.
    export const registerWriteFileTool = async (server: McpServer): Promise<void> => { const registrationContext = requestContextService.createRequestContext({ operation: 'RegisterWriteFileTool' }); logger.info("Attempting to register 'write_file' tool", registrationContext); await ErrorHandler.tryCatch( async () => { server.tool( 'write_file', // Tool name 'Writes content to a specified file. Creates the file (and necessary directories) if it doesn\'t exist, or overwrites it if it does. Accepts relative or absolute paths (resolved like readFile).', // Description WriteFileInputSchema.shape, // Pass the schema shape async (params, extra) => { const typedParams = params as WriteFileInput; const callContext = requestContextService.createRequestContext({ operation: 'WriteFileToolExecution', parentId: registrationContext.requestId }); logger.info(`Executing 'write_file' tool for path: ${typedParams.path}`, callContext); // ErrorHandler will catch McpErrors thrown by the logic const result = await ErrorHandler.tryCatch( () => writeFileLogic(typedParams, callContext), { operation: 'writeFileLogic', context: callContext, input: { path: typedParams.path, content: '[CONTENT REDACTED]' }, // Redact content for logging errorCode: BaseErrorCode.INTERNAL_ERROR } ); logger.info(`Successfully executed 'write_file' for path: ${result.writtenPath}`, callContext); // Format the successful response return { content: [{ type: 'text', text: result.message }], }; } ); logger.info("'write_file' tool registered successfully", registrationContext); }, { operation: 'registerWriteFileTool', context: registrationContext, errorCode: BaseErrorCode.CONFIGURATION_ERROR, critical: true } ); };
  • Top-level call to registerWriteFileTool(server) as part of the array of all filesystem tool registrations during server initialization in createMcpServerInstance.
    const registrationPromises = [ registerReadFileTool(server), registerSetFilesystemDefaultTool(server), registerWriteFileTool(server), registerUpdateFileTool(server), registerListFilesTool(server), registerDeleteFileTool(server), registerDeleteDirectoryTool(server), registerCreateDirectoryTool(server), registerMovePathTool(server), registerCopyPathTool(server) ]; await Promise.all(registrationPromises); logger.info("Filesystem tools registered successfully", context);

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cyanheads/filesystem-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server