anthropic_sdk_dart 1.4.1 copy "anthropic_sdk_dart: ^1.4.1" to clipboard
anthropic_sdk_dart: ^1.4.1 copied to clipboard

Dart client for the Anthropic API. Provides type-safe access to Claude models with streaming, tool use, and batch processing support.

Anthropic Dart Client #

tests anthropic_sdk_dart Discord MIT

Dart client for the Anthropic API to build with Claude — messages, streaming, tool calling, extended thinking, multimodal prompts, files, skills, and batches. It gives Dart and Flutter applications a pure Dart, type-safe client across iOS, Android, macOS, Windows, Linux, Web, and server-side Dart.

Tip

Coding agents: start with llms.txt. It links to the package docs, examples, and optional references in a compact format.

Table of Contents

Features #

Generation and streaming #

  • Messages with typed inputs, system prompts, and multi-turn history
  • SSE streaming with cancelation and token counting
  • Extended thinking and adaptive thinking controls

Tools and multimodal #

  • Custom tool calling with strict schemas and tool choice controls
  • Computer use, web search, code execution, and MCP tool integration
  • Vision and document inputs with citations

Operational APIs #

  • Message batches for large-scale offline processing
  • Model discovery, files (beta), and skills (beta)

Why choose this client? #

  • Pure Dart with no Flutter dependency — works in mobile apps, backends, and CLIs.
  • Type-safe request and response models with minimal dependencies (http, logging, meta).
  • Streaming, retries, interceptors, and cancelation built into the client.
  • Follows Anthropic resource naming closely, so official docs translate directly into Dart code.
  • Strict semver versioning so downstream packages can depend on stable, predictable version ranges.

Quickstart #

dependencies:
  anthropic_sdk_dart: ^1.4.1
import 'package:anthropic_sdk_dart/anthropic_sdk_dart.dart';

Future<void> main() async {
  final client = AnthropicClient.fromEnvironment();

  try {
    final response = await client.messages.create(
      MessageCreateRequest(
        model: 'claude-sonnet-4-6',
        maxTokens: 1024,
        messages: [InputMessage.user('What is the capital of France?')],
      ),
    );

    print(response.text);
  } finally {
    client.close();
  }
}

Configuration #

Configure auth, retries, and custom Anthropic endpoints

Use AnthropicClient.fromEnvironment() when ANTHROPIC_API_KEY is available. Switch to AnthropicConfig when you need a proxy, custom timeout, or a non-default retry policy.

import 'package:anthropic_sdk_dart/anthropic_sdk_dart.dart';

Future<void> main() async {
  final client = AnthropicClient(
    config: AnthropicConfig(
      authProvider: ApiKeyProvider('YOUR_API_KEY'),
      baseUrl: 'https://api.anthropic.com',
      timeout: const Duration(minutes: 10),
      retryPolicy: RetryPolicy(
        maxRetries: 3,
        initialDelay: Duration(seconds: 1),
      ),
    ),
  );

  client.close();
}

Environment variables:

  • ANTHROPIC_API_KEY
  • ANTHROPIC_BASE_URL

Use explicit configuration on web builds where runtime environment variables are not available.

Usage #

How do I send a Claude message? #

Show example

client.messages.create(...) is the main Anthropic entry point. The response already exposes response.text, so you can skip manual content block traversal for common text outputs.

import 'package:anthropic_sdk_dart/anthropic_sdk_dart.dart';

Future<void> main() async {
  final client = AnthropicClient.fromEnvironment();

  try {
    final response = await client.messages.create(
      MessageCreateRequest(
        model: 'claude-sonnet-4-6',
        maxTokens: 512,
        messages: [InputMessage.user('Summarize why Flutter is useful.')],
      ),
    );

    print(response.text);
  } finally {
    client.close();
  }
}

Full example

How do I stream Claude responses? #

Show example

Streaming uses SSE and returns typed events. This keeps token-by-token rendering easy in Dart terminals, servers, and Flutter UIs.

import 'dart:io';

import 'package:anthropic_sdk_dart/anthropic_sdk_dart.dart';

Future<void> main() async {
  final client = AnthropicClient.fromEnvironment();

  try {
    final stream = client.messages.createStream(
      MessageCreateRequest(
        model: 'claude-sonnet-4-6',
        maxTokens: 256,
        messages: [InputMessage.user('Count from 1 to 5 slowly.')],
      ),
    );

    await for (final event in stream) {
      if (event is ContentBlockDeltaEvent && event.delta is TextDelta) {
        stdout.write((event.delta as TextDelta).text);
      }
    }
  } finally {
    client.close();
  }
}

