Define a Server-side Tool
Minimal Tool structure
Define a server-side Tool with defineTools() from @nocobase/ai. The following Tool accepts a name and returns a greeting:
If the file path is src/ai/tools/greetDeveloper.ts, the loader uses the filename greetDeveloper as the final Tool name. Even if definition.name contains another value, registration overrides it with the filename.
Therefore, keep the filename, definition.name, the name referenced by the Skill, and the name registered on the frontend consistent by default.
Tool options
The main defineTools() options are:
The selected scope directly affects how the Tool enters an AI employee's context:
Use SPECIFIED by default. Use GENERAL only when every AI employee definitely needs the capability. Use CUSTOM when administrators should select it per employee.
definition is written for the model
definition.description and definition.schema affect whether the model selects the Tool and how it constructs arguments. The description should explain three things:
- When to call the Tool
- What each argument represents
- Which tasks the Tool should not handle
Zod is recommended for the parameter schema:
The Tool name must also remain stable. Skills, AI employee configurations, frontend cards, and saved chat messages all locate it by name.
What invoke() receives
A server-side invoke() receives three arguments:
Through ctx, you can access the current application, database, authentication information, and action arguments. For example:
A Tool should return a structure that clearly indicates success or failure. Built-in Tools commonly use this shape:
For expected business failures, return a clear status and reason instead of making the model guess whether the operation succeeded.
Directory-based Tools
A Tool can use a directory instead of a single file:
index.ts exports the result of defineTools() by default. When description.md exists, its entire content overrides definition.description, making it suitable for longer Tool instructions.
The directory name documentSearch becomes the final registered name.
Built-in Tool example: subAgentWebSearch
packages/plugins/@nocobase/plugin-ai/src/ai/tools/subAgentWebSearch.ts demonstrates a complete server-side Tool:
This implementation demonstrates several reusable practices:
- Use
SPECIFIEDto limit the Tool to designated employees or Skills - Use Zod to constrain model-generated arguments
- Read the current AI conversation configuration from
ctx.action.params.values - Put multiple independent queries into one ToolCall and run them concurrently with
Promise.all() - Return structured results with clear provenance for the higher-level model to process
Related links
- AI employee plugin development — Choose which capability layer to extend
- Define a Skill — Use a Skill to organize the call flow for multiple Tools
- Complete example: Create a built-in AI employee — See a runnable Tool example
- Add frontend interaction to a Tool — Add confirmation and selection UI to a ToolCall

