Open Source · MIT License
v0.7.1 Go 1.24+

Build AI Agents
in Go

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

Everything you need to build agents

A complete SDK designed for Go developers, with zero external dependencies.

One-Shot Queries

Simple Query() function for single interactions. Send a prompt, get streaming responses through channels.

Interactive Sessions

Bidirectional Client for multi-turn conversations with full session state management.

🔒

Permission Control

Fine-grained tool permissions with callbacks. Approve, deny, or modify tool usage in real-time.

🎣

Hook System

Respond to lifecycle events: PreToolUse, PostToolUse, Notifications, and more with pattern matching.

📡

MCP Support

Full Model Context Protocol integration. Connect external servers or build your own MCP services.

Idiomatic Go

Goroutines, channels, context propagation. Built for Go developers, not a port with Python patterns.

📦

Zero Dependencies

Core SDK uses only the Go standard library. No bloated dependency trees to manage.

📈

Full Streaming

Real-time message streaming with partial outputs, thinking blocks, and tool use events.

Up and running in minutes

Two lines to install, five lines to your first query.

1

Install the CLI

The SDK communicates with Claude through the Claude Code CLI.

bash
npm install -g @anthropic-ai/claude-code
2

Add the SDK

Install the Go module in your project.

bash
go get github.com/schlunsen/claude-agent-sdk-go
3

Set your API key

Authenticate with an API key or OAuth token.

bash
export CLAUDE_API_KEY="sk-ant-..."
4

Query Claude

Send your first query and stream the response.

go
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)
                }
            }
        }
    }
}

Powerful patterns, simple code

From one-shot queries to multi-turn agents with tool control.

Multi-Turn Conversations

The Client maintains session state across multiple queries, enabling natural back-and-forth conversations with Claude.

  • Persistent session context
  • Streaming responses via channels
  • Graceful connection lifecycle
go
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
}

Tool Permission Control

Control exactly which tools Claude can use with callback-based permission checks.

  • Allow/deny tools dynamically
  • Inspect tool inputs before execution
  • Multiple permission modes
go
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
    })

Lifecycle Hooks

React to agent events with pattern-matched hooks for logging, auditing, or custom behavior.

  • Pre/Post tool execution
  • Subagent lifecycle events
  • Pattern-matched filtering
go
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
        },
    })

Why Go?

Purpose-built for production workloads where performance matters.

Startup Time
Go
~30ms
Python
~300ms
Memory per Request
Go
~1KB
Python
~100KB
Concurrent Requests
Go
1M+
Python
~100
GC Pause
Go
<1ms
Python
1-10ms

Documentation

Comprehensive guides to get the most out of the SDK.

Ready to build?

Get started with the Claude Agent SDK for Go today.