Agent Client Protocol (ACP) Go SDK

repository·main·Indexed 41 days ago

https://github.com/coder/acp-go-sdk

A Go library for implementing the Agent Client Protocol (ACP), which standardizes communication between AI-powered coding agents and code editors. The SDK provides interfaces and connection handlers for both agents and clients, including support for file system operations, terminal management, session control, and custom JSON-RPC extension methods. It includes helper constructors for content blocks and tools, as well as unstable support for Model Context Protocol (MCP) and document lifecycle management.

Tokens
24.1K
Snippets
76
Records
115
Agent score
50%

What's inside ACP Go SDK

  1. Implement and use ACP extension methods

    main

    ACP supports custom JSON-RPC methods that start with an underscore (_). These allow you to add functionality without breaking compatibility with future protocol versions.

    Handling inbound extensions

    Implement the acp.ExtensionMethodHandler interface on your Agent or Client. The handler is invoked for any incoming method starting with _.

    Calling extensions

    Use CallExtension (for request/response) or NotifyExtension (for notifications) on the connection object.

    Advertising extensions

    Extensions are negotiated via the _meta field within capability objects:

    • Client to Agent: InitializeRequest.ClientCapabilities.Meta
    • Agent to Client: InitializeResponse.AgentCapabilities.Meta

    Note: traceparent, tracestate, and baggage are reserved in _meta for W3C trace context/OpenTelemetry compatibility.

    // HandleExtensionMethod handles ACP extension methods (names starting with "_").
    func (a MyAgent) HandleExtensionMethod(ctx context.Context, method string, params json.RawMessage) (any, error) {
    	switch method {
    	case "_example.com/hello":
    		var p struct {
    			Name string ` + "`json:\"name\"`" + `
    		}
    		if err := json.Unmarshal(params, &p); err != nil {
    			return nil, err
    		}
    		return map[string]any{"greeting": "hello " + p.Name}, nil
    	default:
    		return nil, acp.NewMethodNotFound(method)
    	}
    }
    
    // Calling an extension
    raw, err := conn.CallExtension(ctx, "_example.com/hello", map[string]any{"name": "world"})
    if err != nil {
    	return err
    }
    
    // Notifying an extension
    if err := conn.NotifyExtension(ctx, "_example.com/progress", map[string]any{"pct": 50}); err != nil {
    	return err
    }
  2. Prerequisites for releasing the ACP Go SDK

    main

    Before attempting to release, ensure your environment meets the following requirements:

    • Tools: make, curl, and git must be in your PATH.
    • Toolchain: mise should be used to provision Go, treefmt, and the necessary formatters/linters.
    • Setup: Run mise install once to provision the environment.
    • CI/CD: For automated release note generation, the repository must have an Actions secret named ANTHROPIC_API_KEY.
  3. Tag and publish a new SDK release

    main

    Once the schema version has been bumped and the code is verified, follow these steps to publish the release:

    1. Commit the changes: Use a descriptive message like release: v0.4.3.
    2. Tag the commit: Create a Go-compatible semver tag and push it to the origin.
      git tag v0.4.3
      git push origin v0.4.3
    3. Create a GitHub release: Create the release on GitHub and include a summary of changes referencing the upstream ACP schema version.

    Note on Release Notes: If the repository has an ANTHROPIC_API_KEY Actions secret configured, a CI workflow will automatically update the GitHub Release body with generated notes after publication. This automation only updates the GitHub Release body and does not maintain a CHANGELOG.md.

    git tag v0.4.3
    git push origin v0.4.3
  4. Run ACP SDK examples

    main

    The example directory contains implementations for testing agents and clients. You can run them directly from your terminal:

    • Minimal Agent: go run ./example/agent (starts an agent over stdio).
    • Claude Code Bridge: go run ./example/claude-code.
    • Client: go run ./example/client (connects to an agent and streams a sample turn).
    • Gemini Bridge: go run ./example/gemini (bridges to Gemini CLI). Supports flags: -model, -sandbox, -debug, -gemini /path/to/gemini.
    go run ./example/agent
    go run ./example/client
  5. Prepare a release by bumping the ACP schema version

    main

    To release a new version of the SDK, you must align it with a specific upstream ACP schema tag (e.g., v0.4.3). This ensures that generated code, helper APIs, and the library version remain in sync. You can either use the automated release helper or perform the steps manually.

    Run the following command to automate the version update, code regeneration, and validation:

    make release VERSION=0.4.3

    This helper:

    1. Writes the version to schema/version.
    2. Runs make version to download schema files and regenerate Go code.
    3. Runs make fmt, make test, and make check.
    4. Asserts that schema/version and the top-level version file match.

    Option B: Manual steps

    If you prefer to run the steps manually, execute this sequence:

    printf '0.4.3\n' > schema/version
    make version
    make fmt
    GOCACHE=$(pwd)/.gocache make test
    make check
    cmp -s schema/version version

    Note: make version downloads the schema files for the requested ACP tag and regenerates all Go code using gofumpt for formatting. The cmp command ensures the version files are synchronized.

  6. How to build an ACP Agent

    main

    To implement an Agent using this SDK, follow these steps:

    1. Implement the Interface: Implement the acp.Agent interface. Optionally, implement acp.AgentLoader if you want to support session/load functionality.
    2. Establish Connection: Create a connection using acp.NewAgentSideConnection(agent, os.Stdout, os.Stdin). This typically uses standard I/O for communication.
    3. Handle Communication: Use the returned connection object to send updates and process client requests.
  7. How to build an ACP Client

    main

    To implement a Client using this SDK, follow these steps:

    1. Implement the Interface: Implement the acp.Client interface. Optionally, implement acp.ClientTerminal to provide terminal features.
    2. Establish Connection: Launch or connect to your Agent process (usually via stdio), then create a connection using acp.NewClientSideConnection(client, stdin, stdout).
    3. Run a Turn: Use the connection to call Initialize, NewSession, and Prompt to execute a turn and stream updates back to the user.
  8. Use the acp package for Agent Client Protocol (ACP) communication

    main

    The acp package provides the core Go types and connection plumbing required to implement the Agent Client Protocol (ACP). It is designed to be used by both agents and clients to facilitate communication. The package includes:

    • Generated dispatchers: For handling incoming protocol messages.
    • Outbound helpers: For constructing and sending messages.
    • Shared request/response types: Standardized data structures used across the protocol.
    • Related utilities: General tools for managing ACP connections and messaging.
  9. Use ClientSideConnection to implement Agent calls

    main
    The ClientSideConnection struct serves as the client's view of the connection. It wraps an internal Connection and a Client implementation, acting as the primary interface for executing Agent calls from the client side.
  10. Configure MCP (Model Context Protocol) servers

    main

    The McpServer type is a union that allows connecting to Model Context Protocol servers via different transports. The available transport depends on the mcpCapabilities reported by the agent.

    Supported transports:

    • Stdio: (Mandatory) Uses McpServerStdio with Command, Args, and Env.
    • Http: Uses McpServerHttpInline (or McpServerHttp) with a Url and Headers.
    • Sse: Uses McpServerSseInline (or McpServerSse) with a Url and Headers.
    • Acp: (Unstable) Uses McpServerAcpInline with an Id (of type McpServerAcpId).
    // Example: Configuring a Stdio MCP server
    server := McpServer{
        Stdio: &McpServerStdio{
            Name:    "my-tool",
            Command: "npx",
            Args:    []string{"-y", "@modelcontextprotocol/server-everything"},
            Env:     []EnvVariable{{Key: "DEBUG", Value: "true"}},
        },
    }
  11. Manage execution plans with the Plan type

    main

    An execution plan (Plan) is used by agents to provide visibility into their execution strategy. It consists of multiple PlanEntry items representing individual tasks or goals.

    Key behaviors:

    • Evolution: Plans can evolve during execution as agents discover new requirements.
    • Updates: When updating a plan, the agent must send a complete list of all entries with their current status. The client replaces the entire existing plan with the new update.
    • Extensibility: All plan types include a Meta field (map[string]any) for attaching additional metadata. Implementations must not make assumptions about the values in this field.
    type Plan struct {
    	Meta    map[string]any `json:"_meta,omitempty"` 
    	Entries []PlanEntry    `json:"entries"` 
    }