Tiptap Editor 3.0 Beta is out. Start here

Server-side tools (Anthropic Claude Messages API)

This guide explains how to call tools in the server-side using the Anthropic Claude Messages API. It presents an example of a tool that returns the weather in a given location.

First, define the tool in the Anthropic Claude Messages API tool format:

const weatherTool = {
  name: 'get_weather',
  description: 'Returns the weather in a given location',
  input_schema: {
    type: 'object',
    properties: {
      location: {
        type: 'string',
        description: 'The location to get the weather for',
      },
    },
    required: ['location'],
  },
}

Then, when you call the Anthropic API, include the tool in the tools array:

import { AiAgentToolkit } from '@tiptap-pro/extension-ai-agent-server'
import { anthropicMessagesAdapter } from '@tiptap-pro/extension-ai-agent'
import Anthropic from '@anthropic-ai/sdk'

const toolkit = new AiAgentToolkit()

// Initialize the Anthropic client
const anthropic = new Anthropic()

// Call the Anthropic Claude Messages API
const response = await anthropic.messages.create({
  model: 'claude-sonnet-4-0',
  system: `
<Your system prompt>
${toolkit.getSystemPrompt()}
`,
  messages: llmMessages,
  // Include the weather tool in the tools array, beside
  // the other tools provided by AiAgentToolkit
  tools: [...toolkit.getTools(anthropicMessagesAdapter), weatherTool],
})

Then, check if the response contains the weather tool. If so, call the tool and add the result to the llmMessages array.

for (const content of response.content) {
  if (content.type !== 'tool_use') {
    continue
  }

  const name = content.name

  if (name !== 'get_weather') {
    continue
  }

  const args = content.input

  const result = getWeather(args)
  llmMessages.push({
    role: 'user',
    content: [
      {
        type: 'tool_result',
        tool_use_id: content.id,
        content: result.toString(),
      },
    ],
  })
}

Finally, when there are no more server-side tool calls, use the anthropicMessagesAdapter to convert the response to the format expected by the AI Agent extension.

const result = anthropicMessagesAdapter.parseResponse(response)

The result should be the response of the API endpoint, and the return value of the resolver function.

You can also add chat messages to the result describing the tool that was called. This will display the result of the tool call in the chat conversation.

// Add the tool call message to the beginning of the list of new chat messages
result.chatMessages.unshift({
  type: 'ai',
  text: 'The weather in Berlin is sunny.',
  metadata: {
    // Include this metadata to mark the message as a server-side tool call
    // and display it differently in the UI
    isServerSideToolCall: true,
  },
})