Skip to main content

Memory & Context Editing

Advanced

A long-running agent has two enemies: it forgets what it learned the moment the conversation ends, and its context window fills up with stale tool output until it overflows. Anthropic ships one primitive for each — the memory tool (persistence) and context editing (pruning) — and they are designed to be used together.

:::note Two different "memory" primitives — don't confuse them This page covers the client-side memory tool for the Messages API — Claude calls tools, you store the files. If you're using Managed Agents instead, the equivalent is the server-side Memory Stores API — Anthropic hosts the store, mounts it into the sandbox at /mnt/memory/, and gives you versioning + a redact endpoint. Different header (agent-memory-2026-07-22), different mental model. :::

What you'll learn
  • What the memory tool is — a client-side file store at /memories that you implement, not Anthropic
  • The six commands your handler must answer: view, create, str_replace, insert, delete, rename
  • Why path-traversal validation is non-negotiable when you wire it up
  • How context editing auto-clears old tool results once the context crosses a token threshold
  • How to combine both under one beta header, and the gotchas with caching and ordering

Two problems, two tools

Keep the two ideas separate in your head:

  • Memory tool = persistence across sessions. Claude reads and writes files; you store them.
  • Context editing = pruning within a session. The API drops stale tool results from the prompt before it reaches Claude.

This page pairs with Prompt Caching and the token economy for the cost side, and with Context Engineering and long-running agent harnesses for the why.

Memory & context vocabulary
Press Enter or Space to flip the card. Use the left and right arrow keys to move between cards.Term shown.
1 / 5

The memory tool is a tool you implement

This trips people up: enabling the memory tool does not give you Anthropic-hosted storage. It is a client-side tool. Claude emits tool calls like view or create; your application executes them against whatever backend you choose — local files, a database, encrypted blobs, cloud storage — and returns the result. You own where the bytes live (which is also why it is Zero-Data-Retention-eligible).

When the tool is enabled, Anthropic injects a system instruction telling Claude to check its memory directory before doing anything else, and to record progress as it works so nothing is lost if the context resets.

Step 1 — enable the tool

Add the tool to your request. The type string is the dated version memory_20250818.

import anthropic

client = anthropic.Anthropic()

message = client.messages.create(
model="claude-opus-5",
max_tokens=2048,
messages=[{"role": "user", "content": "Help me respond to this support ticket."}],
tools=[{"type": "memory_20250818", "name": "memory"}],
)

print(message)

The official SDKs ship memory helpers so you don't hand-roll the tool interface — subclass BetaAbstractMemoryTool (Python, C#), use betaMemoryTool (TypeScript), or implement BetaMemoryToolHandler (Java). They hand you a clean hook where you plug in your storage.

Step 2 — answer the six commands

Your handler must implement these. The strings Claude expects back are specific — match them so the model interprets results correctly.

Guided walkthrough1 of 6
  1. List a directory (files up to 2 levels deep, with human-readable sizes) or return a file's contents with 1-indexed line numbers. Optional view_range to read a slice.

A real view of the directory returns something like this — note the literal header and tab-separated sizes, which the model is trained to parse:

Here're the files and directories up to 2 levels deep in /memories, excluding hidden items and node_modules:
4.0K /memories
1.5K /memories/customer_service_guidelines.xml
2.0K /memories/refund_policies.xml

Step 3 — lock down paths (do not skip this)

The memory tool lets a model emit arbitrary path strings. A poisoned conversation or prompt-injection payload can try to escape /memories and read or clobber files elsewhere on your box. Treat every incoming path as hostile.

Watch out
  • Reject any path that does not resolve to inside /memories.
  • Canonicalize before checking — in Python, Path(p).resolve() then verify .relative_to(memories_root) does not raise.
  • Block ../, ..\, and URL-encoded traversal like %2e%2e%2f.
  • Cap file sizes and read length so a runaway agent can't exhaust disk or blow up the next prompt.

This validator is the whole ballgame — pin it and test it before anything else ships:

Path-traversal guard (Python)

from pathlib import Path

MEMORY_ROOT = Path("/srv/agent/memories").resolve()

def safe_path(requested: str) -> Path:
  # Map the model's /memories/... onto your real root, then prove containment.
  rel = requested.removeprefix("/memories").lstrip("/")
  candidate = (MEMORY_ROOT / rel).resolve()
  candidate.relative_to(MEMORY_ROOT)  # raises ValueError if it escaped
  return candidate

Context editing keeps the window from overflowing

Memory solves forgetting. The opposite problem — a context window stuffed with old tool_result blocks from 40 web searches ago — is what context editing solves. Once the prompt crosses a token threshold, the API clears the oldest tool results (replacing them with a short placeholder so Claude knows they were removed) before the prompt is sent to the model. Your client keeps the full, unedited history; only what reaches the model is trimmed.

It rides on a beta header:

anthropic-beta: context-management-2025-06-27

You configure it with a context_management.edits array. The main strategy is clear_tool_uses_20250919:

message = client.beta.messages.create(
model="claude-opus-5",
max_tokens=2048,
betas=["context-management-2025-06-27"],
messages=[...],
tools=[{"type": "memory_20250818", "name": "memory"}],
context_management={
"edits": [
{
"type": "clear_tool_uses_20250919",
"trigger": {"type": "input_tokens", "value": 30000}, # start clearing past 30k
"keep": {"type": "tool_uses", "value": 3}, # always keep the last 3
"clear_at_least": {"type": "input_tokens", "value": 5000},
"exclude_tools": ["memory"], # never clear memory calls
"clear_tool_inputs": False, # keep the call args, drop results
}
]
},
)

What the knobs mean:

ParameterDefaultWhat it controls
trigger100,000 input tokensWhen clearing kicks in
keep3 tool usesHow many recent tool use/result pairs are always preserved
clear_at_leastnoneMinimum tokens freed per activation — use it so a cache invalidation is actually worth it
exclude_toolsnoneTools never cleared (e.g. memory, web_search)
clear_tool_inputsfalseWhether to also drop the tool call args, not just the result

The response tells you what it did, under context_management.applied_edits — e.g. cleared_tool_uses and cleared_input_tokens — so you can log how much was reclaimed.

There is a sibling strategy, clear_thinking_20251015, that prunes old extended-thinking blocks. If you use both, list clear_thinking_20251015 first in the edits array.

Pro tip
  • Clearing tool results invalidates any prompt-cache prefix at the clear point — pair it with clear_at_least so you only pay that invalidation when you're freeing a meaningful chunk.
  • exclude_tools: ["memory"] is the usual move: you want the agent's own notes to persist, not get swept away with stale search results.
  • Context editing (client-side trim) and compaction (server-side summarization) are different features — for very long runs you can layer both.

Why pair them — the numbers

Used together, the two features let an agent run far past a single context window: context editing keeps the live window lean, and whatever matters gets written to memory before it would be cleared. Anthropic reports that combining memory with context editing gave a 39% improvement on an agentic-search evaluation, and that context editing alone cut token use by 84% in a 100-turn web-search test.

A pattern that works: the multi-session project log

The cleanest use of memory is bootstrapping it deliberately instead of writing files ad hoc:

Guided walkthrough1 of 4
  1. Before any real work, write a progress log, a feature checklist, and a note pointing to any startup script the project needs.

Test your understanding

Check yourself

0/3
  1. Where does memory-tool data actually get stored?
  2. What does context editing's clear_tool_uses_20250919 strategy remove?
  3. Why must you validate every path the memory tool receives?

Sources & further reading