Agent Client Protocol (ACP)
@heronjs/acp exposes agents through the @ACP decorator and the AcpAgentRuntime contract. HTTP is
the default application transport; stdio is selected explicitly. Each endpoint
and accepted connection has independent authentication, initialization, session,
and cancellation state.
Define an agent
import 'reflect-metadata';
import {Module} from '@heronjs/common';
import {HeronJS} from '@heronjs/core';
import {ACP, type AcpAgentRuntime, type AcpSessionContext} from '@heronjs/acp';
@ACP('/acp/review', {name: 'review', version: '1.0.0'})
class ReviewAgent implements AcpAgentRuntime {
createSession() {
return {};
}
async prompt(_request: unknown, context: AcpSessionContext) {
await context.update({sessionUpdate: 'agent_message_chunk', content: {type: 'text', text: 'Reviewed'}});
return {stopReason: 'end_turn' as const};
}
}
@ACP({path: '/acp/chat', name: 'chat', version: '1.0.0'})
class ChatAgent extends ReviewAgent {}
@Module({acps: [ReviewAgent, ChatAgent]})
class App {}
const app = await HeronJS.create({module: App});
await app.listen({port: 3000, host: '127.0.0.1'});@ACP('/path') uses the class name and version 1.0.0. The object form accepts
{ name, version, path? }; its default path is /acp. Give agents distinct paths.
Duplicate paths fail registration before the listener opens. Agents declared in
imported application modules participate in the same registration process.
HTTP transport
HTTP endpoints use the official SDK’s experimental/server and
experimental/node Streamable HTTP transport APIs, with stable ACP v1 agent
messages. The SDK transport API is experimental. Connect with
createHttpStream(url) from @agentclientprotocol/sdk/experimental/http-client.
The adapter shares core’s Node server and releases SDK connections on shutdown.
Endpoint configuration
Configure common limits/authentication through protocols.acp, and override them
per path through endpoints:
app.add({
acp: {
maxSessions: 100,
endpoints: {
'/acp/review': {promptTimeout: 60000},
'/acp/chat': {promptTimeout: 300000},
},
},
});Authentication and sessions
allowedHosts and allowedOrigins default to loopback hostnames. Remote use
requires application authentication or explicit publicAccess, plus the relevant
Host/Origin allowlists. authMethods and authenticate implement ACP application
authentication and are isolated per connection. Session creation requires an
absolute cwd; unsupported content/capabilities fail explicitly. Prompt
cancellation and timeouts abort the context signal, and closeSession runs during
connection cleanup. Handler results support values, Promises, and Observables.
Stdio transport
For stdio, create the application with runtime: { transport: 'stdio' }, then
configure acp: { transport: 'stdio', endpoint: '/acp/review' }. Exactly one endpoint
can own stdio; ambiguous selection fails before consuming stdin. The existing
agent selector also accepts a class name or declared agent name. Stdout contains
only protocol messages; logs go to stderr. MCP and ACP cannot both own stdio in one
process. Multiple HTTP ACP and MCP endpoints can share the same application.
Based on 4.0.0 release source (4.0.0).