# Managed Agents — Java > **Bindings not shown here:** This README covers the most common managed-agents flows for Java. If you need a class, method, namespace, field, or behavior that isn't shown, WebFetch the Java SDK repo **or the relevant docs page** from `shared/live-sources.md` rather than guess. Do not extrapolate from cURL shapes or another language's SDK. > **Agents are persistent — create once, reference by ID.** Store the agent ID returned by `client.beta().agents().create` and pass it to every subsequent `client.beta().sessions().create`; do not call `agents().create` in the request path. The Anthropic CLI is one convenient way to create agents and environments from version-controlled YAML — its URL is in `shared/live-sources.md`. The examples below show in-code creation for completeness; in production the create call belongs in setup, not in the request path. ## Installation ```xml com.anthropic anthropic-java ``` ## Client Initialization ```java import com.anthropic.client.okhttp.AnthropicOkHttpClient; // Default (uses ANTHROPIC_API_KEY env var) var client = AnthropicOkHttpClient.fromEnv(); ``` --- ## Create an Environment ```java import com.anthropic.models.beta.environments.BetaCloudConfigParams; import com.anthropic.models.beta.environments.BetaUnrestrictedNetwork; import com.anthropic.models.beta.environments.EnvironmentCreateParams; var environment = client.beta().environments().create(EnvironmentCreateParams.builder() .name("my-dev-env") .config(BetaCloudConfigParams.builder() .networking(BetaUnrestrictedNetwork.builder().build()) .build()) .build()); System.out.println("Environment ID: " + environment.id()); // env_... ``` --- ## Create an Agent (required first step) > ⚠️ **There is no inline agent config.** Model, system, and tools live on the agent object, not the session. Always start with `client.beta().agents().create()` — the session takes either `.agent(agent.id())` or the typed `BetaManagedAgentsAgentParams.builder()...build()`. ### Minimal ```java import com.anthropic.models.beta.agents.AgentCreateParams; import com.anthropic.models.beta.agents.BetaManagedAgentsAgentToolset20260401Params; import com.anthropic.models.beta.sessions.BetaManagedAgentsAgentParams; import com.anthropic.models.beta.sessions.SessionCreateParams; // 1. Create the agent (reusable, versioned) var agent = client.beta().agents().create(AgentCreateParams.builder() .name("Coding Assistant") .model("{{OPUS_ID}}") .system("You are a helpful coding assistant.") .addTool(BetaManagedAgentsAgentToolset20260401Params.builder() .type(BetaManagedAgentsAgentToolset20260401Params.Type.AGENT_TOOLSET_20260401) .build()) .build()); // 2. Start a session var session = client.beta().sessions().create(SessionCreateParams.builder() .agent(BetaManagedAgentsAgentParams.builder() .type(BetaManagedAgentsAgentParams.Type.AGENT) .id(agent.id()) .version(agent.version()) .build()) .environmentId(environment.id()) .title("Quickstart session") .build()); System.out.println("Session ID: " + session.id()); ``` ### Updating an Agent Updates create new versions; the agent object is immutable per version. ```java import com.anthropic.models.beta.agents.AgentUpdateParams; var updatedAgent = client.beta().agents().update(agent.id(), AgentUpdateParams.builder() .version(agent.version()) .system("You are a helpful coding agent. Always write tests.") .build()); System.out.println("New version: " + updatedAgent.version()); // List all versions for (var version : client.beta().agents().versions().list(agent.id()).autoPager()) { System.out.println("Version " + version.version() + ": " + version.updatedAt()); } // Archive the agent var archived = client.beta().agents().archive(agent.id()); System.out.println("Archived at: " + archived.archivedAt().orElseThrow()); ``` --- ## Send a User Message ```java import com.anthropic.models.beta.sessions.events.BetaManagedAgentsUserMessageEventParams; import com.anthropic.models.beta.sessions.events.EventSendParams; client.beta().sessions().events().send(session.id(), EventSendParams.builder() .addEvent(BetaManagedAgentsUserMessageEventParams.builder() .type(BetaManagedAgentsUserMessageEventParams.Type.USER_MESSAGE) .addTextContent("Review the auth module") .build()) .build()); ``` > 💡 **Stream-first:** Open the stream *before* (or concurrently with) sending the message. The stream only delivers events that occur after it opens — stream-after-send means early events arrive buffered in one batch. See [Steering Patterns](../../shared/managed-agents-events.md#steering-patterns). --- ## Stream Events (SSE) ```java import com.anthropic.models.beta.sessions.events.StreamEvents; // Open the stream first, then send the user message try (var stream = client.beta().sessions().events().streamStreaming(session.id())) { client.beta().sessions().events().send(session.id(), EventSendParams.builder() .addEvent(BetaManagedAgentsUserMessageEventParams.builder() .type(BetaManagedAgentsUserMessageEventParams.Type.USER_MESSAGE) .addTextContent("Summarize the repo README") .build()) .build()); for (var event : (Iterable) stream.stream()::iterator) { if (event.isAgentMessage()) { event.asAgentMessage().content().forEach(block -> System.out.print(block.text())); } else if (event.isAgentToolUse()) { System.out.println("\ [Using tool: " + event.asAgentToolUse().name() + "]"); } else if (event.isSessionStatusIdle()) { break; } else if (event.isSessionError()) { System.out.println("\ [Error]"); break; } } } ``` ### Reconnecting and Tailing When reconnecting mid-session, list past events first to dedupe, then tail live events. The cross-variant `id` field is read from the raw `_json()` value: ```java import com.anthropic.core.JsonValue; import java.util.HashSet; import java.util.Map; import java.util.Optional; try (var stream = client.beta().sessions().events().streamStreaming(session.id())) { // Stream is open and buffering. List history before tailing live. var seenEventIds = new HashSet(); for (var past : client.beta().sessions().events().list(session.id()).autoPager()) { Optional> obj = past._json().orElseThrow().asObject(); seenEventIds.add(obj.orElseThrow().get("id").asStringOrThrow()); } // Tail live events, skipping anything already seen for (var event : (Iterable) stream.stream()::iterator) { Optional> obj = event._json().orElseThrow().asObject(); if (!seenEventIds.add(obj.orElseThrow().get("id").asStringOrThrow())) continue; if (event.isAgentMessage()) { event.asAgentMessage().content().forEach(block -> System.out.print(block.text())); } else if (event.isSessionStatusIdle()) { break; } } } ``` --- ## Provide Custom Tool Result > ℹ️ The Java managed-agents bindings for `user.custom_tool_result` are not yet documented in this skill or in the apps source examples. Refer to `shared/managed-agents-events.md` for the wire format and the `anthropic-java` repository for the corresponding params types. --- ## Poll Events ```java for (var event : client.beta().sessions().events().list(session.id()).autoPager()) { System.out.println(event.type() + ": " + event); } ``` --- ## Upload a File ```java import com.anthropic.models.beta.files.FileUploadParams; import com.anthropic.models.beta.sessions.BetaManagedAgentsFileResourceParams; import java.nio.file.Path; var dataCsv = Path.of("data.csv"); var file = client.beta().files().upload(FileUploadParams.builder() .file(dataCsv) .build()); System.out.println("File ID: " + file.id()); // Mount in a session var session = client.beta().sessions().create(SessionCreateParams.builder() .agent(agent.id()) .environmentId(environment.id()) .addResource(BetaManagedAgentsFileResourceParams.builder() .type(BetaManagedAgentsFileResourceParams.Type.FILE) .fileId(file.id()) .mountPath("/workspace/data.csv") .build()) .build()); ``` ### Add and Manage Resources on an Existing Session ```java import com.anthropic.models.beta.sessions.resources.ResourceAddParams; import com.anthropic.models.beta.sessions.resources.ResourceDeleteParams; // Attach an additional file to an open session var resource = client.beta().sessions().resources().add(session.id(), ResourceAddParams.builder() .betaManagedAgentsFileResourceParams(BetaManagedAgentsFileResourceParams.builder() .type(BetaManagedAgentsFileResourceParams.Type.FILE) .fileId(file.id()) .build()) .build()); System.out.println(resource.id()); // "sesrsc_01ABC..." // List resources on the session — entries are a discriminated union var listed = client.beta().sessions().resources().list(session.id()); for (var entry : listed.data()) { if (entry.isFile()) { var fileResource = entry.asFile(); System.out.println(fileResource.id() + " " + fileResource.type()); } else if (entry.isGitHubRepository()) { var repoResource = entry.asGitHubRepository(); System.out.println(repoResource.id() + " " + repoResource.type()); } } // Detach a resource client.beta().sessions().resources().delete(resource.id(), ResourceDeleteParams.builder() .sessionId(session.id()) .build()); ``` --- ## List and Download Session Files > ℹ️ Listing and downloading files an agent wrote during a session is not yet documented for Java in this skill or in the apps source examples. See `shared/managed-agents-events.md` and the `anthropic-java` repository for the file list/download bindings. --- ## Session Management ```java // List environments var environments = client.beta().environments().list(); // Retrieve a specific environment var env = client.beta().environments().retrieve(environment.id()); // Archive an environment (read-only, existing sessions continue) client.beta().environments().archive(environment.id()); // Delete an environment (only if no sessions reference it) client.beta().environments().delete(environment.id()); // Delete a session client.beta().sessions().delete(session.id()); ``` --- ## MCP Server Integration ```java import com.anthropic.models.beta.agents.BetaManagedAgentsMcpToolsetParams; import com.anthropic.models.beta.agents.BetaManagedAgentsUrlMcpServerParams; // Agent declares MCP server (no auth here — auth goes in a vault) var agent = client.beta().agents().create(AgentCreateParams.builder() .name("GitHub Assistant") .model("{{OPUS_ID}}") .addMcpServer(BetaManagedAgentsUrlMcpServerParams.builder() .type(BetaManagedAgentsUrlMcpServerParams.Type.URL) .name("github") .url("https://api.githubcopilot.com/mcp/") .build()) .addTool(BetaManagedAgentsAgentToolset20260401Params.builder() .type(BetaManagedAgentsAgentToolset20260401Params.Type.AGENT_TOOLSET_20260401) .build()) .addTool(BetaManagedAgentsMcpToolsetParams.builder() .type(BetaManagedAgentsMcpToolsetParams.Type.MCP_TOOLSET) .mcpServerName("github") .build()) .build()); // Session attaches vault(s) containing credentials for those MCP server URLs var session = client.beta().sessions().create(SessionCreateParams.builder() .agent(BetaManagedAgentsAgentParams.builder() .type(BetaManagedAgentsAgentParams.Type.AGENT) .id(agent.id()) .version(agent.version()) .build()) .environmentId(environment.id()) .addVaultId(vault.id()) .build()); ``` See `shared/managed-agents-tools.md` §Vaults for creating vaults and adding credentials. --- ## Vaults ```java import com.anthropic.core.JsonValue; import com.anthropic.models.beta.vaults.VaultCreateParams; import com.anthropic.models.beta.vaults.credentials.BetaManagedAgentsMcpOAuthCreateParams; import com.anthropic.models.beta.vaults.credentials.BetaManagedAgentsMcpOAuthRefreshParams; import com.anthropic.models.beta.vaults.credentials.BetaManagedAgentsMcpOAuthRefreshUpdateParams; import com.anthropic.models.beta.vaults.credentials.BetaManagedAgentsMcpOAuthUpdateParams; import com.anthropic.models.beta.vaults.credentials.CredentialCreateParams; import com.anthropic.models.beta.vaults.credentials.CredentialUpdateParams; import java.time.OffsetDateTime; // Create a vault var vault = client.beta().vaults().create(VaultCreateParams.builder() .displayName("Alice") .metadata(VaultCreateParams.Metadata.builder() .putAdditionalProperty("external_user_id", JsonValue.from("usr_abc123")) .build()) .build()); System.out.println(vault.id()); // "vlt_01ABC..." // Add an OAuth credential var credential = client.beta().vaults().credentials().create(vault.id(), CredentialCreateParams.builder() .displayName("Alice's Slack") .auth(BetaManagedAgentsMcpOAuthCreateParams.builder() .type(BetaManagedAgentsMcpOAuthCreateParams.Type.MCP_OAUTH) .mcpServerUrl("https://mcp.slack.com/mcp") .accessToken("xoxp-...") .expiresAt(OffsetDateTime.parse("2026-04-15T00:00:00Z")) .refresh(BetaManagedAgentsMcpOAuthRefreshParams.builder() .tokenEndpoint("https://slack.com/api/oauth.v2.access") .clientId("1234567890.0987654321") .scope("channels:read chat:write") .refreshToken("xoxe-1-...") .clientSecretPostTokenEndpointAuth("abc123...") .build()) .build()) .build()); // Rotate the credential (e.g., after a token refresh) client.beta().vaults().credentials().update(credential.id(), CredentialUpdateParams.builder() .vaultId(vault.id()) .auth(BetaManagedAgentsMcpOAuthUpdateParams.builder() .type(BetaManagedAgentsMcpOAuthUpdateParams.Type.MCP_OAUTH) .accessToken("xoxp-new-...") .expiresAt(OffsetDateTime.parse("2026-05-15T00:00:00Z")) .refresh(BetaManagedAgentsMcpOAuthRefreshUpdateParams.builder() .refreshToken("xoxe-1-new-...") .build()) .build()) .build()); // Archive a vault client.beta().vaults().archive(vault.id()); ``` --- ## GitHub Repository Integration Mount a GitHub repository as a session resource (a vault holds the GitHub MCP credential): ```java import com.anthropic.models.beta.sessions.BetaManagedAgentsGitHubRepositoryResourceParams; var session = client.beta().sessions().create(SessionCreateParams.builder() .agent(agent.id()) .environmentId(environment.id()) .addVaultId(vault.id()) .addResource(BetaManagedAgentsGitHubRepositoryResourceParams.builder() .type(BetaManagedAgentsGitHubRepositoryResourceParams.Type.GITHUB_REPOSITORY) .url("https://github.com/org/repo") .mountPath("/workspace/repo") .authorizationToken("ghp_your_github_token") .build()) .build()); ``` Multiple repositories on the same session: ```java import java.util.List; var resources = List.of( BetaManagedAgentsGitHubRepositoryResourceParams.builder() .type(BetaManagedAgentsGitHubRepositoryResourceParams.Type.GITHUB_REPOSITORY) .url("https://github.com/org/frontend") .mountPath("/workspace/frontend") .authorizationToken("ghp_your_github_token") .build(), BetaManagedAgentsGitHubRepositoryResourceParams.builder() .type(BetaManagedAgentsGitHubRepositoryResourceParams.Type.GITHUB_REPOSITORY) .url("https://github.com/org/backend") .mountPath("/workspace/backend") .authorizationToken("ghp_your_github_token") .build()); ``` Rotating a repository's authorization token: ```java import com.anthropic.models.beta.sessions.resources.ResourceUpdateParams; var listed = client.beta().sessions().resources().list(session.id()); var repoResourceId = listed.data().get(0).asGitHubRepository().id(); client.beta().sessions().resources().update(repoResourceId, ResourceUpdateParams.builder() .sessionId(session.id()) .authorizationToken("ghp_your_new_github_token") .build()); ```