Agent Client Protocol (ACP) Python SDK
The `agent-client-protocol` is a Python implementation of the Agent Client Protocol (ACP) by Zed Industries, designed to facilitate communication between AI agents and clients. It provides classes for building agents, clients, and handling protocol messages with schema validation. Currently at version 0.9.0, the library releases updates driven by upstream ACP schema changes and SDK improvements, typically every few months.
Warnings
- breaking Version 0.7.0 introduced a major API refactor, moving core classes like `Agent` and `AgentServer` to `acp.agents` and standardizing method names to `snake_case`. Existing code using `camelCase` methods or older import paths will break.
- breaking In version 0.5.0, helper functions `acp.helpers.embedded_text_resource` and `acp.helpers.embedded_blob_resource` changed their return type to directly yield `TextResourceContents` / `BlobResourceContents`. If you were implicitly relying on an outer `ResourceBlock` wrapper, you now need to explicitly use `helpers.resource_block(...)` when emitting embedded resources.
- gotcha The library has a strict Python version requirement: `>=3.10, <3.15`. Using Python 3.9 or older, or 3.15 or newer, will result in installation or runtime errors due to specific dependencies and tested environments.
- gotcha The SDK closely tracks the upstream Agent Client Protocol schema. Minor SDK version bumps (e.g., 0.8.0, 0.9.0) often include `feat(schema): upgrade ACP`, which can introduce new types or modify existing ones. While typically backward-compatible, be aware of potential subtle API shifts in message structures.
Install
-
pip install agent-client-protocol
Imports
- Agent
from acp.agents import Agent
- AgentServer
from acp.agents import AgentServer
- Message
from acp.schemas import Message
Quickstart
import asyncio
from acp.agents import Agent
from acp.schemas import Message, MessageContents, TextResourceContents, MessageID
class SimpleEchoAgent(Agent):
"""
A simple agent that echoes back any text message it receives.
In a real application, this agent would be registered with an AgentServer
and communicate via a transport layer (e.g., stdio).
"""
# In a full setup, send_message would use the transport for communication.
# We override it here purely for demonstration purposes in this quickstart.
async def send_message(self, message: Message) -> None:
if message.contents and message.contents.text:
print(f"Agent sending: '{message.contents.text.text}'")
async def handle_message(self, message: Message) -> None:
if message.contents and message.contents.text:
response_text = f"Echo from agent: {message.contents.text.text}"
response_message = Message(
id=MessageID.new_id(),
contents=MessageContents(
text=TextResourceContents(text=response_text)
),
parent_id=message.id,
)
await self.send_message(response_message)
else:
print(f"Agent received non-text message: {message.id}")
async def run_agent_example():
agent = SimpleEchoAgent()
# Simulate an incoming message that a real server would pass to the agent
incoming_message = Message(
id=MessageID.new_id(),
contents=MessageContents(
text=TextResourceContents(text="Hello ACP!")
)
)
print(f"Simulating client sending: '{incoming_message.contents.text.text}'\n")
await agent.handle_message(incoming_message)
print("\nAgent quickstart example finished.")
if __name__ == "__main__":
asyncio.run(run_agent_example())