---
title: "Claude Agent SDK in production (2026): hosting, containers, sessions resume, multi-tenant, canUseTool and languages — Cadenya"
url: "https://cadenya.com/other-content/claude-agent-sdk-in-production"
description: "Claude Agent SDK hosting in production in 2026: one claude CLI subprocess per session, container patterns, sessions resume and SessionStore persistence, multi-tenant isolation, canUseTool permissions, compaction, Bedrock and Vertex providers, and Cadenya, where the loop is already hosted with sessions, approvals and compaction built in."
---

The Claude Agent SDK ships no hosting. Claude Agent SDK hosting in production means you run one `claude` CLI subprocess per session, inside containers you provision, and you persist its sessions yourself so resume works after a restart.

So pick the Agent SDK when you want Claude Code’s own tools and loop inside a process you operate. Pick the plain Client SDK when you’d rather write the tool loop, and Managed Agents when you want Anthropic to host it. And if you’d rather run no loop, no container, and no session store at all, Cadenya is a hosted agent loop with approvals, conversation state, and resume built in, and a coding agent can set it up with no account, in a temporary workspace you claim later. [What it offers](#what-does-cadenya-offer-that-the-claude-agent-sdk-doesnt) is at the end.

Every price and limit below comes from each vendor’s own pages, checked on October 13, 2026.

## Claude Agent SDK hosting options side by side

Anthropic’s own docs compare four ways to run a Claude agent, and the real difference between them is what each one asks you to run.

|  | Agent SDK | Claude Code CLI with -p | Client SDK and tool runner | Managed Agents | Cadenya |
| --- | --- | --- | --- | --- | --- |
| Who runs the agent loop | A claude CLI subprocess your app spawns | The CLI process you start | Your code, or the tool runner | Anthropic | Cadenya |
| What you host | A container per session pattern, sized for the subprocesses | A container with the CLI | Your application | Your application, which sends events and reads streamed results | Your application, which calls Cadenya over HTTP |
| Where session state lives | JSONL transcripts on local disk, mirrored by a SessionStore you add | JSONL transcripts on local disk | The message list you store | Sessions in the Managed Agents harness | A durable event log per objective, on Cadenya |
| Model providers | Anthropic API, Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, Microsoft Foundry | The same environment variables as the SDK | The Claude API | The Claude API | Any model on OpenRouter, or an endpoint that speaks the OpenAI chat format |

Managed Agents has [its own comparison page](/other-content/claude-managed-agents-alternatives), so the rest of this page is about the Agent SDK you host yourself.

## Claude Agent SDK hosting: subprocess, containers, session patterns

The hosting guide opens with the point that shapes everything else: “Hosting it is not like hosting a stateless API wrapper. Every running agent is a long-lived process tied to local state.”

When your code calls `query()`, the SDK spawns a `claude` CLI process and talks to it over stdio. That subprocess owns a shell, a working directory, and the session transcripts on disk. “One agent session maps to one subprocess,” so 200 concurrent sessions are 200 subprocesses, each with its own process tree.

Anthropic names four session patterns:

1.  **Ephemeral**: “Create a container for each user task and destroy it when the task completes.”
2.  **Long-running**: “Run persistent container instances, often hosting multiple SDK processes per container.”
3.  **Hybrid**: “Ephemeral containers that hydrate from a `SessionStore` on startup and persist updates back.”
4.  **Multi-agent container**: “Run multiple SDK subprocesses inside one container.”

Then you pick where the containers run, and Anthropic’s hosting cookbook has deployable code for local Docker, Modal, and Kubernetes. (For the wider question of what a self-hosted agent stack needs, see [self-hosting AI agent infrastructure](/other-content/self-hosting-ai-agent-infrastructure).)

Sizing is on you too, and the guide’s starting point is “1 GiB RAM, 5 GiB disk, and 1 CPU per agent”, and memory “grows with session length and tool activity.” Concurrency per host follows a formula:

```
agents per host = (host RAM - overhead) / (per-session RAM ceiling)
```

For long-running sessions, you run a pool of containers behind a load balancer and “pin each session to one container using consistent hashing on `sessionId`.” The container needs Python 3.10 or later, or Node.js 18 or later, and the bundled CLI binary “is pinned to the SDK package version, so updating the SDK is how you update the CLI.”

What does it cost? Anthropic’s answer is that tokens win: “A minimally provisioned container runs roughly $0.05 per hour, while a single long agent session can spend dollars in tokens.”

## Claude Agent SDK sessions resume and persistence

A session is “the conversation history the SDK accumulates while your agent works,” written to disk as JSONL under `~/.claude/projects/`. You get three ways back into one:

-   **Continue** “finds the most recent session in the current directory.”
-   **Resume** “takes a specific session ID,” and it’s “required when you have multiple sessions (for example, one per user in a multi-user app).”
-   **Fork** “creates a new session that starts with a copy of the original’s history.”

The catch for production is on the hosting page: session transcripts, `CLAUDE.md` memory files, and working-directory artifacts live on the container’s filesystem, and “none of them survive a container restart, a scale-down, or a move to a different node.”

So any session a user expects to resume needs a `SessionStore` adapter. Here’s the resume call from the hybrid pattern:

```
import { query, type SessionStore } from "@anthropic-ai/claude-agent-sdk";

declare const userInput: string;
declare const sessionId: string;          // looked up from your database by user
declare const sessionStore: SessionStore; // an object store, key-value store, database, or your own adapter

for await (const message of query({
  prompt: userInput,
  options: { resume: sessionId, sessionStore },
})) {
  // ...
}
```

Three details matter here. Anthropic’s adapters for S3, Redis, and Postgres “are not published as packages,” so you copy one into your project. The store mirrors “transcripts only,” not memory files or the working directory. And when a write fails, the SDK “drops the batch, emits a `mirror_error` message, and continues the query,” so you alert on that message yourself. (The store key also derives from the working directory, so resume from the same `cwd` as the first run.)

### Claude Agent SDK compaction in long sessions

“When the context window approaches its limit, the SDK automatically compacts the conversation.” The stream emits a `compact_boundary` system message when it happens, so your app can tell the history changed.

Compaction replaces older messages with a summary, so Anthropic says “persistent rules belong in CLAUDE.md” rather than the first prompt. A `PreCompact` hook can archive the full transcript first, and sending `/compact` as a prompt triggers it by hand. For how this compares across agent stacks, see [agent memory and context windows](/other-content/agent-memory-and-context-windows).

## Claude Agent SDK multi-tenant containers and isolation

Default SDK behavior reads settings and `CLAUDE.md` files from the filesystem, and in a shared container “those files can leak one tenant’s context into another tenant’s session.”

The hosting guide lists five steps per tenant: skip settings sources, turn off auto memory, give each tenant its own config directory, give each tenant its own working directory, and apply per-tenant egress rules at your proxy. Here are the first four together, from the guide:

```
import { query } from "@anthropic-ai/claude-agent-sdk";

declare const prompt: string;
declare const tenantDir: string;
declare const configDir: string;

for await (const message of query({
  prompt,
  options: {
    cwd: tenantDir,
    settingSources: [],
    env: {
      ...process.env,
      CLAUDE_CONFIG_DIR: configDir,
      CLAUDE_CODE_DISABLE_AUTO_MEMORY: "1",
    },
  },
})) {
  // ...
}
```

(In TypeScript, `env` replaces the subprocess environment, which is why the spread keeps `PATH` and `ANTHROPIC_API_KEY`.)

Isolation of the container itself is a separate choice. The secure deployment guide compares Docker, gVisor, and virtual machines such as Firecracker, and it says to route outbound traffic “through an egress proxy that enforces domain allowlists, injects credentials, and logs requests.” Auth sits in front: “The agent should receive pre-authenticated requests and should not be the component that validates user tokens.”

**One rule applies to every multi-tenant product.** Anthropic doesn’t “allow third party developers to offer claude.ai login or rate limits for their products,” so each tenant’s traffic runs on your API key.

## Claude Agent SDK canUseTool permissions and human approval

Both a tool permission request and a clarifying question go to one callback, `canUseTool`, “which pauses execution until you return a response”:

```
import type { CanUseTool } from "@anthropic-ai/claude-agent-sdk";

const handleToolRequest: CanUseTool = async (toolName, input, options) => {
  // options includes { signal: AbortSignal, suggestions?: PermissionUpdate[] }
  // Prompt the user here, then return allow or deny
  return { behavior: "deny", message: "User declined" };
};

const options = { canUseTool: handleToolRequest };
```

Two details change how you host it. First, “the callback never fires for auto-approved tools,” so an allow rule or a mode like `acceptEdits` skips it. For a check that runs on every single tool call, Anthropic points you to a `PreToolUse` hook instead.

Second, the paused execution lives in your subprocess. To let the process exit while an approval is pending, the docs say to return the `defer` decision from a `PreToolUse` hook “so the process can exit and resume later from the persisted session.” That’s the `SessionStore` from the last section again. A `PermissionRequest` hook can post to Slack, email, or push when an approval is waiting. The [human-in-the-loop approvals page](/other-content/human-in-the-loop-approvals-for-ai-agents) covers the same pattern across other stacks.

## Claude Agent SDK languages, Bedrock and Vertex, and release notes

The SDK is “programmable in Python and TypeScript,” and for another language Anthropic’s docs say to “run the CLI as a subprocess with the `-p` flag and `--output-format json`.”

Third-party providers are environment variables on the subprocess:

```
CLAUDE_CODE_USE_BEDROCK=1   # Amazon Bedrock, with AWS credentials
CLAUDE_CODE_USE_VERTEX=1    # Google Cloud's Agent Platform, with Google Cloud credentials
CLAUDE_CODE_USE_FOUNDRY=1   # Microsoft Foundry, with Azure credentials
```

Claude Platform on AWS uses `CLAUDE_CODE_USE_ANTHROPIC_AWS=1` plus `ANTHROPIC_AWS_WORKSPACE_ID`. Every option on that list serves Claude models, so the provider changes but the model family stays the same.

The latest npm release of `@anthropic-ai/claude-agent-sdk` is 0.3.296, from October 9, 2026, and PyPI’s `claude-agent-sdk` is 0.2.165, from October 8. The Python package is under MIT, while the TypeScript SDK “is governed by Anthropic’s Commercial Terms of Service,” including when it powers products you sell to your own customers. Release notes live in each repo’s `CHANGELOG.md`, and Anthropic’s advice is to “take patch releases continuously and review the TypeScript or Python changelog before taking a minor.”

## What does Cadenya offer that the Claude Agent SDK doesn’t?

The Claude Agent SDK gives you a loop to host, and hosting it is the work: subprocesses, containers, a session store, tenant isolation, and an approval wait that lives in your process. **Cadenya is the loop already hosted, with sessions, approvals, and compaction built in, so there’s nothing to run.** Here’s what that covers:

1.  **Nothing else to run.** No subprocess, no container to size, no load balancer pinning sessions, and no `SessionStore` to copy in. The loop runs on Cadenya and your app stays a stateless web tier, so your deploys and restarts never touch a running objective.
2.  **Apache-2.0 SDKs and nothing in your image to license.** Your app calls Cadenya over HTTP through SDKs under Apache-2.0.
3.  **No old code to keep alive.** “The Objective keeps that variation’s configuration snapshot even if you edit the variation later,” so a change to the prompt or tools never breaks a conversation that’s already running.
4.  **Approvals that hold no process.** Mark a tool as needing approval and “Cadenya parks the Agent loop until it receives approval or a denial with optional steering.” Your backend, a webhook handler that posts to Slack, or a person in the React chat widget decides, and multiple tools can wait at the same time.
5.  **SDKs with a long release record.** TypeScript, Python, Ruby, and Go SDKs are all at 1.9.0 under Apache-2.0, and the TypeScript SDK has shipped 113 versions since April 2026. There’s a CLI and a plain HTTP API too.
6.  **A price in one line.** Free for 1,000 loops a month, $49 a month for 50,000, then $0.0015 a loop. A loop is one LLM request, so you pay for model calls and not for containers that sit warm between them.
7.  **Conversation state kept for you.** “Every Objective carries a durable event log of its agent loop.” When an objective enters `STATE_WAITING`, a Continue message resumes it, and the widget’s event stream uses `Last-Event-ID` checkpoints so a dropped connection picks up where it left off.
8.  **Compaction you can see and trigger.** Each compaction emits `contextWindowCompacted` and starts a new context window, and an API call compacts a running objective on demand with its own config if you want one.
9.  **Claude, or any other model, on your own keys.** The model is a setting on a variation. Use any model on OpenRouter or any endpoint that speaks the OpenAI chat format, and weighted variations send more traffic to whichever one users rate higher.
10.  **Per-user credentials without a config directory per tenant.** A widget session can carry the signed-in user’s short-lived token as a secret that overrides the shared API credential, so your API sees that user’s token on each tool call. Tool sets come from your OpenAPI 3 spec or MCP server, and Cadenya checks a spec URL for changes each hour.

[How objectives work](/docs/guides/the-basics/objectives) walks through an agent turn, and the free plan needs no card.

No account yet? A coding agent can create a temporary workspace with `cadenya workspaces create --temporary`, run its first objectives there, and hand you a link to claim it, as [auth.md](https://cadenya.com/auth.md) explains. To create an account, sign up at [app.cadenya.com/signup](https://app.cadenya.com/signup?utm_source=cadenya.com&utm_medium=article&utm_campaign=claude-agent-sdk-in-production), then copy your API key from the API keys page at `app.cadenya.com/account/apiKeys`.