diff --git a/claudetool/edit.go b/claudetool/edit.go
new file mode 100644
index 0000000..df83139
--- /dev/null
+++ b/claudetool/edit.go
@@ -0,0 +1,451 @@
+package claudetool
+
+/*
+
+Note: sketch wrote this based on translating https://raw.githubusercontent.com/anthropics/anthropic-quickstarts/refs/heads/main/computer-use-demo/computer_use_demo/tools/edit.py
+
+## Implementation Notes
+This tool is based on Anthropic's Python implementation of the `text_editor_20250124` tool. It maintains a history of file edits to support the undo functionality, and verifies text uniqueness for the str_replace operation to ensure safe edits.
+
+*/
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+
+	"sketch.dev/ant"
+)
+
+// Constants for the AnthropicEditTool
+const (
+	editName = "str_replace_editor"
+)
+
+// Constants used by the tool
+const (
+	snippetLines     = 4
+	maxResponseLen   = 16000
+	truncatedMessage = "<response clipped><NOTE>To save on context only part of this file has been shown to you. You should retry this tool after you have searched inside the file with `grep -n` in order to find the line numbers of what you are looking for.</NOTE>"
+)
+
+// Command represents the type of operation to perform
+type editCommand string
+
+const (
+	viewCommand       editCommand = "view"
+	createCommand     editCommand = "create"
+	strReplaceCommand editCommand = "str_replace"
+	insertCommand     editCommand = "insert"
+	undoEditCommand   editCommand = "undo_edit"
+)
+
+// editInput represents the expected input format for the edit tool
+type editInput struct {
+	Command    string  `json:"command"`
+	Path       string  `json:"path"`
+	FileText   *string `json:"file_text,omitempty"`
+	ViewRange  []int   `json:"view_range,omitempty"`
+	OldStr     *string `json:"old_str,omitempty"`
+	NewStr     *string `json:"new_str,omitempty"`
+	InsertLine *int    `json:"insert_line,omitempty"`
+}
+
+// fileHistory maintains a history of edits for each file to support undo functionality
+var fileHistory = make(map[string][]string)
+
+// AnthropicEditTool is a tool for viewing, creating, and editing files
+var AnthropicEditTool = &ant.Tool{
+	// Note that Type is model-dependent, and would be different for Claude 3.5, for example.
+	Type: "text_editor_20250124",
+	Name: editName,
+	Run:  EditRun,
+}
+
+// EditRun is the implementation of the edit tool
+func EditRun(ctx context.Context, input json.RawMessage) (string, error) {
+	var editRequest editInput
+	if err := json.Unmarshal(input, &editRequest); err != nil {
+		return "", fmt.Errorf("failed to parse edit input: %v", err)
+	}
+
+	// Validate the command
+	cmd := editCommand(editRequest.Command)
+	if !isValidCommand(cmd) {
+		return "", fmt.Errorf("unrecognized command %s. The allowed commands are: view, create, str_replace, insert, undo_edit", cmd)
+	}
+
+	path := editRequest.Path
+
+	// Validate the path
+	if err := validatePath(cmd, path); err != nil {
+		return "", err
+	}
+
+	// Execute the appropriate command
+	switch cmd {
+	case viewCommand:
+		return handleView(ctx, path, editRequest.ViewRange)
+	case createCommand:
+		if editRequest.FileText == nil {
+			return "", fmt.Errorf("parameter file_text is required for command: create")
+		}
+		return handleCreate(path, *editRequest.FileText)
+	case strReplaceCommand:
+		if editRequest.OldStr == nil {
+			return "", fmt.Errorf("parameter old_str is required for command: str_replace")
+		}
+		newStr := ""
+		if editRequest.NewStr != nil {
+			newStr = *editRequest.NewStr
+		}
+		return handleStrReplace(path, *editRequest.OldStr, newStr)
+	case insertCommand:
+		if editRequest.InsertLine == nil {
+			return "", fmt.Errorf("parameter insert_line is required for command: insert")
+		}
+		if editRequest.NewStr == nil {
+			return "", fmt.Errorf("parameter new_str is required for command: insert")
+		}
+		return handleInsert(path, *editRequest.InsertLine, *editRequest.NewStr)
+	case undoEditCommand:
+		return handleUndoEdit(path)
+	default:
+		return "", fmt.Errorf("command %s is not implemented", cmd)
+	}
+}
+
+// Utility function to check if a command is valid
+func isValidCommand(cmd editCommand) bool {
+	switch cmd {
+	case viewCommand, createCommand, strReplaceCommand, insertCommand, undoEditCommand:
+		return true
+	default:
+		return false
+	}
+}
+
+// validatePath checks if the path/command combination is valid
+func validatePath(cmd editCommand, path string) error {
+	// Check if it's an absolute path
+	if !filepath.IsAbs(path) {
+		suggestedPath := "/" + path
+		return fmt.Errorf("the path %s is not an absolute path, it should start with '/'. Maybe you meant %s?", path, suggestedPath)
+	}
+
+	// Get file info
+	info, err := os.Stat(path)
+
+	// Check if path exists (except for create command)
+	if err != nil {
+		if os.IsNotExist(err) && cmd != createCommand {
+			return fmt.Errorf("the path %s does not exist. Please provide a valid path", path)
+		} else if !os.IsNotExist(err) {
+			return fmt.Errorf("error accessing path %s: %v", path, err)
+		}
+	} else {
+		// Path exists, check if it's a directory
+		if info.IsDir() && cmd != viewCommand {
+			return fmt.Errorf("the path %s is a directory and only the 'view' command can be used on directories", path)
+		}
+
+		// For create command, check if file already exists
+		if cmd == createCommand {
+			return fmt.Errorf("file already exists at: %s. Cannot overwrite files using command 'create'", path)
+		}
+	}
+
+	return nil
+}
+
+// handleView implements the view command
+func handleView(ctx context.Context, path string, viewRange []int) (string, error) {
+	info, err := os.Stat(path)
+	if err != nil {
+		return "", fmt.Errorf("error accessing path %s: %v", path, err)
+	}
+
+	// Handle directory view
+	if info.IsDir() {
+		if viewRange != nil {
+			return "", fmt.Errorf("the view_range parameter is not allowed when path points to a directory")
+		}
+
+		// List files in the directory (up to 2 levels deep)
+		return listDirectory(ctx, path)
+	}
+
+	// Handle file view
+	fileContent, err := readFile(path)
+	if err != nil {
+		return "", err
+	}
+
+	initLine := 1
+	if viewRange != nil {
+		if len(viewRange) != 2 {
+			return "", fmt.Errorf("invalid view_range. It should be a list of two integers")
+		}
+
+		fileLines := strings.Split(fileContent, "\n")
+		nLinesFile := len(fileLines)
+		initLine, finalLine := viewRange[0], viewRange[1]
+
+		if initLine < 1 || initLine > nLinesFile {
+			return "", fmt.Errorf("invalid view_range: %v. Its first element %d should be within the range of lines of the file: [1, %d]",
+				viewRange, initLine, nLinesFile)
+		}
+
+		if finalLine != -1 && finalLine < initLine {
+			return "", fmt.Errorf("invalid view_range: %v. Its second element %d should be larger or equal than its first %d",
+				viewRange, finalLine, initLine)
+		}
+
+		if finalLine > nLinesFile {
+			return "", fmt.Errorf("invalid view_range: %v. Its second element %d should be smaller than the number of lines in the file: %d",
+				viewRange, finalLine, nLinesFile)
+		}
+
+		if finalLine == -1 {
+			fileContent = strings.Join(fileLines[initLine-1:], "\n")
+		} else {
+			fileContent = strings.Join(fileLines[initLine-1:finalLine], "\n")
+		}
+	}
+
+	return makeOutput(fileContent, path, initLine), nil
+}
+
+// handleCreate implements the create command
+func handleCreate(path string, fileText string) (string, error) {
+	// Ensure the directory exists
+	dir := filepath.Dir(path)
+	if err := os.MkdirAll(dir, 0o755); err != nil {
+		return "", fmt.Errorf("failed to create directory %s: %v", dir, err)
+	}
+
+	// Write the file
+	if err := writeFile(path, fileText); err != nil {
+		return "", err
+	}
+
+	// Save to history
+	fileHistory[path] = append(fileHistory[path], fileText)
+
+	return fmt.Sprintf("File created successfully at: %s", path), nil
+}
+
+// handleStrReplace implements the str_replace command
+func handleStrReplace(path, oldStr, newStr string) (string, error) {
+	// Read the file content
+	fileContent, err := readFile(path)
+	if err != nil {
+		return "", err
+	}
+
+	// Replace tabs with spaces
+	fileContent = maybeExpandTabs(path, fileContent)
+	oldStr = maybeExpandTabs(path, oldStr)
+	newStr = maybeExpandTabs(path, newStr)
+
+	// Check if oldStr is unique in the file
+	occurrences := strings.Count(fileContent, oldStr)
+	if occurrences == 0 {
+		return "", fmt.Errorf("no replacement was performed, old_str %q did not appear verbatim in %s", oldStr, path)
+	} else if occurrences > 1 {
+		// Find line numbers where oldStr appears
+		fileContentLines := strings.Split(fileContent, "\n")
+		var lines []int
+		for idx, line := range fileContentLines {
+			if strings.Contains(line, oldStr) {
+				lines = append(lines, idx+1)
+			}
+		}
+		return "", fmt.Errorf("no replacement was performed. Multiple occurrences of old_str %q in lines %v. Please ensure it is unique", oldStr, lines)
+	}
+
+	// Save the current content to history
+	fileHistory[path] = append(fileHistory[path], fileContent)
+
+	// Replace oldStr with newStr
+	newFileContent := strings.Replace(fileContent, oldStr, newStr, 1)
+
+	// Write the new content to the file
+	if err := writeFile(path, newFileContent); err != nil {
+		return "", err
+	}
+
+	// Create a snippet of the edited section
+	parts := strings.Split(fileContent, oldStr)
+	if len(parts) == 0 {
+		// This should never happen due to the earlier check, but let's be safe
+		parts = []string{""}
+	}
+	replacementLine := strings.Count(parts[0], "\n")
+	startLine := max(0, replacementLine-snippetLines)
+	endLine := replacementLine + snippetLines + strings.Count(newStr, "\n")
+	fileLines := strings.Split(newFileContent, "\n")
+	if len(fileLines) == 0 {
+		fileLines = []string{""}
+	}
+	endLine = min(endLine+1, len(fileLines))
+	snippet := strings.Join(fileLines[startLine:endLine], "\n")
+
+	// Prepare the success message
+	successMsg := fmt.Sprintf("The file %s has been edited. ", path)
+	successMsg += makeOutput(snippet, fmt.Sprintf("a snippet of %s", path), startLine+1)
+	successMsg += "Review the changes and make sure they are as expected. Edit the file again if necessary."
+
+	return successMsg, nil
+}
+
+// handleInsert implements the insert command
+func handleInsert(path string, insertLine int, newStr string) (string, error) {
+	// Read the file content
+	fileContent, err := readFile(path)
+	if err != nil {
+		return "", err
+	}
+
+	// Replace tabs with spaces
+	fileContent = maybeExpandTabs(path, fileContent)
+	newStr = maybeExpandTabs(path, newStr)
+
+	// Split the file content into lines
+	fileTextLines := strings.Split(fileContent, "\n")
+	nLinesFile := len(fileTextLines)
+
+	// Validate insert line
+	if insertLine < 0 || insertLine > nLinesFile {
+		return "", fmt.Errorf("invalid insert_line parameter: %d. It should be within the range of lines of the file: [0, %d]",
+			insertLine, nLinesFile)
+	}
+
+	// Save the current content to history
+	fileHistory[path] = append(fileHistory[path], fileContent)
+
+	// Split the new string into lines
+	newStrLines := strings.Split(newStr, "\n")
+
+	// Create new content by inserting the new lines
+	newFileTextLines := make([]string, 0, nLinesFile+len(newStrLines))
+	newFileTextLines = append(newFileTextLines, fileTextLines[:insertLine]...)
+	newFileTextLines = append(newFileTextLines, newStrLines...)
+	newFileTextLines = append(newFileTextLines, fileTextLines[insertLine:]...)
+
+	// Create a snippet of the edited section
+	snippetStart := max(0, insertLine-snippetLines)
+	snippetEnd := min(insertLine+snippetLines, nLinesFile)
+
+	snippetLines := make([]string, 0)
+	snippetLines = append(snippetLines, fileTextLines[snippetStart:insertLine]...)
+	snippetLines = append(snippetLines, newStrLines...)
+	snippetLines = append(snippetLines, fileTextLines[insertLine:snippetEnd]...)
+	snippet := strings.Join(snippetLines, "\n")
+
+	// Write the new content to the file
+	newFileText := strings.Join(newFileTextLines, "\n")
+	if err := writeFile(path, newFileText); err != nil {
+		return "", err
+	}
+
+	// Prepare the success message
+	successMsg := fmt.Sprintf("The file %s has been edited. ", path)
+	successMsg += makeOutput(snippet, "a snippet of the edited file", max(1, insertLine-4+1))
+	successMsg += "Review the changes and make sure they are as expected (correct indentation, no duplicate lines, etc). Edit the file again if necessary."
+
+	return successMsg, nil
+}
+
+// handleUndoEdit implements the undo_edit command
+func handleUndoEdit(path string) (string, error) {
+	history, exists := fileHistory[path]
+	if !exists || len(history) == 0 {
+		return "", fmt.Errorf("no edit history found for %s", path)
+	}
+
+	// Get the last edit and remove it from history
+	lastIdx := len(history) - 1
+	oldText := history[lastIdx]
+	fileHistory[path] = history[:lastIdx]
+
+	// Write the old content back to the file
+	if err := writeFile(path, oldText); err != nil {
+		return "", err
+	}
+
+	return fmt.Sprintf("Last edit to %s undone successfully. %s", path, makeOutput(oldText, path, 1)), nil
+}
+
+// listDirectory lists files and directories up to 2 levels deep
+func listDirectory(ctx context.Context, path string) (string, error) {
+	cmd := fmt.Sprintf("find %s -maxdepth 2 -not -path '*/\\.*'", path)
+	output, err := executeCommand(ctx, cmd)
+	if err != nil {
+		return "", fmt.Errorf("failed to list directory: %v", err)
+	}
+
+	return fmt.Sprintf("Here's the files and directories up to 2 levels deep in %s, excluding hidden items:\n%s\n", path, output), nil
+}
+
+// executeCommand executes a shell command and returns its output
+func executeCommand(ctx context.Context, cmd string) (string, error) {
+	// This is a simplified version without timeouts for now
+	bash := exec.CommandContext(ctx, "bash", "-c", cmd)
+	bash.Dir = WorkingDir(ctx)
+	output, err := bash.CombinedOutput()
+	if err != nil {
+		return "", fmt.Errorf("command execution failed: %v: %s", err, string(output))
+	}
+	return maybetruncate(string(output)), nil
+}
+
+// readFile reads the content of a file
+func readFile(path string) (string, error) {
+	content, err := os.ReadFile(path)
+	if err != nil {
+		return "", fmt.Errorf("failed to read file %s: %v", path, err)
+	}
+	return string(content), nil
+}
+
+// writeFile writes content to a file
+func writeFile(path, content string) error {
+	if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
+		return fmt.Errorf("failed to write to file %s: %v", path, err)
+	}
+	return nil
+}
+
+// makeOutput generates a formatted output for the CLI
+func makeOutput(fileContent, fileDescriptor string, initLine int) string {
+	fileContent = maybetruncate(fileContent)
+	fileContent = maybeExpandTabs(fileDescriptor, fileContent)
+
+	var lines []string
+	for i, line := range strings.Split(fileContent, "\n") {
+		lines = append(lines, fmt.Sprintf("%6d\t%s", i+initLine, line))
+	}
+
+	return fmt.Sprintf("Here's the result of running `cat -n` on %s:\n%s\n", fileDescriptor, strings.Join(lines, "\n"))
+}
+
+// maybetruncate truncates content and appends a notice if content exceeds the specified length
+func maybetruncate(content string) string {
+	if len(content) <= maxResponseLen {
+		return content
+	}
+	return content[:maxResponseLen] + truncatedMessage
+}
+
+// maybeExpandTabs is currently a no-op. The python
+// implementation replaces tabs with spaces, but this strikes
+// me as unwise for our tool.
+func maybeExpandTabs(path, s string) string {
+	// return strings.ReplaceAll(s, "\t", "    ")
+	return s
+}
