| [ Web Proxy ] |
| Viewing: https://agentclientprotocol.github.io/python-sdk/quickstart/ | [Back] [Original] |
Spin up a working ACP agent/client loop in minutes. Keep this page beside the terminal and check off each section as you go. Want inspiration? Hop to the Use Cases list to see how teams like kimi-cli or Zed apply the SDK in production.
| Goal | Command / Link |
|---|---|
| Install the SDK | pip install agent-client-protocol or uv add agent-client-protocol |
| Run the echo agent | python examples/echo_agent.py |
| Point Zed (or another client) at it | Update settings.json as shown below |
| Programmatically drive an agent | Copy the spawn_agent_process example |
| Run tests before hacking further | make check && make test |
pip or uvgemini --acp; use --experimental-acp for older versions) for the bridge exampleInstall the library from PyPI or add it to your uv workspace.
pip install agent-client-protocol
# or
uv add agent-client-protocol
Run the provided streaming agent so clients have something to talk to.
Start the ready-made echo example; it streams text blocks back to any ACP client. Leave it running in a terminal:
python examples/echo_agent.py
Point a client at the script and confirm you can exchange streamed updates.
Add an Agent Server entry in settings.json (Zed Settings Agents panel):
{
"agent_servers": {
"Echo Agent (Python)": {
"type": "custom",
"command": "/abs/path/to/python",
"args": [
"/abs/path/to/agentclientprotocol/python-sdk/examples/echo_agent.py"
]
}
}
}
Or, if using uv:
{
"agent_servers": {
"Echo Agent (Python)": {
"type": "custom",
"command": "uv",
"args": [
"run",
"/abs/path/to/agentclientprotocol/python-sdk/examples/echo_agent.py"
]
}
}
}
Open the Agents panel and start the session. Each message you send should be echoed back via streamed session/update notifications.
Any ACP client that communicates over stdio can spawn the same script; no additional transport configuration is required.
Prefer to drive agents directly from Python? The spawn_agent_process helper wires stdio and lifecycle management for you:
import asyncio
import sys
from pathlib import Path
from typing import Any
from acp import PROTOCOL_VERSION, spawn_agent_process, text_block
from acp.interfaces import Client
class SimpleClient(Client):
async def request_permission(
self, session_id, tool_call, options, **kwargs: Any
):
return {"outcome": {"outcome": "cancelled"}}
async def session_update(self, session_id, update, **kwargs):
print("update:", session_id, update)
async def main() -> None:
script = Path("examples/echo_agent.py")
async with spawn_agent_process(SimpleClient(), sys.executable, str(script)) as (conn, _proc):
await conn.initialize(protocol_version=PROTOCOL_VERSION)
session = await conn.new_session(cwd=str(script.parent), mcp_servers=[])
await conn.prompt(
session_id=session.session_id,
prompt=[text_block("Hello from spawn!")],
)
asyncio.run(main())
spawn_agent_process manages the child process, wires its stdio into ACP framing, and closes everything when the block exits. The mirror helper spawn_client_process lets you drive an ACP client from Python as well.
Swap the echo demo for your own Agent subclass.
Create your own agent by subclassing acp.Agent. The pattern mirrors the echo example:
from acp import Agent, PromptResponse
class MyAgent(Agent):
async def prompt(self, session_id, prompt, **kwargs) -> PromptResponse:
# inspect prompt, stream updates, then finish the turn
return PromptResponse(stop_reason="end_turn")
Run it with run_agent() inside an async entrypoint and wire it to your client. Refer to:
examples/echo_agent.py for the smallest streaming agentexamples/agent.py for an implementation that negotiates capabilities and streams richer updatesexamples/duet.py to see spawn_agent_process in action alongside the interactive clientexamples/gemini.py to drive the Gemini CLI (--acp; use --experimental-acp for older versions) directly from PythonNeed builders for common payloads? acp.helpers mirrors the Go/TS helper APIs:
from acp import start_tool_call, update_tool_call, text_block, tool_content
start_update = start_tool_call("call-42", "Open file", kind="read", status="pending")
finish_update = update_tool_call(
"call-42",
status="completed",
content=[tool_content(text_block("File opened."))],
)
Each helper wraps the generated Pydantic models in acp.schema, so the right discriminator fields (type, sessionUpdate, and friends) are always populated. That keeps examples readable while maintaining the same validation guarantees as constructing the models directly. Golden fixtures in tests/test_golden.py ensure the helpers stay in sync with future schema revisions.
Have the Gemini CLI installed? Run the bridge to exercise permission flows.
If you have the Gemini CLI installed and authenticated:
python examples/gemini.py --skip-trust --yolo # auto-approve permission prompts
python examples/gemini.py --skip-trust --sandbox --model gemini-1.5-pro
Environment helpers:
ACP_GEMINI_BIN override the CLI path (defaults to PATH lookup)ACP_GEMINI_TEST_ARGS extra flags forwarded during the smoke testACP_ENABLE_GEMINI_TESTS=1 opt-in toggle for tests/test_gemini_example.pyAuthentication hiccups (e.g. missing GOOGLE_CLOUD_PROJECT) are surfaced but treated as skips during testing so the suite stays green on machines without credentials.
docs/contrib.md for higher-level utilities like session accumulators and permission brokers.make check / make test before committing changes, and regenerate schema artifacts with make gen-all when ACP versions advance.| Web Proxy Viewer | New URL | Original Page |