Skip to content

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 no error.code.
  • The schema in structured output is not enforced by the provider. Validate the answer.