Skip to content

keepmind9/acp-sdk-go

Repository files navigation

ACP SDK for Go

A Go implementation of the Agent Client Protocol (ACP) — a JSON-RPC 2.0 protocol over stdio for communication between AI agents and their clients (editors, IDEs).

Build ACP-compliant agents and clients in Go with strongly-typed schema models, stdio transport, helper builders, and runnable examples.

Features

  • Schema parity: Type-safe Go structs for every ACP schema type, including discriminated unions for ContentBlock, SessionUpdate, ToolCall, and more.
  • Bidirectional JSON-RPC 2.0: Full request/response over newline-delimited stdio, with notification support for streaming updates.
  • Typed connections: AgentSideConnection and ClientSideConnection wrappers with methods matching the ACP interface.
  • Subprocess transport: transport.Spawn launches agent/client subprocesses with clean environment, configurable timeouts, and graceful shutdown.
  • Helper builders: helpers.AgentMessageUpdate, helpers.ToolCallStartUpdate, helpers.ToolCallProgressUpdate, and more for ergonomic content construction.
  • Contrib utilities: ToolCallTracker, PermissionBroker, and SessionAccumulator for common real-world patterns.
  • Examples: Runnable echo agent, interactive client, and agent+client duet.

Interactive CLI

The examples/cli directory ships a ready-to-use interactive ACP client powered by the SDK:

# Build
go build -o acp-cli ./examples/cli

# Run a session with a local agent
./acp-cli run -- ./examples/agent

# Run with any ACP-compatible agent binary
./acp-cli run -- claude-agent-acp

# Pass environment variables and set working directory
./acp-cli run -- claude-agent-acp --work-dir /project --env API_KEY=xxx

Inside the session:

  • Type any message and press Enter to prompt the agent
  • :cancel — cancel the current prompt
  • :exit or :quit — end the session

Install

go get github.com/keepmind9/acp-sdk-go

Quick Start

Run an Agent

package main

import (
    "context"
    "log"

    "github.com/keepmind9/acp-sdk-go/agent"
    "github.com/keepmind9/acp-sdk-go/core"
    "github.com/keepmind9/acp-sdk-go/schema"
)

type MyAgent struct {
    *agent.Base
}

func (a *MyAgent) Initialize(_ context.Context, req *schema.InitializeRequest) (*schema.InitializeResponse, error) {
    pv := schema.ProtocolVersion(1)
    return &schema.InitializeResponse{
        ProtocolVersion:   &pv,
        AgentCapabilities: &schema.AgentCapabilities{},
        AgentInfo:         &schema.Implementation{Name: "my-agent", Version: "0.1.0"},
    }, nil
}

func (a *MyAgent) NewSession(_ context.Context, req *schema.NewSessionRequest) (*schema.NewSessionResponse, error) {
    return &schema.NewSessionResponse{}, nil
}

func (a *MyAgent) Prompt(_ context.Context, req *schema.PromptRequest) (*schema.PromptResponse, error) {
    return &schema.PromptResponse{}, nil
}

func main() {
    core.RunAgent(&MyAgent{Base: &agent.Base{}})
}

Connect a Client

package main

import (
    "context"
    "log"

    "github.com/keepmind9/acp-sdk-go/client"
    "github.com/keepmind9/acp-sdk-go/core"
    "github.com/keepmind9/acp-sdk-go/schema"
    "github.com/keepmind9/acp-sdk-go/transport"
)

type MyClient struct {
    *client.Base
}

func (c *MyClient) SessionUpdate(_ context.Context, notif *schema.SessionNotification) error {
    if notif.Update.AgentMessageChunk != nil {
        log.Printf("session update: %s", notif.Update.AgentMessageChunk.Content.Text.Text)
    }
    return nil
}

func main() {
    subprocess, err := transport.Spawn("my-agent-binary")
    if err != nil {
        log.Fatal(err)
    }
    defer subprocess.Close()

    conn := core.ConnectToAgent(&MyClient{Base: &client.Base{}}, subprocess)

    pv := schema.ProtocolVersion(1)
    resp, err := conn.Initialize(&schema.InitializeRequest{
        ProtocolVersion:    &pv,
        ClientCapabilities: &schema.ClientCapabilities{},
    })
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("connected: agent %s", resp.AgentInfo.Name)
}

Project Layout

acp-sdk-go/
├── agent/          # Agent-side SDK: Agent interface, AgentSideConnection, router
├── client/         # Client-side SDK: Client interface, ClientSideConnection, router
├── contrib/        # High-level utilities: ToolCallTracker, PermissionBroker, SessionAccumulator
├── core/           # Convenience helpers: RunAgent, ConnectToAgent
├── helpers/        # Factory functions for ContentBlock, SessionUpdate, ToolCall
├── rpc/            # JSON-RPC 2.0 engine: Connection, Handler, Router, DecodeResponse
├── schema/         # All ACP data types, constants, discriminated unions
├── transport/      # Stdio transport and subprocess management
└── examples/       # Runnable examples: agent, client, duet, echo_agent

Schema Code Generation

The schema/ package is auto-generated from the ACP specification. Do not edit generated files directly.

make gen          # download latest schema + regenerate all schema/*.go
make gen-schema   # regenerate from local schema.json (no download)
make gen-download # download schema.json and meta.json from GitHub

After make gen, run make fmt to ensure the generated code is formatted. make all runs both.

Testing

make test        # all tests with race detector
make test-short  # fast tests without race detector
make e2e         # end-to-end smoke test

Contributing

Contributions are welcome. Please ensure:

  • make all passes before opening a PR (build, fmt, vet, test)
  • New code includes table-driven tests with testify
  • Public APIs have doc comments
  • Commits follow Conventional Commits: feat:, fix:, docs:, refactor:, opt:, chore:

License

MIT License. See LICENSE.

About

Go SDK for Agent Client Protocol (ACP) — JSON-RPC 2.0 over stdio for AI agents and editor/IDE clients.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors