createTool()
La fonction createTool() permet de définir des tools personnalisés que vos agents Mastra peuvent exécuter. Les tools étendent les capacités d’un agent en lui permettant d’interagir avec des systèmes externes ou d’effectuer des calculs. Ils peuvent également accéder à des données spécifiques.
Exemple d’utilisationLien direct vers Exemple d’utilisation
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'
export const weatherTool = createTool({
id: 'weather-tool',
description: 'Get the current weather for a location',
inputSchema: z.object({
location: z.string(),
}),
outputSchema: z.object({
location: z.string(),
temperatureCelsius: z.number(),
conditions: z.string(),
}),
execute: async ({ location }) => {
return {
location,
temperatureCelsius: 21,
conditions: 'sunny',
}
},
})
Le premier paramètre de execute est la valeur validée issue de inputSchema. Déstructurez les champs du schéma directement dans la signature de la fonction, comme avec { location }. Le second paramètre, facultatif, contient le contexte d’exécution.
ParamètresLien direct vers Paramètres
id:
description:
inputSchema?:
execute du tool.outputSchema?:
execute du tool.strict?:
toModelOutput?:
execute du tool avant de la renvoyer au modèle. Utilisez-la pour fournir au modèle des sorties au format text, json ou content (y compris des parties multimodales telles que des images ou des fichiers), tout en conservant la sortie brute complète dans le code de votre application.transform?:
display et transcript pour des phases telles que input, inputDelta, output, error, approval, suspend et resume.suspendSchema?:
suspend(). Cette charge utile est renvoyée au client lorsque le tool suspend son exécution.resumeSchema?:
resumeData lors de la reprise du tool. L’agent l’utilise pour extraire les données des messages utilisateur lorsque autoResumeSuspendedTools est activé.requireApproval?:
tool-call-approval, puis se met en pause jusqu’à l’approbation ou au refus.mcp?:
annotations (des indications sur le comportement du tool telles que title, readOnlyHint, destructiveHint, idempotentHint, openWorldHint) et _meta (des métadonnées arbitraires transmises aux clients MCP).requestContextSchema?:
providerOptions?:
anthropic ou openai, et les valeurs sont des objets de configuration propres à chaque provider.inputExamples?:
background?:
execute?:
execute, mais le type autorise son omission pour les définitions de tools exécutées ou adaptées ailleurs. Elle reçoit deux paramètres : les données d’entrée validées selon inputSchema (premier paramètre) et un objet de contexte d’exécution (second paramètre) contenant requestContext, abortSignal et d’autres métadonnées d’exécution.input:
context?:
requestContext?:
abortSignal?:
agent?:
workflow?:
mcp?:
observe:
span exécute directement la fonction et log ne fait rien.onInputStart?:
(options: ToolCallOptions) => void | PromiseLike<void>.onInputDelta?:
({ inputTextDelta, ...options }: { inputTextDelta: string } & ToolCallOptions) => void | PromiseLike<void>.onInputAvailable?:
({ input, ...options }: { input: TSchemaIn } & ToolCallOptions) => void | PromiseLike<void>.onOutput?:
({ output, toolName, ...options }: { output: TSchemaOut; toolName: string } & Omit<ToolCallOptions, 'messages'>) => void | PromiseLike<void>.Les champs renseignés à l’exécution, tels que mastra et mcpMetadata, figurent dans les types sources, mais sont définis par Mastra ou par les adaptateurs MCP. Vous n’avez pas besoin de les configurer pour une utilisation ordinaire de createTool().
Valeur de retourLien direct vers Valeur de retour
La fonction createTool() renvoie un objet Tool.
Tool:
Définir des schémasLien direct vers Définir des schémas
Vous pouvez définir les inputSchema et outputSchema du tool avec toute bibliothèque compatible avec Standard JSON Schema. Cela inclut des bibliothèques telles que Zod, Valibot et ArkType.
- Zod
- Valibot
- ArkType
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'
export const weatherTool = createTool({
id: 'weather-tool',
description: 'Fetches weather for a location',
inputSchema: z.object({
location: z.string(),
}),
outputSchema: z.object({
location: z.string(),
temperatureCelsius: z.number(),
conditions: z.string(),
}),
execute: async ({ location }) => {
return { location, temperatureCelsius: 21, conditions: 'sunny' }
},
})
import { createTool } from '@mastra/core/tools'
import * as v from 'valibot'
import { toStandardJsonSchema } from '@valibot/to-json-schema'
export const weatherTool = createTool({
id: 'weather-tool',
description: 'Fetches weather for a location',
inputSchema: toStandardJsonSchema(
v.object({
location: v.string(),
}),
),
outputSchema: toStandardJsonSchema(
v.object({
location: v.string(),
temperatureCelsius: v.number(),
conditions: v.string(),
}),
),
execute: async ({ location }) => {
return { location, temperatureCelsius: 21, conditions: 'sunny' }
},
})
import { createTool } from '@mastra/core/tools'
import { type } from 'arktype'
export const weatherTool = createTool({
id: 'weather-tool',
description: 'Fetches weather for a location',
inputSchema: type({
location: 'string',
}),
outputSchema: type({
location: 'string',
temperatureCelsius: 'number',
conditions: 'string',
}),
execute: async ({ location }) => {
return { location, temperatureCelsius: 21, conditions: 'sunny' }
},
})
Exemple avec des entrées de tool strictesLien direct vers Exemple avec des entrées de tool strictes
Définissez strict: true lorsque vous souhaitez que Mastra demande aux providers de modèles compatibles de générer des arguments de tool correspondant exactement au schéma du tool.
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'
export const weatherTool = createTool({
id: 'weather-tool',
description: 'Get the current weather for a location',
strict: true,
inputSchema: z.object({
location: z.string(),
}),
outputSchema: z.object({
location: z.string(),
temperatureCelsius: z.number(),
conditions: z.string(),
}),
execute: async ({ location }) => {
return {
location,
temperatureCelsius: 21,
conditions: 'sunny',
}
},
})
Mastra transmet strict: true aux adaptateurs de modèle qui prennent en charge les appels de tool stricts. Sur les adaptateurs qui ne les prennent pas en charge, Mastra ignore cette option.
Exemple avec toModelOutputLien direct vers example-with-tomodeloutput
Utilisez toModelOutput lorsque votre tool doit renvoyer des données internes riches à votre application, tandis que le modèle doit recevoir une valeur simplifiée ou du contenu multimodal.
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'
export const weatherTool = createTool({
id: 'weather-tool',
description: 'Get the current weather for a location',
inputSchema: z.object({
location: z.string(),
}),
outputSchema: z.object({
location: z.string(),
temperatureCelsius: z.number(),
conditions: z.string(),
radarImageUrl: z.string().url(),
}),
execute: async ({ location }) => ({
location,
temperatureCelsius: 21,
conditions: 'sunny',
radarImageUrl: 'https://example.com/radar/seattle.png',
}),
toModelOutput: output => {
return {
type: 'content',
value: [
{
type: 'text',
text: `${output.location}: ${output.temperatureCelsius}°C and ${output.conditions}`,
},
{ type: 'image-url', url: output.radarImageUrl },
],
}
},
})
Le tool renvoie toujours le résultat complet de execute à votre application, tandis que le modèle reçoit la valeur transformée par toModelOutput.
toModelOutput peut renvoyer :
type: 'text'type: 'json'type: 'content'avec des parties telles quetext,image-url,image-data,file-url,file-data,file-id,image-file-idoucustom
Exemple avec transformLien direct vers example-with-transform
Utilisez transform lorsque le tool doit conserver les entrées ou sorties brutes pour son comportement à l’exécution, mais que les flux d’affichage ou les messages de transcription doivent recevoir une structure plus réduite ou plus sûre.
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'
export const customerTool = createTool({
id: 'lookup-customer',
description: 'Looks up a customer',
inputSchema: z.object({
customerId: z.string(),
internalPath: z.string(),
}),
outputSchema: z.object({
displayName: z.string(),
apiKey: z.string(),
debugScore: z.number(),
}),
execute: async () => {
return {
displayName: 'Acme',
apiKey: 'secret-value',
debugScore: 0.97,
}
},
transform: {
display: {
input: ({ input }) => ({ customerId: input?.customerId }),
output: ({ output }) => ({ displayName: output?.displayName }),
error: () => ({ message: 'Customer lookup failed' }),
},
transcript: {
input: ({ input }) => ({ customerId: input?.customerId }),
output: ({ output }) => ({ displayName: output?.displayName }),
error: () => ({ message: 'Customer lookup failed' }),
},
},
})
Le tool reçoit toujours la valeur brute de inputSchema et renvoie le résultat brut de execute. Mastra applique les transformations display aux charges utiles diffusées à l’interface utilisateur et les transformations transcript aux messages de transcription visibles par l’utilisateur.
Exemple avec des annotations MCPLien direct vers Exemple avec des annotations MCP
Lorsque vous exposez des tools via MCP (Model Context Protocol), vous pouvez ajouter des annotations pour décrire leur comportement et personnaliser leur affichage par les clients. Ces propriétés propres à MCP sont regroupées sous la propriété mcp :
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'
export const weatherTool = createTool({
id: 'weather-tool',
description: 'Get the current weather for a location',
inputSchema: z.object({
location: z.string().describe('City name or coordinates'),
}),
outputSchema: z.object({
location: z.string(),
temperatureCelsius: z.number(),
conditions: z.string(),
}),
// MCP-specific properties
mcp: {
// Annotations for client behavior hints
annotations: {
title: 'Weather Lookup', // Human-readable display name
readOnlyHint: true, // Tool doesn't modify environment
destructiveHint: false, // Tool doesn't perform destructive updates
idempotentHint: true, // Same args = same result
openWorldHint: true, // Interacts with external API
},
// Custom metadata for client-specific functionality
_meta: {
version: '1.0.0',
category: 'weather',
},
},
execute: async ({ location }) => {
return {
location,
temperatureCelsius: 21,
conditions: 'sunny',
}
},
})
Hooks du cycle de vie des toolsLien direct vers Hooks du cycle de vie des tools
Les tools prennent en charge des hooks de cycle de vie qui permettent de surveiller les différentes étapes de leur exécution et d’y réagir. Ces hooks sont particulièrement utiles pour la journalisation, l’analyse, la validation et les mises à jour en temps réel pendant la diffusion.
L’exemple suivant présente un tool dont tous les hooks de cycle de vie sont configurés :
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'
export const weatherTool = createTool({
id: 'weather-tool',
description: 'Get the current weather for a location',
inputSchema: z.object({
location: z.string(),
}),
outputSchema: z.object({
location: z.string(),
temperatureCelsius: z.number(),
conditions: z.string(),
}),
execute: async ({ location }) => {
return {
location,
temperatureCelsius: 21,
conditions: 'sunny',
}
},
onInputStart: ({ toolCallId }) => {
console.log(`Tool call ${toolCallId} input started`)
},
onInputDelta: ({ inputTextDelta, toolCallId }) => {
console.log(`Tool call ${toolCallId} received input chunk: ${inputTextDelta}`)
},
onInputAvailable: ({ input, toolCallId }) => {
console.log(`Tool call ${toolCallId} received location: ${input.location}`)
},
onOutput: ({ output, toolCallId, toolName }) => {
console.log(`Tool ${toolName} call ${toolCallId} returned conditions: ${output.conditions}`)
},
})
Hooks disponiblesLien direct vers Hooks disponibles
onInputStartLien direct vers oninputstart
Appelé au début de la diffusion de l’entrée d’un appel de tool, avant la réception de toute donnée d’entrée.
export const tool = createTool({
id: 'example-tool',
description: 'Example tool with hooks',
onInputStart: ({ toolCallId, messages, abortSignal }) => {
console.log(`Tool ${toolCallId} input streaming started`)
},
})
onInputDeltaLien direct vers oninputdelta
Appelé pour chaque fragment incrémentiel du texte d’entrée à mesure de sa diffusion. Utile pour afficher la progression en temps réel ou analyser du JSON partiel.
export const tool = createTool({
id: 'example-tool',
description: 'Example tool with hooks',
onInputDelta: ({ inputTextDelta, toolCallId, messages, abortSignal }) => {
console.log(`Received input chunk: ${inputTextDelta}`)
},
})
onInputAvailableLien direct vers oninputavailable
Appelé lorsque l’entrée complète du tool est disponible, puis a été analysée et validée par rapport à inputSchema.
export const tool = createTool({
id: 'example-tool',
description: 'Example tool with hooks',
inputSchema: z.object({
location: z.string(),
}),
onInputAvailable: ({ input, toolCallId, messages, abortSignal }) => {
console.log(`Tool received complete input:`, input)
// input is fully typed based on inputSchema
},
})
onOutputLien direct vers onoutput
Appelé après l’exécution réussie du tool et le renvoi de sa sortie. Utile pour journaliser les résultats, déclencher des actions de suivi ou effectuer des analyses.
export const tool = createTool({
id: 'example-tool',
description: 'Example tool with hooks',
outputSchema: z.object({
result: z.string(),
}),
execute: async input => {
return { result: 'Success' }
},
onOutput: ({ output, toolCallId, toolName, abortSignal }) => {
console.log(`${toolName} execution completed:`, output)
// output is fully typed based on outputSchema
},
})
Ordre d’exécution des hooksLien direct vers Ordre d’exécution des hooks
Pour un appel de tool diffusé classique, les hooks sont invoqués dans l’ordre suivant :
- onInputStart : le flux d’entrée commence
- onInputDelta : appelé plusieurs fois à mesure que les fragments arrivent
- onInputAvailable : l’entrée complète est analysée et validée
- La fonction execute du tool s’exécute
- onOutput : l’exécution du tool s’est terminée avec succès
Paramètres des hooksLien direct vers Paramètres des hooks
Les callbacks des hooks reçoivent les structures de paramètres suivantes, fondées sur les types sources :
onInputStart: reçoitToolCallOptions, notamment des champs tels quetoolCallId,messagesetabortSignal.onInputDelta: reçoit{ inputTextDelta: string } & ToolCallOptions.onInputAvailable: reçoit{ input: TSchemaIn } & ToolCallOptions, oùinputest typé à partir deinputSchema.onOutput: reçoit{ output: TSchemaOut; toolName: string } & Omit<ToolCallOptions, 'messages'>, oùoutputest typé à partir deoutputSchema. Ce hook ne reçoit pasmessages.
Gestion des erreursLien direct vers Gestion des erreurs
Les erreurs des hooks sont interceptées et journalisées automatiquement, mais n’empêchent pas la poursuite de l’exécution du tool. Si un hook lève une erreur, celle-ci est journalisée dans la console sans faire échouer l’appel du tool.
Annotations de tool MCPLien direct vers Annotations de tool MCP
Lorsque vous exposez des tools via Model Context Protocol (MCP), vous pouvez fournir des annotations décrivant leur comportement. Ces annotations aident les clients MCP tels qu’OpenAI Apps SDK à comprendre comment présenter et gérer vos tools.
Les propriétés propres à MCP sont regroupées sous la propriété mcp, qui comprend annotations et _meta :
mcp: {
annotations: { /* behavior hints */ },
_meta: { /* custom metadata */ },
}
Propriétés de ToolAnnotationsLien direct vers toolannotations-properties
title?:
readOnlyHint?:
destructiveHint?:
idempotentHint?:
openWorldHint?:
Ces annotations respectent la spécification MCP et sont transmises telles quelles lorsque les tools sont répertoriés via MCP.