acp is a Go implementation of the Agent Client Protocol, a standard for communication between code editors ("Clients") and AI coding agents ("Agents"). It is based on JSON-RPC 2.0.
go get github.com/deicod/acpThe protocol defines two roles:
- Client: The initiator (e.g., an IDE or a CLI tool).
- Agent: The responder (e.g., an AI assistant).
Communication happens over any io.ReadWriteCloser (e.g., Stdio, TCP, WebSockets).
Used by an editor to connect to an agent.
package main
import (
"context"
"os/exec"
"github.com/deicod/acp"
)
func main() {
// 1. Start the agent process
cmd := exec.Command("agent-binary")
stdin, _ := cmd.StdinPipe()
stdout, _ := cmd.StdoutPipe()
cmd.Start()
// 2. implementation of ClientHandler (to handle agent requests)
handler := &MyClientHandler{}
// 3. Connect via Stdio
// Use a wrapper to combine stdout (writer) and stdin (reader) into a single io.ReadWriteCloser
// Note: You need to implement or find a helper for this wrapper.
conn := &readWriteCloser{Reader: stdout, Writer: stdin}
transport := acp.NewTransport(conn)
client := acp.NewClient(transport, handler)
client.Start()
defer client.Close()
// 4. Initialize
client.Initialize(context.Background(), "MyEditor", "1.0.0")
// 5. Send Prompt
client.Prompt(context.Background(), "Create a hello world in Go")
}Used to build an AI agent.
package main
import (
"context"
"os"
"github.com/deicod/acp"
)
type MyAgent struct {}
func (a *MyAgent) HandleInitialize(ctx context.Context, req *acp.InitializeRequest) (*acp.InitializeResult, error) {
return &acp.InitializeResult{
AgentInfo: acp.AgentInfo{Name: "MyAI", Version: "0.1"},
}, nil
}
func (a *MyAgent) HandlePrompt(ctx context.Context, req *acp.PromptRequest) (any, error) {
// Logic to handle prompt...
return "Done", nil
}
func main() {
// 1. Connect via Stdio
// Use a wrapper to combine os.Stdin and os.Stdout
conn := &readWriteCloser{Reader: os.Stdin, Writer: os.Stdout}
transport := acp.NewTransport(conn)
agent := acp.NewAgent(transport, &MyAgent{})
agent.Start()
// Block forever
select {}
}
// readWriteCloser is a simple wrapper to satisfy io.ReadWriteCloser
type readWriteCloser struct {
io.Reader
io.Writer
}
func (rwc *readWriteCloser) Close() error {
return nil // Close logic here
}See docs/SPEC.md for the full protocol specification.