Docs/Guides/Anthropic Integration

Anthropic Integration

Step-by-step guide to using Anthropic Claude through Keystore. Give your AI agents access to Claude models without exposing API keys.


Anthropic Integration

This guide walks through connecting an AI agent to Anthropic's Claude API via Keystore. Your agent uses a ks_ token instead of a real Anthropic API key. The Keystore proxy resolves the real credentials at request time.

Prerequisites

  • A Keystore account with an Anthropic provider configured
  • An agent token (starts with ks_)
  • Node.js 18+

If you do not have these yet, use the CLI to set them up:

bash
1
2
3
keystore login
keystore providers add        # choose anthropic, byok, paste your key
keystore agents create        # save the ks_ token

Install Dependencies

bash
1
npm install @anthropic-ai/sdk @keystore/sdk

Option A: Wrap the Client

The wrap method rewrites the Anthropic client's base URL and API key to point at the Keystore proxy.

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
import Anthropic from "@anthropic-ai/sdk";
import { Keystore } from "@keystore/sdk";

const ks = new Keystore({ agentToken: "ks_abc123..." });
const anthropic = ks.wrap(new Anthropic());

const message = await anthropic.messages.create({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Explain quantum computing in one sentence." }],
});

console.log(message.content[0].text);

You can also use the provider-specific wrapper directly:

typescript
1
2
3
4
5
import Anthropic from "@anthropic-ai/sdk";
import { Keystore, wrapAnthropic } from "@keystore/sdk";

const ks = new Keystore({ agentToken: "ks_abc123..." });
const anthropic = wrapAnthropic(new Anthropic(), ks);

Option B: Intercept All Fetch Requests

interceptAll patches globalThis.fetch so that requests to api.anthropic.com are transparently rerouted through the Keystore proxy.

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import Anthropic from "@anthropic-ai/sdk";
import { Keystore } from "@keystore/sdk";

const ks = new Keystore({ agentToken: "ks_abc123..." });
ks.interceptAll(["anthropic"]);

// The Anthropic client works normally -- requests are rerouted automatically.
const anthropic = new Anthropic({ apiKey: "unused" });

const message = await anthropic.messages.create({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  messages: [{ role: "user", content: "What is the capital of France?" }],
});

console.log(message.content[0].text);

// Restore the original fetch when done.
ks.restore();

Option C: Set Environment Variables

Use setupEnv to write ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY into process.env. Useful when the Anthropic client is initialized elsewhere or by a framework.

typescript
1
2
3
4
5
6
7
8
import { Keystore } from "@keystore/sdk";

const ks = new Keystore({ agentToken: "ks_abc123..." });
ks.setupEnv(["anthropic"]);

// Later, anywhere in your app:
import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic(); // reads ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY from env

Streaming

All approaches work with streaming. The proxy forwards the stream from Anthropic to your agent.

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import Anthropic from "@anthropic-ai/sdk";
import { Keystore } from "@keystore/sdk";

const ks = new Keystore({ agentToken: "ks_abc123..." });
const anthropic = ks.wrap(new Anthropic());

const stream = anthropic.messages.stream({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Write a haiku about APIs." }],
});

for await (const event of stream) {
  if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
    process.stdout.write(event.delta.text);
  }
}

Tool Use

Works identically to the standard Anthropic SDK. Keystore is transparent at the protocol level.

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const message = await anthropic.messages.create({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  messages: [{ role: "user", content: "What is the weather in Tokyo?" }],
  tools: [
    {
      name: "get_weather",
      description: "Get current weather for a location",
      input_schema: {
        type: "object",
        properties: {
          location: { type: "string" },
        },
        required: ["location"],
      },
    },
  ],
});

Multi-Provider Setup

You can set up both OpenAI and Anthropic in a single interceptor call:

typescript
1
2
3
4
5
6
7
8
9
10
11
import OpenAI from "openai";
import Anthropic from "@anthropic-ai/sdk";
import { Keystore } from "@keystore/sdk";

const ks = new Keystore({ agentToken: "ks_abc123..." });
ks.interceptAll(["openai", "anthropic"]);

const openai = new OpenAI({ apiKey: "unused" });
const anthropic = new Anthropic({ apiKey: "unused" });

// Both clients are routed through the Keystore proxy.

Monitoring

After making requests, use the CLI to check usage and logs:

bash
1
2
keystore usage ag_abc123
keystore logs ag_abc123 --provider anthropic

Each proxied request is logged with the provider, path, status code, latency, and cost.