Installation
Snapshot builds are published to Maven Central Snapshots. Add the snapshot repository to your build.Maven
Add the snapshot repository, then the dependency:acp-core transitively):
Gradle
Three Agent API Styles
Quick Comparison
All three produce identical protocol behavior and support the same capabilities.
When to Use Each
- Annotation-based — default choice. Least boilerplate, auto-converts return types, supports interceptors and custom argument resolvers.
- Sync — when you want explicit control over every handler without annotations. Blocking void methods for sending updates.
- Async — when your agent needs non-blocking I/O. Uses Project Reactor
Monofor composable async chains.
Client API
AcpClient — Factory
AcpSyncClient — Blocking Client
Builder Configuration
Example — Complete client lifecycle
This launches Gemini CLI as an ACP agent subprocess and sends it a prompt.AgentParameters builds the command line; StdioAcpClientTransport spawns the process and handles JSON-RPC framing over stdin/stdout.
Agent API — Annotation-Based
Theacp-agent-support module provides a declarative programming model using annotations.
Annotations
Class-Level
Handler Methods
Parameter Annotations
Flexible Method Signatures
Handler methods support flexible parameter resolution:Return Value Handling
SyncPromptContext
Available in @Prompt handlers. Provides blocking methods for agent-client interaction:
AcpAgentSupport — Bootstrap
Interceptors
Cross-cutting concerns like logging, metrics, or error handling:Example — Complete annotation-based agent
Agent API — Sync (Builder)
Blocking handlers with plain return values. No annotations.Builder Methods
Example
Prompt Handler Context
Thecontext parameter in promptHandler provides:
Agent API — Async (Builder)
Reactive handlers returningMono. Uses Project Reactor.
Example
sendMessage(), sendUpdate(), etc. return Mono<Void>, composable with .then() and .flatMap().
Convenience Methods vs Full API
The SDK provides convenience methods that cover the most common operations. Use these by default — they produce cleaner code and handle the protocol details for you.When convenience methods are enough (~80% of cases)
When to use the full API (~20% of cases)
Drop to the full API when you need control that convenience methods don’t expose:Protocol Types
All protocol types are defined inAcpSchema as Java records.
Request/Response Types
Content Types
Session Update Types
Stop Reasons
Convenience Methods
Capabilities
Client Capabilities
Advertised duringinitialize:
NegotiatedCapabilities
Check capabilities before using them:
require methods that throw AcpCapabilityException if unsupported:
Transports
Stdio Transport
The default transport. The client launches the agent as a subprocess and communicates via JSON-RPC over stdin/stdout. This is the same mechanism Zed, JetBrains, and VS Code use to talk to agents. Client side —AgentParameters specifies the command to launch. Any executable that speaks ACP over stdin/stdout works (Gemini CLI, your own agent JAR, etc.):
WebSocket Transport
For network-based communication. Client (JDK-native, no extra dependencies):In-Memory Transport
For testing. No subprocess or network I/O.Errors
Exception Hierarchy
Error Codes
Agent-Side Error Handling
ThrowAcpProtocolException from handlers to send structured errors to clients:
Test Utilities
Theacp-test module provides utilities for testing without subprocesses.
InMemoryTransportPair
Packages
Maven Artifacts
See Also
- ACP Java SDK GitHub — Source code
- ACP Java Tutorial — 30 hands-on modules
- Agent Client Protocol — Official specification