Tool search

⚠️
Preview — this feature is being built; the design below is the spec.

When an application has hundreds of tools, sending every definition on every request wastes tokens and makes the model choose worse. With tool search, you mark most tools as defer_loading: true. The model starts with only a search tool and the few tools you always want loaded; when it needs something else, it searches and Syntic loads the matching definitions into the conversation.

When to use it

  • More than about 30 tools, or more than 10,000 tokens of tool definitions.
  • Large MCP servers that expose many tools.
  • Catalogs that grow over time, such as one tool per integration.

With a handful of tools, list them normally.

Endpoint and auth

POST https://app.syntic.ai/v1/chat/completions (and Messages), Authorization: Bearer sk_live_....

Request fields

FieldWhereDetails
defer_loadingeach function tool, or each mcp_servers[] entrytrue keeps the definition out of the prompt until a search finds it.
{"type": "syntic_tool_search"}toolsAdds the search tool. Required when any tool is deferred.
modeon the search toolkeyword (default, matches names and descriptions) or semantic (matches by meaning).
max_resultson the search toolTools loaded per search, 1 to 10. Default 5.

At least one tool must stay loaded (not deferred), or the search tool itself counts as that tool.

How it works

  1. The model sees the search tool, your non-deferred tools and a one-line hint that more tools exist.
  2. It calls syntic_tool_search with a query, for example “refund an order”.
  3. Syntic finds matches among the deferred tools and adds their full definitions to the conversation.
  4. The model calls the tool it needs, which comes back to you as a normal tool_calls entry.

Loaded definitions stay loaded for the rest of the request. To keep them in later requests, return the assistant message unchanged; it carries a tool_search record that Syntic replays.

Response

{
  "message": {
    "role": "assistant",
    "content": "",
    "server_tool_calls": [
      { "id": "srv_05", "type": "syntic_tool_search", "query": "refund an order", "loaded": ["create_refund", "get_order"], "status": "ok" }
    ],
    "tool_calls": [
      { "id": "call_r1", "type": "function", "function": { "name": "create_refund", "arguments": "{\"order_number\":\"582131\",\"amount_pence\":1250}" } }
    ]
  },
  "finish_reason": "tool_calls"
}

Examples

curl https://app.syntic.ai/v1/chat/completions \
  -H "Authorization: Bearer $SYNTIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Amara S1.2",
    "stream": false,
    "tools": [
      { "type": "syntic_tool_search", "mode": "semantic" },
      { "type": "function", "function": { "name": "get_order", "description": "Look up an order.", "parameters": { "type": "object", "properties": { "order_number": { "type": "string" } }, "required": ["order_number"] } } },
      { "type": "function", "defer_loading": true, "function": { "name": "create_refund", "description": "Refund part or all of an order.", "parameters": { "type": "object", "properties": { "order_number": { "type": "string" }, "amount_pence": { "type": "integer" } }, "required": ["order_number", "amount_pence"] } } }
    ],
    "messages": [{ "role": "user", "content": "Refund £12.50 on order 582131." }]
  }'

Errors

Unified envelope.

StatuscodeCause
400tool_search_requiredSome tools are deferred but syntic_tool_search is missing.
400all_tools_deferredNothing would be loaded (search tool aside), and tool_choice names a deferred tool.
400too_many_toolsMore than 10,000 tools in total.

Cost and limits

  • Deferred definitions are not billed until loaded. A search adds the loaded definitions as input tokens.
  • semantic mode embeds your tool descriptions once per distinct catalog (cached by hash); there is no extra fee.
  • Up to 10,000 tools per request, 128 loaded at once.

Build notes for the platform team

  • Index deferred tools per request by hash of the definitions; reuse the index across requests.
  • Semantic mode uses the embeddings backend.
  • Pairs with the MCP connector; build after it.
Was this page helpful?