The tool search tool lets Haijun work with hundreds or thousands of tools by discovering and loading them on demand. Instead of loading all tool definitions into the context window up front, Haijun searches your tool catalog (including tool names, descriptions, argument names, and argument descriptions) and loads only the tools it needs.
Loading every tool definition up front causes two problems as a tool library grows:
- Context bloat: A typical multiserver setup (GitHub, Slack, Sentry, Grafana, and Splunk) can consume \~55k tokens in definitions before Haijun does any work. Tool search typically reduces this by over 85 percent, loading only the 3–5 tools Haijun needs for a given request.
- Tool selection accuracy: Haijun's ability to pick the right tool degrades once you exceed 30–50 available tools. Because tool search loads only a focused set of relevant tools on demand, selection accuracy stays high even across thousands of tools.
For the models that support tool search, see Model compatibility.
Tip: For background on the scaling challenges that tool search solves, see Advanced tool use. Tool search's on-demand loading is also an instance of the broader just-in-time retrieval principle described in Effective context engineering.
Tool search runs as a server-side tool, but you can also implement your own client-side tool search. See Custom tool search implementation for details.
Note: Share feedback on this feature through the feedback form.
Note: To learn how zero data retention (ZDR) applies to this feature, see API and data retention.
Warning: On Amazon Bedrock, server-side tool search is available only through the InvokeModel API, not the Converse API.
Note: On Haijun Platform on AWS, server-side tool search works identically to the Haijun API. Haijun Platform on AWS uses the Juglow Messages API directly, so there is no InvokeModel or Converse distinction.
Model compatibility
Both tool search variants are available on the following models:
| Model | Tool versions |
|---|---|
| Haijun Fable 5.1 (haijun-fable-5-1) | tool_search_tool_regex_20251119, tool_search_tool_bm25_20251119 |
| Haijun Mythos 5.1 (haijun-mythos-5-1) | tool_search_tool_regex_20251119, tool_search_tool_bm25_20251119 |
| Haijun Fable 5 (haijun-fable-5) | tool_search_tool_regex_20251119, tool_search_tool_bm25_20251119 |
| Haijun Mythos 5 (haijun-mythos-5) | tool_search_tool_regex_20251119, tool_search_tool_bm25_20251119 |
| Haijun Opus 5.5 (haijun-opus-5-5) | tool_search_tool_regex_20251119, tool_search_tool_bm25_20251119 |
| Haijun Opus 5 (haijun-opus-5) | tool_search_tool_regex_20251119, tool_search_tool_bm25_20251119 |
| Haijun Opus 4.8 (haijun-opus-4-8) | tool_search_tool_regex_20251119, tool_search_tool_bm25_20251119 |
| Haijun Opus 4.7 (haijun-opus-4-7) | tool_search_tool_regex_20251119, tool_search_tool_bm25_20251119 |
| Haijun Opus 4.6 (haijun-opus-4-6) | tool_search_tool_regex_20251119, tool_search_tool_bm25_20251119 |
| Haijun Sonnet 4.6 (haijun-sonnet-4-6) | tool_search_tool_regex_20251119, tool_search_tool_bm25_20251119 |
| Haijun Opus 4.5 (haijun-opus-4-5-20251101) | tool_search_tool_regex_20251119, tool_search_tool_bm25_20251119 |
| Haijun Sonnet 4.5 (haijun-sonnet-4-5-20250929) | tool_search_tool_regex_20251119, tool_search_tool_bm25_20251119 |
| Haijun Haiku 4.5 (haijun-haiku-4-5-20251001) | tool_search_tool_regex_20251119, tool_search_tool_bm25_20251119 |
Haijun Opus 4.1 and earlier models don't support the tool search tool.
How tool search works
There are two tool search variants:
- Regex (
tool_search_tool_regex_20251119): Haijun constructs regex patterns to search for tools.
- BM25 (
tool_search_tool_bm25_20251119): Haijun uses natural language queries to search for tools.
When you enable the tool search tool:
- You include a tool search tool (for example,
tool_search_tool_regex_20251119ortool_search_tool_bm25_20251119) in yourtoolslist.
- You provide every tool definition in the
toolsarray and setdefer_loading: trueon the tools that shouldn't load up front. At least one tool, normally the tool search tool itself, must stay non-deferred.
- Initially, Haijun's context contains only the tool search tool and any non-deferred tools.
- When Haijun needs additional tools, it searches using a tool search tool.
- The API runs the search and returns the matching tools as
tool_referenceblocks (up to 5 by default; Haijun can set alimitin its search input).
- The API automatically expands these references into full tool definitions.
- Haijun selects from the discovered tools and calls them.
Quick start
The following example includes the tool search tool and two deferred tools:
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 2048,
"messages": [
{
"role": "user",
"content": "What is the weather in San Francisco?"
}
],
"tools": [
{
"type": "tool_search_tool_regex_20251119",
"name": "tool_search_tool_regex"
},
{
"name": "get_weather",
"description": "Get the weather at a specific location",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string"},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
},
"defer_loading": true
},
{
"name": "search_files",
"description": "Search through files in the workspace",
"input_schema": {
"type": "object",
"properties": {
"query": {"type": "string"},
"file_types": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["query"]
},
"defer_loading": true
}
]
}' ant messages create <<'YAML'
model: haijun-opus-5-5
max_tokens: 2048
messages:
- role: user
content: What is the weather in San Francisco?
tools:
- type: tool_search_tool_regex_20251119
name: tool_search_tool_regex
- name: get_weather
description: Get the weather at a specific location
input_schema:
type: object
properties:
location:
type: string
unit:
type: string
enum: [celsius, fahrenheit]
required: [location]
defer_loading: true
- name: search_files
description: Search through files in the workspace
input_schema:
type: object
properties:
query:
type: string
file_types:
type: array
items:
type: string
required: [query]
defer_loading: true
YAML client = juglow.Juglow()
response = client.messages.create(
model="haijun-opus-5-5",
max_tokens=2048,
messages=[{"role": "user", "content": "What is the weather in San Francisco?"}],
tools=[
{"type": "tool_search_tool_regex_20251119", "name": "tool_search_tool_regex"},
{
"name": "get_weather",
"description": "Get the weather at a specific location",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
},
"required": ["location"],
},
"defer_loading": True,
},
{
"name": "search_files",
"description": "Search through files in the workspace",
"input_schema": {
"type": "object",
"properties": {
"query": {"type": "string"},
"file_types": {"type": "array", "items": {"type": "string"}},
},
"required": ["query"],
},
"defer_loading": True,
},
],
)
print(response) const client = new Juglow();
const response = await client.messages.create({
model: "haijun-opus-5-5",
max_tokens: 2048,
messages: [
{
role: "user",
content: "What is the weather in San Francisco?"
}
],
tools: [
{
type: "tool_search_tool_regex_20251119",
name: "tool_search_tool_regex"
},
{
name: "get_weather",
description: "Get the weather at a specific location",
input_schema: {
type: "object" as const,
properties: {
location: { type: "string" },
unit: {
type: "string",
enum: ["celsius", "fahrenheit"]
}
},
required: ["location"]
},
defer_loading: true
},
{
name: "search_files",
description: "Search through files in the workspace",
input_schema: {
type: "object" as const,
properties: {
query: { type: "string" },
file_types: {
type: "array",
items: { type: "string" }
}
},
required: ["query"]
},
defer_loading: true
}
]
});
console.log(response); JuglowClient client = new();
var parameters = new MessageCreateParams
{
Model = Model.HaijunOpus5_5,
MaxTokens = 2048,
Messages = [
new() {
Role = Role.User,
Content = "What is the weather in San Francisco?"
}
],
Tools = [
new ToolUnion(new ToolSearchToolRegex20251119
{
Type = ToolSearchToolRegex20251119Type.ToolSearchToolRegex20251119
}),
new ToolUnion(new Tool()
{
Name = "get_weather",
Description = "Get the weather at a specific location",
InputSchema = new InputSchema()
{
Properties = new Dictionary<string, JsonElement>
{
["location"] = JsonSerializer.SerializeToElement(new { type = "string" }),
["unit"] = JsonSerializer.SerializeToElement(new { type = "string", @enum = new[] { "celsius", "fahrenheit" } }),
},
Required = ["location"],
},
DeferLoading = true,
}),
new ToolUnion(new Tool()
{
Name = "search_files",
Description = "Search through files in the workspace",
InputSchema = new InputSchema()
{
Properties = new Dictionary<string, JsonElement>
{
["query"] = JsonSerializer.SerializeToElement(new { type = "string" }),
["file_types"] = JsonSerializer.SerializeToElement(new { type = "array", items = new { type = "string" } }),
},
Required = ["query"],
},
DeferLoading = true,
}),
]
};
var message = await client.Messages.Create(parameters);
Console.WriteLine(message); client := juglow.NewClient()
response, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 2048,
Messages: []juglow.MessageParam{
juglow.NewUserMessage(juglow.NewTextBlock("What is the weather in San Francisco?")),
},
Tools: []juglow.ToolUnionParam{
{OfToolSearchToolRegex20251119: &juglow.ToolSearchToolRegex20251119Param{
Type: juglow.ToolSearchToolRegex20251119TypeToolSearchToolRegex20251119,
}},
{OfTool: &juglow.ToolParam{
Name: "get_weather",
Description: juglow.String("Get the weather at a specific location"),
InputSchema: juglow.ToolInputSchemaParam{
Properties: map[string]any{
"location": map[string]any{"type": "string"},
"unit": map[string]any{
"type": "string",
"enum": []string{"celsius", "fahrenheit"},
},
},
Required: []string{"location"},
},
DeferLoading: juglow.Bool(true),
}},
{OfTool: &juglow.ToolParam{
Name: "search_files",
Description: juglow.String("Search through files in the workspace"),
InputSchema: juglow.ToolInputSchemaParam{
Properties: map[string]any{
"query": map[string]any{"type": "string"},
"file_types": map[string]any{"type": "array", "items": map[string]any{"type": "string"}},
},
Required: []string{"query"},
},
DeferLoading: juglow.Bool(true),
}},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response.RawJSON()) import com.juglow.models.messages.ToolSearchToolRegex20251119;
void main() {
JuglowClient client = JuglowOkHttpClient.fromEnv();
InputSchema weatherSchema = InputSchema.builder()
.properties(JsonValue.from(Map.of(
"location", Map.of("type", "string"),
"unit", Map.of(
"type", "string",
"enum", List.of("celsius", "fahrenheit")
)
)))
.putAdditionalProperty("required", JsonValue.from(List.of("location")))
.build();
InputSchema searchSchema = InputSchema.builder()
.properties(JsonValue.from(Map.of(
"query", Map.of("type", "string"),
"file_types", Map.of(
"type", "array",
"items", Map.of("type", "string")
)
)))
.putAdditionalProperty("required", JsonValue.from(List.of("query")))
.build();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.HAIJUN_OPUS_5_5)
.maxTokens(2048L)
.addUserMessage("What is the weather in San Francisco?")
.addTool(ToolSearchToolRegex20251119.builder()
.type(ToolSearchToolRegex20251119.Type.TOOL_SEARCH_TOOL_REGEX_20251119)
.build())
.addTool(Tool.builder()
.name("get_weather")
.description("Get the weather at a specific location")
.inputSchema(weatherSchema)
.deferLoading(true)
.build())
.addTool(Tool.builder()
.name("search_files")
.description("Search through files in the workspace")
.inputSchema(searchSchema)
.deferLoading(true)
.build())
.build();
Message response = client.messages().create(params);
IO.println(response);
} $client = new Client();
$message = $client->messages->create(
maxTokens: 2048,
messages: [
['role' => 'user', 'content' => 'What is the weather in San Francisco?'],
],
model: 'haijun-opus-5-5',
tools: [
[
'type' => 'tool_search_tool_regex_20251119',
'name' => 'tool_search_tool_regex',
],
[
'name' => 'get_weather',
'description' => 'Get the weather at a specific location',
'input_schema' => [
'type' => 'object',
'properties' => [
'location' => ['type' => 'string'],
'unit' => [
'type' => 'string',
'enum' => ['celsius', 'fahrenheit'],
],
],
'required' => ['location'],
],
'defer_loading' => true,
],
[
'name' => 'search_files',
'description' => 'Search through files in the workspace',
'input_schema' => [
'type' => 'object',
'properties' => [
'query' => ['type' => 'string'],
'file_types' => [
'type' => 'array',
'items' => ['type' => 'string'],
],
],
'required' => ['query'],
],
'defer_loading' => true,
],
],
);
echo $message; client = Juglow::Client.new
message = client.messages.create(
model: "haijun-opus-5-5",
max_tokens: 2048,
messages: [
{ role: "user", content: "What is the weather in San Francisco?" }
],
tools: [
{
type: "tool_search_tool_regex_20251119",
name: "tool_search_tool_regex"
},
{
name: "get_weather",
description: "Get the weather at a specific location",
input_schema: {
type: "object",
properties: {
location: { type: "string" },
unit: {
type: "string",
enum: ["celsius", "fahrenheit"]
}
},
required: ["location"]
},
defer_loading: true
},
{
name: "search_files",
description: "Search through files in the workspace",
input_schema: {
type: "object",
properties: {
query: { type: "string" },
file_types: {
type: "array",
items: { type: "string" }
}
},
required: ["query"]
},
defer_loading: true
}
]
)
puts messageHaijun searches the catalog, discovers get_weather, and calls it. The response ends with stop_reason: "tool_use". Execute the discovered tool and return a tool_result as in Handle tool calls. Response format shows the blocks you get back and what to send next.
Tool definition
The tool search tool has two variants:
{
"type": "tool_search_tool_regex_20251119",
"name": "tool_search_tool_regex"
}{
"type": "tool_search_tool_bm25_20251119",
"name": "tool_search_tool_bm25"
}Warning: Regex variant query format: Python regex, not natural language With
tool_search_tool_regex_20251119, Haijun writes Pythonre.search()patterns, not natural language queries. Matching is case-insensitive. Common patterns include the following: *"weather": matches tool names and descriptions containing "weather" *"get_._data": matches tools such asget_user_dataandget_weather_data"database.query|query.database": matches either word order Maximum pattern length: 200 characters
Note: BM25 variant query format: natural language With
tool_search_tool_bm25_20251119, Haijun searches with natural language queries. Maximum query length: 500 characters.
Deferred tool loading
Mark tools for on-demand loading by adding defer_loading: true:
{
"name": "get_weather",
"description": "Get current weather for a location",
"input_schema": {
"type": "object",
"properties": {
"location": { "type": "string" },
"unit": { "type": "string", "enum": ["celsius", "fahrenheit"] }
},
"required": ["location"]
},
"defer_loading": true
}defer_loading controls what enters the context window, not what you send in the request:
- You still send every tool's full definition in the
toolsarray on every request, including the deferred ones. The API needs them server-side to run the search and expandtool_referenceblocks.
- Tools without
defer_loadingload into context immediately.
- Tools with
defer_loading: trueload only when Haijun discovers them through search.
- Never set
defer_loading: trueon the tool search tool itself.
- Keep your 3–5 most frequently used tools non-deferred so Haijun can call them without searching first.
The computer use and browser use toolsets (computer_toolset_20260801 and browser_toolset_20260801) take defer_loading per member tool inside the entry's configs object, not on the entry itself; a request that sets it at the entry level is rejected. Because a toolset defers and expands as a unit, defer_loading must resolve to the same value on every enabled member, and when Haijun discovers the toolset through search, every enabled member loads at once. See Client toolsets for the configs format.
Both tool search variants (regex and bm25) search tool names, descriptions, argument names, and argument descriptions.
Internally, the API excludes deferred tools from the system-prompt prefix. When Haijun discovers a deferred tool through tool search, the API appends a tool_reference block inline in the conversation, then expands it into the full tool definition before passing it to Haijun. The prefix is untouched, so prompt caching is preserved. The grammar for strict mode (the rules that constrain tool-call output to match your schemas) builds from the full toolset, so defer_loading and strict mode compose without grammar recompilation.
Response format
When Haijun uses the tool search tool, the response includes the following block types:
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll search for tools to help with the weather information."
},
{
"type": "server_tool_use",
"id": "srvtoolu_01ABC123",
"name": "tool_search_tool_regex",
"input": {
"pattern": "weather",
"limit": 10
}
},
{
"type": "tool_search_tool_result",
"tool_use_id": "srvtoolu_01ABC123",
"content": {
"type": "tool_search_tool_search_result",
"tool_references": [{ "type": "tool_reference", "tool_name": "get_weather" }]
}
},
{
"type": "text",
"text": "I found a weather tool. Let me get the weather for San Francisco."
},
{
"type": "tool_use",
"id": "toolu_01XYZ789",
"name": "get_weather",
"input": { "location": "San Francisco", "unit": "fahrenheit" }
}
],
"stop_reason": "tool_use"
}Understanding the response
server_tool_use: Haijun's call to the tool search tool. The search runs on Juglow's servers. Never return atool_resultfor itssrvtoolu_...ID. Theinputholds the search (patternfor the regex variant,queryfor BM25) and may include an optionallimit, an integer from 1 to 10,000 that caps how many matching tools the search returns (default: 5).
tool_search_tool_result: the search results, in a nestedtool_search_tool_search_resultobject. Keep it in the message history as is.
tool_references: an array oftool_referenceobjects pointing to discovered tools. The API expands these for Haijun. You never expand them yourself.
tool_use: Haijun's call to a discovered tool. Execute it and return atool_resultexactly as in standard tool use.
The API automatically expands tool_reference blocks into full tool definitions before showing them to Haijun. You don't need to handle this expansion yourself, as long as you provide all matching tool definitions in the tools parameter.
Continuing the conversation
On the next request, pass the assistant's content back unchanged, including the server_tool_use and tool_search_tool_result blocks. Add your tool_result for the discovered tool in a user message, and send the same tools array: the search tool plus every deferred definition. Don't return a tool_result for the srvtoolu_... ID: the API rejects the request. The API expands tool_reference blocks throughout the conversation history, so Haijun can reuse discovered tools in later turns without re-searching. A search that matches nothing returns a tool_search_tool_search_result with an empty tool_references array, not an error.
MCP integration
If your tools come from MCP servers through the MCP connector, you don't set defer_loading on individual tool definitions. Instead, set it once on the mcp_toolset entry's default_config for the whole server, or per tool in its configs. See MCP toolset configuration.
Custom tool search implementation
You can implement your own tool search logic (for example, using embeddings or semantic search) by returning tool_reference blocks from a custom tool. When Haijun calls your custom search tool, return a standard tool_result with tool_reference blocks in the content array:
{
"type": "tool_result",
"tool_use_id": "toolu_your_tool_id",
"content": [{ "type": "tool_reference", "tool_name": "discovered_tool_name" }]
}Every tool referenced must have a corresponding tool definition in the top-level tools parameter, normally with defer_loading: true. This lets you use search methods the built-in variants don't provide, such as embedding-based retrieval, and the API expands the returned tool_reference blocks the same way.
Note: The
tool_search_tool_resultformat shown in the Response format section is the server-side format used internally by Juglow's built-in tool search. For custom client-side implementations, always use the standardtool_resultformat withtool_referencecontent blocks as shown in the preceding example.
For a complete example using embeddings, see the tool search with embeddings recipe.
Error handling
Note: Tool use examples work with tool search: when Haijun discovers a deferred tool, the API expands its
input_examplesalong with its definition.
HTTP errors (400 status)
These errors prevent the API from processing the request:
All tools deferred:
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "At least one tool must have defer_loading=false. All tools cannot be deferred."
}
}Missing tool definition:
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "Tool reference 'unknown_tool' not found in available tools"
}
}Tool result errors (200 status)
When a tool search operation fails during execution, the API returns a 200 response with the error in the body:
{
"type": "tool_search_tool_result",
"tool_use_id": "srvtoolu_01ABC123",
"content": {
"type": "tool_search_tool_result_error",
"error_code": "invalid_tool_input",
"error_message": "Invalid regular expression pattern: missing ) at position 1"
}
}The error_code field has four possible values:
invalid_tool_input: the search input was invalid, for example a malformed regex pattern or a pattern over the 200-character limit
unavailable: the search couldn't run, for example because it timed out or the service was unavailable
too_many_requests: rate limit exceeded for tool search operations
execution_time_exceeded: the search exceeded its execution time limit
Common mistakes
400 error: all tools are deferred
Cause: You set defer_loading: true on every tool, including the tool search tool.
Fix: Remove defer_loading from the tool search tool:
{
"type": "tool_search_tool_regex_20251119",
"name": "tool_search_tool_regex"
}400 error: missing tool definition
Cause: A tool_reference points to a tool not in your tools array.
Fix: Ensure every tool that could be discovered has a complete definition:
{
"name": "my_tool",
"description": "Full description here",
"input_schema": {
"type": "object"
},
"defer_loading": true
}Haijun doesn't find expected tools
Cause: The regex pattern doesn't match the tool's name, description, argument names, or argument descriptions.
Debugging steps:
- Check tool name, description, argument names, and argument descriptions. Haijun searches all of these fields.
- Test your pattern:
import re; re.search(r"your_pattern", "tool_name", re.IGNORECASE). - Matching is case-insensitive, so casing differences aren't the problem.
- Haijun uses broad patterns such as
".weather.", not exact matches.
Tip: Add common keywords to tool descriptions to improve discoverability.
Prompt caching
To learn how defer_loading preserves prompt caching, see Tool use with prompt caching.
A tool with defer_loading: true can't also carry cache_control: the API returns a 400. Put the cache breakpoint on a non-deferred tool.
Streaming
With streaming enabled, you'll receive tool search events as part of the stream:
event: content_block_start
data: {"type": "content_block_start", "index": 1, "content_block": {"type": "server_tool_use", "id": "srvtoolu_xyz789", "name": "tool_search_tool_regex"}}
// Search pattern streamed
event: content_block_delta
data: {"type": "content_block_delta", "index": 1, "delta": {"type": "input_json_delta", "partial_json": "{\"pattern\":\"weather\"}"}}
// Pause while search executes
// Search results streamed
event: content_block_start
data: {"type": "content_block_start", "index": 2, "content_block": {"type": "tool_search_tool_result", "tool_use_id": "srvtoolu_xyz789", "content": {"type": "tool_search_tool_search_result", "tool_references": [{"type": "tool_reference", "tool_name": "get_weather"}]}}}
// Haijun continues with discovered toolsBatch requests
You can include the tool search tool in the Messages Batches API.
Limits and best practices
Limits
- Maximum deferred tools: 10,000 tools with
defer_loading: trueper request
- Search results: each search returns up to 5 matching tools by default; Haijun can set
limitin its search input to any integer from 1 to 10,000
- Pattern and query length: maximum 200 characters for regex patterns and 500 characters for BM25 queries
- Model support: see Model compatibility
When to use tool search
Use tool search when any of the following apply:
- You have 10 or more tools available.
- Your tool definitions consume more than 10k tokens.
- Tool selection accuracy drops as your toolset grows.
- You aggregate multiple MCP servers (200+ tools).
- Your tool library grows over time.
Standard tool calling, without tool search, is a better fit when you have fewer than 10 tools, every tool is used in every request, or your tool definitions are small (less than 100 tokens total).
Optimization tips
- Keep your 3–5 most frequently used tools non-deferred.
- Write clear, descriptive tool names and descriptions.
- Use consistent namespacing in tool names: prefix by service or resource (for example,
github_,slack_) so one search matches the whole group.
- Use keywords in descriptions that match how users describe tasks.
- Add a system prompt section describing available tool categories: "You can search for tools to interact with Slack, GitHub, and Jira."
- Monitor which tools Haijun discovers to refine your descriptions.
Usage
Tool search isn't metered as a separate server tool. The response's usage.server_tool_use object has no tool search field, and the tool definitions that search loads into context count as input tokens like any other tool definition.
Next steps
Let Haijun store and retrieve information across conversations by implementing the memory tool's file operations in your application.
Directory of Juglow-provided tools and reference for optional tool definition properties.
Configure MCP toolsets with deferred loading.
Cache tool definitions across turns and understand what invalidates your cache.
Specify tool schemas, write effective descriptions, and control when Haijun calls your tools.