Skip to main content
Claude Code ships four built-in tools for interacting with files: FileReadTool, FileEditTool, FileWriteTool, and NotebookEditTool. Together they cover the full read-modify-write loop for text files, images, PDFs, and Jupyter notebooks.

FileReadTool

Read text, images, PDFs, and notebooks from disk

FileEditTool

In-place string replacement inside an existing file

FileWriteTool

Create or fully overwrite a file

NotebookEditTool

Add, replace, or delete Jupyter notebook cells

FileReadTool

Reads a file from the local filesystem and returns its contents. Handles plain text, images (PNG, JPEG, GIF, WebP), PDFs, and Jupyter notebooks (.ipynb) transparently based on file extension. Tool name: Read
Read-only: yes
Concurrency-safe: yes
Destructive: no

Parameters

file_path
string
required
Absolute path to the file to read. Tilde (~) and relative segments are expanded automatically.
offset
number
Line number (1-indexed) to start reading from. Omit to read from the beginning. Only relevant for text files.
limit
number
Maximum number of lines to return. Omit to read to the end of the file (subject to the per-session token limit).
pages
string
Page range for PDF files, e.g. "1-5", "3", or "10-20". Only applies to .pdf files. Maximum 20 pages per request. Pages are 1-indexed.

Return value

The return type is a discriminated union keyed on type:
typeDescription
textPlain text with filePath, content, numLines, startLine, totalLines
imageBase64-encoded image with base64, media type, originalSize, and optional dimensions
notebookJupyter notebook with filePath and cells array
pdfBase64-encoded PDF with filePath, base64, and originalSize
file_unchangedDeduplication stub — file content is identical to a prior read still in context
Lines are returned with N: prefixes (e.g. 1: import React from 'react') to make line-number references unambiguous.

Concurrency and staleness

FileReadTool stores a modification-time snapshot in readFileState for every file it reads. FileEditTool and FileWriteTool check this snapshot before writing and refuse to proceed if the file has been modified since the last read.
You must read a file before editing it. Attempting to call FileEditTool or FileWriteTool on a file that has not been read in the current session returns an error.

Usage example

{
  "tool": "Read",
  "input": {
    "file_path": "/home/user/project/src/index.ts",
    "offset": 1,
    "limit": 50
  }
}
Reading a specific page range of a PDF:
{
  "tool": "Read",
  "input": {
    "file_path": "/home/user/docs/report.pdf",
    "pages": "1-5"
  }
}

Blocked paths

For security, the tool refuses to read device files that produce infinite output or block on input: /dev/zero, /dev/random, /dev/urandom, /dev/stdin, /dev/tty, and their /proc/self/fd/ aliases.

FileEditTool

Performs an exact in-place string replacement inside an existing file. The model supplies the literal text to find (old_string) and the literal text to write in its place (new_string). Tool name: Edit
Read-only: no
Concurrency-safe: no
Destructive: yes (modifies file in-place; a backup can be enabled via file history)

Parameters

file_path
string
required
Absolute path to the file to modify.
old_string
string
required
The exact text to search for and replace. Must match a unique substring of the file (use more context if the string appears more than once and replace_all is false). Pass an empty string to write to an empty or non-existent file.
new_string
string
required
The text to replace old_string with. Must differ from old_string.
replace_all
boolean
default:"false"
When true, all occurrences of old_string in the file are replaced. When false (default), the tool rejects the call if old_string appears more than once.

Return value

On success the tool returns a FileEditOutput object:
filePath
string
Path to the file that was edited.
oldString
string
The actual string that was replaced (may differ slightly from old_string due to quote-style normalization).
newString
string
The replacement text.
structuredPatch
array
Unified-diff hunks describing the change.
userModified
boolean
true if the user manually edited the proposed change before approving it.

Validation rules

The tool performs several checks before writing:
  1. old_string and new_string must differ.
  2. The file must have been read in the current session (FileReadTool updates the cache).
  3. The file must not have been modified since the last read (stale-write guard).
  4. When replace_all is false, old_string must appear exactly once.
  5. .ipynb files must be edited with NotebookEditTool instead.

Usage example

{
  "tool": "Edit",
  "input": {
    "file_path": "/home/user/project/src/utils.ts",
    "old_string": "function add(a, b) {\n  return a + b\n}",
    "new_string": "function add(a: number, b: number): number {\n  return a + b\n}"
  }
}
Include several lines of surrounding context in old_string when the target string is short or likely to appear elsewhere in the file. This ensures the correct occurrence is replaced.

FileWriteTool

Creates a new file or fully overwrites an existing file with the supplied content. Unlike FileEditTool, this is a whole-file operation — use it for new files or when a large portion of the file changes. Tool name: Write
Read-only: no
Concurrency-safe: no
Destructive: yes (existing content is replaced)

Parameters

file_path
string
required
Absolute path to the file to write. Parent directories are created automatically.
content
string
required
The full content to write to the file. The tool always uses LF (\n) line endings regardless of the platform or previous file content.

Return value

type
string
Either "create" (new file) or "update" (existing file overwritten).
filePath
string
Path to the file that was written.
content
string
The content that was written.
structuredPatch
array
Diff hunks relative to the previous content (empty array for new files).
originalFile
string | null
The previous file content before the write, or null for new files.

Staleness guard

Like FileEditTool, FileWriteTool refuses to overwrite a file that has changed on disk since it was last read. Read the file first if you need to overwrite an existing one.

Usage example

{
  "tool": "Write",
  "input": {
    "file_path": "/home/user/project/README.md",
    "content": "# My Project\n\nA short description.\n"
  }
}

NotebookEditTool

Edits cells inside a Jupyter notebook (.ipynb). Supports inserting new cells, replacing cell source, and deleting cells. FileEditTool will reject .ipynb files and redirect to this tool. Tool name: NotebookEdit
Read-only: no
Concurrency-safe: no
Destructive: yes (modifies notebook in-place)

Parameters

notebook_path
string
required
Absolute path to the Jupyter notebook file.
cell_id
string
The ID of the target cell. For replace and delete modes, identifies the cell to operate on. For insert mode, the new cell is inserted after this cell (omit to insert at the beginning).
new_source
string
required
The source code or markdown text for the cell.
cell_type
string
Cell type: "code" or "markdown". Required when edit_mode is "insert". Defaults to the existing cell’s type for replace.
edit_mode
string
default:"replace"
Operation to perform:
  • "replace" — update an existing cell’s source (default)
  • "insert" — add a new cell after cell_id
  • "delete" — remove the cell identified by cell_id

Usage example

Inserting a new markdown cell at the top of a notebook:
{
  "tool": "NotebookEdit",
  "input": {
    "notebook_path": "/home/user/analysis/notebook.ipynb",
    "new_source": "## Data Cleaning\n\nRemove nulls and normalize column types.",
    "cell_type": "markdown",
    "edit_mode": "insert"
  }
}
Replacing an existing code cell:
{
  "tool": "NotebookEdit",
  "input": {
    "notebook_path": "/home/user/analysis/notebook.ipynb",
    "cell_id": "abc123",
    "new_source": "df = pd.read_csv('data.csv')\ndf.dropna(inplace=True)",
    "cell_type": "code",
    "edit_mode": "replace"
  }
}

Build docs developers (and LLMs) love