---
title: サーバーツール
url: https://platform.claude.com/docs/ja/agents-and-tools/tool-use/server-tools
description: Anthropicが実行するツールを扱います：server_tool_useブロック、pause_turnによる継続、サーバーツールとクライアントツールが混在するターン、ドメインフィルタリング。
---

サーバーで実行されるツールには、次の共通の仕組みがあります：`server_tool_use`ブロック、`pause_turn`による継続、サーバーツールとクライアントツールが混在するターン、「Zero Data Retention」（ゼロデータ保持）、すなわちZDRの適格性、そして「domain filtering」（ドメインフィルタリング）です。個々のツールについては、[ツールリファレンス](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/tool-reference)を参照してください。

## server\_tool\_useブロック

`server_tool_use`ブロックは、サーバーで実行されるツールが動作したときにClaudeのレスポンスに現れます。その`id`フィールドには、クライアントツールの呼び出しと区別するために`srvtoolu_`プレフィックスが使用されます：

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

APIはツールを内部で実行します。レスポンスには呼び出しとその結果が表示されますが、実行を処理する必要はありません。クライアントの`tool_use`ブロックとは異なり、`tool_result`で応答する必要はありません。ツールの結果ブロック（たとえば、ウェブ検索の場合は`web_search_tool_result`）は、同じアシスタントターン内で`server_tool_use`ブロックの後に続き、`tool_use_id`によって対応付けられます。Claudeが同時にクライアントツールのいずれかを呼び出した場合、`server_tool_use`ブロックは結果なしで現れ、レスポンスは`stop_reason: "tool_use"`で終了します。APIは、次のリクエストでクライアントの`tool_result`ブロックを返したときにツールを実行します。

## サーバー側ループとpause\_turn

ウェブ検索などのサーバーツールを使用する場合、APIはサーバー側の「agentic loop」（エージェントループ）でツール呼び出しを実行します。長時間実行されるターンでは、APIがそのループを一時停止し、`pause_turn`停止理由を返すことがあります。

`pause_turn`停止理由の処理方法は次のとおりです：

<CodeGroup>
  ```bash cURL
  # 最初のリクエストです。レスポンスの "stop_reason" が "pause_turn" の場合は、
  # アシスタントのコンテンツを 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
  # 最初のリクエストです。出力の "stop_reason" が "pause_turn" の場合は、
  # アシスタントのコンテンツを messages に追加して再実行します（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()

  # 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}],
  )

  # レスポンスの stop reason が pause_turn かどうかを確認します
  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}],
      )

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

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

  // 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
      }
    ]
  });

  // レスポンスの stop reason が pause_turn かどうかを確認します
  if (response.stop_reason === "pause_turn") {
    // 一時停止されたコンテンツで会話を続行します
    const messages: Anthropic.MessageParam[] = [
      {
        role: "user",
        content:
          "Search for comprehensive information about quantum computing breakthroughs in 2025"
      },
      { role: "assistant", content: response.content }
    ];

    // 続行リクエストを送信します
    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)
  {
      // 一時停止されたコンテンツを使って会話を続行します
      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 {
  	// 一時停止したレスポンスをそのまま返し、Claude がターンを続行できるようにします
  	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>

`pause_turn`を処理する際は、次の点に注意してください：

* **会話を継続する：** 一時停止されたレスポンスを後続のリクエストでそのまま返し、Claudeがターンを継続できるようにします。
* **ツールの状態を保持する：** 継続リクエストには同じツールを含めてください。一時停止されたターンは、まだ実行されていないツールの`server_tool_use`ブロックで終わることがあり、そのツールが継続リクエストに含まれていない場合、APIはバリデーションエラーを返します。
* **必要に応じて繰り返す：** 継続されたターンが再び一時停止することがあります。各レスポンスの`stop_reason`を確認し、別の停止理由が返されるまで継続してください。その際、他のリトライループと同様に継続回数に上限を設けてください。

その他の`stop_reason`の値と一般的な処理パターンについては、[停止理由とフォールバック](https://platform.claude.com/docs/ja/build-with-claude/handling-stop-reasons)を参照してください。

## 1つのターンでサーバーツールとクライアントツールを混在させる

Claudeは、同じ並列ツール呼び出しのグループ内で、サーバーツールとクライアントツールを呼び出すことができます。たとえば、`web_fetch`とユーザー定義ツールを一緒に呼び出す場合です。クライアントツールとは、コードで実行され`tool_use`ブロックを生成するツールのことで、ユーザー定義のものか、[Bashツール](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/bash-tool)のようなAnthropicスキーマのクライアントツールかは問いません。このような場合、APIはサーバーツールを実行しません。クライアントツールを先に実行できるよう、すぐにレスポンスを返します：

* `stop_reason`は`"pause_turn"`ではなく`"tool_use"`です。
* `content`には`server_tool_use`ブロックとクライアントの`tool_use`ブロックが含まれますが、サーバーツールの結果ブロックは含まれません。その呼び出しはまだ完了していないためです。
* 他のマーカーはありません。レスポンス内に対応する結果ブロックがない`id`を持つ`server_tool_use`ブロックを探すことで、この状態を検出してください。[MCPコネクタ](https://platform.claude.com/docs/ja/agents-and-tools/mcp-connector)からの`mcp_tool_use`ブロックも同じように動作します。同じレスポンス内にすでに結果ブロックがあるサーバーツール呼び出しは完了しており、対応は不要です。

<Note>
  [プログラムによるツール呼び出し](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/programmatic-tool-calling)では、同じ形のレスポンスが異なる意味を持ちます。クライアントの`tool_use`ブロックはClaudeから直接ではなく、`code_execution`ツール内で実行中のコードから生成され、その`caller`フィールドには呼び出し元の`code_execution`ブロックが示されます。そのコードはすでに開始されています。`tool_result`ブロックを待って一時停止しており、それらを送信すると、保留中のツールを開始するのではなく実行が再開されます。`code_execution`ブロック自体の結果ブロックはコードが終了した時点で届き、それには複数回のツール結果のやり取りが必要になる場合があります。フォローアップのユーザーメッセージ自体はどちらの場合も同じです。プログラムによるツール呼び出しでは、そのページに示されているように、レスポンスの`container`フィールドの`id`も返してください。
</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" }
    }
  ]
}
```

ターンを継続するには、クライアントツールを実行し、そのレスポンス内の各`tool_use`ブロックに対して1つずつ、`tool_result`ブロックのみをコンテンツとするユーザーメッセージを送信します。同じ`tools`配列を維持してください。待機中のサーバーツールが定義されていない再開リクエストは、メッセージが``but no `web_fetch` tool was provided``で終わる400エラーで失敗します。

```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"
    }
  ]
}
```

APIは、まだ開いているアシスタントターンに結果を付加し、保留中のサーバーツールを実行し（一時停止されたコード実行の場合は再開し）、その後Claudeに継続させます。Claudeが直接呼び出したサーバーツールの場合、次のレスポンスは前のレスポンスの`server_tool_use`の`id`に対応する結果ブロックで始まり、その後に新たに生成されたコンテンツと新しい`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..."
    }
  ]
}
```

`server_tool_use`ブロックとその結果ブロックは、位置ではなく`tool_use_id`によって対応付けられます。このフローでは、それらは2つの異なるレスポンスで届き、`server_tool_use`ブロックは2番目のレスポンスでは繰り返されません。以降のリクエストでは、他のツール使用のやり取りを蓄積するのと同じように、やり取り全体を順番どおりに`messages`配列に保持してください。つまり、最初のレスポンスを`assistant`メッセージとして、次に`tool_result`のユーザーメッセージ、そして次のレスポンスを別の`assistant`メッセージとして保持します。

<Warning>
  フォローアップのユーザーメッセージには、`tool_result`ブロック以外を含めてはいけません。結果の後にテキストなどのブロックを追加すると、アシスタントターンが終了したことをAPIに伝えることになります。Claudeが直接呼び出したサーバーツールの場合、ターンに未解決のサーバーツール呼び出しが残り、リクエストは400 `invalid_request_error`で失敗します：

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

  結果の前にコンテンツを置いたフォローアップ、クライアントの`tool_use` IDの一部にしか応答していないフォローアップ、または`tool_result`ブロックをまったく含まないフォローアップは、それより前の段階で、[ツール呼び出しの処理](https://platform.claude.com/docs/ja/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.
  ```

  Claudeに追加の入力を与えるには、ターンが完了した後に別のユーザーメッセージとして送信してください。
</Warning>

**`pause_turn`との違い：** [`pause_turn`レスポンス](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/server-tools#the-server-side-loop-and-pause-turn)も、まだ実行されていない`server_tool_use`ブロックで終わることがありますが、クライアントの`tool_use`ブロックを待機状態のまま残すことはないため、アシスタントのコンテンツをそのまま再送信することで継続します。クライアントの`tool_use`ブロックを待機状態のまま残すレスポンスの`stop_reason`が`pause_turn`になることはありません。Claudeがツールを呼び出すために停止した場合、`stop_reason`は`tool_use`であり、レスポンスを再送信するのではなく、クライアントの`tool_result`ブロックを送信することで継続します。どちらの場合も、APIは次のリクエストの開始時に保留中のサーバーツールを実行します。

次の例では、ウェブフェッチとユーザー定義の`run_command`ツールを一緒に有効にし、混在したレスポンスを処理します：

<CodeGroup>
  ```bash cURL
  # "stop_reason" が "tool_use" で、server_tool_use ブロックに対応する
  # 結果ブロックがない場合、その呼び出しは完了していません。クライアントツールを実行し、
  # それらの tool_result ブロックのみを含むユーザーメッセージを1つ追加して、
  # 同じ tools 配列とともに再度 POST してください（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
  # "stop_reason" が "tool_use" で、server_tool_use ブロックに対応する
  # result ブロックがない場合は、クライアントツールを実行し、それらの
  # tool_result ブロックのみを追加した user メッセージで再実行します（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,
          # ここでツールを実行します。この例では固定の文字列を返します。
          "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:
      # このレスポンス内に結果ブロックがない server_tool_use ブロックは未完了です。その結果は後続のレスポンスで届きます。
      # クライアントの tool_result ブロックのみを、同じツールを指定して送り返します。
      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},
          ],
      )
      # web_fetch が延期されていた場合は、このリクエストで実行され、その
      # web_fetch_tool_result が 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,
        // ここでツールを実行します。この例では固定の文字列を返します。
        content: "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux"
      });
    }
  }

  if (response.stop_reason === "tool_use" && toolResults.length > 0) {
    // このレスポンス内に結果ブロックがない server_tool_use ブロックは未完了です。その結果は後続のレスポンスで返されます。
    // 同じツールを指定して、クライアントの tool_result ブロックのみを送り返します。
    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 }
      ]
    });
    // web_fetch が保留されていた場合、このリクエストで実行され、その
    // web_fetch_tool_result が 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,
              // ここでツールを実行します。この例では固定の文字列を返します。
              Content = "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux",
          }));
      }
  }

  if (response.StopReason?.Value() == StopReason.ToolUse && toolResults.Count > 0)
  {
      // このレスポンス内で結果ブロックを持たない server_tool_use ブロックは未完了であり、その結果は後続のレスポンスで届きます。
      // 同じツールを指定して、クライアントの tool_result ブロックのみを送り返します。
      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) }
          ]
      });
      // web_fetch が保留されていた場合、このリクエストで実行され、その
      // web_fetch_tool_result が 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 {
  		// ここでツールを実行します。この例では固定の文字列を返します。
  		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 {
  	// このレスポンス内で結果ブロックを伴わない server_tool_use ブロックは未完了です。その結果は後続のレスポンスで返されます。
  	// クライアントの tool_result ブロックのみを、同じツールを指定して送り返します。
  	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)
  	}
  	// web_fetch が延期された場合、このリクエストで実行され、その
  	// web_fetch_tool_result が 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())
                  // ここでツールを実行します。この例では固定の文字列を返します。
                  .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()) {
          // このレスポンス内で結果ブロックを伴わない server_tool_use ブロックは未完了です。その結果は後続のレスポンスで返されます。
          // クライアントの tool_result ブロックのみを、同じツールを指定して送り返します。
          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());
          // web_fetch が延期されていた場合、このリクエストで実行され、その
          // web_fetch_tool_result が 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,
              // ここでツールを実行します。この例では固定の文字列を返します。
              'content' => 'Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux'
          ];
      }
  }

  if ($response->stopReason === 'tool_use' && count($toolResults) > 0) {
      // このレスポンス内で結果ブロックを伴わない server_tool_use ブロックは未完了であり、その結果は後続のレスポンスで届きます。
      // 同じ tools を指定し、クライアントの tool_result ブロックのみを送り返します。
      $continuation = $client->messages->create(
          maxTokens: 1024,
          messages: [
              $userMessage,
              ['role' => 'assistant', 'content' => $response->content],
              ['role' => 'user', 'content' => $toolResults],
          ],
          model: 'claude-opus-5-5',
          tools: $tools,
      );
      // web_fetch が保留されていた場合、このリクエストで実行され、その
      // web_fetch_tool_result が $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,
      # ここでツールを実行します。この例では固定の文字列を返します。
      content: "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux"
    }
  end

  if response.stop_reason == :tool_use && !tool_results.empty?
    # このレスポンス内に結果ブロックがない server_tool_use ブロックは未完了です。その結果は後続のレスポンスで届きます。
    # クライアントの tool_result ブロックのみを、同じツールを指定して送り返します。
    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 }
      ]
    )
    # web_fetch が保留されていた場合は、このリクエストで実行され、その
    # web_fetch_tool_result が continuation.content の最初のブロックになります。
    puts continuation
  else
    puts response
  end
  ```
</CodeGroup>

このコードは、Claudeが2種類の呼び出しを混在させない場合にも正しく動作します。クライアントの`tool_use`ブロックのみを含むターンは同じ継続パスをたどり、サーバーツール呼び出しのみを含むターンではクライアントの`tool_result`ブロックは不要です。その結果ブロックは通常すでに存在しており、[`pause_turn`レスポンス](https://platform.claude.com/docs/ja/agents-and-tools/tool-use/server-tools#the-server-side-loop-and-pause-turn)のように一時停止された状態で返されたものは、代わりにそのまま再送信します。

## ZDRとallowed\_callers

ウェブ検索（`web_search_20250305`）とウェブフェッチ（`web_fetch_20250910`）の基本バージョンは、[Zero Data Retention（ZDR）](https://platform.claude.com/docs/ja/manage-claude/api-and-data-retention)の対象です。

「dynamic filtering」（動的フィルタリング）を備えた`_20260209`以降のバージョンは、動的フィルタリングが内部でコード実行に依存しているため、デフォルトではZDRの対象**ではありません**。

`_20260209`以降のサーバーツールをZDRで使用するには、ツールに`"allowed_callers": ["direct"]`を設定して動的フィルタリングを無効にします：

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

これにより、ツールは直接呼び出しのみに制限され、内部のコード実行ステップがバイパスされます。

`allowed_callers`は、ツールの呼び出し方法を制御します。Claudeによる直接呼び出し（`"direct"`）、コード実行コンテナ内からの呼び出し（たとえば`"code_execution_20260120"`）、またはその両方です。ウェブツールの`_20260209`バージョンは、デフォルトでコード実行の呼び出し元のみに設定されています。それ以前のバージョンのデフォルトは`["direct"]`です。プログラムによるツール呼び出しをサポートしていないモデルでは、これらのバージョンには`allowed_callers: ["direct"]`が必要です。これがない場合、APIはその設定を求めるバリデーションエラーを返します。

<Note>
  ウェブフェッチをZDR対象の構成で使用している場合でも、Claudeがウェブサイトからコンテンツを取得すると、そのサイトの運営者がURLに渡されたパラメータを保持する可能性があります。
</Note>

## ドメインフィルタリング

ウェブにアクセスするサーバーツールは、Claudeがアクセスできるドメインを制御するための`allowed_domains`および`blocked_domains`パラメータを受け付けます。どちらもツールオブジェクトのフィールドです：

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

ドメインフィルタを使用する場合：

* ドメインにはHTTP/HTTPSスキームを含めないでください（`https://example.com`ではなく`example.com`を使用します）。
* サブドメインは自動的に含まれます（`example.com`は`docs.example.com`をカバーします）。
* 特定のサブドメインを指定すると、結果はそのサブドメインのみに制限されます（`docs.example.com`はそのサブドメインからの結果のみを返し、`example.com`や`api.example.com`からの結果は返しません）。
* ウェブ検索ではサブパスがサポートされており、パス以降の任意の部分に一致します（`example.com/blog`は`example.com/blog/post-1`に一致します）。
* ウェブフェッチはドメインのみで照合します。パスを含むエントリがウェブフェッチのURLに一致することはありません。
* `allowed_domains`または`blocked_domains`のいずれかを使用できますが、同じリクエストで両方を使用することはできません。