Full example

How do I use tool calling? #

Show example

Anthropic tool calling supports custom schemas plus built-in tools. Keep the first request focused on the tool declaration, then feed the tool result back as another message turn.

import 'package:anthropic_sdk_dart/anthropic_sdk_dart.dart';

Future<void> main() async {
  final client = AnthropicClient.fromEnvironment();

  try {
    final response = await client.messages.create(
      MessageCreateRequest(
        model: 'claude-sonnet-4-6',
        maxTokens: 512,
        messages: [InputMessage.user('What is the weather in Madrid?')],
        tools: [
          Tool(
            name: 'get_weather',
            description: 'Get the current weather for a location',
            inputSchema: const InputSchema(
              properties: {
                'location': {'type': 'string'},
              },
              required: ['location'],
            ),
          ),
        ],
      ),
    );

    print(response.stopReason);
  } finally {
    client.close();
  }
}

Built-in tools like computer use, web search, code execution, and MCP are also available:

final response = await client.messages.create(
  MessageCreateRequest(
    model: 'claude-sonnet-4-6',
    maxTokens: 1024,
    messages: [InputMessage.user('Find the latest Dart release notes')],
    tools: [Tool.webSearch()],
  ),
);

Full example

How do I enable extended thinking? #

Show example

Extended thinking is configured on the request, not through a separate client. That makes it easy to mix regular and higher-reasoning calls in the same Dart application.

import 'package:anthropic_sdk_dart/anthropic_sdk_dart.dart';

Future<void> main() async {
  final client = AnthropicClient.fromEnvironment();

  try {
    final response = await client.messages.create(
      MessageCreateRequest(
        model: 'claude-sonnet-4-6',
        maxTokens: 1024,
        thinking: const ThinkingEnabled(budgetTokens: 512),
        messages: [InputMessage.user('Explain the tradeoffs of isolates in Dart.')],
      ),
    );

    print(response.text);
  } finally {
    client.close();
  }
}

Full example

How do I send images or documents? #

Show example

Anthropic accepts images and documents as typed content blocks. Use this surface when you need OCR, PDF analysis, citations, or multimodal reasoning in the same Claude request.

import 'package:anthropic_sdk_dart/anthropic_sdk_dart.dart';

Future<void> main() async {
  final client = AnthropicClient.fromEnvironment();

  try {
    final response = await client.messages.create(
      MessageCreateRequest(
        model: 'claude-sonnet-4-6',
        maxTokens: 512,
        messages: [
          InputMessage.userBlocks([
            InputContentBlock.text('Describe this image.'),
            InputContentBlock.image(ImageSource.url('https://example.com/image.png')),
          ]),
        ],
      ),
    );

    print(response.text);
  } finally {
    client.close();
  }
}

Full example

How do I count tokens? #

Show example

Use client.messages.countTokens(...) to estimate prompt cost and context usage before you send a full Claude request. This is useful when you need budget checks, truncation guards, or preflight validation in Dart services.

import 'package:anthropic_sdk_dart/anthropic_sdk_dart.dart';

Future<void> main() async {
  final client = AnthropicClient.fromEnvironment();

  try {
    final count = await client.messages.countTokens(
      TokenCountRequest.fromMessageCreateRequest(
        MessageCreateRequest(
          model: 'claude-sonnet-4-6',
          maxTokens: 256,
          messages: [InputMessage.user('How many tokens is this message?')],
        ),
      ),
    );

    print(count.inputTokens);
  } finally {
    client.close();
  }
}

Full example

How do I run message batches? #

Show example

Use client.messages.batches for offline or queue-driven workloads where Anthropic can process many requests asynchronously. This is the right surface for backfills, evaluations, and other large batch jobs that do not need an immediate interactive response.

import 'package:anthropic_sdk_dart/anthropic_sdk_dart.dart';

Future<void> main() async {
  final client = AnthropicClient.fromEnvironment();

  try {
    final batch = await client.messages.batches.create(
      MessageBatchCreateRequest(
        requests: [
          BatchRequestItem(
            customId: 'greeting-1',
            params: MessageCreateRequest(
              model: 'claude-sonnet-4-6',
              maxTokens: 50,
              messages: [InputMessage.user('Say hello!')],
            ),
          ),
        ],
      ),
    );

    print(batch.id);
  } finally {
    client.close();
  }
}

Full example

How do I list available models? #

Show example

Use client.models.list() to discover available Claude models and inspect their metadata.

