---
title: Strumenti server
url: https://platform.claude.com/docs/it/agents-and-tools/tool-use/server-tools
description: "Lavora con gli strumenti eseguiti da Anthropic: blocchi server_tool_use, continuazione con pause_turn, turni misti con strumenti server e client, e filtraggio dei domini."
---

Gli strumenti eseguiti lato server condividono queste meccaniche: il blocco `server_tool_use`, la continuazione con `pause_turn`, i turni che combinano strumenti server e client, l'idoneità alla "Zero Data Retention" (conservazione zero dei dati), o ZDR, e il filtraggio dei domini. Per i singoli strumenti, consulta il [riferimento degli strumenti](https://platform.claude.com/docs/it/agents-and-tools/tool-use/tool-reference).

## Il blocco server\_tool\_use

Il blocco `server_tool_use` compare nella risposta di Claude quando viene eseguito uno strumento lato server. Il suo campo `id` usa il prefisso `srvtoolu_` per distinguerlo dalle chiamate agli strumenti client:

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

L'API esegue lo strumento internamente. Vedi la chiamata e il suo risultato nella risposta, ma non gestisci l'esecuzione. A differenza dei blocchi `tool_use` client, non devi rispondere con un `tool_result`. Il blocco di risultato dello strumento (ad esempio, `web_search_tool_result` per la ricerca web) segue il blocco `server_tool_use` nello stesso turno dell'assistente, abbinato tramite `tool_use_id`. Se Claude chiama contemporaneamente uno dei tuoi strumenti client, il blocco `server_tool_use` compare senza il suo risultato e la risposta termina con `stop_reason: "tool_use"`. L'API esegue lo strumento quando restituisci i blocchi `tool_result` client nella tua richiesta successiva.

## Il ciclo lato server e pause\_turn

Quando usi strumenti server come la ricerca web, l'API esegue le chiamate agli strumenti in un ciclo agentico lato server. In un turno di lunga durata, l'API potrebbe mettere in pausa quel ciclo e restituire uno stop reason `pause_turn`.

Ecco come gestire lo stop reason `pause_turn`:

<CodeGroup>
  ```bash cURL
  # Richiesta iniziale. Se "stop_reason" nella risposta è "pause_turn", continua
  # il turno reinviando la richiesta con il contenuto dell'assistente aggiunto ai messaggi.
  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
  # Richiesta iniziale. Se "stop_reason" nell'output è "pause_turn", riesegui con
  # il contenuto dell'assistente aggiunto ai messaggi (vedi le schede dell'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()

  # Richiesta iniziale con ricerca 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 la risposta ha il motivo di arresto pause_turn
  if response.stop_reason == "pause_turn":
      # Continua la conversazione con il contenuto in pausa
      messages = [
          {
              "role": "user",
              "content": "Search for comprehensive information about quantum computing breakthroughs in 2025",
          },
          {"role": "assistant", "content": response.content},
      ]

      # Invia la richiesta di continuazione
      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();

  // Richiesta iniziale con ricerca 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 la risposta ha il motivo di arresto pause_turn
  if (response.stop_reason === "pause_turn") {
    // Continua la conversazione con il contenuto in pausa
    const messages: Anthropic.MessageParam[] = [
      {
        role: "user",
        content:
          "Search for comprehensive information about quantum computing breakthroughs in 2025"
      },
      { role: "assistant", content: response.content }
    ];

    // Invia la richiesta di continuazione
    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)
  {
      // Continua la conversazione con il contenuto in pausa
      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 {
  	// Restituisci la risposta in pausa così com'è in modo che Claude possa continuare il 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>

Quando gestisci `pause_turn`:

* **Continua la conversazione:** Ripassa la risposta in pausa così com'è in una richiesta successiva per permettere a Claude di continuare il suo turno.
* **Preserva lo stato degli strumenti:** Includi gli stessi strumenti nella richiesta di continuazione. Un turno in pausa può terminare con un blocco `server_tool_use` il cui strumento non è ancora stato eseguito, e l'API restituisce un errore di validazione se quello strumento manca nella continuazione.
* **Ripeti se necessario:** Un turno continuato può andare di nuovo in pausa. Controlla `stop_reason` in ogni risposta e continua finché non ottieni uno stop reason diverso, limitando il numero di continuazioni come faresti con qualsiasi ciclo di retry.

Per gli altri valori di `stop_reason` e i pattern generali di gestione, consulta [Stop reason e fallback](https://platform.claude.com/docs/it/build-with-claude/handling-stop-reasons).

## Combinare strumenti server e strumenti client in un unico turno

Claude può chiamare uno strumento server e uno strumento client nello stesso gruppo di chiamate parallele agli strumenti, ad esempio `web_fetch` insieme a uno strumento definito dall'utente. Uno strumento client è qualsiasi strumento che il tuo codice esegue e che produce un blocco `tool_use`, sia esso definito dall'utente o uno strumento client con schema Anthropic come lo [strumento Bash](https://platform.claude.com/docs/it/agents-and-tools/tool-use/bash-tool). Quando ciò accade, l'API non esegue lo strumento server. Restituisce immediatamente la risposta in modo che tu possa eseguire prima lo strumento client:

* `stop_reason` è `"tool_use"`, non `"pause_turn"`.
* `content` contiene il blocco `server_tool_use` e il blocco `tool_use` client, ma nessun blocco di risultato per lo strumento server: quella chiamata non è terminata.
* Non c'è nessun altro indicatore. Rileva lo stato cercando un blocco `server_tool_use` il cui `id` non ha un blocco di risultato corrispondente nella risposta. Un blocco `mcp_tool_use` proveniente dal [connettore MCP](https://platform.claude.com/docs/it/agents-and-tools/mcp-connector) si comporta allo stesso modo. Le chiamate agli strumenti server che hanno già il loro blocco di risultato nella stessa risposta sono complete e non richiedono nulla da parte tua.

<Note>
  Con la [chiamata programmatica degli strumenti](https://platform.claude.com/docs/it/agents-and-tools/tool-use/programmatic-tool-calling), la stessa forma di risposta ha un significato diverso. Il blocco `tool_use` client proviene da codice in esecuzione nello strumento `code_execution` anziché direttamente da Claude, e il suo campo `caller` indica il blocco `code_execution` che lo ha chiamato. Quel codice è già stato avviato: è in pausa in attesa dei tuoi blocchi `tool_result`, e inviarli riprende l'esecuzione invece di avviare uno strumento differito. Il blocco di risultato proprio del blocco `code_execution` arriva una volta che il codice termina, il che può richiedere più di un ciclo di risultati degli strumenti. Il messaggio utente di follow-up in sé è lo stesso in entrambi i casi; con la chiamata programmatica degli strumenti, ripassa anche l'`id` dal campo `container` della risposta, come mostra quella pagina.
</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" }
    }
  ]
}
```

Per continuare il turno, esegui gli strumenti client e invia un messaggio utente il cui contenuto sia costituito solo dai blocchi `tool_result`, uno per ogni blocco `tool_use` in quella risposta. Mantieni lo stesso array `tools`: una richiesta di ripresa che non definisce più lo strumento server in attesa fallisce con un 400 il cui messaggio termina con ``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"
    }
  ]
}
```

L'API allega i tuoi risultati al turno dell'assistente ancora aperto, esegue lo strumento server differito (per l'esecuzione di codice in pausa, la riprende) e poi lascia che Claude continui. Per uno strumento server chiamato direttamente da Claude, la risposta successiva inizia con il blocco di risultato che risponde all'`id` del `server_tool_use` della risposta precedente, seguito dal contenuto appena generato e da un nuovo `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..."
    }
  ]
}
```

Un blocco `server_tool_use` e il suo blocco di risultato si abbinano tramite `tool_use_id`, non per posizione: in questo flusso arrivano in due risposte diverse, e il blocco `server_tool_use` non viene ripetuto nella seconda. Nelle richieste successive, mantieni l'intero scambio nel tuo array `messages` in ordine: la prima risposta come messaggio `assistant`, il messaggio utente con i `tool_result`, e poi la risposta successiva come un altro messaggio `assistant`, nello stesso modo in cui accumuli qualsiasi altro scambio di uso degli strumenti.

<Warning>
  Il messaggio utente di follow-up non deve contenere nient'altro che blocchi `tool_result`. Un blocco aggiunto dopo i risultati, come del testo, indica all'API che il turno dell'assistente è terminato. Per uno strumento server chiamato direttamente da Claude, ciò lascia il turno con una chiamata a strumento server non risolta, e la richiesta fallisce con un 400 `invalid_request_error`:

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

  Un follow-up che inserisce contenuto prima dei risultati, risponde solo ad alcuni degli ID `tool_use` client, o non contiene alcun blocco `tool_result` fallisce prima, con l'errore dello strumento client descritto in [Gestire le chiamate agli strumenti](https://platform.claude.com/docs/it/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.
  ```

  Per fornire a Claude ulteriore input, invialo come messaggio utente separato dopo il completamento del turno.
</Warning>

