query y controlar a qué herramientas puede acceder Claude. También cubre manejo de errores, anotaciones de herramientas y devolución de contenido no textual como imágenes.
Referencia rápida
| Si desea… | Haga esto |
|---|---|
| Definir una herramienta | Use @tool (Python) o tool() (TypeScript) con un nombre, descripción, esquema y controlador. Vea Crear una herramienta personalizada. |
| Registrar una herramienta con Claude | Envuelva en create_sdk_mcp_server / createSdkMcpServer y pase a mcpServers en query(). Vea Llamar a una herramienta personalizada. |
| Preaprobación de una herramienta | Agregue a sus herramientas permitidas. Vea Configurar herramientas permitidas. |
| Eliminar una herramienta integrada del contexto de Claude | Pase un array tools listando solo los integrados que desea. Vea Configurar herramientas permitidas. |
| Permitir que Claude llame herramientas en paralelo | Establezca readOnlyHint: true en herramientas sin efectos secundarios. Vea Agregar anotaciones de herramientas. |
| Manejar errores sin detener el bucle | Devuelva isError: true en lugar de lanzar una excepción. Vea Manejar errores. |
| Devolver imágenes o archivos | Use bloques image o resource en el array de contenido. Vea Devolver imágenes y recursos. |
| Devolver un resultado JSON legible por máquina | Establezca structuredContent en el resultado. Vea Devolver datos estructurados. |
| Escalar a muchas herramientas | Use búsqueda de herramientas para cargar herramientas bajo demanda. |
Crear una herramienta personalizada
Una herramienta se define por cuatro partes, pasadas como argumentos al ayudantetool() en TypeScript o al decorador @tool en Python:
- Nombre: un identificador único que Claude usa para llamar a la herramienta.
- Descripción: qué hace la herramienta. Claude lee esto para decidir cuándo llamarla.
- Esquema de entrada: los argumentos que Claude debe proporcionar. En TypeScript esto es siempre un esquema Zod, y los
argsdel controlador se tipan automáticamente desde él. En Python esto es un diccionario que mapea nombres a tipos, como{"latitude": float}, que el SDK convierte a JSON Schema para usted. El decorador de Python también acepta un diccionario completo de JSON Schema directamente cuando necesita enumeraciones, rangos, campos opcionales u objetos anidados. - Controlador: la función asincrónica que se ejecuta cuando Claude llama a la herramienta. Recibe los argumentos validados y debe devolver un objeto con:
content(requerido): un array de bloques de resultado, cada uno con untypede"text","image"o"resource". Vea Devolver imágenes y recursos para bloques no textuales.structuredContent(opcional): un objeto JSON que contiene el resultado como datos legibles por máquina, devuelto junto acontent. Vea Devolver datos estructurados.isError(opcional): establezca entruepara señalar un fallo de herramienta para que Claude pueda reaccionar a él. Vea Manejar errores.
createSdkMcpServer (TypeScript) o create_sdk_mcp_server (Python). El servidor se ejecuta en proceso dentro de su aplicación, no como un proceso separado.
Ejemplo de herramienta meteorológica
Este ejemplo define una herramientaget_temperature y la envuelve en un servidor MCP. Solo configura la herramienta; para pasarla a query y ejecutarla, vea Llamar a una herramienta personalizada abajo.
tool() o la referencia de Python @tool para detalles completos de parámetros, incluyendo formatos de entrada JSON Schema y estructura de valor de retorno.
Llamar a una herramienta personalizada
Pase el servidor MCP que creó aquery a través de la opción mcpServers. La clave en mcpServers se convierte en el segmento {server_name} en el nombre completamente calificado de cada herramienta: mcp__{server_name}__{tool_name}. Liste ese nombre en allowedTools para que la herramienta se ejecute sin un aviso de permiso.
Estos fragmentos reutilizan el weatherServer del ejemplo anterior para preguntarle a Claude cuál es el clima en una ubicación específica.
Agregar más herramientas
Un servidor contiene tantas herramientas como liste en su arraytools. Con más de una herramienta en un servidor, puede listar cada una en allowedTools individualmente o usar el comodín mcp__weather__* para cubrir cada herramienta que el servidor expone.
El ejemplo abajo agrega una segunda herramienta, get_precipitation_chance, al weatherServer del ejemplo de herramienta meteorológica y lo reconstruye con ambas herramientas en el array.
Agregar anotaciones de herramientas
Las anotaciones de herramientas son metadatos opcionales que describen cómo se comporta una herramienta. Páselas como el quinto argumento al ayudantetool() en TypeScript o a través del argumento de palabra clave annotations para el decorador @tool en Python. Todos los campos de sugerencia son booleanos.
| Campo | Predeterminado | Significado |
|---|---|---|
readOnlyHint | false | La herramienta no modifica su entorno. Controla si la herramienta puede ser llamada en paralelo con otras herramientas de solo lectura. |
destructiveHint | true | La herramienta puede realizar actualizaciones destructivas. Solo informativo. |
idempotentHint | false | Las llamadas repetidas con los mismos argumentos no tienen efecto adicional. Solo informativo. |
openWorldHint | true | La herramienta alcanza sistemas fuera de su proceso. Solo informativo. |
readOnlyHint: true aún puede escribir en disco si eso es lo que hace el controlador. Mantenga la anotación precisa con respecto al controlador.
Este ejemplo agrega readOnlyHint a la herramienta get_temperature del ejemplo de herramienta meteorológica.
ToolAnnotations en la referencia de TypeScript o Python.
Controlar el acceso a herramientas
El ejemplo de herramienta meteorológica registró un servidor y listó herramientas enallowedTools. Esta sección cubre cómo se construyen los nombres de herramientas y cómo limitar el acceso cuando tiene múltiples herramientas o desea restringir integrados.
Formato de nombre de herramienta
Cuando las herramientas MCP se exponen a Claude, sus nombres siguen un formato específico:- Patrón:
mcp__{server_name}__{tool_name} - Ejemplo: Una herramienta nombrada
get_temperatureen servidorweatherse convierte enmcp__weather__get_temperature
Configurar herramientas permitidas
La opcióntools y las listas permitidas/no permitidas afectan dos capas: disponibilidad, que controla si una herramienta aparece en el contexto de Claude, y permiso, que controla si una llamada se aprueba una vez que Claude intenta hacerla. tools y las entradas de disallowedTools con nombre simple cambian la disponibilidad. allowedTools y las reglas de disallowedTools con alcance cambian solo el permiso.
| Opción | Capa | Efecto |
|---|---|---|
tools: ["Read", "Grep"] | Disponibilidad | Solo los integrados listados están en el contexto de Claude. Los integrados no listados se eliminan. Las herramientas MCP no se ven afectadas. |
tools: [] | Disponibilidad | Todos los integrados se eliminan. Claude solo puede usar sus herramientas MCP. |
| herramientas permitidas | Permiso | Las herramientas listadas se ejecutan sin un aviso de permiso. Las herramientas no listadas permanecen disponibles; las llamadas pasan por el flujo de permiso. |
| herramientas no permitidas | Ambas | Un nombre de herramienta simple como "Bash" elimina la herramienta del contexto de Claude, lo mismo que omitirla de tools. Una regla con alcance como "Bash(rm *)" deja la herramienta en contexto y deniega solo las llamadas coincidentes. |
tools o liste su nombre simple en disallowedTools (Python: disallowed_tools); ambos mantienen la herramienta fuera del contexto para que Claude nunca la intente. Una regla de disallowedTools con alcance bloquea las llamadas coincidentes pero deja la herramienta visible, por lo que Claude puede desperdiciar un turno intentándola. Vea Configurar permisos para el orden de evaluación completo.
Manejar errores
Cómo su controlador reporta errores determina si el bucle del agente continúa o se detiene:| Qué sucede | Resultado |
|---|---|
| El controlador lanza una excepción no capturada | El bucle del agente se detiene. Claude nunca ve el error, y la llamada query falla. |
El controlador captura el error y devuelve isError: true (TS) / "is_error": True (Python) | El bucle del agente continúa. Claude ve el error como datos y puede reintentar, intentar una herramienta diferente o explicar el fallo. |
try/except (Python) o try/catch (TypeScript) circundante y también se devuelve como un resultado de error. En ambos casos el controlador devuelve normalmente y el bucle del agente continúa.
Devolver imágenes y recursos
El arraycontent en un resultado de herramienta acepta bloques text, image y resource. Puede mezclarlos en la misma respuesta.
Imágenes
Un bloque de imagen lleva los bytes de imagen en línea, codificados como base64. No hay campo de URL. Para devolver una imagen que vive en una URL, búsquela en el controlador, lea los bytes de respuesta y codifíquelos en base64 antes de devolver. El resultado se procesa como entrada visual.| Campo | Tipo | Notas |
|---|---|---|
type | "image" | |
data | string | Bytes codificados en base64. Solo base64 sin procesar, sin prefijo data:image/...;base64, |
mimeType | string | Requerido. Por ejemplo image/png, image/jpeg, image/webp, image/gif |
Recursos
Un bloque de recurso incrusta un contenido identificado por un URI. El URI es una etiqueta para que Claude la referencie; el contenido real va en el campotext o blob del bloque. Use esto cuando su herramienta produce algo que tiene sentido direccionar por nombre más tarde, como un archivo generado o un registro de un sistema externo.
| Campo | Tipo | Notas |
|---|---|---|
type | "resource" | |
resource.uri | string | Identificador para el contenido. Cualquier esquema de URI |
resource.text | string | El contenido, si es texto. Proporcione esto o blob, no ambos |
resource.blob | string | El contenido codificado en base64, si es binario |
resource.mimeType | string | Opcional |
file:///tmp/report.md es una etiqueta que Claude puede referenciar más tarde; el SDK no lee desde esa ruta.
CallToolResult. Vea la especificación MCP para la definición completa.
Devolver datos estructurados
structuredContent es un objeto JSON opcional en el resultado, separado del array content. Úselo para devolver valores sin procesar que Claude pueda leer como campos exactos en lugar de analizarlos de una cadena de texto o imagen.
Cuando structuredContent se establece, Claude recibe el JSON más cualquier bloque de imagen o recurso de content. Los bloques de texto en content no se reenvían, ya que se asume que duplican los datos estructurados. El ejemplo abajo renderiza un gráfico como un bloque de imagen y devuelve los puntos de datos detrás de él en structuredContent del mismo controlador.
TypeScript
El decorador
@tool de Python reenvía solo content e is_error del diccionario de retorno del controlador. Para devolver structuredContent desde Python, ejecute un servidor MCP independiente en lugar de un servidor SDK en proceso.Ejemplo: convertidor de unidades
Esta herramienta convierte valores entre unidades de longitud, temperatura y peso. Un usuario puede preguntar “convertir 100 kilómetros a millas” o “¿cuál es 72°F en Celsius?” y Claude elige el tipo de unidad correcto y las unidades de la solicitud. Demuestra dos patrones:- Esquemas de enumeración:
unit_typeestá restringido a un conjunto fijo de valores. En TypeScript, usez.enum(). En Python, el esquema dict no admite enumeraciones, por lo que se requiere el diccionario JSON Schema completo. - Manejo de entrada no admitida: cuando no se encuentra un par de conversión, el controlador devuelve
isError: truepara que Claude pueda decirle al usuario qué salió mal en lugar de tratar un fallo como un resultado normal.
query de la misma manera que el ejemplo meteorológico. Este ejemplo envía tres indicaciones diferentes en un bucle para mostrar la misma herramienta manejando diferentes tipos de unidades. Para cada respuesta, inspecciona objetos AssistantMessage (que contienen las llamadas de herramienta que Claude hizo durante ese turno) e imprime cada ToolUseBlock antes de imprimir el texto final de ResultMessage. Esto le permite ver cuándo Claude está usando la herramienta versus respondiendo desde su propio conocimiento.
Próximos pasos
Las herramientas personalizadas envuelven funciones asincrónicas en una interfaz estándar. Puede mezclar los patrones en esta página en el mismo servidor: un único servidor puede contener una herramienta de base de datos, una herramienta de puerta de enlace de API y un renderizador de imágenes uno al lado del otro. Desde aquí:- Si su servidor crece a docenas de herramientas, vea búsqueda de herramientas para diferir la carga hasta que Claude las necesite.
- Para conectarse a servidores MCP externos (sistema de archivos, GitHub, Slack) en lugar de construir los suyos propios, vea Conectar servidores MCP.
- Para controlar qué herramientas se ejecutan automáticamente versus requerir aprobación, vea Configurar permisos.