---
title: "Anthropic"
description: "Use the Anthropic API for MainSDK AI calls - API keys, main.yaml, the model allowlist, data-use rules, local testing and swapping."
section: "integrations"
canonical: "https://mainsdk.dev/docs/integrations/anthropic"
updated: "2026-10-28"
---

# Anthropic

> Use the Anthropic API for MainSDK AI calls - API keys, main.yaml, the model allowlist, data-use rules, local testing and swapping.

Canonical: https://mainsdk.dev/docs/integrations/anthropic · Updated: 2026-10-28

Anthropic makes the Claude models, and its API is one of the drivers behind [`ai`](https://mainsdk.dev/docs/interfaces/ai). Your app calls `ai.generate()` and `ai.embed()` as usual; the driver sends the redacted prompt straight to the Anthropic API. Pick it when you want Claude models without an AWS account, or as a fallback next to Amazon Bedrock, the default driver.

## Interfaces it serves

### AI calls (`ai`)

- Status: Building for 0.3 · ships as a beta API
- Driver: `anthropic` (Anthropic)
- Docs: https://mainsdk.dev/docs/interfaces/ai.md

```yaml
ai:
  driver: anthropic
```

Swap to another provider: `local`, `openai`, `gateway`, `bedrock`, `ollama`, `llama-cpp`, `openai-compatible`.

## Before you start

You need an Anthropic account with API access.

1. **Create an API key.** In the Anthropic Console, create a key for your app. Use separate keys for development, stage and production so you can revoke one without touching the others.
2. **Set spend limits on the account.** MainSDK caps spend in your app, but a limit on the provider side is a second line of defence.
3. **Review the data terms for your account.** `ai.data` requires no training and no retention. Check how Anthropic handles API inputs for your account, and whether you need an arrangement with Anthropic for the retention your `main.yaml` asks for.

Store the key in your secrets manager, never in code or a committed env file.

## Configure

```yaml title="main.yaml"
ai:
  driver: anthropic
  key: secret:ANTHROPIC_API_KEY      # suggested name; [TBD] key field name for drivers that need one
  models: [anthropic/claude-*]       # allowlist
  data: { training: never, retention: zero }
  limits: { per-user: $1/day, per-feature: { chat: $200/month }, total: $500/month }
```

The key is always a `secret:` reference. A literal key in `main.yaml` fails `mainsdk check`. Anthropic's API host comes from the driver's declared hosts, so you don't add it to `network.allow`.

## Use it

```ts title="app/chat/actions.ts"
"use server";
import { ai, auth } from "mainsdk";
import { listOrders, refundOrder } from "@/actions/orders";

export async function chat(req: Request, messages: { role: "user" | "assistant"; content: string }[]) {
  const session = await auth.require(req);

  return ai.generate({
    model: "anthropic/claude-sonnet",          // [TBD] model identifiers per driver
    feature: "chat",
    user: session.user,
    messages,
    tools: [ai.tool(listOrders), ai.tool(refundOrder)],   // only functions declared with action()
  });
}
```

Tool results go back to the model through the injection check, and destructive actions still need a person's yes.

## Local development and testing

- **No key:** set `ai.driver: local` in `main.env.dev.yaml` to use the built-in local fake.
- **Real calls in development:** use a development key with a low cap in the dev overlay, for example `limits: { total: $10/month }`.
- **Tests:** `createTestApp()` from `@mainsdk/testing` runs `ai` on its in-memory fake with redaction, caps and audit enforced. `chaos.on("ai:anthropic", { outage: true })` simulates an Anthropic outage. The spec's conformance suite runs the Anthropic driver against recorded responses.

```ts title="lib/ai-caps.test.ts"
import { it } from "node:test";
import assert from "node:assert/strict";
import { createTestApp } from "@mainsdk/testing";
import { ai } from "mainsdk";

it("ai.AC4 refuses a call that would pass the per-user cap", async () => {
  createTestApp({ main: "./main.yaml" });   // limits.per-user: $1/day
  const user = { id: "u_1" };
  // [TBD] helper to set a user's spend on the fake to $0.98
  await assert.rejects(ai.generate({ model: "anthropic/claude-sonnet", feature: "chat", user, prompt: "hello" }), { code: "MAIN-AI-0007" });
});
```

## What MainSDK adds on top

- The API key never in your code, only a `secret:` reference.
- Providers, models or account modes that train on or keep prompts are refused; a declaration that doesn't meet `ai.data` fails `mainsdk check` with `MAIN-AI-0001`.
- Personal data redacted before Claude sees it, and restored only inside your app.
- Spend limits per user, per feature and in total, checked before the call (`MAIN-AI-0007` at the limit).
- Every call audited with feature, model, tokens and cost, never the prompt.

See [AI calls](https://mainsdk.dev/docs/interfaces/ai) for the full contract.

## Limits and notes

- The Anthropic driver comes with the `ai` spec (phase 1, milestone 0.3).
- The name of the key field for keyed AI drivers is not final [TBD].
- How "no retention" is proven for a provider, by checking account settings or by your declaration, is an open question in the spec [TBD].
- The Anthropic API is not region-pinned in the way Bedrock is. If your prompts must stay in a MainSDK region (US, EU or India), check Anthropic's processing locations, or use Bedrock with a region set.
- `ai.raw()` returns the Anthropic client for features `ai` does not wrap. `mainsdk check` lists every use.

## Swap to or from it

AI calls are stateless, so a swap is instant once `mainsdk swap` has run the contract tests:

```yaml title="main.yaml"
ai:
  driver: bedrock                    # was anthropic
  region: us-east-1
```

Your `ai.generate()`, `ai.embed()` and `ai.tool()` calls stay the same. The new driver must meet `ai.data` and serve a model in `ai.models`.

## FAQ

**Can I use the same Claude models through Bedrock instead?** Yes. Keep `models: [anthropic/claude-*]` and change the driver to `bedrock` with a region. No code changes.

**Where does my Anthropic API key go?** In your secrets manager, referenced as `secret:ANTHROPIC_API_KEY`. It is read on the server only.

**Do I need MainSDK Cloud for caps or audit?** No. Caps, redaction and audit run in your app and are free.

## Next

- [AI calls](https://mainsdk.dev/docs/interfaces/ai)
- [Amazon Bedrock](https://mainsdk.dev/docs/integrations/amazon-bedrock), [OpenAI](https://mainsdk.dev/docs/integrations/openai) and [AI gateway](https://mainsdk.dev/docs/integrations/ai-gateway)
- [Swap a driver](https://mainsdk.dev/docs/guides/swap-a-driver)
