Skip to main content
Glama

edit

Apply sequential text replacements to files by specifying exact strings to modify. Use dry run to preview changes before applying them to ensure accuracy.

Instructions

Apply sequential literal string replacements to a file (first occurrence per edit). oldText must match exactly — include 3–5 lines of context for unique targeting. Use dryRun:true to preview.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathYesAbsolute path to file or directory.
editsYesList of replacements to apply sequentially. Each edit replaces the first occurrence of oldText.
dryRunNoPreview edits without writing. Check `unmatchedEdits` in response.
ignoreWhitespaceNoTreat all whitespace sequences as equivalent when matching oldText.

Implementation Reference

  • The handler function `handleEditFile` executes the "edit" tool by reading the target file, applying requested edits, and writing the changes back.
    async function handleEditFile(
      args: EditInput,
      signal?: AbortSignal
    ): Promise<ToolResponse<EditOutput>> {
      const { validPath, content } = await loadEditableFile(args.path, signal);
      const editResult = await applyEdits(
        content,
        args.edits,
        args.ignoreWhitespace
      );
      const structured = buildStructuredEditOutput(validPath, editResult);
    
      if (args.dryRun) {
        if (editResult.appliedEdits > 0) {
          structured.diff = await buildDiff(validPath, content, editResult.content);
        }
    
        return buildToolResponse(
          `Dry run complete. ${editResult.appliedEdits} edits would be applied.`,
          structured
        );
      }
    
      if (editResult.appliedEdits === 0 && editResult.unmatchedEdits.length > 0) {
        throw new McpError(
          ErrorCode.E_INVALID_INPUT,
          `All ${editResult.unmatchedEdits.length} edits failed to match. Verify oldText includes exact content with surrounding context.`,
          args.path
        );
      }
    
      if (editResult.appliedEdits > 0) {
        await atomicWriteFile(validPath, editResult.content, {
          encoding: 'utf-8',
          signal,
        });
      }
    
      return buildToolResponse(buildEditMessage(args.path, editResult), structured);
    }
  • The `registerEditFileTool` function registers the "edit" tool with the MCP server.
    export function registerEditFileTool(
      server: McpServer,
      options: ToolRegistrationOptions = {}
    ): void {
      const handler = (
        args: EditInput,
        extra: ToolExtra
      ): Promise<ToolResult<EditOutput>> =>
        executeToolWithDiagnostics({
          toolName: 'edit',
          extra,
          outputSchema: EditFileOutputSchema,
          timedSignal: {},
          context: { path: args.path },
          run: (signal) => handleEditFile(args, signal),
          onError: (error) =>
            buildToolErrorResponse(error, ErrorCode.E_UNKNOWN, args.path),
        });
    
      const wrappedHandler = wrapToolHandler(handler, {
        guard: options.isInitialized,
        progressMessage: buildEditProgressMessage,
        completionMessage: buildEditCompletionMessage,
      });
    
      const validatedHandler = withValidatedArgs(
        EditFileInputSchema,
        wrappedHandler
      );
    
      if (
        registerToolTaskIfAvailable(
          server,
          'edit',
          EDIT_FILE_TOOL,
          validatedHandler,
          options.iconInfo,
          options.isInitialized
        )
      )
        return;
    
      server.registerTool(
        'edit',
        withDefaultIcons({ ...EDIT_FILE_TOOL }, options.iconInfo),
        validatedHandler
      );
    }
  • The tool definition `EDIT_FILE_TOOL` provides the schema and metadata for the "edit" tool.
    export const EDIT_FILE_TOOL: ToolContract = {
      name: 'edit',
      title: 'Edit File',
      description:
        'Apply sequential literal string replacements to a file (first occurrence per edit). ' +
        '`oldText` must match exactly — include 3–5 lines of context for unique targeting. ' +
        'Use `dryRun:true` to preview.',
      inputSchema: EditFileInputSchema,
      outputSchema: EditFileOutputSchema,
      annotations: DESTRUCTIVE_WRITE_TOOL_ANNOTATIONS,
      nuances: ['Each edit applies to the output of the previous edit.'],
      taskSupport: 'forbidden',
    } as const;

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/j0hanz/filesystem-mcp'

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