> ## Documentation Index
> Fetch the complete documentation index at: https://langchain-5e9cc07a-preview-opensw-1781706951-9d0138e.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Anthropic middleware integration

> Integrate with the Anthropic middleware using LangChain Python.

Middleware specifically designed for Anthropic's Claude models. Learn more about [middleware](/oss/python/langchain/middleware/overview).

| Middleware                        | Description                                                    |
| --------------------------------- | -------------------------------------------------------------- |
| [Prompt caching](#prompt-caching) | Reduce costs by caching repetitive prompt prefixes             |
| [Bash tool](#bash-tool)           | Execute Claude's native bash tool with local command execution |
| [Text editor](#text-editor)       | Provide Claude's text editor tool for file editing             |
| [Memory](#memory)                 | Provide Claude's memory tool for persistent agent memory       |
| [File search](#file-search)       | Search tools for state-based file systems                      |

## Middleware vs tools

`langchain-anthropic` provides two ways to use Claude's native tools:

* **Middleware** (this page): Production-ready implementations with built-in execution, state management, and security policies
* **Tools** (via [`bind_tools`](/oss/python/integrations/chat/anthropic#built-in-tools)): Low-level building blocks where you provide your own execution logic

### When to use which

| Use case                                                                                                                           | Recommended | Why                                                                                                                |
| ---------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------ |
| Production agents with bash                                                                                                        | Middleware  | Persistent sessions, Docker isolation, output redaction                                                            |
| State-based file editing                                                                                                           | Middleware  | Built-in LangGraph state persistence                                                                               |
| Filesystem file editing                                                                                                            | Middleware  | Writes to disk with path validation                                                                                |
| Custom execution logic                                                                                                             | Tools       | Full control over execution                                                                                        |
| Quick prototype                                                                                                                    | Tools       | Simpler, bring your own callback                                                                                   |
| Non-agent use with [`bind_tools`](https://reference.langchain.com/python/langchain-anthropic/chat_models/ChatAnthropic/bind_tools) | Tools       | Middleware requires [`create_agent`](https://reference.langchain.com/python/langchain/agents/factory/create_agent) |

### Feature comparison

| Feature                                                                                                                    | Middleware | Tools |
| -------------------------------------------------------------------------------------------------------------------------- | :--------: | :---: |
| Works with [`create_agent`](https://reference.langchain.com/python/langchain/agents/factory/create_agent)                  |      ✅     |   ✅   |
| Works with [`bind_tools`](https://reference.langchain.com/python/langchain-anthropic/chat_models/ChatAnthropic/bind_tools) |      ❌     |   ✅   |
| Built-in state management                                                                                                  |      ✅     |   ❌   |
| Custom execute callback                                                                                                    |      ❌     |   ✅   |

<Accordion title="Example: Middleware vs tools comparison">
  **Using middleware** (turnkey solution):

  ```python theme={null}
  from langchain_anthropic import ChatAnthropic
  from langchain_anthropic.middleware import ClaudeBashToolMiddleware
  from langchain.agents import create_agent
  from langchain.agents.middleware import DockerExecutionPolicy

  # Production-ready with Docker isolation, session management, etc.
  agent = create_agent(
      model=ChatAnthropic(model="claude-sonnet-4-6"),
      middleware=[
          ClaudeBashToolMiddleware(
              workspace_root="/workspace",
              execution_policy=DockerExecutionPolicy(image="python:3.11"),
              startup_commands=["pip install pandas"],
          ),
      ],
  )
  ```

  **Using tools** (bring your own execution):

  ```python theme={null}
  import subprocess

  from anthropic.types.beta import BetaToolBash20250124Param
  from langchain_anthropic import ChatAnthropic
  from langchain.agents import create_agent
  from langchain.tools import tool

  tool_spec = BetaToolBash20250124Param(
      name="bash",
      type="bash_20250124",
      strict=True,
  )

  @tool(extras={"provider_tool_definition": tool_spec})
  def bash(*, command: str, restart: bool = False, **kw):
      """Execute a bash command."""
      if restart:
          return "Bash session restarted"
      try:
          result = subprocess.run(
              command,
              shell=True,
              capture_output=True,
              text=True,
              timeout=30,
          )
          return result.stdout + result.stderr
      except Exception as e:
          return f"Error: {e}"


  agent = create_agent(
      model=ChatAnthropic(model="claude-sonnet-4-6"),
      tools=[bash],
  )

  result = agent.invoke(
      {"messages": [{"role": "user", "content": "List files in this directory"}]}
  )
  print(result["messages"][-1].content)
  ```
</Accordion>

***

## Prompt caching

Reduce costs and latency by caching static or repetitive prompt content (like system prompts, tool definitions, and conversation history) on Anthropic's servers. This middleware implements a **conversational caching strategy** that places explicit cache breakpoints on the system message, tool definitions, and the most recent user message, allowing the entire conversation history to be cached and reused in subsequent API calls.

Prompt caching is useful for the following:

* Applications with long, static system prompts that don't change between requests
* Agents with many tool definitions that remain constant across invocations
* Conversations where early message history is reused across multiple turns
* High-volume deployments where reducing API costs and latency is critical

<Tip>
  For simpler use cases, you can also use [automatic caching](/oss/python/integrations/chat/anthropic#automatic-caching) by passing `cache_control` at invocation time without middleware. The middleware is recommended when you need explicit control over cache breakpoints on system prompts and tool definitions.
</Tip>

<Info>
  Learn more about [Anthropic prompt caching](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#cache-limitations) strategies and limitations.
</Info>

**API reference:** [`AnthropicPromptCachingMiddleware`](https://reference.langchain.com/python/langchain-anthropic/middleware/prompt_caching/AnthropicPromptCachingMiddleware)

```python theme={null}
from langchain_anthropic import ChatAnthropic
from langchain_anthropic.middleware import AnthropicPromptCachingMiddleware
from langchain.agents import create_agent

agent = create_agent(
    model=ChatAnthropic(model="claude-sonnet-4-6"),
    system_prompt="<Your long system prompt here>",
    middleware=[AnthropicPromptCachingMiddleware(ttl="5m")], # [!code highlight]
)
```

<Accordion title="Configuration options">
  <ParamField body="type" type="string" default="ephemeral">
    Cache type. Only `'ephemeral'` is currently supported.
  </ParamField>

  <ParamField body="ttl" type="string" default="5m">
    Time to live for cached content. Valid values: `'5m'` or `'1h'`
  </ParamField>

  <ParamField body="min_messages_to_cache" type="number" default="0">
    Minimum number of messages before caching starts
  </ParamField>

  <ParamField body="unsupported_model_behavior" type="string" default="warn">
    Behavior when using non-Anthropic models. Options: `'ignore'`, `'warn'`, or `'raise'`
  </ParamField>
</Accordion>

<Accordion title="Full example">
  The middleware caches content up to and including the latest message in each request. On subsequent requests within the TTL window (5 minutes or 1 hour), previously seen content is retrieved from cache rather than reprocessed, significantly reducing costs and latency.

  **How it works:**

  1. First request: System prompt, tools, and the user message *"Hi, my name is Bob"* are sent to the API and cached
  2. Second request: The cached content (system prompt, tools, and first message) is retrieved from cache. Only the new message *"What's my name?"* needs to be processed, plus the model's response from the first request
  3. This pattern continues for each turn, with each request reusing the cached conversation history

  <Note>
    Prompt caching reduces API costs by caching tokens, but does **not** provide conversation memory. To persist conversation history across invocations, use a [checkpointer](https://langchain-ai.github.io/langgraph/concepts/persistence/#checkpointer-libraries) like `MemorySaver`.
  </Note>

  ```python theme={null}
  from langchain_anthropic import ChatAnthropic
  from langchain_anthropic.middleware import AnthropicPromptCachingMiddleware
  from langchain.agents import create_agent
  from langchain.messages import HumanMessage
  from langchain_core.runnables import RunnableConfig
  from langgraph.checkpoint.memory import MemorySaver


  LONG_PROMPT = """
  Please be a helpful assistant.

  <Lots more context ...>
  """

  agent = create_agent(
      model=ChatAnthropic(model="claude-sonnet-4-6"),
      system_prompt=LONG_PROMPT,
      middleware=[AnthropicPromptCachingMiddleware(ttl="5m")], # [!code highlight]
      checkpointer=MemorySaver(),  # Persists conversation history
  )

  # Use a thread_id to maintain conversation state
  config: RunnableConfig = {"configurable": {"thread_id": "user-123"}}

  # First invocation: Creates cache with system prompt, tools, and "Hi, my name is Bob"
  agent.invoke({"messages": [HumanMessage("Hi, my name is Bob")]}, config=config)

  # Second invocation: Reuses cached system prompt, tools, and previous messages
  # The checkpointer maintains conversation history, so the agent remembers "Bob"
  result = agent.invoke({"messages": [HumanMessage("What's my name?")]}, config=config)
  print(result["messages"][-1].content)
  ```

  ```text theme={null}
  Your name is Bob! You told me that when you introduced yourself at the start of our conversation.
  ```
</Accordion>

## Bash tool

Execute Claude's native `bash_20250124` tool with local command execution.

The bash tool middleware is useful for the following:

* Using Claude's built-in bash tool with local execution
* Leveraging Claude's optimized bash tool interface
* Agents that need persistent shell sessions with Anthropic models

<Info>
  This middleware wraps `ShellToolMiddleware` and exposes it as Claude's native bash tool.
</Info>

**API reference:** [`ClaudeBashToolMiddleware`](https://reference.langchain.com/python/langchain-anthropic/middleware/bash/ClaudeBashToolMiddleware)

```python theme={null}
from langchain_anthropic import ChatAnthropic
from langchain_anthropic.middleware import ClaudeBashToolMiddleware
from langchain.agents import create_agent

agent = create_agent(
    model=ChatAnthropic(model="claude-sonnet-4-6"),
    tools=[],
    middleware=[ # [!code highlight]
        ClaudeBashToolMiddleware( # [!code highlight]
            workspace_root="/workspace", # [!code highlight]
        ), # [!code highlight]
    ], # [!code highlight]
)
```

<Accordion title="Configuration options">
  `ClaudeBashToolMiddleware` accepts all parameters from [`ShellToolMiddleware`](https://reference.langchain.com/python/langchain/agents/middleware/shell_tool/ShellToolMiddleware), including:

  <ParamField body="workspace_root" type="str | Path | None">
    Base directory for the shell session
  </ParamField>

  <ParamField body="startup_commands" type="tuple[str, ...] | list[str] | str | None">
    Commands to run when the session starts
  </ParamField>

  <ParamField body="execution_policy" type="BaseExecutionPolicy | None">
    Execution policy (`HostExecutionPolicy`, `DockerExecutionPolicy`, or `CodexSandboxExecutionPolicy`)
  </ParamField>

  <ParamField body="redaction_rules" type="tuple[RedactionRule, ...] | list[RedactionRule] | None">
    Rules for sanitizing command output
  </ParamField>

  See [Shell tool](/oss/python/langchain/middleware/built-in#shell-tool) for full configuration details.
</Accordion>

<Accordion title="Full example">
  ```python theme={null}
  import tempfile

  from langchain_anthropic import ChatAnthropic
  from langchain_anthropic.middleware import ClaudeBashToolMiddleware
  from langchain.agents import create_agent
  from langchain.agents.middleware import DockerExecutionPolicy

  # Create a temporary workspace directory for this demo.
  # In production, use a persistent directory path.
  workspace = tempfile.mkdtemp(prefix="agent-workspace-")

  agent = create_agent(
      model=ChatAnthropic(model="claude-sonnet-4-6"),
      tools=[],
      middleware=[ # [!code highlight]
          ClaudeBashToolMiddleware( # [!code highlight]
              workspace_root=workspace, # [!code highlight]
              startup_commands=["echo 'Session initialized'"], # [!code highlight]
              execution_policy=DockerExecutionPolicy( # [!code highlight]
                  image="python:3.11-slim", # [!code highlight]
              ), # [!code highlight]
          ), # [!code highlight]
      ], # [!code highlight]
  )

  # Claude can now use its native bash tool
  result = agent.invoke(
      {"messages": [{"role": "user", "content": "What version of Python is installed?"}]}
  )
  print(result["messages"][-1].content)
  ```

  ```text theme={null}
  Python 3.11.14 is installed.
  ```
</Accordion>

## Text editor

Provide Claude's text editor tool (`text_editor_20250728`) for file creation and editing.

The text editor middleware is useful for the following:

* File-based agent workflows
* Code editing and refactoring tasks
* Multi-file project work
* Agents that need persistent file storage

<Note>
  Available in two variants: **State-based** (files in LangGraph state) and **Filesystem-based** (files on disk).
</Note>

**API references:**

* [`StateClaudeTextEditorMiddleware`](https://reference.langchain.com/python/langchain-anthropic/middleware/anthropic_tools/StateClaudeTextEditorMiddleware)
* [`FilesystemClaudeTextEditorMiddleware`](https://reference.langchain.com/python/langchain-anthropic/middleware/anthropic_tools/FilesystemClaudeTextEditorMiddleware)

```python State-based text editor theme={null}
from langchain_anthropic import ChatAnthropic
from langchain_anthropic.middleware import StateClaudeTextEditorMiddleware
from langchain.agents import create_agent

agent = create_agent(
    model=ChatAnthropic(model="claude-sonnet-4-6"),
    tools=[],
    middleware=[StateClaudeTextEditorMiddleware()], # [!code highlight]
)
```

```python Filesystem-based text editor theme={null}
from langchain_anthropic import ChatAnthropic
from langchain_anthropic.middleware import FilesystemClaudeTextEditorMiddleware
from langchain.agents import create_agent

agent = create_agent(
    model=ChatAnthropic(model="claude-sonnet-4-6"),
    tools=[],
    middleware=[ # [!code highlight]
        FilesystemClaudeTextEditorMiddleware( # [!code highlight]
            root_path="/workspace", # [!code highlight]
        ), # [!code highlight]
    ], # [!code highlight]
)
```

Claude's text editor tool supports the following commands:

* `view` - View file contents or list directory
* `create` - Create a new file
* `str_replace` - Replace string in file
* `insert` - Insert text at line number
* `delete` - Delete a file
* `rename` - Rename/move a file

<Accordion title="Configuration options">
  **[`StateClaudeTextEditorMiddleware`](https://reference.langchain.com/python/langchain-anthropic/middleware/anthropic_tools/StateClaudeTextEditorMiddleware) (state-based)**

  <ParamField body="allowed_path_prefixes" type="Sequence[str] | None">
    Optional list of allowed path prefixes. If specified, only paths starting with these prefixes are allowed.
  </ParamField>

  **[`FilesystemClaudeTextEditorMiddleware`](https://reference.langchain.com/python/langchain-anthropic/middleware/anthropic_tools/FilesystemClaudeTextEditorMiddleware) (filesystem-based)**

  <ParamField body="root_path" type="str" required>
    Root directory for file operations
  </ParamField>

  <ParamField body="allowed_prefixes" type="list[str] | None">
    Optional list of allowed virtual path prefixes (default: `["/"]`)
  </ParamField>

  <ParamField body="max_file_size_mb" type="int" default="10">
    Maximum file size in MB
  </ParamField>
</Accordion>

<AccordionGroup>
  <Accordion title="Full example: State-based text editor">
    ```python theme={null}
    from langchain_anthropic import ChatAnthropic
    from langchain_anthropic.middleware import StateClaudeTextEditorMiddleware
    from langchain.agents import create_agent
    from langchain_core.runnables import RunnableConfig
    from langgraph.checkpoint.memory import MemorySaver


    agent = create_agent(
        model=ChatAnthropic(model="claude-sonnet-4-6"),
        tools=[],
        middleware=[
            StateClaudeTextEditorMiddleware( # [!code highlight]
                allowed_path_prefixes=["/project"], # [!code highlight]
            ), # [!code highlight]
        ],
        checkpointer=MemorySaver(),
    )

    # Use a thread_id to persist state across invocations
    config: RunnableConfig = {"configurable": {"thread_id": "my-session"}}

    # Claude can now create and edit files (stored in LangGraph state)
    result = agent.invoke(
        {"messages": [{"role": "user", "content": "Create a file at /project/hello.py with a simple hello world program"}]},
        config=config,
    )
    print(result["messages"][-1].content)
    ```

    ```text theme={null}
    I've created a simple "Hello, World!" program at `/project/hello.py`. The program uses Python's `print()` function to display "Hello, World!" to the console when executed.
    ```
  </Accordion>

  <Accordion title="Full example: Filesystem-based text editor">
    ```python theme={null}
    import tempfile

    from langchain_anthropic import ChatAnthropic
    from langchain_anthropic.middleware import FilesystemClaudeTextEditorMiddleware
    from langchain.agents import create_agent


    # Create a temporary workspace directory for this demo.
    # In production, use a persistent directory path.
    workspace = tempfile.mkdtemp(prefix="editor-workspace-")

    agent = create_agent(
        model=ChatAnthropic(model="claude-sonnet-4-6"),
        tools=[],
        middleware=[
            FilesystemClaudeTextEditorMiddleware( # [!code highlight]
                root_path=workspace, # [!code highlight]
                allowed_prefixes=["/src"], # [!code highlight]
                max_file_size_mb=10, # [!code highlight]
            ), # [!code highlight]
        ],
    )

    # Claude can now create and edit files (stored on disk)
    result = agent.invoke(
        {"messages": [{"role": "user", "content": "Create a file at /src/hello.py with a simple hello world program"}]}
    )
    print(result["messages"][-1].content)
    ```

    ```text theme={null}
    I've created a simple "Hello, World!" program at `/src/hello.py`. The program uses Python's `print()` function to display "Hello, World!" to the console when executed.
    ```
  </Accordion>
</AccordionGroup>

## Memory

Provide Claude's memory tool (`memory_20250818`) for persistent agent memory across conversation turns.

The memory middleware is useful for the following:

* Long-running agent conversations
* Maintaining context across interruptions
* Task progress tracking
* Persistent agent state management

<Info>
  Claude's memory tool uses a `/memories` directory and automatically injects a system prompt encouraging the agent to check and update memory.
</Info>

**API reference:** [`StateClaudeMemoryMiddleware`](https://reference.langchain.com/python/langchain-anthropic/middleware/anthropic_tools/StateClaudeMemoryMiddleware), [`FilesystemClaudeMemoryMiddleware`](https://reference.langchain.com/python/langchain-anthropic/middleware/anthropic_tools/FilesystemClaudeMemoryMiddleware)

```python State-based memory theme={null}
from langchain_anthropic import ChatAnthropic
from langchain_anthropic.middleware import StateClaudeMemoryMiddleware
from langchain.agents import create_agent

agent = create_agent(
    model=ChatAnthropic(model="claude-sonnet-4-6"),
    tools=[],
    middleware=[StateClaudeMemoryMiddleware()], # [!code highlight]
)
```

```python Filesystem-based memory theme={null}
from langchain_anthropic import ChatAnthropic
from langchain_anthropic.middleware import FilesystemClaudeMemoryMiddleware
from langchain.agents import create_agent

agent_fs = create_agent(
    model=ChatAnthropic(model="claude-sonnet-4-6"),
    tools=[],
    middleware=[ # [!code highlight]
        FilesystemClaudeMemoryMiddleware( # [!code highlight]
            root_path="/workspace", # [!code highlight]
        ), # [!code highlight]
    ], # [!code highlight]
)
```

<Accordion title="Configuration options">
  **[`StateClaudeMemoryMiddleware`](https://reference.langchain.com/python/langchain-anthropic/middleware/anthropic_tools/StateClaudeMemoryMiddleware) (state-based)**

  <ParamField body="allowed_path_prefixes" type="Sequence[str] | None">
    Optional list of allowed path prefixes. Defaults to `["/memories"]`.
  </ParamField>

  <ParamField body="system_prompt" type="str">
    System prompt to inject. Defaults to Anthropic's recommended memory prompt that encourages the agent to check and update memory.
  </ParamField>

  **[`FilesystemClaudeMemoryMiddleware`](https://reference.langchain.com/python/langchain-anthropic/middleware/anthropic_tools/FilesystemClaudeMemoryMiddleware) (filesystem-based)**

  <ParamField body="root_path" type="str" required>
    Root directory for file operations
  </ParamField>

  <ParamField body="allowed_prefixes" type="list[str] | None">
    Optional list of allowed virtual path prefixes. Defaults to `["/memories"]`.
  </ParamField>

  <ParamField body="max_file_size_mb" type="int" default="10">
    Maximum file size in MB
  </ParamField>

  <ParamField body="system_prompt" type="str">
    System prompt to inject
  </ParamField>
</Accordion>

<AccordionGroup>
  <Accordion title="Full example: State-based memory">
    The agent will automatically:

    1. Check `/memories` directory at start
    2. Record progress and thoughts during execution
    3. Update memory files as work progresses

    ```python theme={null}
    from langchain_anthropic import ChatAnthropic
    from langchain_anthropic.middleware import StateClaudeMemoryMiddleware
    from langchain.agents import create_agent
    from langchain_core.runnables import RunnableConfig
    from langgraph.checkpoint.memory import MemorySaver


    agent = create_agent(
        model=ChatAnthropic(model="claude-sonnet-4-6"),
        tools=[],
        middleware=[StateClaudeMemoryMiddleware()], # [!code highlight]
        checkpointer=MemorySaver(),
    )

    # Use a thread_id to persist state across invocations
    config: RunnableConfig = {"configurable": {"thread_id": "my-session"}}

    # Claude can now use memory to track progress (stored in LangGraph state)
    result = agent.invoke(
        {"messages": [{"role": "user", "content": "Remember that my favorite color is blue, then confirm what you stored."}]},
        config=config,
    )
    print(result["messages"][-1].content)
    ```

    ```text theme={null}
    Perfect! I've stored your favorite color as **blue** in my memory system. The information is saved in my user preferences file where I can access it in future conversations.
    ```
  </Accordion>

  <Accordion title="Full example: Filesystem-based memory">
    The agent will automatically:

    1. Check `/memories` directory at start
    2. Record progress and thoughts during execution
    3. Update memory files as work progresses

    ```python theme={null}
    import tempfile

    from langchain_anthropic import ChatAnthropic
    from langchain_anthropic.middleware import FilesystemClaudeMemoryMiddleware
    from langchain.agents import create_agent


    # Create a temporary workspace directory for this demo.
    # In production, use a persistent directory path.
    workspace = tempfile.mkdtemp(prefix="memory-workspace-")

    agent = create_agent(
        model=ChatAnthropic(model="claude-sonnet-4-6"),
        tools=[],
        middleware=[
            FilesystemClaudeMemoryMiddleware( # [!code highlight]
                root_path=workspace, # [!code highlight]
            ), # [!code highlight]
        ],
    )

    # Claude can now use memory to track progress (stored on disk)
    result = agent.invoke(
        {"messages": [{"role": "user", "content": "Remember that my favorite color is blue, then confirm what you stored."}]}
    )
    print(result["messages"][-1].content)
    ```

    ```text theme={null}
    Perfect! I've stored your favorite color as **blue** in my memory system. The information is saved in my user preferences file where I can access it in future conversations.
    ```
  </Accordion>
</AccordionGroup>

## File search

Provide Glob and Grep search tools for files stored in LangGraph state. File search middleware is useful for the following:

* Searching through state-based virtual file systems
* Works with text editor and memory tools
* Finding files by patterns
* Content search with regex

**API reference:** [`StateFileSearchMiddleware`](https://reference.langchain.com/python/langchain-anthropic/middleware/file_search/StateFileSearchMiddleware)

```python theme={null}
from langchain_anthropic import ChatAnthropic
from langchain_anthropic.middleware import (
    StateClaudeTextEditorMiddleware,
    StateFileSearchMiddleware,
)
from langchain.agents import create_agent

agent = create_agent(
    model=ChatAnthropic(model="claude-sonnet-4-6"),
    tools=[],
    middleware=[ # [!code highlight]
        StateClaudeTextEditorMiddleware(), # [!code highlight]
        StateFileSearchMiddleware(),  # Search text editor files [!code highlight]
    ], # [!code highlight]
)
```

<Accordion title="Configuration options">
  <ParamField body="state_key" type="str" default="text_editor_files">
    State key containing files to search. Use `"text_editor_files"` for text editor files or `"memory_files"` for memory files.
  </ParamField>
</Accordion>

<AccordionGroup>
  <Accordion title="Full example: Search text editor files">
    The middleware adds Glob and Grep search tools that work with state-based files.

    ```python theme={null}
    from langchain_anthropic import ChatAnthropic
    from langchain_anthropic.middleware import (
        StateClaudeTextEditorMiddleware,
        StateFileSearchMiddleware,
    )
    from langchain.agents import create_agent
    from langchain.messages import HumanMessage
    from langchain_core.runnables import RunnableConfig
    from langgraph.checkpoint.memory import MemorySaver


    agent = create_agent(
        model=ChatAnthropic(model="claude-sonnet-4-6"),
        tools=[],
        middleware=[
            StateClaudeTextEditorMiddleware(),
            StateFileSearchMiddleware(state_key="text_editor_files"), # [!code highlight]
        ],
        checkpointer=MemorySaver(),
    )

    # Use a thread_id to persist state across invocations
    config: RunnableConfig = {"configurable": {"thread_id": "my-session"}}

    # First invocation: Create some files using the text editor tool
    result = agent.invoke(
        {"messages": [HumanMessage("Create a Python project with main.py, utils/helpers.py, and tests/test_main.py")]},
        config=config,
    )

    # The agent creates files, which are stored in state
    print("Files created:", list(result["text_editor_files"].keys()))

    # Second invocation: Search the files we just created
    # State is automatically persisted via the checkpointer
    result = agent.invoke(
        {"messages": [HumanMessage("Find all Python files in the project")]},
        config=config,
    )
    print(result["messages"][-1].content)
    ```

    ```text theme={null}
    Files created: ['/project/main.py', '/project/utils/helpers.py', '/project/utils/__init__.py', '/project/tests/test_main.py', '/project/tests/__init__.py', '/project/README.md']
    ```

    ```text theme={null}
    I found 5 Python files in the project:

    1. `/project/main.py` - Main application file
    2. `/project/utils/__init__.py` - Utils package initialization
    3. `/project/utils/helpers.py` - Helper utilities
    4. `/project/tests/__init__.py` - Tests package initialization
    5. `/project/tests/test_main.py` - Main test file

    Would you like me to view the contents of any of these files?
    ```
  </Accordion>

  <Accordion title="Full example: Search memory files">
    ```python theme={null}
    from langchain_anthropic import ChatAnthropic
    from langchain_anthropic.middleware import (
        StateClaudeMemoryMiddleware,
        StateFileSearchMiddleware,
    )
    from langchain.agents import create_agent
    from langchain.messages import HumanMessage
    from langchain_core.runnables import RunnableConfig
    from langgraph.checkpoint.memory import MemorySaver


    agent = create_agent(
        model=ChatAnthropic(model="claude-sonnet-4-6"),
        tools=[],
        middleware=[
            StateClaudeMemoryMiddleware(),
            StateFileSearchMiddleware(state_key="memory_files"), # [!code highlight]
        ],
        checkpointer=MemorySaver(),
    )

    # Use a thread_id to persist state across invocations
    config: RunnableConfig = {"configurable": {"thread_id": "my-session"}}

    # First invocation: Record some memories
    result = agent.invoke(
        {"messages": [HumanMessage("Remember that the project deadline is March 15th and code review deadline is March 10th")]},
        config=config,
    )

    # The agent creates memory files, which are stored in state
    print("Memory files created:", list(result["memory_files"].keys()))

    # Second invocation: Search the memories we just recorded
    # State is automatically persisted via the checkpointer
    result = agent.invoke(
        {"messages": [HumanMessage("Search my memories for project deadlines")]},
        config=config,
    )
    print(result["messages"][-1].content)
    ```

    ```text theme={null}
    Memory files created: ['/memories/project_info.md']
    ```

    ```text theme={null}
    I found your project deadlines in my memory! Here's what I have recorded:

    ## Important Deadlines
    - **Code Review Deadline:** March 10th
    - **Project Deadline:** March 15th

    ## Notes
    - Code review must be completed 5 days before final project deadline
    - Need to ensure all code is ready for review by March 10th

    Is there anything specific about these deadlines you'd like to know or update?
    ```
  </Accordion>
</AccordionGroup>

***

<div className="source-links">
  <Callout icon="terminal-2">
    [Connect these docs](/use-these-docs) to Claude, VSCode, and more via MCP for real-time answers.
  </Callout>

  <Callout icon="edit">
    [Edit this page on GitHub](https://github.com/langchain-ai/docs/edit/main/src/oss/python/integrations/middleware/anthropic.mdx) or [file an issue](https://github.com/langchain-ai/docs/issues/new/choose).
  </Callout>
</div>
