## Client-side tools

Client-side tools are tools that run in the browser. Use them to interact with the editor's content. For example:

- Count the number of words in the document
- Replace all instances of a word in the document
- Format the document.

All [built-in tools](/content/docs/content-ai/capabilities/agent/custom-llms/tools#built-in-tools/index.html) are client-side tools.

This guide shows how to implement a tool that replaces all occurrences of a word in the document with another word. It assumes you have already [set up the AI Agent extension with your custom backend](/content/docs/content-ai/capabilities/agent/custom-llms/get-started/index.html).

### Code demo available

This guide includes a code demo to help you get started. See the [GitHub repository](https://github.com/ueberdosis/ai-agent-custom-llm-demos).

## Client-side setup

Declare a tool call handler for your tool. Tool handlers are functions that apply the tool call in the editor. They must implement the `AiAgentToolHandler` interface.

```
import { z } from 'zod'
import type { AiAgentToolHandler } from '@tiptap-pro/extension-ai-agent'
import { ToolCallError, invalidArgumentsResponseFormatter } from '@tiptap-pro/extension-ai-agent'

// Schema for validating tool arguments
const replaceAllToolSchema = z.object({
  find: z.string().min(1, 'Find text cannot be empty'),
  replace: z.string(),
})

export const replaceAllToolHandler = (): AiAgentToolHandler => ({
  // Unique identifier for the tool
  name: 'replace_all',
  modifiesEditor: true,
  handleToolCall: ({ editor, state, toolCall }) => {
    // Validate the arguments
    const result = replaceAllToolSchema.safeParse(toolCall.arguments)
    if (!result.success) {
      // Return an error message to the AI
      throw new ToolCallError(invalidArgumentsResponseFormatter(result.error))
    }
    const args = result.data

try {
      // Get the current HTML content
      const html = editor.getHTML()

// Replace all occurrences of the find text with the replace text
      const replacedHtml = html.replaceAll(args.find, args.replace)

// Set the new content in the editor
      editor.commands.setContent(replacedHtml)

// Return a success message
      return `Successfully replaced all occurrences of \
