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
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","audio","resource"o"resource_link". 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.
Las anotaciones son metadatos, no aplicación. Una herramienta marcada como
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.
Para eliminar un integrado completamente, omítalo de
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
Un error del controlador no detiene el bucle del agente. El servidor MCP en proceso del SDK captura excepciones no capturadas y las devuelve como resultados de error, por lo que la forma en que reporta un error determina qué lee Claude, no si la consulta falla:
En ambos casos Claude puede reintentar, intentar una herramienta diferente o explicar el fallo. Capture errores usted mismo cuando el mensaje de excepción sin procesar no sea suficiente para que Claude actúe.
El ejemplo abajo captura dos tipos de fallos dentro del controlador y compone el mensaje de error que Claude lee. Un estado HTTP no 200 se captura de la respuesta y se devuelve como un resultado de error. Un error de red o JSON inválido se captura por el
try/except (Python) o try/catch (TypeScript) circundante y también se devuelve como un resultado de error. En ambos casos Claude recibe un mensaje que describe el fallo en lugar de una cadena de excepción sin procesar.
Devolver imágenes y recursos
El arraycontent en un resultado de herramienta acepta bloques text, image, audio, resource y resource_link. Puede mezclarlos en la misma respuesta. En TypeScript, los bloques de audio se guardan en disco y Claude recibe un bloque de texto con la ruta del archivo guardado; en Python, el SDK elimina los bloques de audio del resultado de la herramienta y registra una advertencia. Los bloques de enlace de recurso se convierten en un bloque de texto que contiene el nombre del enlace, el URI y la descripción.
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.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.
Este ejemplo muestra un bloque de recurso devuelto desde dentro de un controlador de herramienta. El URI
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.