createTool()
createTool() 函式用於定義 Mastra Agent 可執行的自訂 Tool。Tool 能讓 Agent 與外部系統互動、執行計算或存取特定資料,藉此擴充 Agent 的能力。
使用範例「使用範例」的直接連結
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',
}
},
})
execute 的第一個參數是經 inputSchema 驗證的值。請直接在函式 signature 中解構 schema 欄位,如 { location } 所示。選填的第二個參數包含 execution context。
參數「參數」的直接連結
id:
description:
inputSchema?:
execute 函式預期的輸入參數。outputSchema?:
execute 函式預期的輸出結構。strict?:
toModelOutput?:
execute 輸出傳回模型前進行轉換。可用來將 text、json 或 content 結構的輸出(包括圖片/檔案等多模態部分)回傳給模型,同時在應用程式碼中保留完整原始輸出。transform?:
input、inputDelta、output、error、approval、suspend 與 resume 等階段設定 display 和 transcript transform。suspendSchema?:
suspend() 的 payload 結構。Tool 暫停執行時會將此 payload 回傳給 client。resumeSchema?:
resumeData 結構。啟用 autoResumeSuspendedTools 時,Agent 會使用此 schema 從使用者訊息擷取資料。requireApproval?:
tool-call-approval 區塊並暫停,直到核准或拒絕為止。mcp?:
annotations(例如 title、readOnlyHint、destructiveHint、idempotentHint、openWorldHint 等 Tool 行為提示)與 _meta(原樣傳給 MCP client 的任意中繼資料)。requestContextSchema?:
providerOptions?:
anthropic 或 openai 等 Provider 名稱,值則是 Provider 特定設定物件。inputExamples?:
background?:
execute?:
execute,但對於在其他位置執行或調整的 Tool 定義,此型別允許省略。它接受兩個參數:根據 inputSchema 驗證的輸入資料(第一個參數),以及包含 requestContext、abortSignal 與其他執行中繼資料的 execution context 物件(第二個參數)。input:
context?:
requestContext?:
abortSignal?:
agent?:
workflow?:
mcp?:
observe:
span 會直接執行函式,而 log 不會執行任何操作。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>。mastra 與 mcpMetadata 等由 runtime 填入的欄位會出現在來源型別中,但由 Mastra 或 MCP adapter 設定。一般使用 createTool() 時不需要設定這些欄位。
回傳值「回傳值」的直接連結
createTool() 函式會回傳 Tool 物件。
Tool:
定義 schema「定義 schema」的直接連結
你可以使用任何支援 Standard JSON Schema 的函式庫定義 Tool 的 inputSchema 與 outputSchema,包括 Zod、Valibot 與 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' }
},
})
使用嚴格 Tool 輸入的範例「使用嚴格 Tool 輸入的範例」的直接連結
若要讓 Mastra 要求支援此功能的模型 Provider 產生完全符合 Tool schema 的引數,請設定 strict: true。
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 會將 strict: true 轉送至支援嚴格 Tool 呼叫的 model adapter。不支援此功能的 adapter 會忽略此選項。
使用 toModelOutput 的範例「example-with-tomodeloutput」的直接連結
若 Tool 應向應用程式回傳豐富的內部資料,但模型只應接收簡化值或多模態內容,請使用 toModelOutput。
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 },
],
}
},
})
Tool 仍會將完整的 execute 結果回傳給應用程式,而模型會收到轉換後的 toModelOutput 值。
toModelOutput 可回傳:
type: 'text'type: 'json'type: 'content',並包含text、image-url、image-data、file-url、file-data、file-id、image-file-id或custom等部分
使用 transform 的範例「example-with-transform」的直接連結
若 Tool 應保留原始輸入或輸出供 runtime 行為使用,但顯示串流或 transcript 訊息應接收更小或更安全的結構,請使用 transform。
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' }),
},
},
})
Tool 仍會接收原始 inputSchema 值並回傳原始 execute 結果。Mastra 會對串流 UI payload 套用 display transform,並對使用者可見的 transcript 訊息套用 transcript transform。
使用 MCP annotation 的範例「使用 MCP annotation 的範例」的直接連結
透過 MCP(Model Context Protocol)公開 Tool 時,你可以加入 annotation 來說明 Tool 行為,並自訂 client 顯示 Tool 的方式。這些 MCP 特定屬性會集中在 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',
}
},
})
Tool lifecycle hook「Tool lifecycle hook」的直接連結
Tool 支援 lifecycle hook,讓你監控 Tool 執行的不同階段並做出回應。這些 hook 特別適合用於 logging、分析、驗證與串流期間的即時更新。
下列範例示範設定所有 lifecycle hook 的 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',
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}`)
},
})
可用的 hook「可用的 hook」的直接連結
onInputStart「oninputstart」的直接連結
Tool 呼叫的輸入串流開始、但尚未收到任何輸入資料時叫用。
export const tool = createTool({
id: 'example-tool',
description: 'Example tool with hooks',
onInputStart: ({ toolCallId, messages, abortSignal }) => {
console.log(`Tool ${toolCallId} input streaming started`)
},
})
onInputDelta「oninputdelta」的直接連結
輸入文字串流傳入時,針對每個增量區塊叫用。適合用來顯示即時進度或解析部分 JSON。
export const tool = createTool({
id: 'example-tool',
description: 'Example tool with hooks',
onInputDelta: ({ inputTextDelta, toolCallId, messages, abortSignal }) => {
console.log(`Received input chunk: ${inputTextDelta}`)
},
})
onInputAvailable「oninputavailable」的直接連結
完整 Tool 輸入可用,且已根據 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「onoutput」的直接連結
Tool 成功執行並回傳輸出後叫用。適合用於記錄結果、觸發後續動作或分析。
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
},
})
Hook 執行順序「Hook 執行順序」的直接連結
一般串流 Tool 呼叫會依下列順序叫用 hook:
- onInputStart:輸入串流開始
- onInputDelta:區塊抵達時叫用多次
- onInputAvailable:解析並驗證完整輸入
- 執行 Tool 的 execute 函式
- onOutput:Tool 已成功完成
Hook 參數「Hook 參數」的直接連結
Hook callback 會收到下列由來源型別支援的參數結構:
onInputStart:接收ToolCallOptions,包括toolCallId、messages與abortSignal等欄位。onInputDelta:接收{ inputTextDelta: string } & ToolCallOptions。onInputAvailable:接收{ input: TSchemaIn } & ToolCallOptions,其中input的型別來自inputSchema。onOutput:接收{ output: TSchemaOut; toolName: string } & Omit<ToolCallOptions, 'messages'>,其中output的型別來自outputSchema。此 hook 不會接收messages。
錯誤處理「錯誤處理」的直接連結
系統會自動攔截並記錄 hook 錯誤,但不會阻止 Tool 繼續執行。若 hook 擲回錯誤,系統會將其記錄到主控台,但 Tool 呼叫不會失敗。
MCP Tool annotation「MCP Tool annotation」的直接連結
透過 Model Context Protocol(MCP)公開 Tool 時,你可以提供描述 Tool 行為的 annotation。這些 annotation 可協助 OpenAI Apps SDK 等 MCP client 了解如何呈現與處理 Tool。
MCP 特定屬性會集中在 mcp 屬性下,其中包括 annotations 與 _meta:
mcp: {
annotations: { /* behavior hints */ },
_meta: { /* custom metadata */ },
}
ToolAnnotations 屬性「toolannotations-properties」的直接連結
title?:
readOnlyHint?:
destructiveHint?:
idempotentHint?:
openWorldHint?:
這些 annotation 遵循 MCP 規範,並會在透過 MCP 列出 Tool 時原樣傳遞。