Skip to content

Instantly share code, notes, and snippets.

@adam91holt
Created January 9, 2026 02:57
Show Gist options
  • Select an option

  • Save adam91holt/4b9117e5838c3123a42e0a969e03f105 to your computer and use it in GitHub Desktop.

Select an option

Save adam91holt/4b9117e5838c3123a42e0a969e03f105 to your computer and use it in GitHub Desktop.
Claude Agent SDK Architecture - how to call the model with tools

Claude Agent SDK Architecture

This document explains how the WhatsApp bot uses the Claude Agent SDK to respond to messages.

Installation

npm install @anthropic-ai/claude-agent-sdk

Authentication

The SDK uses Claude Code CLI authentication - not an API key. It piggybacks on the existing auth from the claude CLI tool.

To authenticate:

claude login

This stores credentials locally (typically in ~/.claude/) and the SDK picks them up automatically. No ANTHROPIC_API_KEY needed.

Core Import

import { query } from "@anthropic-ai/claude-agent-sdk";

Calling the Model

The SDK's query() function returns an async iterable that streams events:

async function runQueryWithTools(prompt: string, systemPrompt?: string): Promise<QueryResult> {
  const q = query({
    prompt,
    options: {
      model: "sonnet",              // or "haiku"
      systemPrompt: systemPrompt,
      maxTurns: 50,                 // agentic turns allowed
      allowedTools: ["WebSearch", "WebFetch", "Read", "Edit", "Write", "Glob", "Grep"],
      permissionMode: "acceptEdits",
      cwd: WORKSPACE_DIR,
    },
  });

  let result = "";
  for await (const msg of q) {
    if (msg.type === "result") {
      if (msg.subtype === "success") {
        result = msg.result;
      } else if (msg.subtype === "error") {
        throw new Error(msg.error);
      }
    }
  }
  return { result };
}

Query Options

Option Description
model Model to use: "sonnet", "haiku", "opus"
systemPrompt System prompt for the conversation
maxTurns Maximum agentic turns (API round-trips)
allowedTools Array of tool names the model can use
permissionMode How to handle tool permissions ("acceptEdits", etc.)
cwd Working directory for file operations
mcpServers Custom MCP servers with additional tools

Built-in Tools

The SDK provides these tools out of the box:

  • WebSearch - Search the web
  • WebFetch - Fetch and read web pages
  • Read - Read files
  • Edit - Edit files
  • Write - Write files
  • Glob - Find files by pattern
  • Grep - Search file contents

Streaming Events

The query returns an async iterable. Key event types:

for await (const msg of query) {
  switch (msg.type) {
    case "assistant":
      // Model response, may contain tool_use blocks
      break;
    case "result":
      if (msg.subtype === "success") {
        // Final result text
        result = msg.result;
      } else if (msg.subtype === "error") {
        // Error occurred
        throw new Error(msg.error);
      }
      break;
  }
}

Simple Query (No Tools)

For simple queries without tool use (e.g., moderation):

async function runQuery(prompt: string, systemPrompt?: string): Promise<string> {
  const q = query({
    prompt,
    options: {
      model: "haiku",
      systemPrompt: systemPrompt,
      maxTurns: 1,  // Single turn, no tools
    },
  });

  let result = "";
  for await (const msg of q) {
    if (msg.type === "result" && msg.subtype === "success") {
      result = msg.result;
    }
  }
  return result;
}

Key Points

  1. query() takes a prompt and options object
  2. Authentication is automatic via ANTHROPIC_API_KEY env var
  3. Streaming: iterate with for await...of to receive events
  4. Result: look for msg.type === "result" with subtype === "success"
  5. Tools: the SDK handles tool execution automatically during the agentic loop
  6. Models: use "haiku" for fast/cheap, "sonnet" for quality responses
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment