Las herramientas ejecutadas en el servidor comparten estas mecánicas: el bloque server_tool_use, la continuación con pause_turn, los turnos que mezclan herramientas de servidor y cliente, la elegibilidad para "Zero Data Retention" (retención cero de datos), o ZDR, y el filtrado de dominios. Para herramientas individuales, consulta la referencia de herramientas.
El bloque server_tool_use aparece en la respuesta de Claude cuando se ejecuta una herramienta del lado del servidor. Su campo id usa el prefijo srvtoolu_ para distinguirlo de las llamadas a herramientas de cliente:
{
"type": "server_tool_use",
"id": "srvtoolu_01A2B3C4D5E6F7G8H9",
"name": "web_search",
"input": { "query": "latest quantum computing breakthroughs" }
}La API ejecuta la herramienta internamente. Ves la llamada y su resultado en la respuesta, pero no gestionas la ejecución. A diferencia de los bloques tool_use de cliente, no necesitas responder con un tool_result. El bloque de resultado de la herramienta (por ejemplo, web_search_tool_result para búsqueda web) sigue al bloque server_tool_use en el mismo turno del asistente, emparejado por tool_use_id. Si Claude llama a una de tus herramientas de cliente al mismo tiempo, el bloque server_tool_use aparece sin su resultado, y la respuesta termina con stop_reason: "tool_use". La API ejecuta la herramienta cuando devuelves los bloques tool_result de cliente en tu siguiente solicitud.
Al usar herramientas de servidor como la búsqueda web, la API ejecuta las llamadas a herramientas en un bucle agéntico del lado del servidor. En un turno de larga duración, la API podría pausar ese bucle y devolver un stop reason pause_turn.
Así es como se maneja el stop reason pause_turn:
client = anthropic.Anthropic()
# Solicitud inicial con búsqueda web
response = client.messages.create(
model="claude-opus-4-8",
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 si la respuesta tiene stop_reason pause_turn
if response.stop_reason == "pause_turn":
# Continúa la conversación con el contenido pausado
messages = [
{
"role": "user",
"content": "Search for comprehensive information about quantum computing breakthroughs in 2025",
},
{"role": "assistant", "content": response.content},
]
# Envía la solicitud de continuación
continuation = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
messages=messages,
tools=[{"type": "web_search_20250305", "name": "web_search", "max_uses": 10}],
)
print(continuation)
else:
print(response)Al manejar pause_turn:
server_tool_use cuya herramienta aún no se ha ejecutado, y la API devuelve un error de validación si esa herramienta falta en la continuación.stop_reason en cada respuesta y continúa hasta obtener un stop reason diferente, limitando el número de continuaciones como lo harías con cualquier bucle de reintentos.Para los otros valores de stop_reason y patrones generales de manejo, consulta Stop reasons y fallback.
Claude puede llamar a una herramienta de servidor y a una herramienta de cliente en el mismo grupo de llamadas paralelas a herramientas, por ejemplo, web_fetch junto con una herramienta definida por el usuario. Una herramienta de cliente es cualquier herramienta que tu código ejecuta y que produce un bloque tool_use, ya sea definida por el usuario o una herramienta de cliente con esquema de Anthropic como la herramienta Bash. Cuando eso sucede, la API no ejecuta la herramienta de servidor. Devuelve la respuesta de inmediato para que puedas ejecutar primero la herramienta de cliente:
stop_reason es "tool_use", no "pause_turn".content contiene el bloque server_tool_use y el bloque tool_use de cliente, pero ningún bloque de resultado para la herramienta de servidor: esa llamada no ha terminado.server_tool_use cuyo id no tenga un bloque de resultado correspondiente en la respuesta. Un bloque mcp_tool_use del conector MCP se comporta de la misma manera. Las llamadas a herramientas de servidor que ya tienen su bloque de resultado en la misma respuesta están completas y no necesitan nada de tu parte.Con la llamada programática a herramientas, la misma forma de respuesta significa algo diferente. El bloque tool_use de cliente proviene de código que se está ejecutando en la herramienta code_execution en lugar de directamente de Claude, y su campo caller nombra el bloque code_execution que lo llamó. Ese código ya ha comenzado: está pausado esperando tus bloques tool_result, y enviarlos reanuda la ejecución en lugar de iniciar una herramienta diferida. El bloque de resultado propio del bloque code_execution llega una vez que el código termina, lo cual puede requerir más de una ronda de resultados de herramientas. El mensaje de usuario de seguimiento en sí es el mismo en ambos casos; con la llamada programática a herramientas, también devuelve el id del campo container de la respuesta, como muestra esa página.
{
"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 el turno, ejecuta las herramientas de cliente y envía un mensaje de usuario cuyo contenido sea únicamente los bloques tool_result, uno por cada bloque tool_use de esa respuesta. Mantén el mismo array tools: una solicitud de reanudación que ya no define la herramienta de servidor en espera falla con un error 400 cuyo mensaje termina en but no `web_fetch` tool was provided.
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01PjgRJLbXrXEMZwDNYLnBqk",
"content": "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux"
}
]
}La API adjunta tus resultados al turno del asistente aún abierto, ejecuta la herramienta de servidor diferida (en el caso de ejecución de código pausada, la reanuda) y luego permite que Claude continúe. Para una herramienta de servidor que Claude llamó directamente, la siguiente respuesta comienza con el bloque de resultado que responde al id del server_tool_use de la respuesta anterior, seguido del contenido recién generado y un nuevo stop_reason:
{
"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 bloque server_tool_use y su bloque de resultado se emparejan por tool_use_id, no por posición: en este flujo llegan en dos respuestas diferentes, y el bloque server_tool_use no se repite en la segunda. En solicitudes posteriores, mantén todo el intercambio en tu array messages en orden: la primera respuesta como un mensaje assistant, el mensaje de usuario con tool_result, y luego la siguiente respuesta como otro mensaje assistant, de la misma manera en que acumulas cualquier otro intercambio de uso de herramientas.
El mensaje de usuario de seguimiento no debe contener nada excepto bloques tool_result. Un bloque añadido después de los resultados, como texto, le indica a la API que el turno del asistente ha terminado. Para una herramienta de servidor que Claude llamó directamente, eso deja el turno con una llamada a herramienta de servidor sin resolver, y la solicitud falla con un error 400 invalid_request_error:
`web_fetch` tool use with id `srvtoolu_01HxbWnMRmbWyMfUtJKC45rA` was found without a corresponding `web_fetch_tool_result` blockUn seguimiento que coloca contenido antes de los resultados, responde solo a algunos de los IDs de tool_use de cliente, o no contiene ningún bloque tool_result falla antes, con el error de herramienta de cliente descrito en Manejar llamadas a herramientas:
`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 darle a Claude más información de entrada, envíala como un mensaje de usuario separado después de que el turno se complete.
En qué se diferencia esto de pause_turn: Una respuesta pause_turn también puede terminar con un bloque server_tool_use que no se ha ejecutado, pero nunca deja un bloque tool_use de cliente esperando por ti, así que la continúas reenviando el contenido del asistente tal cual. Una respuesta que deja un bloque tool_use de cliente esperando por ti nunca tiene un stop_reason de pause_turn: cuando Claude se detiene para llamar a tus herramientas, stop_reason es tool_use, y la continúas enviando los bloques tool_result de cliente en lugar de reenviar la respuesta. En ambos casos la API ejecuta la herramienta de servidor pendiente al inicio de la siguiente solicitud.
El siguiente ejemplo habilita web fetch junto con una herramienta run_command definida por el usuario y maneja la respuesta mixta:
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-4-8", max_tokens=1024, tools=tools, messages=messages
)
tool_results = [
{
"type": "tool_result",
"tool_use_id": block.id,
# Ejecuta tu herramienta aquí. Este ejemplo devuelve una cadena fija.
"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 bloque server_tool_use sin bloque de resultado en esta respuesta no ha terminado; su resultado llega en una respuesta posterior.
# Devuelve solo los bloques tool_result del cliente, con las mismas herramientas.
continuation = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
tools=tools,
messages=[
*messages,
{"role": "assistant", "content": response.content},
{"role": "user", "content": tool_results},
],
)
# Si un web_fetch quedó diferido, se ejecuta en esta solicitud y su
# web_fetch_tool_result es el primer bloque de continuation.content.
print(continuation)
else:
print(response)Este código también es correcto cuando Claude no mezcla los dos tipos de llamada. Un turno con solo bloques tool_use de cliente sigue la misma ruta de continuación, y un turno con solo llamadas a herramientas de servidor no necesita bloques tool_result de cliente de tu parte: sus bloques de resultado normalmente ya están presentes, y uno que regresa suspendido, como una respuesta pause_turn, se reenvía tal cual en su lugar.
Las versiones básicas de búsqueda web (web_search_20250305) y web fetch (web_fetch_20250910) son elegibles para Zero Data Retention (ZDR).
Las versiones _20260209 y posteriores con filtrado dinámico no son elegibles para ZDR de forma predeterminada porque el filtrado dinámico depende internamente de la ejecución de código.
Para usar una herramienta de servidor _20260209 o posterior con ZDR, deshabilita el filtrado dinámico estableciendo "allowed_callers": ["direct"] en la herramienta:
{
"type": "web_search_20260209",
"name": "web_search",
"allowed_callers": ["direct"]
}Esto restringe la herramienta a invocación directa únicamente, omitiendo el paso interno de ejecución de código.
allowed_callers controla cómo se puede invocar una herramienta: directamente por Claude ("direct"), desde dentro de un contenedor de ejecución de código (por ejemplo, "code_execution_20260120"), o ambos. Las versiones _20260209 de las herramientas web tienen como valor predeterminado únicamente el caller de ejecución de código; las versiones anteriores tienen como valor predeterminado ["direct"]. En modelos que no admiten la llamada programática a herramientas, estas versiones requieren allowed_callers: ["direct"]; sin ello, la API devuelve un error de validación que indica que debes establecerlo.
Incluso cuando web fetch se usa en una configuración elegible para ZDR, los editores de sitios web pueden retener cualquier parámetro pasado a la URL si Claude obtiene contenido de su sitio.
Las herramientas de servidor que acceden a la web aceptan los parámetros allowed_domains y blocked_domains para controlar a qué dominios puede acceder Claude. Ambos son campos del objeto de herramienta:
{
"type": "web_search_20250305",
"name": "web_search",
"allowed_domains": ["example.com", "docs.python.org"]
}Al usar filtros de dominio:
example.com en lugar de https://example.com).example.com cubre docs.example.com).docs.example.com devuelve solo resultados de ese subdominio, no de example.com ni de api.example.com).example.com/blog coincide con example.com/blog/post-1).allowed_domains o blocked_domains, pero no ambos en la misma solicitud.Compatibilidad con comodines:
*) no están permitidos en el dominio en sí, solo en la ruta después de él.example.com/*, example.com/*/articles*.example.com, ex*.comLos formatos de dominio inválidos se rechazan en el momento de la solicitud con un error 400 invalid_request_error.
Las restricciones de dominio a nivel de solicitud funcionan junto con cualquier restricción de dominio a nivel de organización configurada en Claude Console. Los allowed_domains a nivel de solicitud deben ser un subconjunto de la lista permitida a nivel de organización; las entradas fuera de ella hacen que la API devuelva un error de validación. Los dominios que tu organización bloquea se eliminan de una lista permitida a nivel de solicitud en lugar de devolver un error.
Los caracteres Unicode en nombres de dominio pueden eludir los filtros de dominio mediante ataques homógrafos: аmazon.com (con una а cirílica) se ve idéntico a amazon.com pero es un dominio diferente. Usa nombres de dominio solo ASCII en las listas de permitidos y bloqueados, y audita las entradas existentes en busca de caracteres no ASCII.
Las versiones _20260209 y posteriores de búsqueda web y web fetch usan ejecución de código internamente para aplicar filtros dinámicos a los resultados de búsqueda.
No necesitas añadir una herramienta code_execution para estas versiones: cuando se ejecuta el filtrado dinámico, la API aprovisiona la ejecución de código para la solicitud automáticamente, y ambas herramientas comparten un único contenedor de ejecución. Si incluyes una, usa code_execution_20260120 o posterior; la API rechaza versiones anteriores de ejecución de código junto con estas versiones de herramientas web.
Los eventos de herramientas de servidor se transmiten como parte del flujo normal de "server-sent events" (eventos enviados por el servidor), o SSE. Un bloque server_tool_use que Claude llama directamente se transmite como un bloque tool_use de cliente: un evento content_block_start seguido de eventos input_json_delta. El bloque de resultado llega completo en un único evento content_block_start, sin deltas.
Consulta Streaming para la referencia completa de eventos. Las páginas de herramientas individuales documentan los nombres de eventos específicos de cada herramienta cuando difieren.
Todas las herramientas de servidor admiten el procesamiento por lotes. En un lote, el bucle agéntico se ejecuta igual que en las solicitudes síncronas, con un límite de iteraciones por turno más alto. Si el bucle alcanza ese límite, la respuesta termina con stop_reason: "pause_turn"; puedes continuarla enviando una solicitud de seguimiento con el contenido devuelto. Consulta Herramientas de servidor y el bucle agéntico para más detalles.
Las cargas de trabajo por lotes comunes incluyen enriquecer un conjunto de datos con información de la web, verificar un gran conjunto de documentos contra fuentes actuales y ejecutar código de análisis sobre muchos archivos.
Corrige los errores más comunes de uso de herramientas con tablas de diagnóstico de síntoma a solución.
Busca en la web y cita resultados.
Obtén y lee contenido de URLs específicas para aumentar el contexto de Claude con contenido web en vivo.
Ejecuta código Python y bash en un contenedor aislado para analizar datos, generar archivos e iterar sobre soluciones.
Descubre y carga herramientas bajo demanda.
Was this page helpful?