Skip to Content
HeronJS v4 is now available.

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).

Last updated on