# Claude API — Java > **Note:** The Java SDK supports the Claude API and beta tool use with annotated classes. Agent SDK is not yet available for Java. ## Installation Maven: \`\`\`xml com.anthropic anthropic-java 2.11.1 \`\`\` Gradle: \`\`\`groovy implementation("com.anthropic:anthropic-java:2.11.1") \`\`\` ## Client Initialization \`\`\`java import com.anthropic.client.AnthropicClient; import com.anthropic.client.okhttp.AnthropicOkHttpClient; // Default (reads ANTHROPIC_API_KEY from environment) AnthropicClient client = AnthropicOkHttpClient.fromEnv(); // Explicit API key AnthropicClient client = AnthropicOkHttpClient.builder() .apiKey("your-api-key") .build(); \`\`\` --- ## Basic Message Request \`\`\`java import com.anthropic.models.messages.MessageCreateParams; import com.anthropic.models.messages.Message; import com.anthropic.models.messages.Model; MessageCreateParams params = MessageCreateParams.builder() .model(Model.CLAUDE_OPUS_4_6) .maxTokens(1024L) .addUserMessage("What is the capital of France?") .build(); Message response = client.messages().create(params); response.content().stream() .flatMap(block -> block.text().stream()) .forEach(textBlock -> System.out.println(textBlock.text())); \`\`\` --- ## Streaming \`\`\`java MessageCreateParams params = MessageCreateParams.builder() .model(Model.CLAUDE_OPUS_4_6) .maxTokens(1024L) .addUserMessage("Write a haiku") .build(); try (var streamResponse = client.messages().createStreaming(params)) { streamResponse.stream().forEach(event -> { event.contentBlockDelta().ifPresent(deltaEvent -> deltaEvent.delta().text().ifPresent(td -> System.out.print(td.text()) ) ); }); } \`\`\` --- ## Tool Use (Beta) The Java SDK supports beta tool use with annotated classes. Tool classes implement \`Supplier\` for automatic execution via \`BetaToolRunner\`. ### Tool Runner (automatic loop) \`\`\`java import com.anthropic.models.beta.messages.MessageCreateParams; import com.anthropic.models.beta.messages.BetaMessage; import com.anthropic.helpers.BetaToolRunner; import com.fasterxml.jackson.annotation.JsonClassDescription; import com.fasterxml.jackson.annotation.JsonPropertyDescription; import java.util.function.Supplier; @JsonClassDescription("Get the weather in a given location") static class GetWeather implements Supplier { @JsonPropertyDescription("The city and state, e.g. San Francisco, CA") public String location; @Override public String get() { return "The weather in " + location + " is sunny and 72°F"; } } BetaToolRunner toolRunner = client.beta().messages().toolRunner( MessageCreateParams.builder() .model("claude-opus-4-6") .maxTokens(1024L) .addTool(GetWeather.class) .addUserMessage("What's the weather in San Francisco?") .build()); for (BetaMessage message : toolRunner) { System.out.println(message); } \`\`\` ### Manual Loop For manual tool loops, define tools as JSON schema in the request, handle \`tool_use\` blocks in the response, send \`tool_result\` back, and loop until \`stop_reason\` is \`"end_turn"\`. See the [shared tool use concepts](../shared/tool-use-concepts.md) for the agentic loop pattern.