The unofficial Go SDK for building multi-turn AI agent applications with Claude. Idiomatic Go. Zero dependencies. Full streaming.
go get github.com/schlunsen/claude-agent-sdk-go
A complete SDK designed for Go developers, with zero external dependencies.
Simple Query() function for single interactions. Send a prompt, get streaming responses through channels.
Bidirectional Client for multi-turn conversations with full session state management.
Fine-grained tool permissions with callbacks. Approve, deny, or modify tool usage in real-time.
Respond to lifecycle events: PreToolUse, PostToolUse, Notifications, and more with pattern matching.
Full Model Context Protocol integration. Connect external servers or build your own MCP services.
Goroutines, channels, context propagation. Built for Go developers, not a port with Python patterns.
Core SDK uses only the Go standard library. No bloated dependency trees to manage.
Real-time message streaming with partial outputs, thinking blocks, and tool use events.
Two lines to install, five lines to your first query.
The SDK communicates with Claude through the Claude Code CLI.
npm install -g @anthropic-ai/claude-code
Install the Go module in your project.
go get github.com/schlunsen/claude-agent-sdk-go
Authenticate with an API key or OAuth token.
export CLAUDE_API_KEY="sk-ant-..."
Send your first query and stream the response.
package main
import (
"context"
"fmt"
"log"
claude "github.com/schlunsen/claude-agent-sdk-go"
"github.com/schlunsen/claude-agent-sdk-go/types"
)
func main() {
ctx := context.Background()
opts := types.NewClaudeAgentOptions()
messages, err := claude.Query(ctx, "What is 2 + 2?", opts)
if err != nil {
log.Fatal(err)
}
for msg := range messages {
if a, ok := msg.(*types.AssistantMessage); ok {
for _, block := range a.Content {
if t, ok := block.(*types.TextBlock); ok {
fmt.Println(t.Text)
}
}
}
}
}
From one-shot queries to multi-turn agents with tool control.
The Client maintains session state across multiple queries, enabling natural back-and-forth conversations with Claude.
client, _ := claude.NewClient(ctx, opts)
client.Connect(ctx)
defer client.Close(ctx)
// First turn
client.Query(ctx, "Explain goroutines")
for msg := range client.ReceiveResponse(ctx) {
// process streaming response
}
// Follow-up (maintains context)
client.Query(ctx, "How do they compare to threads?")
for msg := range client.ReceiveResponse(ctx) {
// Claude remembers the conversation
}
Control exactly which tools Claude can use with callback-based permission checks.
opts := types.NewClaudeAgentOptions().
WithCanUseTool(func(
tool string, input map[string]any,
) (*types.PermissionResponse, error) {
if tool == "Bash" {
cmd := input["command"].(string)
if strings.Contains(cmd, "rm -rf") {
return types.DenyPermission(
"Destructive commands blocked",
), nil
}
}
return types.AllowPermission(), nil
})
React to agent events with pattern-matched hooks for logging, auditing, or custom behavior.
opts := types.NewClaudeAgentOptions().
WithHook(types.PreToolUse, types.HookMatcher{
ToolName: "Bash",
Handler: func(
input map[string]any,
) (*types.HookResponse, error) {
fmt.Printf("Running: %s\n",
input["command"])
return &types.HookResponse{
Decision: types.HookApprove,
}, nil
},
})
Purpose-built for production workloads where performance matters.
Comprehensive guides to get the most out of the SDK.
Deep dive into Go vs Python design decisions, concurrency models, and type systems.
Read guide →Step-by-step guide with side-by-side code examples for Python developers.
Read guide →Complete feature comparison matrix with the official Python SDK (~95% parity).
Read guide →Full GoDoc API reference with all types, functions, and interfaces.
pkg.go.dev →