# ClaudeAgent hands images and PDFs to Claude Code inside the message

> Agno's ClaudeAgent sends attached PNG, JPEG, GIF and WEBP images and PDFs up to 4 MiB to the Claude Agent SDK as content blocks, so large images no longer overflow the SDK buffer or the sandbox event frame.

- Published: 2026-10-16
- Author: Kaustubh Shukla
- Categories: Changelog
- Canonical: https://www.agno.com/blog/claudeagent-hands-images-and-pdfs-to-claude-code-inside-the-message
- Markdown: https://www.agno.com/blog/claudeagent-hands-images-and-pdfs-to-claude-code-inside-the-message.md

Agno's `ClaudeAgent` still stages each attachment under `.agno/uploads/<run_id>/`, then sends the Claude Agent SDK one streamed user message holding the prompt text followed by an `image` or `document` block for every image and PDF. Claude sees the picture directly and has no reason to open the file.

Earlier releases listed the paths and left Claude to open them with Read. For an image, Read returns the whole file as base64 inside a tool result, and a PNG of a few hundred KB overflowed the SDK's 1 MiB message buffer or the sandbox's 256 KiB event frame. In the PR's live test, a 467 KB PNG uploaded through AgentOS to a Docker-sandboxed Claude agent used to fail on the SDK buffer, and with this change it completed in 7.5 s with no tool calls.

We ran `ClaudeAgent.arun()` with a PNG, a real PDF and a `memo.pdf` that holds HTML, against a stand-in SDK client that records what it receives.

```text
# real output, earlier release: what the SDK client received (stand-in Claude SDK)
SDK received: str
What does the chart show?
Attached files. Read them before answering; images and PDFs can be opened with the file tools:
- <cwd>/.agno/uploads/<run_id>/image-1.png (image/png, 74 bytes)
- <cwd>/.agno/uploads/<run_id>/report.pdf (application/pdf, 45 bytes)
- <cwd>/.agno/uploads/<run_id>/memo.pdf (application/pdf, 22 bytes)
```

```text
# real output, this release: same run, same stand-in
SDK received: streamed user message
What does the chart show?
Attached files:
- <cwd>/.agno/uploads/<run_id>/image-1.png (image/png, 74 bytes; already included in this message, do not read it, the file is on disk for programs)
- <cwd>/.agno/uploads/<run_id>/report.pdf (application/pdf, 45 bytes; already included in this message, do not read it, the file is on disk for programs)
- <cwd>/.agno/uploads/<run_id>/memo.pdf (application/pdf, 22 bytes; read it with the file tools before answering)
block: {"type": "image", "media_type": "image/png", "base64_chars": 100}
block: {"type": "document", "media_type": "application/pdf", "base64_chars": 60}
```

Agno reads each file's signature to choose what goes inline, so `memo.pdf` keeps its label in the prompt and stays a file for the Read tool. Text, CSV and other files, plus any image or PDF over 4 MiB, keep the Read path too. Every file still lands on disk, so a program Claude writes can open it. Sandboxed agents pick this up once you rebuild the runtime image with `build_image.py`, or redeploy it on AgentCore.

See the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/frameworks/claude-agent-sdk/claude_media.py), and learn more about [where attachments live](https://docs.agno.com/agent-os/multi-framework/media#where-attachments-live) in the documentation.
