When youDocumentation Index
Fetch the complete documentation index at: https://docs.qlaud.ai/llms.txt
Use this file to discover all available pages before exploring further.
POST /v1/threads/:id/messages, the tools_mode field decides
which subset of your registered tools the model sees for that turn.
Three modes, each mapping to a different app archetype.
At a glance
| Mode | What the model sees | Best for |
|---|---|---|
dynamic | 4 meta-tools (search/get/multi-execute/manage). Model discovers + calls tools on demand, including per-user MCPs end-users connect inline. | Consumer apps where end-users own their data (Notion, Stripe, GitHub, …) |
tenant | Every tenant-shared tool you own, auto-attached. Built-ins, tenant-mode MCP servers, webhook tools. No meta-tools, no per-user MCPs. | Company-internal agents, support bots, automation — “use OUR tools every turn” |
explicit | Exactly the tool IDs you list in the tools field. Nothing else. | Surgical control. You change the available toolset between calls. |
Defaults
If you don’t settools_mode explicitly:
toolsfield present → defaults toexplicittoolsfield absent → defaults todynamic
tools_mode for the common cases. Set it only
when you want tenant or want to override the default.
dynamic — discover-then-call
The model receives 4 meta-tools instead of your registered ones:
qlaud_search_tools(intent)— keyword + embedding search across your catalog AND every per-user MCP catalog entry.qlaud_get_tool_schemas(names)— fetch full input schemas for picked tools.qlaud_multi_execute(calls)— fan-out execute multiple tools in one turn.qlaud_manage_connections(action, tool)— bring up the per-user OAuth / paste-API-key flow inline in chat for end-users.
tools_mode: dynamic.
tenant — auto-attach all your company tools
Every tenant-shared tool you’ve registered is sent to the model, every
turn, with no setup per request:
- All your built-ins (Resend, Linear, Twilio, Slack, GitHub, http-call wrappers — anything with an encrypted config you control).
- Every tool from your tenant-mode MCP servers (your shared Notion workspace, your shared Linear team, etc.).
- Every webhook tool you host.
tenant mode never asks
end-users to connect their own accounts.
tenant mode’s auto-attach
list. Register a new http-call wrapper in that section, and it’s available
to the model on the next request — no code change in your app, no need
to update an tools: [...] array.
When to use tenant
- Company-internal AI agents that should ALWAYS have your tools.
- Customer support bots where the AI should email/ticket/Slack on behalf of YOUR company.
- Automation pipelines where end-users (if any) shouldn’t see per-user OAuth UX.
- Wrapping internal APIs with
qlaud-builtin/http-calland exposing them broadly without per-message ID enumeration.
When NOT to use tenant
- Your end-users need to connect their own accounts (use
dynamic). - You want to gate which tools are available per-conversation (use
explicit). - You have 50+ tenant-shared tools and want to reduce token overhead
(use
dynamic— it’s bounded regardless of tool count).
Hard cap
Tenant mode loads up to 200 tenant-shared tools per request. If you exceed that, switch todynamic (no token cost from the bloat) or
to explicit with a curated subset.
explicit — exactly these IDs
You enumerate the tool IDs in the tools field. The model sees those
verbatim, nothing else.
- Your conversation logic decides per-message which tools the model may use (e.g. step 1 = research only, step 2 = action only).
- You’re building a guided wizard where each step exposes one tool.
- You’re testing a new tool in isolation before going broader.
Mixing modes across a thread
tools_mode is per-message, not per-thread. You can call message 1 with
tenant to give the model your full company toolset, then message 2
with explicit: ["tool_xyz"] to constrain it. The model sees a different
tool array on each call; previous tool_use blocks remain in history but
no longer dispatch unless the tool is in the current request’s set.
Errors
| Status | Meaning |
|---|---|
| 400 | tools_mode is set to anything other than dynamic, tenant, or explicit. |
| 400 | tools_mode: "dynamic" but you also passed tools: [...]. Drop the tools field — meta-tools handle discovery. |
| 400 | tools_mode: "tenant" but you also passed tools: [...]. Drop the tools field — tenant mode auto-attaches everything. |
| 400 | tools_mode: "explicit" (or default with tools) but one of the listed IDs is unknown / revoked. |
See also
tools_mode: dynamicdeep dive — token math, meta-tool semantics- Built-in catalog — every built-in shows up in
tenantmode automatically - Custom HTTP endpoint — the universal “wrap any REST API” tool, perfect companion to
tenantmode - Threads API — the thread message endpoint that consumes
tools_mode