import 'package:anthropic_sdk_dart/anthropic_sdk_dart.dart';

Future<void> main() async {
  final client = AnthropicClient.fromEnvironment();

  try {
    final response = await client.models.list();

    for (final model in response.data) {
      print('${model.id} — ${model.displayName}');
    }
  } finally {
    client.close();
  }
}

Full example

How do I manage files? #

Show example

Use client.files to upload, list, and delete files. This beta API lets you attach stored files to messages without re-uploading each time.

import 'dart:typed_data';

import 'package:anthropic_sdk_dart/anthropic_sdk_dart.dart';

Future<void> main() async {
  final client = AnthropicClient.fromEnvironment();

  try {
    final uploaded = await client.files.uploadBytes(
      bytes: Uint8List.fromList([0x48, 0x65, 0x6C, 0x6C, 0x6F]),
      fileName: 'hello.txt',
      mimeType: 'text/plain',
    );

    print('Uploaded: ${uploaded.id}');

    final files = await client.files.list(limit: 10);
    print('Total files: ${files.data.length}');

    await client.files.deleteFile(fileId: uploaded.id);
  } finally {
    client.close();
  }
}

Full example

How do I manage skills? #

Show example

Use client.skills to list reusable skills. The full API also lets you create, version, and delete skills, packaging prompts and tools into versioned units that Claude can invoke.

import 'package:anthropic_sdk_dart/anthropic_sdk_dart.dart';

Future<void> main() async {
  final client = AnthropicClient.fromEnvironment();

  try {
    final response = await client.skills.list(limit: 10);

    for (final skill in response.data) {
      print('${skill.id}: ${skill.displayTitle ?? "untitled"}');
    }
  } finally {
    client.close();
  }
}

Full example

Error Handling #

Handle retries, validation failures, and request aborts

anthropic_sdk_dart throws typed exceptions so retry logic and validation handling stay explicit. Catch ApiException and its subclasses first, then fall back to AnthropicException for other transport or parsing failures.

import 'dart:io';

import 'package:anthropic_sdk_dart/anthropic_sdk_dart.dart';

Future<void> main() async {
  final client = AnthropicClient.fromEnvironment();

  try {
    await client.messages.create(
      MessageCreateRequest(
        model: 'claude-sonnet-4-6',
        maxTokens: 64,
        messages: [InputMessage.user('Ping')],
      ),
    );
  } on RateLimitException catch (error) {
    stderr.writeln('Retry after: ${error.retryAfter}');
  } on ApiException catch (error) {
    stderr.writeln('Anthropic API error ${error.statusCode}: ${error.message}');
  } on AnthropicException catch (error) {
    stderr.writeln('Anthropic client error: $error');
  } finally {
    client.close();
  }
}

Full example

Examples #

See the example/ directory for complete examples:

Example Description
messages_example.dart Basic message creation
streaming_example.dart Streaming responses
tool_calling_example.dart Tool calling with schemas
web_search_example.dart Web search tool
computer_use_example.dart Computer use tool
thinking_example.dart Extended thinking
vision_example.dart Image and document inputs
document_example.dart Document inputs with citations
token_counting_example.dart Token counting
message_batches_example.dart Batch processing
files_example.dart File management (beta)
skills_example.dart Skills management (beta)
mcp_example.dart MCP tool integration
models_example.dart Model listing
error_handling_example.dart Exception handling patterns
anthropic_sdk_dart_example.dart Quick-start overview

API Coverage #

API Status
Messages ✅ Full
Message Batches ✅ Full
Models ✅ Full
Files (Beta) ✅ Full
Skills (Beta) ✅ Full

Official Documentation #

If these packages are useful to you or your company, please consider sponsoring the project. Development and maintenance are provided to the community for free, but integration tests against real APIs and the tooling required to build and verify releases still have real costs. Your support, at any level, helps keep these packages maintained and free for the Dart & Flutter community.

License #

This package is licensed under the MIT License.

This is a community-maintained package and is not affiliated with or endorsed by Anthropic.

12
likes
160
points
10.8k
downloads

Documentation

Documentation
API reference

Publisher

verified publisherdavidmiguel.com

Weekly Downloads

Dart client for the Anthropic API. Provides type-safe access to Claude models with streaming, tool use, and batch processing support.

Homepage
Repository (GitHub)
View/report issues

Topics

#nlp #gen-ai #llms #anthropic #claude

Funding

Consider supporting this project:

github.com

License

MIT (license)

Dependencies

http, logging, meta

More

Packages that depend on anthropic_sdk_dart