anthropic_sdk_dart 1.4.1
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 #
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_KEYANTHROPIC_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();
}
}
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();
}
}
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()],
),
);
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();
}
}
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();
}
}
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();
}
}
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();
}
}
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();
}
}
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();
}
}
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();
}
}
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();
}
}
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 #
Sponsor #
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.