**In cosa differisce da `pause_turn`:** Una [risposta `pause_turn`](https://platform.claude.com/docs/it/agents-and-tools/tool-use/server-tools#the-server-side-loop-and-pause-turn) può anch'essa terminare con un blocco `server_tool_use` non ancora eseguito, ma non lascia mai un blocco `tool_use` client in attesa di te, quindi la continui reinviando il contenuto dell'assistente così com'è. Una risposta che lascia un blocco `tool_use` client in attesa di te non ha mai uno `stop_reason` pari a `pause_turn`: quando Claude si ferma per chiamare i tuoi strumenti, `stop_reason` è `tool_use`, e la continui inviando i blocchi `tool_result` client anziché reinviando la risposta. In entrambi i casi l'API esegue lo strumento server in sospeso all'inizio della richiesta successiva.

L'esempio seguente abilita il web fetch insieme a uno strumento `run_command` definito dall'utente e gestisce la risposta mista:

<CodeGroup>
  ```bash cURL
  # Se "stop_reason" è "tool_use" e un blocco server_tool_use non ha un blocco
  # di risultato corrispondente, la chiamata non è terminata. Esegui gli strumenti client, poi invia
  # di nuovo una POST con un ulteriore messaggio utente contenente solo i loro blocchi tool_result
  # e lo stesso array tools (vedi le schede 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" è "tool_use" e un blocco server_tool_use non ha un blocco
  # risultato corrispondente, esegui gli strumenti client e riesegui aggiungendo un messaggio utente
  # contenente solo i loro blocchi tool_result (vedi le schede 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,
          # Esegui qui il tuo strumento. Questo esempio restituisce una stringa fissa.
          "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:
      # Un blocco server_tool_use senza blocco di risultato in questa risposta non è terminato; il suo risultato arriva in una risposta successiva.
      # Rimanda indietro solo i blocchi tool_result del client, con gli stessi strumenti.
      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 un web_fetch è stato rinviato, viene eseguito in questa richiesta e il suo
      # web_fetch_tool_result è il primo blocco di 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,
        // Esegui qui il tuo strumento. Questo esempio restituisce una stringa fissa.
        content: "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux"
      });
    }
  }

  if (response.stop_reason === "tool_use" && toolResults.length > 0) {
    // Un blocco server_tool_use senza blocco di risultato in questa risposta non è terminato; il suo risultato arriva in una risposta successiva.
    // Rimanda indietro solo i blocchi tool_result del client, con gli stessi strumenti.
    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 un web_fetch è stato rinviato, viene eseguito in questa richiesta e il suo
    // web_fetch_tool_result è il primo blocco di 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,
              // Esegui qui il tuo strumento. Questo esempio restituisce una stringa fissa.
              Content = "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux",
          }));
      }
  }

  if (response.StopReason?.Value() == StopReason.ToolUse && toolResults.Count > 0)
  {
      // Un blocco server_tool_use senza blocco di risultato in questa risposta non è terminato; il suo risultato arriva in una risposta successiva.
      // Rimanda indietro solo i blocchi tool_result del client, con gli stessi strumenti.
      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 un web_fetch è stato rinviato, viene eseguito in questa richiesta e il suo
      // web_fetch_tool_result è il primo blocco di 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 {
  		// Esegui qui il tuo strumento. Questo esempio restituisce una stringa fissa.
  		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 {
  	// Un blocco server_tool_use senza blocco di risultato in questa risposta non è terminato; il suo risultato arriva in una risposta successiva.
  	// Rimanda indietro solo i blocchi tool_result del client, con gli stessi strumenti.
  	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 un web_fetch è stato rinviato, viene eseguito in questa richiesta e il suo
  	// web_fetch_tool_result è il primo blocco di 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())
                  // Esegui qui il tuo strumento. Questo esempio restituisce una stringa fissa.
                  .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()) {
          // Un blocco server_tool_use senza blocco di risultato in questa risposta non è terminato; il suo risultato arriva in una risposta successiva.
          // Rimanda indietro solo i blocchi tool_result del client, con gli stessi strumenti.
          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 un web_fetch è stato rinviato, viene eseguito in questa richiesta e il suo
          // web_fetch_tool_result è il primo blocco di 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,
              // Esegui qui il tuo strumento. Questo esempio restituisce una stringa fissa.
              'content' => 'Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux'
          ];
      }
  }

  if ($response->stopReason === 'tool_use' && count($toolResults) > 0) {
      // Un blocco server_tool_use senza blocco di risultato in questa risposta non è terminato; il suo risultato arriva in una risposta successiva.
      // Rimanda indietro solo i blocchi tool_result del client, con gli stessi strumenti.
      $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 un web_fetch è stato rinviato, viene eseguito in questa richiesta e il suo
      // web_fetch_tool_result è il primo blocco di $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,
      # Esegui qui il tuo strumento. Questo esempio restituisce una stringa fissa.
      content: "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux"
    }
  end

  if response.stop_reason == :tool_use && !tool_results.empty?
    # Un blocco server_tool_use senza blocco di risultato in questa risposta non è terminato; il suo risultato arriva in una risposta successiva.
    # Rimanda indietro solo i blocchi tool_result del client, con gli stessi strumenti.
    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 un web_fetch è stato rinviato, viene eseguito in questa richiesta e il suo
    # web_fetch_tool_result è il primo blocco di continuation.content.
    puts continuation
  else
    puts response
  end
  ```
</CodeGroup>

Questo codice è corretto anche quando Claude non combina i due tipi di chiamata. Un turno con soli blocchi `tool_use` client segue lo stesso percorso di continuazione, e un turno con sole chiamate a strumenti server non richiede blocchi `tool_result` client da parte tua: i suoi blocchi di risultato sono normalmente già presenti, e uno che ritorna sospeso, come una [risposta `pause_turn`](https://platform.claude.com/docs/it/agents-and-tools/tool-use/server-tools#the-server-side-loop-and-pause-turn), viene invece reinviato così com'è.

## ZDR e allowed\_callers

Le versioni base della ricerca web (`web_search_20250305`) e del web fetch (`web_fetch_20250910`) sono idonee alla [Zero Data Retention (ZDR)](https://platform.claude.com/docs/it/manage-claude/api-and-data-retention).

Le versioni `_20260209` e successive con filtraggio dinamico **non** sono idonee alla ZDR per impostazione predefinita, perché il filtraggio dinamico si basa internamente sull'esecuzione di codice.

Per usare uno strumento server `_20260209` o successivo con ZDR, disabilita il filtraggio dinamico impostando `"allowed_callers": ["direct"]` sullo strumento:

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

Questo limita lo strumento alla sola invocazione diretta, bypassando il passaggio interno di esecuzione del codice.

`allowed_callers` controlla come uno strumento può essere invocato: direttamente da Claude (`"direct"`), dall'interno di un container di esecuzione del codice (ad esempio, `"code_execution_20260120"`), o entrambi. Le versioni `_20260209` degli strumenti web usano per impostazione predefinita solo il chiamante di esecuzione del codice; le versioni precedenti usano per impostazione predefinita `["direct"]`. Sui modelli che non supportano la chiamata programmatica degli strumenti, queste versioni richiedono `allowed_callers: ["direct"]`; senza di esso l'API restituisce un errore di validazione che indica di impostarlo.

<Note>
  Anche quando il web fetch viene usato in una configurazione idonea alla ZDR, gli editori dei siti web potrebbero conservare eventuali parametri passati all'URL se Claude recupera contenuti dal loro sito.
</Note>

## Filtraggio dei domini

Gli strumenti server che accedono al web accettano i parametri `allowed_domains` e `blocked_domains` per controllare quali domini Claude può raggiungere. Entrambi sono campi dell'oggetto strumento:

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

Quando usi i filtri di dominio:

* I domini non devono includere lo schema HTTP/HTTPS (usa `example.com` invece di `https://example.com`).
* I sottodomini sono inclusi automaticamente (`example.com` copre `docs.example.com`).
* I sottodomini specifici limitano i risultati a quel solo sottodominio (`docs.example.com` restituisce solo risultati da quel sottodominio, non da `example.com` o `api.example.com`).
* I sottopercorsi sono supportati per la ricerca web e corrispondono a qualsiasi cosa dopo il percorso (`example.com/blog` corrisponde a `example.com/blog/post-1`).
* Il web fetch effettua la corrispondenza solo sul dominio: una voce che include un percorso non corrisponde mai a un URL di web fetch.
* Puoi usare `allowed_domains` oppure `blocked_domains`, ma non entrambi nella stessa richiesta.

**Supporto dei wildcard:**

* I wildcard (`*`) non sono consentiti nel dominio stesso, solo nel percorso che lo segue.
* Valido: `example.com/*`, `example.com/*/articles`
* Non valido: `*.example.com`, `ex*.com`

I formati di dominio non validi vengono rifiutati al momento della richiesta con un 400 `invalid_request_error`.

<Note>
  Le restrizioni di dominio a livello di richiesta funzionano insieme a eventuali restrizioni di dominio a livello di organizzazione configurate in Claude Console. Gli `allowed_domains` a livello di richiesta devono essere un sottoinsieme della lista consentita a livello di organizzazione; le voci al di fuori di essa fanno sì che l'API restituisca un errore di validazione. Una lista consentita a livello di richiesta che include un dominio bloccato dalla tua organizzazione viene rifiutata con un errore `400` che indica le voci in conflitto.
</Note>

<Warning>
  I caratteri Unicode nei nomi di dominio possono aggirare i filtri di dominio tramite attacchi omografici: `аmazon.com` (con una `а` cirillica) appare identico a `amazon.com` ma è un dominio diverso. Usa nomi di dominio solo ASCII nelle liste di autorizzazione e di blocco, e verifica le voci esistenti alla ricerca di caratteri non ASCII.
</Warning>

[Claude Managed Agents](https://platform.claude.com/docs/it/managed-agents/overview) usa gli stessi campi `allowed_domains` e `blocked_domains` nelle voci `web_search` e `web_fetch` del toolset dell'agente. Su Managed Agents, ogni elenco contiene al massimo 64 voci, i domini elencati per `web_fetch` non possono includere un percorso, e i campi specifici degli strumenti della Messages API, come `max_uses`, `citations` e `cache_control`, non sono disponibili. Consulta [Regole degli elenchi di domini](https://platform.claude.com/docs/it/managed-agents/tools-web-restrictions#domain-list-rules) per le regole complete.

Le impostazioni di ricerca web e web fetch a livello di organizzazione nella Claude Console si applicano solo alle richieste della Messages API. Non si applicano alle sessioni di Managed Agents, che usano invece gli elenchi per strumento nel toolset dell'agente. Per una sessione in un ambiente cloud con networking `limited`, anche gli `allowed_hosts` dell'ambiente si applicano a `web_search` e `web_fetch`; consulta [Networking](https://platform.claude.com/docs/it/managed-agents/environments#networking). Gli elenchi per strumento limitano ulteriormente questi strumenti, all'interno degli host consentiti da `allowed_hosts`.

## Filtraggio dinamico con esecuzione del codice

Le versioni `_20260209` e successive della ricerca web e del web fetch usano internamente l'esecuzione del codice per applicare filtri dinamici ai risultati di ricerca.

<Note>
  Non devi aggiungere uno strumento `code_execution` per queste versioni: quando il filtraggio dinamico viene eseguito, l'API predispone automaticamente l'esecuzione del codice per la richiesta, ed entrambi gli strumenti condividono un unico container di esecuzione. Se ne includi uno, usa `code_execution_20260120` o successivo; l'API rifiuta le versioni precedenti di esecuzione del codice insieme a queste versioni degli strumenti web.
</Note>

## Streaming degli eventi degli strumenti server

Gli eventi degli strumenti server vengono trasmessi in streaming come parte del normale flusso di "server-sent events" (eventi inviati dal server), o SSE. Un blocco `server_tool_use` chiamato direttamente da Claude viene trasmesso come un blocco `tool_use` client: un evento `content_block_start` seguito da eventi `input_json_delta`. Il blocco di risultato arriva completo in un singolo evento `content_block_start`, senza delta.

Consulta [Streaming](https://platform.claude.com/docs/it/build-with-claude/streaming) per il riferimento completo degli eventi. Le pagine dei singoli strumenti documentano i nomi degli eventi specifici dello strumento laddove differiscono.

## Richieste batch

Tutti gli strumenti server supportano l'elaborazione batch. In un batch, il ciclo agentico viene eseguito esattamente come per le richieste sincrone, con un limite di iterazioni per turno più elevato. Se il ciclo raggiunge quel limite, la risposta termina con `stop_reason: "pause_turn"`; puoi continuarla inviando una richiesta di follow-up con il contenuto restituito. Consulta [Strumenti server e il ciclo agentico](https://platform.claude.com/docs/it/build-with-claude/batch-processing#server-tools-and-the-agentic-loop) per i dettagli.

I carichi di lavoro batch comuni includono l'arricchimento di un dataset con informazioni dal web, la verifica di un ampio insieme di documenti rispetto a fonti aggiornate e l'esecuzione di codice di analisi su molti file.

## Prossimi passi

<CardGroup cols={2}>
  <Card title="Risoluzione dei problemi dell'uso degli strumenti" icon="wrench" href="https://platform.claude.com/docs/it/agents-and-tools/tool-use/troubleshooting-tool-use">
    Risolvi gli errori più comuni dell'uso degli strumenti con tabelle diagnostiche dal sintomo alla soluzione.
  </Card>

  <Card title="Strumento di ricerca web" icon="magnifying-glass" href="https://platform.claude.com/docs/it/agents-and-tools/tool-use/web-search-tool">
    Cerca nel web e cita i risultati.
  </Card>

  <Card title="Strumento web fetch" icon="download" href="https://platform.claude.com/docs/it/agents-and-tools/tool-use/web-fetch-tool">
    Recupera e leggi contenuti da URL specifici per arricchire il contesto di Claude con contenuti web in tempo reale.
  </Card>

  <Card title="Strumento di esecuzione del codice" icon="terminal" href="https://platform.claude.com/docs/it/agents-and-tools/tool-use/code-execution-tool">
    Esegui codice Python e bash in un container sandbox per analizzare dati, generare file e iterare sulle soluzioni.
  </Card>

  <Card title="Strumento di ricerca strumenti" icon="compass" href="https://platform.claude.com/docs/it/agents-and-tools/tool-use/tool-search-tool">
    Scopri e carica strumenti su richiesta.
  </Card>
</CardGroup>
