---
title: Ferramentas de servidor
url: https://platform.claude.com/docs/pt-BR/agents-and-tools/tool-use/server-tools
description: "Trabalhe com ferramentas executadas pela Anthropic: blocos server_tool_use, continuação com pause_turn, turnos mistos com ferramentas de servidor e de cliente, e filtragem de domínio."
---

As ferramentas executadas no servidor compartilham estes mecanismos: o bloco `server_tool_use`, a continuação com `pause_turn`, turnos que misturam ferramentas de servidor e de cliente, a elegibilidade para "Zero Data Retention" (retenção zero de dados), ou ZDR, e a "domain filtering" (filtragem de domínio). Para ferramentas individuais, consulte a [referência de ferramentas](https://platform.claude.com/docs/pt-BR/agents-and-tools/tool-use/tool-reference).

## O bloco server\_tool\_use

O bloco `server_tool_use` aparece na resposta de Claude quando uma ferramenta executada no servidor é executada. Seu campo `id` usa o prefixo `srvtoolu_` para diferenciá-lo das chamadas de ferramentas de cliente:

```json
{
  "type": "server_tool_use",
  "id": "srvtoolu_01A2B3C4D5E6F7G8H9",
  "name": "web_search",
  "input": { "query": "latest quantum computing breakthroughs" }
}
```

A API executa a ferramenta internamente. Você vê a chamada e seu resultado na resposta, mas não cuida da execução. Diferentemente dos blocos `tool_use` de cliente, você não precisa responder com um `tool_result`. O bloco de resultado da ferramenta (por exemplo, `web_search_tool_result` para a pesquisa na web) vem depois do bloco `server_tool_use` no mesmo turno do assistente, pareado por `tool_use_id`. Se Claude chamar uma das suas ferramentas de cliente ao mesmo tempo, o bloco `server_tool_use` aparece sem seu resultado, e a resposta termina com `stop_reason: "tool_use"`. A API executa a ferramenta quando você retorna os blocos `tool_result` de cliente na sua próxima solicitação.

## O loop no servidor e pause\_turn

Ao usar ferramentas de servidor, como a pesquisa na web, a API executa as chamadas de ferramentas em um "agentic loop" (loop agêntico) no servidor. Em um turno de longa duração, a API pode pausar esse loop e retornar o motivo de parada `pause_turn`.

Veja como lidar com o motivo de parada `pause_turn`:

<CodeGroup>
  ```bash cURL
  # Requisição inicial. Se "stop_reason" na resposta for "pause_turn", continue
  # o turno reenviando a requisição com o conteúdo do assistente anexado a messages.
  curl https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{
      "model": "claude-opus-5-5",
      "max_tokens": 1024,
      "messages": [
        {
          "role": "user",
          "content": "Search for comprehensive information about quantum computing breakthroughs in 2025"
        }
      ],
      "tools": [{"type": "web_search_20250305", "name": "web_search", "max_uses": 10}]
    }'
  ```

  ```bash CLI
  # Requisição inicial. Se "stop_reason" na saída for "pause_turn", execute novamente com
  # o conteúdo do assistente anexado a messages (veja as abas do SDK).
  ant messages create <<'YAML'
  model: claude-opus-5-5
  max_tokens: 1024
  tools:
    - {type: web_search_20250305, name: web_search, max_uses: 10}
  messages:
    - {role: user, content: "Search for comprehensive information about quantum computing breakthroughs in 2025"}
  YAML
  ```

  ```python Python
  client = anthropic.Anthropic()

  # Requisição inicial com pesquisa na web
  response = client.messages.create(
      model="claude-opus-5-5",
      max_tokens=1024,
      messages=[
          {
              "role": "user",
              "content": "Search for comprehensive information about quantum computing breakthroughs in 2025",
          }
      ],
      tools=[{"type": "web_search_20250305", "name": "web_search", "max_uses": 10}],
  )

  # Verifica se a resposta tem o stop reason pause_turn
  if response.stop_reason == "pause_turn":
      # Continua a conversa com o conteúdo pausado
      messages = [
          {
              "role": "user",
              "content": "Search for comprehensive information about quantum computing breakthroughs in 2025",
          },
          {"role": "assistant", "content": response.content},
      ]

      # Envia a requisição de continuação
      continuation = client.messages.create(
          model="claude-opus-5-5",
          max_tokens=1024,
          messages=messages,
          tools=[{"type": "web_search_20250305", "name": "web_search", "max_uses": 10}],
      )

      print(continuation)
  else:
      print(response)
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  // Requisição inicial com pesquisa na web
  const response = await client.messages.create({
    model: "claude-opus-5-5",
    max_tokens: 1024,
    messages: [
      {
        role: "user",
        content:
          "Search for comprehensive information about quantum computing breakthroughs in 2025"
      }
    ],
    tools: [
      {
        type: "web_search_20250305",
        name: "web_search",
        max_uses: 10
      }
    ]
  });

  // Verifica se a resposta tem o stop reason pause_turn
  if (response.stop_reason === "pause_turn") {
    // Continua a conversa com o conteúdo pausado
    const messages: Anthropic.MessageParam[] = [
      {
        role: "user",
        content:
          "Search for comprehensive information about quantum computing breakthroughs in 2025"
      },
      { role: "assistant", content: response.content }
    ];

    // Envia a requisição de continuação
    const continuation = await client.messages.create({
      model: "claude-opus-5-5",
      max_tokens: 1024,
      messages,
      tools: [
        {
          type: "web_search_20250305",
          name: "web_search",
          max_uses: 10
        }
      ]
    });

    console.log(continuation);
  } else {
    console.log(response);
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  var parameters = new MessageCreateParams
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 1024,
      Messages = [
          new() {
              Role = Role.User,
              Content = "Search for comprehensive information about quantum computing breakthroughs in 2025"
          }
      ],
      Tools = [new ToolUnion(new WebSearchTool20250305 { MaxUses = 10 })]
  };

  var response = await client.Messages.Create(parameters);

  if (response.StopReason?.Value() == StopReason.PauseTurn)
  {
      // Continue a conversa com o conteúdo pausado
      var continuationParams = new MessageCreateParams
      {
          Model = Model.ClaudeOpus5_5,
          MaxTokens = 1024,
          Messages = [
              new() {
                  Role = Role.User,
                  Content = "Search for comprehensive information about quantum computing breakthroughs in 2025"
              },
              new() {
                  Role = Role.Assistant,
                  Content = response.Content.Select(block => new ContentBlockParam(block.Json)).ToList()
              }
          ],
          Tools = [new ToolUnion(new WebSearchTool20250305 { MaxUses = 10 })]
      };

      var continuation = await client.Messages.Create(continuationParams);
      Console.WriteLine(continuation);
  }
  else
  {
      Console.WriteLine(response);
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  webSearchTool := []anthropic.ToolUnionParam{
  	{OfWebSearchTool20250305: &anthropic.WebSearchTool20250305Param{
  		MaxUses: anthropic.Int(10),
  	}},
  }

  response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
  	Model:     anthropic.ModelClaudeOpus5_5,
  	MaxTokens: 1024,
  	Messages: []anthropic.MessageParam{
  		anthropic.NewUserMessage(anthropic.NewTextBlock("Search for comprehensive information about quantum computing breakthroughs in 2025")),
  	},
  	Tools: webSearchTool,
  })
  if err != nil {
  	log.Fatal(err)
  }

  if response.StopReason == anthropic.StopReasonPauseTurn {
  	// Repasse a resposta pausada sem alterações para que o Claude possa continuar o turno
  	continuation, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
  		Model:     anthropic.ModelClaudeOpus5_5,
  		MaxTokens: 1024,
  		Messages: []anthropic.MessageParam{
  			anthropic.NewUserMessage(anthropic.NewTextBlock("Search for comprehensive information about quantum computing breakthroughs in 2025")),
  			response.ToParam(),
  		},
  		Tools: webSearchTool,
  	})
  	if err != nil {
  		log.Fatal(err)
  	}
  	fmt.Println(continuation)
  } else {
  	fmt.Println(response)
  }
  ```

  ```java Java
  import com.anthropic.models.messages.StopReason;
  import com.anthropic.models.messages.WebSearchTool20250305;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      MessageCreateParams params = MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024L)
          .addUserMessage("Search for comprehensive information about quantum computing breakthroughs in 2025")
          .addTool(WebSearchTool20250305.builder()
              .maxUses(10L)
              .build())
          .build();

      Message response = client.messages().create(params);

      if (response.stopReason().isPresent()
              && response.stopReason().get().equals(StopReason.PAUSE_TURN)) {
          MessageCreateParams continuationParams = MessageCreateParams.builder()
              .model(Model.CLAUDE_OPUS_5_5)
              .maxTokens(1024L)
              .addUserMessage("Search for comprehensive information about quantum computing breakthroughs in 2025")
              .addMessage(response)
              .addTool(WebSearchTool20250305.builder()
                  .maxUses(10L)
                  .build())
              .build();

          Message continuation = client.messages().create(continuationParams);
          IO.println(continuation);
      } else {
          IO.println(response);
      }
  }
  ```

  ```php PHP
  $client = new Client();

  $response = $client->messages->create(
      maxTokens: 1024,
      messages: [
          [
              'role' => 'user',
              'content' => 'Search for comprehensive information about quantum computing breakthroughs in 2025'
          ]
      ],
      model: 'claude-opus-5-5',
      tools: [
          [
              'type' => 'web_search_20250305',
              'name' => 'web_search',
              'max_uses' => 10
          ]
      ],
  );

  if ($response->stopReason === 'pause_turn') {
      $messages = [
          [
              'role' => 'user',
              'content' => 'Search for comprehensive information about quantum computing breakthroughs in 2025'
          ],
          [
              'role' => 'assistant',
              'content' => $response->content
          ]
      ];

      $continuation = $client->messages->create(
          maxTokens: 1024,
          messages: $messages,
          model: 'claude-opus-5-5',
          tools: [
              [
                  'type' => 'web_search_20250305',
                  'name' => 'web_search',
                  'max_uses' => 10
              ]
          ],
      );

      echo $continuation;
  } else {
      echo $response;
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  response = client.messages.create(
    model: "claude-opus-5-5",
    max_tokens: 1024,
    messages: [
      {
        role: "user",
        content:
          "Search for comprehensive information about quantum computing breakthroughs in 2025"
      }
    ],
    tools: [
      {
        type: "web_search_20250305",
        name: "web_search",
        max_uses: 10
      }
    ]
  )

  if response.stop_reason == :pause_turn
    messages = [
      {
        role: "user",
        content: "Search for comprehensive information about quantum computing breakthroughs in 2025"
      },
      {
        role: "assistant",
        content: response.content
      }
    ]

    continuation = client.messages.create(
      model: "claude-opus-5-5",
      max_tokens: 1024,
      messages: messages,
      tools: [
        {
          type: "web_search_20250305",
          name: "web_search",
          max_uses: 10
        }
      ]
    )

    puts continuation
  else
    puts response
  end
  ```
</CodeGroup>

Ao lidar com `pause_turn`:

* **Continue a conversa:** Envie a resposta pausada de volta sem alterações em uma solicitação subsequente para permitir que Claude continue seu turno.
* **Preserve o estado das ferramentas:** Inclua as mesmas ferramentas na solicitação de continuação. Um turno pausado pode terminar com um bloco `server_tool_use` cuja ferramenta ainda não foi executada, e a API retorna um erro de validação se essa ferramenta estiver ausente na continuação.
* **Repita conforme necessário:** Um turno continuado pode ser pausado novamente. Verifique o `stop_reason` em cada resposta e continue até obter um motivo de parada diferente, limitando o número de continuações como você faria em qualquer loop de novas tentativas.

Para os outros valores de `stop_reason` e padrões gerais de tratamento, consulte [Motivos de parada e fallback](https://platform.claude.com/docs/pt-BR/build-with-claude/handling-stop-reasons).

## Misturando ferramentas de servidor e ferramentas de cliente em um turno

Claude pode chamar uma ferramenta de servidor e uma ferramenta de cliente no mesmo grupo de chamadas de ferramentas paralelas, por exemplo, `web_fetch` junto com uma ferramenta definida pelo usuário. Uma ferramenta de cliente é qualquer ferramenta que o seu código executa e que produz um bloco `tool_use`, seja ela definida pelo usuário ou uma ferramenta de cliente com esquema da Anthropic, como a [ferramenta Bash](https://platform.claude.com/docs/pt-BR/agents-and-tools/tool-use/bash-tool). Quando isso acontece, a API não executa a ferramenta de servidor. Ela retorna imediatamente para que você possa executar a ferramenta de cliente primeiro:

* `stop_reason` é `"tool_use"`, não `"pause_turn"`.
* `content` contém o bloco `server_tool_use` e o bloco `tool_use` de cliente, mas nenhum bloco de resultado para a ferramenta de servidor: essa chamada não foi concluída.
* Não há nenhum outro marcador. Detecte esse estado procurando um bloco `server_tool_use` cujo `id` não tenha um bloco de resultado correspondente na resposta. Um bloco `mcp_tool_use` do [conector MCP](https://platform.claude.com/docs/pt-BR/agents-and-tools/mcp-connector) se comporta da mesma forma. Chamadas de ferramentas de servidor que já têm seu bloco de resultado na mesma resposta estão concluídas e não precisam de nada da sua parte.

<Note>
  Com a [chamada programática de ferramentas](https://platform.claude.com/docs/pt-BR/agents-and-tools/tool-use/programmatic-tool-calling), o mesmo formato de resposta significa algo diferente. O bloco `tool_use` de cliente vem de um código que está sendo executado na ferramenta `code_execution`, e não diretamente de Claude, e seu campo `caller` indica o bloco `code_execution` que o chamou. Esse código já começou: ele está pausado aguardando seus blocos `tool_result`, e enviá-los retoma a execução em vez de iniciar uma ferramenta adiada. O próprio bloco de resultado do bloco `code_execution` chega quando o código termina, o que pode levar mais de uma rodada de resultados de ferramentas. A mensagem de usuário de acompanhamento em si é a mesma nos dois casos; com a chamada programática de ferramentas, envie também de volta o `id` do campo `container` da resposta, como mostra aquela página.
</Note>

```json
{
  "stop_reason": "tool_use",
  "content": [
    {
      "type": "text",
      "text": "I'll fetch the article and check your system at the same time."
    },
    {
      "type": "server_tool_use",
      "id": "srvtoolu_01HxbWnMRmbWyMfUtJKC45rA",
      "name": "web_fetch",
      "input": { "url": "https://example.com/article" }
    },
    {
      "type": "tool_use",
      "id": "toolu_01PjgRJLbXrXEMZwDNYLnBqk",
      "name": "run_command",
      "input": { "command": "uname -a" }
    }
  ]
}
```

Para continuar o turno, execute as ferramentas de cliente e envie uma mensagem de usuário cujo conteúdo seja apenas os blocos `tool_result`, um para cada bloco `tool_use` naquela resposta. Mantenha o mesmo array `tools`: uma solicitação de retomada que não define mais a ferramenta de servidor pendente falha com um erro 400 cuja mensagem termina com ``but no `web_fetch` tool was provided``.

```json
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01PjgRJLbXrXEMZwDNYLnBqk",
      "content": "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux"
    }
  ]
}
```

A API anexa seus resultados ao turno do assistente ainda aberto, executa a ferramenta de servidor adiada (no caso de execução de código pausada, retoma-a) e então permite que Claude continue. Para uma ferramenta de servidor que Claude chamou diretamente, a próxima resposta começa com o bloco de resultado que responde ao `id` do `server_tool_use` da resposta anterior, seguido pelo conteúdo recém-gerado e por um novo `stop_reason`:

```json
{
  "stop_reason": "end_turn",
  "content": [
    {
      "type": "web_fetch_tool_result",
      "tool_use_id": "srvtoolu_01HxbWnMRmbWyMfUtJKC45rA",
      "content": {
        "type": "web_fetch_result",
        "url": "https://example.com/article",
        "content": {
          "type": "document",
          "source": {
            "type": "text",
            "media_type": "text/plain",
            "data": "Full text content of the article..."
          }
        }
      }
    },
    {
      "type": "text",
      "text": "The article argues that... and your machine is running Linux..."
    }
  ]
}
```

Um bloco `server_tool_use` e seu bloco de resultado são pareados por `tool_use_id`, não pela posição: nesse fluxo, eles chegam em duas respostas diferentes, e o bloco `server_tool_use` não é repetido na segunda. Nas solicitações posteriores, mantenha toda a troca no seu array `messages`, em ordem: a primeira resposta como uma mensagem `assistant`, a mensagem de usuário com `tool_result` e, em seguida, a próxima resposta como outra mensagem `assistant`, da mesma forma que você acumula qualquer outra troca de uso de ferramentas.

<Warning>
  A mensagem de usuário de acompanhamento não deve conter nada além de blocos `tool_result`. Um bloco adicionado após os resultados, como texto, indica à API que o turno do assistente terminou. Para uma ferramenta de servidor que Claude chamou diretamente, isso deixa o turno com uma chamada de ferramenta de servidor não resolvida, e a solicitação falha com um erro 400 `invalid_request_error`:

  ```text wrap
  `web_fetch` tool use with id `srvtoolu_01HxbWnMRmbWyMfUtJKC45rA` was found without a corresponding `web_fetch_tool_result` block
  ```

  Um acompanhamento que coloca conteúdo antes dos resultados, responde apenas a alguns dos IDs de `tool_use` de cliente ou não contém nenhum bloco `tool_result` falha antes, com o erro de ferramenta de cliente descrito em [Lidar com chamadas de ferramentas](https://platform.claude.com/docs/pt-BR/agents-and-tools/tool-use/handle-tool-calls):

  ```text wrap
  `tool_use` ids were found without `tool_result` blocks immediately after: toolu_01PjgRJLbXrXEMZwDNYLnBqk. Each `tool_use` block must have a corresponding `tool_result` block in the next message.
  ```

  Para fornecer mais informações a Claude, envie-as como uma mensagem de usuário separada depois que o turno for concluído.
</Warning>

**Como isso difere de `pause_turn`:** Uma [resposta `pause_turn`](https://platform.claude.com/docs/pt-BR/agents-and-tools/tool-use/server-tools#the-server-side-loop-and-pause-turn) também pode terminar com um bloco `server_tool_use` que não foi executado, mas ela nunca deixa um bloco `tool_use` de cliente aguardando por você, então você a continua reenviando o conteúdo do assistente sem alterações. Uma resposta que deixa um bloco `tool_use` de cliente aguardando por você nunca tem `stop_reason` igual a `pause_turn`: quando Claude para para chamar suas ferramentas, o `stop_reason` é `tool_use`, e você a continua enviando os blocos `tool_result` de cliente em vez de reenviar a resposta. Em ambos os casos, a API executa a ferramenta de servidor pendente no início da próxima solicitação.

O exemplo a seguir habilita o web fetch junto com uma ferramenta `run_command` definida pelo usuário e lida com a resposta mista:

<CodeGroup>
  ```bash cURL
  # Se "stop_reason" for "tool_use" e um bloco server_tool_use não tiver um bloco
  # de resultado correspondente, essa chamada não terminou. Execute as ferramentas do cliente e faça POST
  # de novo com mais uma mensagem de usuário contendo apenas os blocos tool_result delas
  # e o mesmo array tools (veja as abas do SDK).
  curl https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{
      "model": "claude-opus-5-5",
      "max_tokens": 1024,
      "messages": [
        {
          "role": "user",
          "content": "Summarize https://example.com/article and run uname -a to tell me what system this is on."
        }
      ],
      "tools": [
        {"type": "web_fetch_20250910", "name": "web_fetch", "max_uses": 5},
        {
          "name": "run_command",
          "description": "Run a shell command on this computer and return its output.",
          "input_schema": {
            "type": "object",
            "properties": {"command": {"type": "string", "description": "The command to run"}},
            "required": ["command"]
          }
        }
      ]
    }'
  ```

  ```bash CLI
  # Se "stop_reason" for "tool_use" e um bloco server_tool_use não tiver bloco
  # de resultado correspondente, execute as ferramentas do cliente e reexecute com uma mensagem de usuário contendo só
  # os blocos tool_result delas anexados (veja as abas do SDK).
  ant messages create <<'YAML'
  model: claude-opus-5-5
  max_tokens: 1024
  messages:
    - role: user
      content: "Summarize https://example.com/article and run uname -a to tell me what system this is on."
  tools:
    - {type: web_fetch_20250910, name: web_fetch, max_uses: 5}
    - name: run_command
      description: Run a shell command on this computer and return its output.
      input_schema:
        type: object
        properties:
          command: {type: string, description: The command to run}
        required: [command]
  YAML
  ```

  ```python Python
  client = anthropic.Anthropic()

  tools = [
      {"type": "web_fetch_20250910", "name": "web_fetch", "max_uses": 5},
      {
          "name": "run_command",
          "description": "Run a shell command on this computer and return its output.",
          "input_schema": {
              "type": "object",
              "properties": {
                  "command": {"type": "string", "description": "The command to run"}
              },
              "required": ["command"],
          },
      },
  ]
  messages = [
      {
          "role": "user",
          "content": "Summarize https://example.com/article and run uname -a to tell me what system this is on.",
      }
  ]

  response = client.messages.create(
      model="claude-opus-5-5", max_tokens=1024, tools=tools, messages=messages
  )

  tool_results = [
      {
          "type": "tool_result",
          "tool_use_id": block.id,
          # Execute sua ferramenta aqui. Este exemplo retorna uma string fixa.
          "content": "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux",
      }
      for block in response.content
      if block.type == "tool_use"
  ]

  if response.stop_reason == "tool_use" and tool_results:
      # Um bloco server_tool_use sem bloco de resultado nesta resposta não terminou; o resultado chega em uma resposta posterior.
      # Envie de volta apenas os blocos tool_result do cliente, com as mesmas ferramentas.
      continuation = client.messages.create(
          model="claude-opus-5-5",
          max_tokens=1024,
          tools=tools,
          messages=[
              *messages,
              {"role": "assistant", "content": response.content},
              {"role": "user", "content": tool_results},
          ],
      )
      # Se um web_fetch foi adiado, ele é executado nesta requisição e seu
      # web_fetch_tool_result é o primeiro bloco de continuation.content.
      print(continuation)
  else:
      print(response)
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const webFetchTool = {
    type: "web_fetch_20250910",
    name: "web_fetch",
    max_uses: 5
  } as const;
  const runCommandTool: Anthropic.Tool = {
    name: "run_command",
    description: "Run a shell command on this computer and return its output.",
    input_schema: {
      type: "object" as const,
      properties: {
        command: { type: "string", description: "The command to run" }
      },
      required: ["command"]
    }
  };
  const messages: Anthropic.MessageParam[] = [
    {
      role: "user",
      content:
        "Summarize https://example.com/article and run uname -a to tell me what system this is on."
    }
  ];

  const response = await client.messages.create({
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools: [webFetchTool, runCommandTool],
    messages
  });

  const toolResults: Anthropic.ToolResultBlockParam[] = [];
  for (const block of response.content) {
    if (block.type === "tool_use") {
      toolResults.push({
        type: "tool_result",
        tool_use_id: block.id,
        // Execute sua ferramenta aqui. Este exemplo retorna uma string fixa.
        content: "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux"
      });
    }
  }

  if (response.stop_reason === "tool_use" && toolResults.length > 0) {
    // Um bloco server_tool_use sem bloco de resultado nesta resposta não terminou; o resultado chega em uma resposta posterior.
    // Envie de volta apenas os blocos tool_result do cliente, com as mesmas ferramentas.
    const continuation = await client.messages.create({
      model: "claude-opus-5-5",
      max_tokens: 1024,
      tools: [webFetchTool, runCommandTool],
      messages: [
        ...messages,
        { role: "assistant", content: response.content },
        { role: "user", content: toolResults }
      ]
    });
    // Se um web_fetch foi adiado, ele é executado nesta requisição e seu
    // web_fetch_tool_result é o primeiro bloco de continuation.content.
    console.log(continuation);
  } else {
    console.log(response);
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  List<ToolUnion> tools =
  [
      new ToolUnion(new WebFetchTool20250910() { MaxUses = 5 }),
      new ToolUnion(new Tool()
      {
          Name = "run_command",
          Description = "Run a shell command on this computer and return its output.",
          InputSchema = new InputSchema()
          {
              Properties = new Dictionary<string, JsonElement>
              {
                  ["command"] = JsonSerializer.SerializeToElement(
                      new { type = "string", description = "The command to run" }
                  ),
              },
              Required = ["command"],
          },
      }),
  ];
  MessageParam userMessage = new()
  {
      Role = Role.User,
      Content = "Summarize https://example.com/article and run uname -a to tell me what system this is on."
  };

  var response = await client.Messages.Create(new MessageCreateParams
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 1024,
      Tools = tools,
      Messages = [userMessage]
  });

  var toolResults = new List<ContentBlockParam>();
  foreach (var block in response.Content)
  {
      if (block.TryPickToolUse(out var toolUse))
      {
          toolResults.Add(new ContentBlockParam(new ToolResultBlockParam()
          {
              ToolUseID = toolUse.ID,
              // Execute sua ferramenta aqui. Este exemplo retorna uma string fixa.
              Content = "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux",
          }));
      }
  }

  if (response.StopReason?.Value() == StopReason.ToolUse && toolResults.Count > 0)
  {
      // Um bloco server_tool_use sem bloco de resultado nesta resposta não foi concluído; o resultado chega em uma resposta posterior.
      // Envie de volta apenas os blocos tool_result do cliente, com as mesmas ferramentas.
      var continuation = await client.Messages.Create(new MessageCreateParams
      {
          Model = Model.ClaudeOpus5_5,
          MaxTokens = 1024,
          Tools = tools,
          Messages =
          [
              userMessage,
              new()
              {
                  Role = Role.Assistant,
                  Content = response.Content.Select(block => new ContentBlockParam(block.Json)).ToList()
              },
              new() { Role = Role.User, Content = new MessageParamContent(toolResults) }
          ]
      });
      // Se um web_fetch foi adiado, ele é executado nesta requisição e seu
      // web_fetch_tool_result é o primeiro bloco de continuation.Content.
      Console.WriteLine(continuation);
  }
  else
  {
      Console.WriteLine(response);
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  tools := []anthropic.ToolUnionParam{
  	{OfWebFetchTool20250910: &anthropic.WebFetchTool20250910Param{
  		MaxUses: anthropic.Int(5),
  	}},
  	{OfTool: &anthropic.ToolParam{
  		Name:        "run_command",
  		Description: anthropic.String("Run a shell command on this computer and return its output."),
  		InputSchema: anthropic.ToolInputSchemaParam{
  			Properties: map[string]any{
  				"command": map[string]any{
  					"type":        "string",
  					"description": "The command to run",
  				},
  			},
  			Required: []string{"command"},
  		},
  	}},
  }
  userMessage := anthropic.NewUserMessage(anthropic.NewTextBlock("Summarize https://example.com/article and run uname -a to tell me what system this is on."))

  response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
  	Model:     anthropic.ModelClaudeOpus5_5,
  	MaxTokens: 1024,
  	Tools:     tools,
  	Messages:  []anthropic.MessageParam{userMessage},
  })
  if err != nil {
  	log.Fatal(err)
  }

  var toolResults []anthropic.ContentBlockParamUnion
  for _, block := range response.Content {
  	if toolUse, ok := block.AsAny().(anthropic.ToolUseBlock); ok {
  		// Execute sua ferramenta aqui. Este exemplo retorna uma string fixa.
  		output := "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux"
  		toolResults = append(toolResults, anthropic.NewToolResultBlock(toolUse.ID, output, false))
  	}
  }

  if response.StopReason == anthropic.StopReasonToolUse && len(toolResults) > 0 {
  	// Um bloco server_tool_use sem bloco de resultado nesta resposta não terminou; o resultado chega em uma resposta posterior.
  	// Envie de volta apenas os blocos tool_result do cliente, com as mesmas ferramentas.
  	continuation, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
  		Model:     anthropic.ModelClaudeOpus5_5,
  		MaxTokens: 1024,
  		Tools:     tools,
  		Messages: []anthropic.MessageParam{
  			userMessage,
  			response.ToParam(),
  			anthropic.NewUserMessage(toolResults...),
  		},
  	})
  	if err != nil {
  		log.Fatal(err)
  	}
  	// Se um web_fetch foi adiado, ele é executado nesta requisição e seu
  	// web_fetch_tool_result é o primeiro bloco de continuation.Content.
  	fmt.Println(continuation)
  } else {
  	fmt.Println(response)
  }
  ```

  ```java Java
  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      Tool runCommandTool = Tool.builder()
          .name("run_command")
          .description("Run a shell command on this computer and return its output.")
          .inputSchema(Tool.InputSchema.builder()
              .properties(JsonValue.from(Map.of(
                  "command", Map.of("type", "string", "description", "The command to run")
              )))
              .putAdditionalProperty("required", JsonValue.from(List.of("command")))
              .build())
          .build();
      String prompt = "Summarize https://example.com/article and run uname -a to tell me what system this is on.";

      Message response = client.messages().create(MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024L)
          .addTool(WebFetchTool20250910.builder().maxUses(5L).build())
          .addTool(runCommandTool)
          .addUserMessage(prompt)
          .build());

      List<ContentBlockParam> toolResults = new ArrayList<>();
      for (ContentBlock block : response.content()) {
          block.toolUse().ifPresent(toolUse -> toolResults.add(ContentBlockParam.ofToolResult(
              ToolResultBlockParam.builder()
                  .toolUseId(toolUse.id())
                  // Execute sua ferramenta aqui. Este exemplo retorna uma string fixa.
                  .content("Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux")
                  .build()
          )));
      }

      boolean isToolUse = response.stopReason()
          .map(StopReason.TOOL_USE::equals)
          .orElse(false);
      if (isToolUse && !toolResults.isEmpty()) {
          // Um bloco server_tool_use sem bloco de resultado nesta resposta não terminou; o resultado chega em uma resposta posterior.
          // Envie de volta apenas os blocos tool_result do cliente, com as mesmas ferramentas.
          Message continuation = client.messages().create(MessageCreateParams.builder()
              .model(Model.CLAUDE_OPUS_5_5)
              .maxTokens(1024L)
              .addTool(WebFetchTool20250910.builder().maxUses(5L).build())
              .addTool(runCommandTool)
              .addUserMessage(prompt)
              .addMessage(response)
              .addUserMessageOfBlockParams(toolResults)
              .build());
          // Se um web_fetch foi adiado, ele é executado nesta requisição e seu
          // web_fetch_tool_result é o primeiro bloco de continuation.content().
          IO.println(continuation);
      } else {
          IO.println(response);
      }
  }
  ```

  ```php PHP
  $client = new Client();

  $tools = [
      ['type' => 'web_fetch_20250910', 'name' => 'web_fetch', 'max_uses' => 5],
      [
          'name' => 'run_command',
          'description' => 'Run a shell command on this computer and return its output.',
          'input_schema' => [
              'type' => 'object',
              'properties' => [
                  'command' => ['type' => 'string', 'description' => 'The command to run']
              ],
              'required' => ['command']
          ]
      ]
  ];
  $userMessage = ['role' => 'user', 'content' => 'Summarize https://example.com/article and run uname -a to tell me what system this is on.'];

  $response = $client->messages->create(
      maxTokens: 1024,
      messages: [$userMessage],
      model: 'claude-opus-5-5',
      tools: $tools,
  );

  $toolResults = [];
  foreach ($response->content as $block) {
      if ($block->type === 'tool_use') {
          $toolResults[] = [
              'type' => 'tool_result',
              'tool_use_id' => $block->id,
              // Execute sua ferramenta aqui. Este exemplo retorna uma string fixa.
              'content' => 'Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux'
          ];
      }
  }

  if ($response->stopReason === 'tool_use' && count($toolResults) > 0) {
      // Um bloco server_tool_use sem bloco de resultado nesta resposta não terminou; o resultado chega em uma resposta posterior.
      // Envie de volta apenas os blocos tool_result do cliente, com as mesmas ferramentas.
      $continuation = $client->messages->create(
          maxTokens: 1024,
          messages: [
              $userMessage,
              ['role' => 'assistant', 'content' => $response->content],
              ['role' => 'user', 'content' => $toolResults],
          ],
          model: 'claude-opus-5-5',
          tools: $tools,
      );
      // Se um web_fetch foi adiado, ele é executado nesta requisição e seu
      // web_fetch_tool_result é o primeiro bloco de $continuation->content.
      echo $continuation;
  } else {
      echo $response;
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  tools = [
    { type: "web_fetch_20250910", name: "web_fetch", max_uses: 5 },
    {
      name: "run_command",
      description: "Run a shell command on this computer and return its output.",
      input_schema: {
        type: "object",
        properties: {
          command: { type: "string", description: "The command to run" }
        },
        required: ["command"]
      }
    }
  ]
  user_message = {
    role: "user",
    content: "Summarize https://example.com/article and run uname -a to tell me what system this is on."
  }

  response = client.messages.create(
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools: tools,
    messages: [user_message]
  )

  tool_results = []
  response.content.each do |block|
    next unless block.type == :tool_use

    tool_results << {
      type: "tool_result",
      tool_use_id: block.id,
      # Execute sua ferramenta aqui. Este exemplo retorna uma string fixa.
      content: "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux"
    }
  end

  if response.stop_reason == :tool_use && !tool_results.empty?
    # Um bloco server_tool_use sem bloco de resultado nesta resposta não terminou; o resultado chega em uma resposta posterior.
    # Envie de volta apenas os blocos tool_result do cliente, com as mesmas ferramentas.
    continuation = client.messages.create(
      model: "claude-opus-5-5",
      max_tokens: 1024,
      tools: tools,
      messages: [
        user_message,
        { role: "assistant", content: response.content },
        { role: "user", content: tool_results }
      ]
    )
    # Se um web_fetch foi adiado, ele é executado nesta requisição e seu
    # web_fetch_tool_result é o primeiro bloco de continuation.content.
    puts continuation
  else
    puts response
  end
  ```
</CodeGroup>

Este código também está correto quando Claude não mistura os dois tipos de chamada. Um turno com apenas blocos `tool_use` de cliente segue o mesmo caminho de continuação, e um turno com apenas chamadas de ferramentas de servidor não precisa de nenhum bloco `tool_result` de cliente da sua parte: seus blocos de resultado normalmente já estão presentes, e um turno que retorna suspenso, como uma [resposta `pause_turn`](https://platform.claude.com/docs/pt-BR/agents-and-tools/tool-use/server-tools#the-server-side-loop-and-pause-turn), é reenviado sem alterações.

## ZDR e allowed\_callers

As versões básicas da pesquisa na web (`web_search_20250305`) e do web fetch (`web_fetch_20250910`) são elegíveis para [Zero Data Retention (ZDR)](https://platform.claude.com/docs/pt-BR/manage-claude/api-and-data-retention).

As versões `_20260209` e posteriores com "dynamic filtering" (filtragem dinâmica) **não** são elegíveis para ZDR por padrão, porque a filtragem dinâmica depende internamente da execução de código.

Para usar uma ferramenta de servidor `_20260209` ou posterior com ZDR, desative a filtragem dinâmica definindo `"allowed_callers": ["direct"]` na ferramenta:

```json
{
  "type": "web_search_20260209",
  "name": "web_search",
  "allowed_callers": ["direct"]
}
```

Isso restringe a ferramenta apenas à invocação direta, ignorando a etapa interna de execução de código.

`allowed_callers` controla como uma ferramenta pode ser invocada: diretamente por Claude (`"direct"`), de dentro de um contêiner de execução de código (por exemplo, `"code_execution_20260120"`) ou ambos. As versões `_20260209` das ferramentas web usam por padrão apenas o chamador de execução de código; as versões anteriores usam `["direct"]` por padrão. Em modelos que não oferecem suporte à chamada programática de ferramentas, essas versões exigem `allowed_callers: ["direct"]`; sem isso, a API retorna um erro de validação que pede para defini-lo.

<Note>
  Mesmo quando o web fetch é usado em uma configuração elegível para ZDR, os editores de sites podem reter quaisquer parâmetros passados na URL se Claude buscar conteúdo do site deles.
</Note>

## Filtragem de domínio

As ferramentas de servidor que acessam a web aceitam os parâmetros `allowed_domains` e `blocked_domains` para controlar quais domínios Claude pode acessar. Ambos são campos no objeto da ferramenta:

```json
{
  "type": "web_search_20250305",
  "name": "web_search",
  "allowed_domains": ["example.com", "docs.python.org"]
}
```

Ao usar filtros de domínio:

* Os domínios não devem incluir o esquema HTTP/HTTPS (use `example.com` em vez de `https://example.com`).
* Os subdomínios são incluídos automaticamente (`example.com` abrange `docs.example.com`).
* Subdomínios específicos restringem os resultados apenas a esse subdomínio (`docs.example.com` retorna apenas resultados desse subdomínio, e não de `example.com` ou `api.example.com`).
* Subcaminhos são suportados na pesquisa na web e correspondem a qualquer coisa após o caminho (`example.com/blog` corresponde a `example.com/blog/post-1`).
* O web fetch faz a correspondência apenas pelo domínio: uma entrada que inclui um caminho nunca corresponde a uma URL do web fetch.
* Você pode usar `allowed_domains` ou `blocked_domains`, mas não ambos na mesma solicitação.

**Suporte a curingas:**

* Curingas (`*`) não são permitidos no próprio domínio, apenas no caminho após ele.
* Válidos: `example.com/*`, `example.com/*/articles`
* Inválidos: `*.example.com`, `ex*.com`

Formatos de domínio inválidos são rejeitados no momento da solicitação com um erro 400 `invalid_request_error`.

<Note>
  As restrições de domínio no nível da solicitação funcionam em conjunto com quaisquer restrições de domínio no nível da organização configuradas no Claude Console. O `allowed_domains` no nível da solicitação deve ser um subconjunto da lista de permissões no nível da organização; entradas fora dela fazem a API retornar um erro de validação. Uma lista de permissões no nível da solicitação que inclua um domínio bloqueado pela sua organização é rejeitada com um erro `400` que indica as entradas conflitantes.
</Note>

<Warning>
  Caracteres Unicode em nomes de domínio podem contornar os filtros de domínio por meio de "homograph attacks" (ataques homográficos): `аmazon.com` (com um `а` cirílico) parece idêntico a `amazon.com`, mas é um domínio diferente. Use apenas nomes de domínio ASCII nas listas de permissão e de bloqueio, e audite as entradas existentes em busca de caracteres não ASCII.
</Warning>

O [Claude Managed Agents](https://platform.claude.com/docs/pt-BR/managed-agents/overview) usa os mesmos campos `allowed_domains` e `blocked_domains` nas entradas `web_search` e `web_fetch` do conjunto de ferramentas do agente. No Managed Agents, cada lista contém no máximo 64 entradas, os domínios listados para `web_fetch` não podem incluir um caminho, e campos específicos das ferramentas da Messages API, como `max_uses`, `citations` e `cache_control`, não estão disponíveis. Consulte [Regras da lista de domínios](https://platform.claude.com/docs/pt-BR/managed-agents/tools-web-restrictions#domain-list-rules) para ver as regras completas.

As configurações de pesquisa na web e web fetch no nível da organização no Claude Console se aplicam apenas às solicitações da Messages API. Elas não se aplicam às sessões do Managed Agents, que usam as listas por ferramenta no conjunto de ferramentas do agente. Para uma sessão em um ambiente de nuvem com rede `limited`, o `allowed_hosts` do ambiente também se aplica a `web_search` e `web_fetch`; consulte [Rede](https://platform.claude.com/docs/pt-BR/managed-agents/environments#networking). As listas por ferramenta restringem ainda mais essas ferramentas, dentro dos hosts que o `allowed_hosts` permite.

## Filtragem dinâmica com execução de código

As versões `_20260209` e posteriores da pesquisa na web e do web fetch usam internamente a execução de código para aplicar filtros dinâmicos aos resultados da pesquisa.

<Note>
  Você não precisa adicionar uma ferramenta `code_execution` para essas versões: quando a filtragem dinâmica é executada, a API provisiona automaticamente a execução de código para a solicitação, e ambas as ferramentas compartilham um único contêiner de execução. Se você incluir uma, use `code_execution_20260120` ou posterior; a API rejeita versões mais antigas de execução de código junto com essas versões das ferramentas web.
</Note>

## Eventos de streaming de ferramentas de servidor

Os eventos de ferramentas de servidor são transmitidos como parte do fluxo normal de "server-sent events" (eventos enviados pelo servidor), ou SSE. Um bloco `server_tool_use` que Claude chama diretamente é transmitido como um bloco `tool_use` de cliente: um evento `content_block_start` seguido por eventos `input_json_delta`. O bloco de resultado chega completo em um único evento `content_block_start`, sem deltas.

Consulte [Streaming](https://platform.claude.com/docs/pt-BR/build-with-claude/streaming) para ver a referência completa de eventos. As páginas de cada ferramenta documentam os nomes de eventos específicos da ferramenta quando eles diferem.

## Solicitações em lote

Todas as ferramentas de servidor oferecem suporte a "batch processing" (processamento em lote). Em um lote, o loop agêntico é executado da mesma forma que nas solicitações síncronas, com um limite maior de iterações por turno. Se o loop atingir esse limite, a resposta termina com `stop_reason: "pause_turn"`; você pode continuá-la enviando uma solicitação de acompanhamento com o conteúdo retornado. Consulte [Ferramentas de servidor e o loop agêntico](https://platform.claude.com/docs/pt-BR/build-with-claude/batch-processing#server-tools-and-the-agentic-loop) para obter detalhes.

Cargas de trabalho comuns em lote incluem enriquecer um conjunto de dados com informações da web, verificar um grande conjunto de documentos em relação a fontes atuais e executar código de análise em muitos arquivos.

## Próximos passos

<CardGroup cols={2}>
  <Card title="Solução de problemas de uso de ferramentas" icon="wrench" href="https://platform.claude.com/docs/pt-BR/agents-and-tools/tool-use/troubleshooting-tool-use">
    Corrija os erros mais comuns de uso de ferramentas com tabelas de diagnóstico que relacionam sintomas a correções.
  </Card>

  <Card title="Ferramenta de pesquisa na web" icon="magnifying-glass" href="https://platform.claude.com/docs/pt-BR/agents-and-tools/tool-use/web-search-tool">
    Pesquise na web e cite os resultados.
  </Card>

  <Card title="Ferramenta web fetch" icon="download" href="https://platform.claude.com/docs/pt-BR/agents-and-tools/tool-use/web-fetch-tool">
    Busque e leia conteúdo de URLs específicas para ampliar o contexto de Claude com conteúdo da web em tempo real.
  </Card>

  <Card title="Ferramenta de execução de código" icon="terminal" href="https://platform.claude.com/docs/pt-BR/agents-and-tools/tool-use/code-execution-tool">
    Execute código Python e bash em um contêiner isolado para analisar dados, gerar arquivos e iterar sobre soluções.
  </Card>

  <Card title="Ferramenta de busca de ferramentas" icon="compass" href="https://platform.claude.com/docs/pt-BR/agents-and-tools/tool-use/tool-search-tool">
    Descubra e carregue ferramentas sob demanda.
  </Card>
</CardGroup>
