diff --git a/docs.json b/docs.json
index 6cd73304..2976cb53 100644
--- a/docs.json
+++ b/docs.json
@@ -298,6 +298,7 @@
{
"group": "Agent Features",
"pages": [
+ "sdk/guides/agent-acp",
"sdk/guides/agent-interactive-terminal",
"sdk/guides/agent-browser-use",
"sdk/guides/agent-custom",
diff --git a/sdk/guides/agent-acp.mdx b/sdk/guides/agent-acp.mdx
new file mode 100644
index 00000000..00e3b718
--- /dev/null
+++ b/sdk/guides/agent-acp.mdx
@@ -0,0 +1,154 @@
+---
+title: ACP Agent
+description: Delegate to an ACP-compatible server (Claude Code, Gemini CLI, etc.) instead of calling an LLM directly.
+---
+
+import RunExampleCode from "/sdk/shared-snippets/how-to-run-example.mdx";
+
+> A ready-to-run example is available [here](#ready-to-run-example)!
+
+`ACPAgent` lets you use any [Agent Client Protocol](https://agentclientprotocol.com/protocol/overview) server as the backend for an OpenHands conversation. Instead of calling an LLM directly, the agent spawns an ACP server subprocess and communicates with it over JSON-RPC. The server manages its own LLM, tools, and execution — your code just sends messages and collects responses.
+
+## Basic Usage
+
+```python icon="python" highlight={5-7}
+from openhands.sdk.agent import ACPAgent
+from openhands.sdk.conversation import Conversation
+
+# Point at any ACP-compatible server
+agent = ACPAgent(acp_command=["npx", "-y", "claude-code-acp"])
+
+conversation = Conversation(agent=agent, workspace="./my-project")
+conversation.send_message("Explain the architecture of this project.")
+conversation.run()
+
+agent.close()
+```
+
+The `acp_command` is the shell command used to spawn the server process. The SDK communicates with it over stdin/stdout JSON-RPC.
+
+
+**Key difference from standard agents:** With `ACPAgent`, you don't need an `LLM_API_KEY` in your code. The ACP server handles its own LLM authentication and API calls. This is *delegation* — your code sends messages to the ACP server, which manages all LLM interactions internally.
+
+
+### What ACPAgent Does Not Support
+
+Because the ACP server manages its own tools and context, these `AgentBase` features are not available on `ACPAgent`:
+
+- `tools` / `include_default_tools` — the server has its own tools
+- `mcp_config` — configure MCP on the server side
+- `condenser` — the server manages its own context window
+- `critic` — the server manages its own evaluation
+- `agent_context` — configure the server directly
+
+Passing any of these raises `NotImplementedError` at initialization.
+
+## How It Works
+
+1. `ACPAgent` spawns the ACP server as a subprocess
+2. The SDK initializes the ACP protocol and creates a session
+3. When you call `conversation.send_message(...)`, the message is forwarded to the ACP server via `conn.prompt()`
+4. The server processes the request using its own LLM and tools, streaming session updates (text chunks, thought chunks, tool calls) back to the SDK
+5. The SDK accumulates the response and emits it as a `MessageEvent`
+6. Permission requests from the server are auto-approved — this means the SDK automatically grants any tool execution or file access the server requests, so ensure you trust the ACP server you're running
+7. Token usage and cost metrics from the ACP server are captured into the agent's `LLM.metrics`
+
+## Configuration
+
+### Server Command and Arguments
+
+```python icon="python"
+agent = ACPAgent(
+ acp_command=["npx", "-y", "claude-code-acp"],
+ acp_args=["--profile", "my-profile"], # extra CLI args
+ acp_env={"CLAUDE_API_KEY": "sk-..."}, # extra env vars
+)
+```
+
+| Parameter | Description |
+|-----------|-------------|
+| `acp_command` | Command to start the ACP server (required) |
+| `acp_args` | Additional arguments appended to the command |
+| `acp_env` | Additional environment variables for the server process |
+
+## Metrics
+
+Token usage and cost data are automatically captured from the ACP server's responses. You can inspect them through the standard `LLM.metrics` interface:
+
+```python icon="python"
+metrics = agent.llm.metrics
+print(f"Total cost: ${metrics.accumulated_cost:.6f}")
+
+for usage in metrics.token_usages:
+ print(f" prompt={usage.prompt_tokens} completion={usage.completion_tokens}")
+```
+
+Usage data comes from two ACP protocol sources:
+- **`PromptResponse.usage`** — per-turn token counts (input, output, cached, reasoning tokens)
+- **`UsageUpdate` notifications** — cumulative session cost and context window size
+
+## Cleanup
+
+Always call `agent.close()` when you are done to terminate the ACP server subprocess. A `try/finally` block is recommended:
+
+```python icon="python"
+agent = ACPAgent(acp_command=["npx", "-y", "claude-code-acp"])
+try:
+ conversation = Conversation(agent=agent, workspace=".")
+ conversation.send_message("Hello!")
+ conversation.run()
+finally:
+ agent.close()
+```
+
+## Ready-to-run Example
+
+
+This example is available on GitHub: [examples/01_standalone_sdk/40_acp_agent_example.py](https://github.com/OpenHands/software-agent-sdk/blob/main/examples/01_standalone_sdk/40_acp_agent_example.py)
+
+
+```python icon="python" expandable examples/01_standalone_sdk/40_acp_agent_example.py
+"""Example: Using ACPAgent with Claude Code ACP server.
+
+This example shows how to use an ACP-compatible server (claude-code-acp)
+as the agent backend instead of direct LLM calls.
+
+Prerequisites:
+ - Node.js / npx available
+ - Claude Code CLI authenticated (or CLAUDE_API_KEY set)
+
+Usage:
+ uv run python examples/01_standalone_sdk/40_acp_agent_example.py
+"""
+
+import os
+
+from openhands.sdk.agent import ACPAgent
+from openhands.sdk.conversation import Conversation
+
+
+agent = ACPAgent(acp_command=["npx", "-y", "claude-code-acp"])
+
+try:
+ cwd = os.getcwd()
+ conversation = Conversation(agent=agent, workspace=cwd)
+
+ conversation.send_message(
+ "List the Python source files under openhands-sdk/openhands/sdk/agent/, "
+ "then read the __init__.py and summarize what agent classes are exported."
+ )
+ conversation.run()
+finally:
+ # Clean up the ACP server subprocess
+ agent.close()
+
+print("Done!")
+```
+
+This example does not use an LLM API key directly — the ACP server (Claude Code) handles authentication on its own.
+
+## Next Steps
+
+- **[Creating Custom Agents](/sdk/guides/agent-custom)** — Build specialized agents with custom tool sets and system prompts
+- **[Agent Delegation](/sdk/guides/agent-delegation)** — Compose multiple agents for complex workflows
+- **[LLM Metrics](/sdk/guides/metrics)** — Track token usage and costs across models