**ワイルドカードのサポート：**

* ワイルドカード（`*`）はドメイン自体には使用できず、その後のパス部分でのみ使用できます。
* 有効：`example.com/*`、`example.com/*/articles`
* 無効：`*.example.com`、`ex*.com`

無効なドメイン形式は、リクエスト時に400 `invalid_request_error`で拒否されます。

<Note>
  リクエストレベルのドメイン制限は、Claude Consoleで設定された組織レベルのドメイン制限と組み合わせて機能します。リクエストレベルの`allowed_domains`は、組織レベルの許可リストのサブセットである必要があります。その範囲外のエントリがあると、APIはバリデーションエラーを返します。組織がブロックしているドメインを含むリクエストレベルの許可リストは、競合するエントリを示す`400`エラーで拒否されます。
</Note>

<Warning>
  ドメイン名に含まれるUnicode文字は、「homograph attack」（ホモグラフ攻撃）によってドメインフィルタを回避する可能性があります。`аmazon.com`（キリル文字の`а`を含む）は`amazon.com`と見た目は同じですが、別のドメインです。許可リストとブロックリストにはASCIIのみのドメイン名を使用し、既存のエントリに非ASCII文字が含まれていないか監査してください。
</Warning>

[Claude Managed Agents](https://platform.claude.com/docs/ja/managed-agents/overview)は、エージェントツールセットの`web_search`および`web_fetch`エントリで同じ`allowed_domains`および`blocked_domains`フィールドを使用します。Managed Agentsでは、各リストに含められるエントリは最大64個で、`web_fetch`に指定するドメインにはパスを含めることができず、`max_uses`、`citations`、`cache_control`などのMessages APIツール固有のフィールドは使用できません。完全なルールについては、[ドメインリストのルール](https://platform.claude.com/docs/ja/managed-agents/tools-web-restrictions#domain-list-rules)を参照してください。

Claude Consoleの組織レベルのウェブ検索およびウェブフェッチの設定は、Messages APIリクエストにのみ適用されます。Managed Agentsセッションには適用されず、代わりにエージェントツールセットのツールごとのリストが使用されます。`limited`ネットワーキングを使用するクラウド環境のセッションでは、環境の`allowed_hosts`も`web_search`と`web_fetch`に適用されます。[ネットワーキング](https://platform.claude.com/docs/ja/managed-agents/environments#networking)を参照してください。ツールごとのリストは、`allowed_hosts`が許可するホストの範囲内で、これらのツールをさらに制限します。

## コード実行による動的フィルタリング

ウェブ検索とウェブフェッチの`_20260209`以降のバージョンは、内部でコード実行を使用して検索結果に動的フィルタを適用します。

<Note>
  これらのバージョンでは、`code_execution`ツールを追加する必要はありません。動的フィルタリングが実行されると、APIはリクエストに対してコード実行を自動的にプロビジョニングし、両方のツールが単一の実行コンテナを共有します。コード実行ツールを含める場合は、`code_execution_20260120`以降を使用してください。APIは、これらのウェブツールのバージョンと併用される古いコード実行バージョンを拒否します。
</Note>

## サーバーツールイベントのストリーミング

サーバーツールのイベントは、通常の「server-sent events」（サーバー送信イベント）、すなわちSSEのフローの一部としてストリーミングされます。Claudeが直接呼び出す`server_tool_use`ブロックは、クライアントの`tool_use`ブロックと同様にストリーミングされます。つまり、`content_block_start`イベントの後に`input_json_delta`イベントが続きます。結果ブロックは、デルタなしで単一の`content_block_start`イベントとして完全な形で届きます。

イベントの完全なリファレンスについては、[ストリーミング](https://platform.claude.com/docs/ja/build-with-claude/streaming)を参照してください。ツール固有のイベント名が異なる場合は、個々のツールのページに記載されています。

## バッチリクエスト

すべてのサーバーツールは「batch processing」（バッチ処理）をサポートしています。バッチでは、エージェントループは同期リクエストの場合と同じように実行されますが、ターンごとの反復回数の上限がより高くなります。ループがその上限に達すると、レスポンスは`stop_reason: "pause_turn"`で終了します。返されたコンテンツを使ってフォローアップリクエストを送信することで継続できます。詳細については、[サーバーツールとエージェントループ](https://platform.claude.com/docs/ja/build-with-claude/batch-processing#server-tools-and-the-agentic-loop)を参照してください。

一般的なバッチワークロードには、ウェブからの情報によるデータセットの拡充、大量のドキュメントと最新の情報源との照合、多数のファイルに対する分析コードの実行などがあります。

## 次のステップ

<CardGroup cols={2}>
  <Card title="ツール使用のトラブルシューティング" icon="wrench" href="https://platform.claude.com/docs/ja/agents-and-tools/tool-use/troubleshooting-tool-use">
    症状から修正方法を導く診断表を使って、最も一般的なツール使用のエラーを修正します。
  </Card>

  <Card title="ウェブ検索ツール" icon="magnifying-glass" href="https://platform.claude.com/docs/ja/agents-and-tools/tool-use/web-search-tool">
    ウェブを検索し、結果を引用します。
  </Card>

  <Card title="ウェブフェッチツール" icon="download" href="https://platform.claude.com/docs/ja/agents-and-tools/tool-use/web-fetch-tool">
    特定のURLからコンテンツを取得して読み込み、ライブのウェブコンテンツでClaudeのコンテキストを拡張します。
  </Card>

  <Card title="コード実行ツール" icon="terminal" href="https://platform.claude.com/docs/ja/agents-and-tools/tool-use/code-execution-tool">
    サンドボックス化されたコンテナでPythonとbashのコードを実行し、データの分析、ファイルの生成、ソリューションの反復改善を行います。
  </Card>

  <Card title="ツール検索ツール" icon="compass" href="https://platform.claude.com/docs/ja/agents-and-tools/tool-use/tool-search-tool">
    必要に応じてツールを検出して読み込みます。
  </Card>
</CardGroup>
