The ACPAgentServer class is the core of the Python ACP integration. It wraps DeepAgents with the Agent Client Protocol, enabling communication with IDEs like Zed, JetBrains, and other ACP-compatible clients.
Learn more: For the ACP specification, see agentclientprotocol.com.
import asyncio
from deepagents_acp.server import serve_acp_stdio
asyncio.run(serve_acp_stdio(root_dir="/path/to/project"))
The serve_acp_stdio convenience function creates an ACPAgentServer with sensible defaults and runs it over stdio.
The ACPAgentServer accepts the following configuration:
| Parameter | Type | Description |
|---|---|---|
root_dir |
str |
Root directory accessible to the agent |
checkpointer |
Checkpointer |
LangGraph checkpointer for session persistence |
mode |
str |
Initial operating mode ("ask_before_edits" or "auto") |
from langgraph.checkpoint.memory import MemorySaver
from deepagents_acp.server import ACPAgentServer
server = ACPAgentServer(
root_dir="/path/to/project",
checkpointer=MemorySaver(),
mode="ask_before_edits",
)
The server supports two operating modes, switchable via the ACP session/set_mode request:
| Mode | Description |
|---|---|
ask_before_edits |
Ask permission before file edits and writes (default) |
auto |
Auto-accept edit operations, only ask for plan approval |
Switching modes recreates the underlying DeepAgent with the appropriate interrupt configuration.
The server configures a CompositeBackend that combines:
FilesystemBackend — for real filesystem access within root_dir (using virtual mode)StateBackend — for ephemeral in-memory storage of /memories/ and /conversation_history/ pathsfrom deepagents.backends import CompositeBackend, FilesystemBackend, StateBackend
def create_backend(tr):
ephemeral = StateBackend(tr)
return CompositeBackend(
default=FilesystemBackend(root_dir=root_dir, virtual_mode=True),
routes={
"/memories/": ephemeral,
"/conversation_history/": ephemeral,
},
)
The interrupt configuration is determined by the current mode:
ask_before_edits mode requires approval for edit_file, write_file, and write_todos.
auto mode only requires approval for write_todos (plan changes).
When a protected tool is invoked, the IDE shows a permission dialog with Approve and Reject options. For write_todos, rejected plans prompt the agent to ask for feedback and create an improved plan.
The server tracks plan state per session and supports:
write_todos calls are auto-approved to allow the agent to update task statusPlanEntry updates and visible text messagesTool calls are reported to the IDE with rich metadata:
| Tool | Kind | Title Format |
|---|---|---|
read_file |
read |
Read `path` |
edit_file |
edit |
Edit `path` |
write_file |
edit |
Write `path` |
ls |
search |
ls |
glob |
search |
glob |
grep |
search |
grep |
For edit_file tool calls, the server sends diff content (tool_diff_content) so the IDE can render inline diffs.
The server streams agent responses using LangGraph's astream with stream_mode="messages". Tool call chunks are accumulated and started once the arguments JSON is complete, providing real-time tool call notifications to the IDE.