Anthropic SDK
The gateway supports the Anthropic Messages API. Point the official @anthropic-ai/sdk at the gateway and all requests are proxied with automatic memory.
Before you begin
Complete Anthropic's Get started with Claude guide first. It covers SDK installation, API keys, and the base Messages API setup.
Configure the client
Create an Anthropic client with your gateway API key and base URL. The Anthropic SDK sends the key via x-api-key, which the gateway accepts natively.
import Anthropic from "@anthropic-ai/sdk";
export const client = new Anthropic({
apiKey: "YOUR_API_KEY",
baseURL: "https://gateway-api.mastra.ai",
});All subsequent examples import this client instance from ./gateway.
Messages
Send a standard messages request. The gateway routes it to Anthropic and returns the response.
import { client } from "./gateway";
const message = await client.messages.create({
model: "anthropic/claude-sonnet-4-6",
max_tokens: 20,
messages: [
{ role: "user", content: "What is 2+2? Reply with just the number." },
],
});
if (message.content[0].type === "text") {
console.log(message.content[0].text);
}
// Returns "4"System messages
Set the model's behavior with the top-level system parameter.
const message = await client.messages.create({
model: "anthropic/claude-sonnet-4-6",
max_tokens: 100,
system: "You are a calculator. Only respond with numbers, no words.",
messages: [
{ role: "user", content: "What is 10 * 5?" },
],
});
if (message.content[0].type === "text") {
console.log(message.content[0].text);
}
// Returns "50"
Multi-turn conversations
Pass the full conversation history in the messages array so the model retains context across turns.
const message = await client.messages.create({
model: "anthropic/claude-sonnet-4-6",
max_tokens: 100,
messages: [
{ role: "user", content: "Remember this word: banana" },
{ role: "assistant", content: "Got it, I will remember the word banana." },
{ role: "user", content: "What word did I ask you to remember? Reply with just the word." },
],
});
if (message.content[0].type === "text") {
console.log(message.content[0].text);
}
// Returns "banana"
Streaming
Use client.messages.stream() to receive deltas incrementally.
import { client } from "./gateway";
const stream = client.messages.stream({
model: "anthropic/claude-sonnet-4-6",
max_tokens: 50,
messages: [
{ role: "user", content: "Count from 1 to 5, separated by commas." },
],
});
for await (const event of stream) {
if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
process.stdout.write(event.delta.text);
}
}
// Returns "1, 2, 3, 4, 5"Memory with thread and resource IDs
Pass x-thread-id and x-resource-id as extra headers. The gateway stores observations per thread and injects them as context on subsequent requests.
import { client } from "./gateway";
// First request: introduce yourself
await client.messages.create({
model: "anthropic/claude-sonnet-4-6",
max_tokens: 256,
messages: [
{ role: "user", content: "My name is Alex and I prefer concise answers." },
],
// @ts-expect-error - extra headers passed through to the gateway
headers: {
"x-thread-id": "my-thread-1",
"x-resource-id": "user-42",
},
});
// Second request: the gateway remembers
const response = await client.messages.create({
model: "anthropic/claude-sonnet-4-6",
max_tokens: 256,
messages: [
{ role: "user", content: "What is my name?" },
],
// @ts-expect-error - extra headers passed through to the gateway
headers: {
"x-thread-id": "my-thread-1",
"x-resource-id": "user-42",
},
});
if (response.content[0].type === "text") {
console.log(response.content[0].text);
}
// Returns "Alex"Tool calling
Define tools using the Anthropic tool format with input_schema.
import Anthropic from "@anthropic-ai/sdk";
import { client } from "./gateway";
export const helloWorldTool: Anthropic.Tool = {
name: "helloWorld",
description: "Returns a greeting for the given name",
input_schema: {
type: "object",
properties: {
name: { type: "string", description: "The name to greet" },
},
required: ["name"],
},
};
// Step 1: Send the request with tools
const first = await client.messages.create({
model: "anthropic/claude-sonnet-4-6",
max_tokens: 200,
messages: [
{ role: "user", content: "Use the helloWorld tool to greet Alice." },
],
tools: [helloWorldTool],
});
const toolUseBlock = first.content.find((b) => b.type === "tool_use");
if (toolUseBlock?.type !== "tool_use") throw new Error("Expected tool_use block");
const args = toolUseBlock.input as { name: string };
// Execute the tool locally
const result = { greeting: `Hello, ${args.name}!` };
// Step 2: Send the tool result back
const second = await client.messages.create({
model: "anthropic/claude-sonnet-4-6",
max_tokens: 200,
messages: [
{ role: "user", content: "Use the helloWorld tool to greet Alice." },
{ role: "assistant", content: first.content },
{
role: "user",
content: [
{
type: "tool_result",
tool_use_id: toolUseBlock.id,
content: JSON.stringify(result),
},
],
},
],
tools: [helloWorldTool],
});
const textBlock = second.content.find((b) => b.type === "text");
if (textBlock?.type === "text") {
console.log(textBlock.text);
// Returns "Hello, Alice!"
}Streaming tool calls
Stream a tool-calling request to receive input_json_delta events as the model generates tool arguments.
import Anthropic from "@anthropic-ai/sdk";
import { client } from "./gateway";
import { helloWorldTool } from "./tools";
const stream = client.messages.stream({
model: "anthropic/claude-sonnet-4-6",
max_tokens: 200,
messages: [
{ role: "user", content: "Use the helloWorld tool to greet Bob." },
],
tools: [helloWorldTool],
});
const events: Anthropic.MessageStreamEvent[] = [];
for await (const event of stream) {
events.push(event);
}
// Find the tool_use block
const toolUseStart = events.find(
(e) => e.type === "content_block_start" && e.content_block.type === "tool_use",
);
// Accumulate the JSON deltas
const jsonDeltas = events
.filter((e) => e.type === "content_block_delta" && e.delta.type === "input_json_delta")
.map((e) => {
if (e.type === "content_block_delta" && e.delta.type === "input_json_delta") {
return e.delta.partial_json;
}
return "";
});
const fullArgs = JSON.parse(jsonDeltas.join(""));
console.log(fullArgs.name); // Returns "Bob"
Related
- Features: Observational memory, streaming, BYOK, and gateway tools
- Models: Supported providers and model routing
- API reference: Complete endpoint documentation