Production-ready Go SDK for Claude AI agent integration
Features β’ Installation β’ Quick Start β’ Examples β’ Documentation
The Claude Agent SDK for Go provides a clean, idiomatic interface to build AI-powered applications with Claude. Designed for production use with comprehensive error handling, automatic resource management, and full feature parity with the official Python SDK.
- π― Two Powerful APIs: Query API for automation, Client API for interactive workflows
- π¦ Zero-Config Deployment: Optional bundled CLI - no separate installation required
- π Production-Ready: Comprehensive error handling, timeouts, resource cleanup
- π 100% Python SDK Parity: Same features, Go-native design (v0.1.9)
- πͺ Advanced Hook System: Intercept and control tool execution with custom callbacks
- π Structured Outputs: JSON schema validation for guaranteed response formats
- π Rich Integrations: File operations, MCP servers, external tools
- π‘οΈ Security-First: Granular permissions, access controls, runtime hooks
go get github.com/jonnyquan/claude-agent-sdk-go/pkg/claudesdkRequirements:
- Go 1.18 or later
- Claude CLI 2.0.50+ (auto-bundled or manual installation)
Optional: The SDK can bundle the Claude CLI for zero-dependency deployment. For custom installations:
curl -fsSL https://claude.ai/install.sh | bashThe new API provides a cleaner, more organized structure:
package main
import (
"context"
"fmt"
"log"
"github.com/jonnyquan/claude-agent-sdk-go/pkg/claudesdk"
)
func main() {
ctx := context.Background()
// Query API - Simple one-shot operations
messages, err := claudesdk.Query(ctx, "Explain Go channels in 2 sentences")
if err != nil {
log.Fatal(err)
}
// Process response
for {
msg, err := messages.Next(ctx)
if err != nil {
if err == claudesdk.ErrNoMoreMessages {
break
}
log.Fatal(err)
}
if assistant, ok := msg.(*claudesdk.AssistantMessage); ok {
for _, block := range assistant.Content {
if text, ok := block.(*claudesdk.TextBlock); ok {
fmt.Println(text.Text)
}
}
}
}
}package main
import (
"context"
"fmt"
"log"
"github.com/jonnyquan/claude-agent-sdk-go/pkg/claudesdk"
)
func main() {
ctx := context.Background()
// WithClient provides automatic resource management
err := claudesdk.WithClient(ctx, func(client claudesdk.Client) error {
// Send query
if err := client.Query(ctx, "Write a hello world in Go"); err != nil {
return err
}
// Receive streaming response
messages := client.ReceiveResponse(ctx)
for {
msg, err := messages.Next(ctx)
if err != nil {
if err == claudesdk.ErrNoMoreMessages {
break
}
return err
}
if assistant, ok := msg.(*claudesdk.AssistantMessage); ok {
for _, block := range assistant.Content {
if text, ok := block.(*claudesdk.TextBlock); ok {
fmt.Print(text.Text)
}
}
}
}
return nil
})
if err != nil {
log.Fatal(err)
}
}The old API is still supported via the compatibility layer:
import "github.com/jonnyquan/claude-agent-sdk-go" // Old API
// Works exactly as before
messages, err := claudecode.Query(ctx, "Hello!")Perfect for one-shot operations, automation, and CI/CD integration:
// Simple query with options
messages, err := claudesdk.Query(ctx,
"Analyze this codebase and suggest improvements",
claudesdk.WithCwd("/path/to/project"),
claudesdk.WithAllowedTools("Read", "List"),
claudesdk.WithModel("claude-sonnet-4-5"),
)Use Query API when you:
- Need automated code analysis or generation
- Want one-shot task completion
- Are building CI/CD integrations
- Prefer stateless operations
For complex workflows and interactive applications:
err := claudesdk.WithClient(ctx, func(client claudesdk.Client) error {
// First query
client.Query(ctx, "Initialize a Go project")
// Follow-up in same context
client.Query(ctx, "Add unit tests")
// Another follow-up
return client.Query(ctx, "Add CI/CD configuration")
},
claudesdk.WithSystemPrompt("You are a Go expert"),
claudesdk.WithMaxTurns(10),
)Use Client API when you:
- Need multi-turn conversations
- Want to build context across requests
- Are creating interactive applications
- Need real-time streaming
Get validated JSON responses with schema enforcement:
schema := map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"summary": map[string]interface{}{
"type": "string",
},
"line_count": map[string]interface{}{
"type": "number",
},
"languages": map[string]interface{}{
"type": "array",
"items": map[string]interface{}{"type": "string"},
},
},
"required": []string{"summary", "line_count", "languages"},
}
messages, err := claudesdk.Query(ctx,
"Analyze this repository",
claudesdk.WithOutputFormat(map[string]interface{}{
"type": "json_schema",
"schema": schema,
}),
)
// Get validated structured output
for {
msg, _ := messages.Next(ctx)
if result, ok := msg.(*claudesdk.ResultMessage); ok {
if result.StructuredOutput != nil {
data := result.StructuredOutput.(map[string]interface{})
fmt.Printf("Summary: %s\n", data["summary"])
fmt.Printf("Lines: %.0f\n", data["line_count"])
}
}
}Intercept and control AI operations with custom hooks:
// Security hook to block dangerous operations
securityHook := func(input claudesdk.HookInput, toolUseID *string,
ctx claudesdk.HookContext) (claudesdk.HookJSONOutput, error) {
if toolName, ok := input["tool_name"].(string); ok && toolName == "Bash" {
command := input["tool_input"].(map[string]any)["command"].(string)
if strings.Contains(command, "rm -rf") {
return claudesdk.HookJSONOutput{
"hookEventName": "PreToolUse",
"permissionDecision": claudesdk.PermissionDecisionDeny,
"permissionDecisionReason": "Dangerous command blocked",
}, nil
}
}
return claudesdk.NewPreToolUseOutput(
claudesdk.PermissionDecisionAllow, "", nil,
), nil
}
// Apply hook
err := claudesdk.WithClient(ctx, func(client claudesdk.Client) error {
return client.Query(ctx, "Run system maintenance")
},
claudesdk.WithHook(claudesdk.HookEventPreToolUse, claudesdk.HookMatcher{
Callback: securityHook,
Timeout: claudesdk.IntPtr(30),
}),
)Available hook events:
PreToolUse- Before tool executionPostToolUse- After tool executionUserPromptSubmit- On user inputStop- On conversation completionSubagentStop- On subagent completionPreCompact- Before context compaction
Maintain isolated conversation contexts:
err := claudesdk.WithClient(ctx, func(client claudesdk.Client) error {
// Session A: Math problems
client.QueryWithSession(ctx, "x = 5", "math")
client.QueryWithSession(ctx, "What is x * 2?", "math") // Returns 10
// Session B: Coding (separate context)
client.QueryWithSession(ctx, "language = Go", "coding")
client.QueryWithSession(ctx, "What language?", "coding") // Returns Go
// Default session (isolated from A and B)
return client.Query(ctx, "What did I ask?") // No prior context
})Connect to external tools and data sources:
// Create custom MCP server
server := claudesdk.CreateSDKMcpServer(&claudesdk.McpSdkServerConfig{
Name: "calculator",
Description: "Math operations",
Tools: []claudesdk.McpTool{
{
Name: "add",
Description: "Add two numbers",
Handler: func(args map[string]interface{}) (string, error) {
a := args["a"].(float64)
b := args["b"].(float64)
return fmt.Sprintf("%.2f", a+b), nil
},
},
},
})
// Use in query
err := claudesdk.WithClient(ctx, func(client claudesdk.Client) error {
return client.Query(ctx, "Calculate 15 + 27")
},
claudesdk.WithMcpServers(map[string]claudesdk.McpServerConfig{
"calculator": server,
}),
)We provide 24 comprehensive examples covering all use cases:
- 01: Quick Start - Basic Query API
- 02: Client Streaming - Real-time responses
- 03: Multi-turn Conversations
- 04: Query with Tools
- 05: Client with Tools
- 06: Query with MCP
- 07: Client with MCP
- 08: Advanced Client Patterns
- 09: Client vs Query Comparison
- 10: Context Manager Patterns
- 11: Session Management
- 12: Hook System
- 14: Plugin Support
- 15: SDK MCP Server
- 17: Structured Outputs
- 18: New API Basics
- 19: Query Patterns - Multiple configurations, timeouts
- 20: Client Streaming - WithClient patterns, multi-turn
- 21: Structured Outputs - JSON schema validation
- 22: Hooks System - Event handling and callbacks
- 23: MCP Integration - Server configuration
- 24: Error Handling - Production patterns
Run any example:
cd examples/19_new_query_patterns
go run main.goFull documentation available at pkg.go.dev
// Tool and permission control
claudesdk.WithAllowedTools("Read", "Write", "List")
claudesdk.WithPermissionMode(claudesdk.PermissionModeAcceptEdits)
// System behavior
claudesdk.WithSystemPrompt("You are a helpful assistant")
claudesdk.WithModel("claude-sonnet-4-5")
claudesdk.WithMaxTurns(20)
claudesdk.WithMaxBudgetUSD(1.0)
// Context and environment
claudesdk.WithCwd("/path/to/project")
claudesdk.WithAddDirs("src", "tests")
claudesdk.WithEnv(map[string]string{"DEBUG": "1"})
// Advanced features
claudesdk.WithFallbackModel("claude-3-haiku-20240307")
claudesdk.WithOutputFormat(jsonSchema)
claudesdk.WithHook(eventType, matcher)
claudesdk.WithMcpServers(serverMap)Migrating from old API to new API? See MIGRATION.md for a complete guide.
Quick reference:
// Old API
import "github.com/jonnyquan/claude-agent-sdk-go"
claudecode.Query(ctx, "Hello")
// New API (recommended)
import "github.com/jonnyquan/claude-agent-sdk-go/pkg/claudesdk"
claudesdk.Query(ctx, "Hello")Both APIs work - the new one is better organized and recommended for new projects.
claude-agent-sdk-go/
βββ pkg/
β βββ claudesdk/ # π New public API
β βββ client.go # Client interface
β βββ query.go # Query operations
β βββ types.go # Public types
β βββ options.go # Configuration options
β βββ hooks.go # Hook system
β βββ mcp.go # MCP integration
β βββ errors.go # Error definitions
β βββ permissions.go # Permission management
βββ internal/
β βββ client/ # Client implementation
β βββ query/ # Query implementation
β βββ transport/ # Claude CLI communication
β βββ discovery/ # CLI discovery and bundling
β βββ parsing/ # Message parsing
β βββ mcp/ # MCP server implementation
β βββ shared/ # Shared types and utilities
βββ claudecode.go # Backward compatibility layer
βββ examples/ # 24 comprehensive examples
βββ MIGRATION.md # Migration guide
# Run all tests
go test ./...
# Run specific package tests
go test ./pkg/claudesdk
go test ./internal/...
# With coverage
go test -cover ./...# Build all examples
for dir in examples/*/; do
(cd "$dir" && go build)
done
# Run specific example
cd examples/19_new_query_patterns
go run main.goContributions are welcome! Please feel free to submit issues and pull requests.
- Follow Go best practices and idioms
- Add tests for new features
- Update documentation
- Ensure backward compatibility when possible
- β¨ New
pkg/claudesdkAPI with cleaner structure - π Structured outputs with JSON schema validation
- π§ CLI auto-bundling for zero-dependency deployment
- πͺ Hook system timeout configuration
- π Enhanced error handling with AssistantMessageError
- π 6 new comprehensive examples (19-24)
- π Full backward compatibility via
claudecode.go - π Complete MIGRATION.md guide
- π Fallback model support
- π― Enhanced session management
- π Documentation improvements
- π Initial release
- π― Query and Client APIs
- πͺ Hook system
- π MCP integration
- π¦ Core tool support
MIT License - see LICENSE for details.
Copyright (c) 2025 Jonny Quan and Contributors
Built with β€οΈ for the Go community
Report Bug β’ Request Feature β’ Documentation