Aller au contenu principal

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’utilisation
Lien direct vers Exemple d’utilisation

src/mastra/tools/weather-tool.ts
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ètres
Lien direct vers Paramètres

id:

string
Identifiant unique du tool.

description:

string
Description de ce que fait le tool. L’agent l’utilise pour déterminer quand employer le tool.

inputSchema?:

StandardJSONSchemaV1
Standard JSON Schema définissant les paramètres d’entrée attendus par la fonction execute du tool.

outputSchema?:

StandardJSONSchemaV1
Standard JSON Schema définissant la structure de sortie attendue de la fonction execute du tool.

strict?:

boolean
Lorsque cette valeur est true, Mastra active la génération stricte des entrées de tool sur les adaptateurs de modèle compatibles. Les providers pris en charge peuvent ainsi renvoyer des arguments qui correspondent plus précisément au schéma du tool.

toModelOutput?:

(output: TSchemaOut) => unknown
Fonction facultative qui transforme la sortie de 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?:

ToolPayloadTransform
Transformation facultative tenant compte de la cible, appliquée aux charges utiles du tool avant qu’elles ne quittent l’environnement d’exécution pour les flux d’affichage ou les messages de transcription visibles par l’utilisateur. Configurez les transformations display et transcript pour des phases telles que input, inputDelta, output, error, approval, suspend et resume.

suspendSchema?:

StandardJSONSchemaV1
Standard JSON Schema définissant la structure de la charge utile transmise à suspend(). Cette charge utile est renvoyée au client lorsque le tool suspend son exécution.

resumeSchema?:

StandardJSONSchemaV1
Standard JSON Schema définissant la structure attendue de resumeData lors de la reprise du tool. L’agent l’utilise pour extraire les données des messages utilisateur lorsque autoResumeSuspendedTools est activé.

requireApproval?:

boolean
Lorsque cette valeur est true, le tool exige une approbation explicite avant son exécution. L’agent émet un fragment tool-call-approval, puis se met en pause jusqu’à l’approbation ou au refus.

mcp?:

MCPToolProperties
Propriétés propres à MCP pour les tools exposés via Model Context Protocol. Elles comprennent 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?:

StandardJSONSchemaV1
Standard JSON Schema servant à valider les valeurs du contexte de requête. Lorsqu’il est fourni, le contexte est validé avant l’exécution de execute(), et un objet d’erreur est renvoyé si la validation échoue.

providerOptions?:

Record<string, Record<string, unknown>>
Options propres au provider transmises au modèle lorsque ce tool est utilisé. Les clés sont des noms de providers, tels que anthropic ou openai, et les valeurs sont des objets de configuration propres à chaque provider.

inputExamples?:

Array<{ input: Record<string, unknown> }>
Exemples d’entrées valides du tool que les providers de modèles compatibles peuvent utiliser comme exemples d’entrée.

background?:

ToolBackgroundConfig
Configuration des tâches en arrière-plan pour ce tool. Lorsqu’elle est activée, le tool peut s’exécuter en arrière-plan pendant que la conversation de l’agent se poursuit.

execute?:

function
Fonction qui contient la logique du tool. Les tools personnalisés ordinaires fournissent généralement 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:

z.infer<TInput>
Données d’entrée validées selon inputSchema

context?:

ToolExecutionContext
Contexte d’exécution facultatif contenant des métadonnées
ToolExecutionContext

requestContext?:

RequestContext
Request Context permettant d’accéder à l’état partagé et aux dépendances

abortSignal?:

AbortSignal
Signal permettant d’interrompre l’exécution du tool

agent?:

AgentToolExecutionContext
Contexte propre à l’agent, disponible lorsque le tool est exécuté par un agent.
string
string
CoreMessage[]
(payload, options?) => Promise<void>
TResume
string
string
WritableStream<any>

workflow?:

WorkflowToolExecutionContext
Contexte propre au Workflow (state, setState, suspend, etc.)

mcp?:

MCPToolExecutionContext
Contexte propre à MCP (elicitation, etc.)

observe:

ToolObserve
Utilitaires d’observabilité permettant d’enregistrer des spans enfants et des journaux structurés depuis la fonction execute d’un tool. Toujours fournis : lorsqu’aucun contexte de traçage n’est actif, span exécute directement la fonction et log ne fait rien.
(name: string, fn: () => Promise<T> | T, attributes?: Record<string, unknown>) => Promise<T>
(level: 'debug' | 'info' | 'warn' | 'error' | 'fatal', message: string, data?: Record<string, unknown>) => void

onInputStart?:

function
Callback facultatif appelé lorsque commence la diffusion de l’entrée de l’appel du tool. Signature : (options: ToolCallOptions) => void | PromiseLike<void>.

onInputDelta?:

function
Callback facultatif appelé pour chaque fragment incrémentiel du texte d’entrée à mesure de sa diffusion. Signature : ({ inputTextDelta, ...options }: { inputTextDelta: string } & ToolCallOptions) => void | PromiseLike<void>.

onInputAvailable?:

function
Callback facultatif appelé lorsque l’entrée complète du tool est disponible et analysée. Signature : ({ input, ...options }: { input: TSchemaIn } & ToolCallOptions) => void | PromiseLike<void>.

onOutput?:

function
Callback facultatif appelé après l’exécution réussie du tool et le renvoi de sa sortie. Signature : ({ 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 retour
Lien direct vers Valeur de retour

La fonction createTool() renvoie un objet Tool.

Tool:

object
Objet représentant le tool défini, prêt à être ajouté à un agent.

Définir des schémas
Lien 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.

src/mastra/tools/weather-tool.ts
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' }
},
})

Exemple avec des entrées de tool strictes
Lien 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.

src/mastra/tools/weather-tool.ts
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 toModelOutput
Lien 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.

src/mastra/tools/weather-tool.ts
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 que text, image-url, image-data, file-url, file-data, file-id, image-file-id ou custom

Exemple avec transform
Lien 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.

src/mastra/tools/customer-tool.ts
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 MCP
Lien 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 :

src/mastra/tools/weather-tool.ts
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 tools
Lien 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 :

src/mastra/tools/weather-tool.ts
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 disponibles
Lien direct vers Hooks disponibles

onInputStart
Lien 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`)
},
})

onInputDelta
Lien 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}`)
},
})

onInputAvailable
Lien 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
},
})

onOutput
Lien 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 hooks
Lien direct vers Ordre d’exécution des hooks

Pour un appel de tool diffusé classique, les hooks sont invoqués dans l’ordre suivant :

  1. onInputStart : le flux d’entrée commence
  2. onInputDelta : appelé plusieurs fois à mesure que les fragments arrivent
  3. onInputAvailable : l’entrée complète est analysée et validée
  4. La fonction execute du tool s’exécute
  5. onOutput : l’exécution du tool s’est terminée avec succès

Paramètres des hooks
Lien 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çoit ToolCallOptions, notamment des champs tels que toolCallId, messages et abortSignal.
  • onInputDelta : reçoit { inputTextDelta: string } & ToolCallOptions.
  • onInputAvailable : reçoit { input: TSchemaIn } & ToolCallOptions, où input est typé à partir de inputSchema.
  • onOutput : reçoit { output: TSchemaOut; toolName: string } & Omit<ToolCallOptions, 'messages'>, où output est typé à partir de outputSchema. Ce hook ne reçoit pas messages.

Gestion des erreurs
Lien 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 MCP
Lien 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 ToolAnnotations
Lien direct vers toolannotations-properties

title?:

string
Titre lisible par l’utilisateur pour le tool. Utilisé à des fins d’affichage dans les composants d’interface utilisateur.

readOnlyHint?:

boolean
Si cette valeur est true, le tool ne modifie pas son environnement. Cette indication signifie que le tool ne fait que lire des données et n’a aucun effet secondaire. La valeur par défaut est false.

destructiveHint?:

boolean
Si cette valeur est true, le tool peut effectuer des mises à jour destructives de son environnement. Si elle est false, le tool effectue uniquement des mises à jour additives. Cette indication aide les clients à déterminer si une confirmation doit être exigée. La valeur par défaut est true.

idempotentHint?:

boolean
Si cette valeur est true, appeler plusieurs fois le tool avec les mêmes arguments n’aura aucun effet supplémentaire sur son environnement. Cette indication signale un comportement idempotent. La valeur par défaut est false.

openWorldHint?:

boolean
Si cette valeur est true, ce tool peut interagir avec un « monde ouvert » d’entités externes (par exemple, une recherche sur le Web ou des API externes). Si elle est false, le domaine du tool est fermé et entièrement défini. La valeur par défaut est true.

Ces annotations respectent la spécification MCP et sont transmises telles quelles lorsque les tools sont répertoriés via MCP.