Anthropic TypeScript SDK
The official @anthropic-ai/sdk package, on plugboard's Messages API.
Connect
Use the base URL without /v1. The SDK adds /v1/messages itself.
ts
const plugboardURL = process.env.PLUGBOARD_BASE_URL!.replace(/\/v1$/, "")
export const client = new Anthropic({ baseURL: plugboardURL, apiKey: process.env.PLUGBOARD_KEY!, maxRetries: 0 })Chat
ts
const message = await client.messages.create({
model,
max_tokens: 1024,
messages: [{ role: "user", content: "Reply with exactly: pong" }],
})Tool calls
The answer has a tool_use block. Your code runs the tool and sends a tool_result back.
ts
const first = await client.messages.create({ model, max_tokens: 1024, tools, messages })
const call = first.content.find((block): block is Anthropic.ToolUseBlock => block.type === "tool_use")
if (!call) throw new Error("turn 1 had no tool_use block")
const second = await client.messages.create({
model,
max_tokens: 1024,
tools,
messages: [
...messages,
{ role: "assistant", content: first.content },
{ role: "user", content: [{ type: "tool_result", tool_use_id: call.id, content: JSON.stringify(weatherResult) }] },
],
})Streaming
ts
const stream = client.messages.stream({ model, max_tokens: 1024, messages: [{ role: "user", content: PROMPT }] })
for await (const event of stream) {
if (event.type === "content_block_delta" && event.delta.type === "text_delta") text += event.delta.text
}
const message = await stream.finalMessage()Structured output
Pass output_config: { format: { type: "json_schema", schema } }; the answer is one text block holding the JSON. See Structured outputs. A forced tool also works: a tool whose input_schema is the schema, with tool_choice set to that tool, and the call's input is the answer.
ts
const message = await client.messages.create({
model,
max_tokens: 1024,
tools: [
{
name: "record_meal",
description: "Record the estimated nutrition for a meal",
input_schema: {
type: "object",
properties: { calories: { type: "number" }, protein_g: { type: "number" } },
required: KEYS,
additionalProperties: false,
},
},
],
tool_choice: { type: "tool", name: "record_meal" },
messages: [{ role: "user", content: PROMPT }],
})Files
client.beta.files.upload({ file }) returns an id you can use in an image or document block with source: { type: "file", file_id }. See Files.
Limits
- Errors carry
error.type(authentication_error,not_found_error) and noerror.code. - The schema in structured output is not enforced by the provider. Validate the answer.