An open API service indexing awesome lists of open source software.

https://github.com/xemantic/anthropic-sdk-kotlin

Unofficial Kotlin multiplatform variant of the Anthropic SDK
https://github.com/xemantic/anthropic-sdk-kotlin

agent agentic agentic-ai agentic-ai-development ai claude claude-ai claude-api kotlin kotlin-library kotlin-multiplatform ktor ktor-client machine-learning sdk

Last synced: 20 days ago
JSON representation

Unofficial Kotlin multiplatform variant of the Anthropic SDK

Awesome Lists containing this project

README

          

# anthropic-sdk-kotlin

Unofficial Kotlin multiplatform variant of the
[Anthropic SDK](https://docs.anthropic.com/en/api/client-sdks).

[Maven Central Version](https://central.sonatype.com/artifact/com.xemantic.ai/anthropic-sdk-kotlin)
[GitHub Release Date](https://github.com/xemantic/anthropic-sdk-kotlin/releases)
[license](https://github.com/xemantic/anthropic-sdk-kotlin/blob/main/LICENSE)

[GitHub Actions Workflow Status](https://github.com/xemantic/anthropic-sdk-kotlin/actions/workflows/build-main.yml)
[GitHub branch check runs](https://github.com/xemantic/anthropic-sdk-kotlin/actions/workflows/build-main.yml)
[GitHub commits since latest release](https://github.com/xemantic/anthropic-sdk-kotlin/commits/main/)
[GitHub last commit](https://github.com/xemantic/anthropic-sdk-kotlin/commits/main/)

[GitHub contributors](https://github.com/xemantic/anthropic-sdk-kotlin/graphs/contributors)
[GitHub commit activity](https://github.com/xemantic/anthropic-sdk-kotlin/commits/main/)
[GitHub code size in bytes]()
[GitHub Created At](https://github.com/xemantic/anthropic-sdk-kotlin/commits)
[kotlin version](https://kotlinlang.org/docs/releases.html)
[ktor version](https://ktor.io/)
[discord users online](https://discord.gg/vQktqqN2Vn)
[![Bluesky](https://img.shields.io/badge/Bluesky-0285FF?logo=bluesky&logoColor=fff)](https://bsky.app/profile/xemantic.com)

> [!IMPORTANT]
> 🤖 **Build Your Own AI Agents** - Details:

## Why?

Because I believe that coding AI agents should be as easy as possible. I am coming from the [creative coding community](https://creativecode.berlin/), where we are teaching artists, without prior programming experience, how to express their creations through code as a medium.
I want to give creators of all kinds this extremely powerful tool, so that also **you can turn your own machine into an outside window, through which, the AI system can perceive your world, values and needs, and act upon this information.** My first AI agent, which emerged on top of this project, is called [Claudine](https://github.com/xemantic/claudine).

There is no official Anthropic SDK for Kotlin, a de facto standard for Android development. The one for Java is also lacking. Even if they will appear one day, we can expect them to be autogenerated by the
[Stainless API bot](https://www.stainlessapi.com/), which is used by both, Anthropic and OpenAI, to automate
their SDK development based on evolving API. While such an approach seem to work with dynamically typed languages,
it might fail short with statically typed languages like Kotlin, sacrificing typical language idioms in favor
of [over-verbose constructs](https://github.com/anthropics/anthropic-sdk-go/blob/main/examples/tools/main.go).
This library is a [Kotlin multiplatform](https://kotlinlang.org/docs/multiplatform.html)
one, therefore your AI agents developed with it can be seamlessly used in Android, JVM, JavaScript, macOS, iOS, WebAssembly,
and many other environments.

## Usage

> [!CAUTION]
> This SDK is in the early stage of development, so still a subject to API changes,
> however at the same time it is completely functional and passing all the
> [test cases](src/commonTest/kotlin).

The easiest way to use this project is to start with [anthropic-sdk-kotlin-jvm-template](https://github.com/xemantic/anthropic-sdk-kotlin-jvm-template) as a template repository. There are also many ready examples and use cases in the
[anthropic-sdk-kotlin-demo](https://github.com/xemantic/anthropic-sdk-kotlin-demo) repo.

Otherwise, you need to add to your `build.gradle.kts`:

```kotlin
dependencies {
implementation("com.xemantic.ai:anthropic-sdk-kotlin:0.26.0")
}
```

, and in case of JVM:

```kotlin
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
implementation("io.ktor:ktor-client-java:3.0.1") // or the latest ktor version
// and if you don't care about configuring logging
implementation("org.slf4j:slf4j-simple:2.0.16")
}
```

, if you are planning to use tools, you will also need:

```kotlin
plugins {
// ... other plugins like kotlin jvm or multiplatform
kotlin("plugin.serialization") version "2.1.10"
}

dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3")
}
```

The simplest code look like:

```kotlin
fun main() {
val anthropic = Anthropic()
val response = runBlocking {
anthropic.messages.create {
+"Hello, Claude"
}
}
println(response)
}
```

### Response streaming

Streaming is also possible:

```kotlin
fun main() = runBlocking {
val client = Anthropic()
client.messages.stream {
+"Write me a poem."
}
.filter { it.delta is Event.ContentBlockDelta.Delta.TextDelta }
.map { (it.delta as Event.ContentBlockDelta.Delta.TextDelta).text }
.collect { delta -> print(delta) }
}
```

The `toMessageResponse` function will return the complete `MessageResponse` from the stream:

```kotlin
fun main() = runBlocking {
val client = Anthropic()
val response = client.messages.stream {
+"Write me a poem."
}
.onEach { println("Event: $it") }
.toMessageResponse()
println(response)
}
```

### Customizing the HTTP client

Under the hood the SDK uses [ktor](https://ktor.io/)'s `HttpClient`. The `httpClientConfig` block on `Anthropic.Config` is applied last, so it can install additional plugins or layer extra defaults on top of the SDK's own configuration. This is the place to add custom headers (for example `Authorization: Bearer …` when routing through a gateway), tweak timeouts, or attach a custom logger.

```kotlin
val anthropic = Anthropic {
httpClientConfig = {
install(HttpTimeout) {
requestTimeoutMillis = 60_000
}
defaultRequest {
header("Authorization", "Bearer $gatewayToken")
header("X-Tenant-Id", tenantId)
}
}
}
```

Notes:

- Multiple `defaultRequest { }` blocks accumulate in ktor 3.x, so headers added here are appended to the SDK's defaults (`x-api-key`, `anthropic-version`, etc.) rather than replacing them.
- `apiKey` is still required at construction time and the SDK will always send `x-api-key`. If your gateway only accepts a Bearer token, supply a placeholder `apiKey` and have the gateway strip the unwanted header.
- For proxies and self-hosted gateways, override the base URL via `apiBase` instead of trying to rewrite it from `httpClientConfig`.
- Avoid re-installing plugins already set up by the SDK (`SSE`, `ContentNegotiation`, `Logging`, `HttpRequestRetry`) — ktor will fail at install time or silently override SDK behavior.

### Using tools

> [!NOTE]
> Check [Tool Use Guide](docs/tool_use_guide.md) document for full documentation.

If you want to write AI agents, you need tools, and this is where this library shines, while removing any boilerplate code:

```kotlin
@Description("Get the weather for a specific location")
data class GetWeather(val location: String)

fun main() = runBlocking {
val toolbox = Toolbox {
tool {
"The weather in $location is 73f" // it would be returned by API
}
}
val anthropic = Anthropic {
defaultTools = toolbox.tools
}

val conversation = mutableListOf()
conversation += "What is the weather in SF?"

val initialResponse = client.messages.create {
messages = conversation
}
println("Initial response: ${initialResponse.text}")

conversation += initialResponse
conversation += initialResponse.useTools(toolbox)

val finalResponse = client.messages.create {
messages = conversation
}
println("Final response: ${finalResponse.text}")
}
```

The JSON schema of `get_weather` tool is automatically extracted from the class definition and sent to the Anthropic API when creating the message containing `tools`.

For the reference check equivalent examples in the official Anthropic SDKs:

* [TypeScript](https://github.com/anthropics/anthropic-sdk-typescript/blob/main/examples/tools.ts)
* [Python](https://github.com/anthropics/anthropic-sdk-python/blob/main/examples/tools.py)
* [Go](https://github.com/anthropics/anthropic-sdk-go/blob/main/examples/tools/main.go)

### Calculating usage costs

Each `MessageResponse` carries the `Usage` reported by the API. Cost is computed on the caller side — `response.usage * model.cost` for a single response, or accumulate across calls with `costWithUsage += response.usage.pricedBy(model)`. See the [Cost aggregation guide](docs/cost_aggregation.md) for details, including how to share an accumulator across coroutines.

## Projects using anthropic-sdk-kotlin

* [anthropic-sdk-kotlin-demo](https://github.com/xemantic/anthropic-sdk-kotlin-demo): more complex examples
and use cases
* [claudine](https://github.com/xemantic/claudine): Claudine, the only AI assistant you will ever need, the actual
reason why `anthropic-sdk-kotlin` came to being, to allow me building Claudine and other AI agents.

## Building the project

```shell
export ANTHROPIC_API_KEY=your-key-goes-here
./gradlew build
```

Many [unit tests](src/commonTest/kotlin) are actually integration tests calling Anthropic APIs
and asserting against results. Tests default to Claude Haiku model to reduce API costs.
These integration test might be flaky from time to time. For example, if the test image
is misinterpreted, or Claude is randomly fantasizing too much.

### Environment variables in browser tests

Browser-based tests for the `js` and `wasmJs` targets run inside a headless Chrome via Karma and have no access to the operating system environment. Any env var that a browser test needs to read (via `process.env.X` or the `getEnv(name)` helper from `xemantic-kotlin-test`) must be explicitly injected into the Webpack bundle through [`webpack.config.d/env-config.js`](webpack.config.d/env-config.js), which uses Webpack's `DefinePlugin` to substitute `process.env.X` references at bundle time from the OS environment of the Gradle process.

When adding a new integration test that depends on a new env var, update three places:

1. `build.gradle.kts` — forward the var to the test task via `environment(name, value)` for `KotlinJvmTest`, `KotlinJsTest`, and `KotlinNativeTest` (and `SIMCTL_CHILD_*` for iOS simulator).
2. `webpack.config.d/env-config.js` — add `'': JSON.stringify(process.env.)` so browser bundles can see it.
3. The CI workflow secrets — ensure the var is exported into the Gradle process by the reusable workflow at `xemantic/.github`.

Without step 2, the JVM, Native and Node-based JS/wasmJs tests pass while the browser test fails with "No such environment variable: \".

## Project dependencies

API dependencies (will be provided as transitive dependencies of `anthropic-sdk-kotlin`):

* [xemantic-ai-tool-schema](https://github.com/xemantic/xemantic-ai-tool-schema)
* [xemantic-ai-money](https://github.com/xemantic/xemantic-ai-money)
* [xemantic-kotlin-core](https://github.com/xemantic/xemantic-kotlin-core)

Implementation dependencies:

* [ktor](https://ktor.io/)