anthropic-ts
purpose
Configuring and calling Anthropic Claude models from TypeScript using the official SDK. Covers direct API usage, tool use, streaming, vision, and integration patterns for bots.
rules
- Use the official
@anthropic-ai/sdkpackage.npm install @anthropic-ai/sdk. This is the only supported TypeScript/JavaScript SDK. docs.anthropic.com/en/docs/build-with-claude/getting-started - The SDK reads
ANTHROPIC_API_KEYfrom the environment by default. You can also pass it explicitly:new Anthropic(\{ apiKey: process.env.ANTHROPIC_API_KEY \}). docs.anthropic.com/en/api/client-sdks - Use the Messages API, not the legacy Completions API. All Claude models use
client.messages.create(). The legacyclient.completions.create()is deprecated. docs.anthropic.com/en/api/messages - Always specify
max_tokens. Unlike OpenAI, Anthropic requiresmax_tokenson every request. There is no default. Omitting it throws an error. docs.anthropic.com/en/api/messages - System messages go in the
systemparameter, not inmessages. Claude uses a top-levelsystemstring, not a\{ role: 'system', content: '...' \}message. Putting system content inmessageswith role'system'will error. docs.anthropic.com/en/docs/build-with-claude/prompt-caching - Use
modelIDs likeclaude-opus-4-6,claude-sonnet-4-6,claude-haiku-4-5-20251001. Check the model names page for the latest IDs. Aliases likeclaude-3-5-sonnet-latestare available but less predictable. docs.anthropic.com/en/docs/about-claude/models - Tool use follows the
tools+tool_use/tool_resultpattern. Define tools in the request, receivetool_usecontent blocks in the response, execute them, then sendtool_resultblocks back. docs.anthropic.com/en/docs/build-with-claude/tool-use - Streaming uses
client.messages.stream(). Returns aMessageStreamwith event-driven or async iteration. Usestream.on('text', (text) => ...)for incremental text orfor await (const event of stream)for full events. docs.anthropic.com/en/api/messages-streaming - Handle rate limits with exponential backoff. The SDK throws
RateLimitError(HTTP 429). Implement retry logic with backoff, or use the SDK's built-inmaxRetriesoption (defaults to 2). docs.anthropic.com/en/api/rate-limits - For Bedrock-hosted Claude, use the Bedrock expert instead. This expert covers direct Anthropic API access. If you're accessing Claude through AWS Bedrock, see
bedrock-ts.md— the SDK and auth are completely different.
patterns
Basic chat completion
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
maxRetries: 3,
timeout: 30000,
});
const response = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
system: 'You are a helpful assistant in a Slack workspace.',
messages: [
{ role: 'user', content: userMessage },
],
});
const reply = response.content[0].type === 'text'
? response.content[0].text
: '';Streaming
const stream = client.messages.stream({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
system: 'You are a helpful assistant.',
messages: [{ role: 'user', content: userMessage }],
});
stream.on('text', (text) => {
process.stdout.write(text);
});
const finalMessage = await stream.finalMessage();Tool use (function calling)
const response = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
tools: [{
name: 'get_weather',
description: 'Get current weather for a location',
input_schema: {
type: 'object',
properties: {
location: { type: 'string', description: 'City name' },
},
required: ['location'],
},
}],
messages: [{ role: 'user', content: 'What is the weather in Seattle?' }],
});
// Check for tool use in the response
const toolUseBlock = response.content.find((b) => b.type === 'tool_use');
if (toolUseBlock && toolUseBlock.type === 'tool_use') {
const result = await executeFunction(toolUseBlock.name, toolUseBlock.input);
// Send tool result back
const followUp = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
tools: [/* same tools */],
messages: [
{ role: 'user', content: 'What is the weather in Seattle?' },
{ role: 'assistant', content: response.content },
{
role: 'user',
content: [{
type: 'tool_result',
tool_use_id: toolUseBlock.id,
content: JSON.stringify(result),
}],
},
],
});
}Multi-turn conversation
const conversationHistory: Anthropic.MessageParam[] = [];
async function chat(userInput: string): Promise<string> {
conversationHistory.push({ role: 'user', content: userInput });
const response = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
system: 'You are a helpful Slack bot.',
messages: conversationHistory,
});
const assistantText = response.content
.filter((b) => b.type === 'text')
.map((b) => b.text)
.join('');
conversationHistory.push({ role: 'assistant', content: response.content });
return assistantText;
}pitfalls
- Putting system message in
messagesarray. Claude requiressystemas a top-level parameter.\{ role: 'system', content: '...' \}inmessageswill error. - Forgetting
max_tokens. Anthropic requires this on every request. Unlike OpenAI, there's no default. - Response content is an array, not a string.
response.contentisContentBlock[]. Each block has atype(text,tool_use). Don't treat it as a plain string. - Tool result must reference
tool_use_id. When sendingtool_resultblocks, you must include the exacttool_use_idfrom the model's response. Mismatches cause errors. stop_reasonvsfinish_reason. Anthropic usesstop_reason(values:end_turn,max_tokens,stop_sequence,tool_use). Don't confuse with OpenAI'sfinish_reason.- Model ID format differs from OpenAI. Anthropic uses IDs like
claude-sonnet-4-6, notgpt-4o. Check the models page for current IDs.
references
instructions
This expert covers direct Anthropic API usage from TypeScript. Use it when the developer is calling Claude models via the Anthropic API (not through Bedrock). For Bedrock-hosted Claude, see bedrock-ts.md instead.
Pair with: bedrock-ts.md (if also using Bedrock), openai-azure-openai-ts.md (if mixing providers), ../security/secrets-ts.md (API key management).
research
Deep Research prompt:
"Write a micro expert on using the @anthropic-ai/sdk TypeScript package. Cover: client initialization, Messages API, system messages, max_tokens requirement, streaming with MessageStream, tool use (defining tools, handling tool_use blocks, sending tool_result), multi-turn conversations, vision/image input, prompt caching, rate limits and retries, error handling, and model selection guidance."