Skip to content

App Control Tool Reference

This page is the per-tool reference for the application-control tools the host exposes to plugins that opt into tool calling, plus the separate Data category covering the five Data Hub document tools. For how a plugin opts in and renders the loop, read the Tool Calling section of the Plugin Authoring Guide first. This page assumes you have.

These tools share one Rust tool category, AppControl, and one property: every one goes through an existing internal service (the inference pool, the model manager, the download manager, the statistics manager, Hugging Face search, autonomous providers, Hermes settings, or squad storage) rather than any new or platform-specific code path. They observe and operate the running application.

The catalog

Every tool below is category AppControl. "Approval" is required when the tool's definition sets requires_approval: true (mutating tools), and none for read-only tools. The model-oriented backend tools are desktop-only (see Runtime availability); the autonomous-agent and squad tools run on both runtimes; navigate_to_page runs in the WebView.

Tool Approval Purpose
list_models none List models known to this application: downloaded local models and their loaded state, with recommendation-grade metadata and a device-fit label.
get_inference_status none Live status of the local inference server pool: which models are loaded, their serving aliases, ports, and health.
list_downloads none List active and recently finished model downloads with progress.
get_token_usage_stats none Token usage and request statistics: totals, a per-day breakdown, and per-model usage.
search_huggingface_models none Search Hugging Face for downloadable models and report whether each fits this machine's memory and accelerator. Network-requiring.
list_autonomous_providers none List autonomous-agent providers known to this runtime, including availability, unavailable reasons, capabilities, install state, and gateway status.
get_autonomous_gateway none Return the latest cached gateway status for one autonomous-agent provider.
list_autonomous_channels none List up to 50 messaging channels for an autonomous-agent provider.
list_autonomous_channel_messages none List recent messages for one provider channel, capped at 50 messages.
send_autonomous_message required Send a message through one provider channel. Headless callers also need autonomous_message_send or Admin.
list_hermes_pending_approvals none List Hermes governance requests waiting for an operator decision.
decide_hermes_approval required Approve or deny one pending Hermes governance request. Headless callers also need container_write or Admin.
list_squads none List existing squads with their name, description, agent count, and status.
get_squad none One squad's configuration: status, workspace path, planner agent, and the agent roster with each agent's id, name, role, and model.
list_squad_templates none List installed squad templates, both built-in and user-created.
list_squad_tasks none A squad's managed tasks with title, assignee, status, and dependencies. Optionally filtered by status.
get_squad_execution none One execution's stage, wave progress, plan tasks, final result, and token usage.
list_squad_executions none Recorded execution history for a squad, newest first.
load_model required Load a downloaded local model into the inference server. Starts loading and returns immediately.
unload_model required Unload a currently loaded model from the inference server.
download_model required Download a model from Hugging Face into the local model store. One call fetches everything the chosen model needs: every shard of a split model, and for safetensors models the config and tokenizer files too. Starts the download and returns immediately. Network-requiring.
create_squad required Create a new squad, preferring a templateId from list_squad_templates so it starts with a proven agent lineup.
submit_squad_request required Submit a request to a squad, creating an execution.
approve_squad_plan required Approve a plan that is awaiting approval and start the run, the same on the desktop and on a headless server.
reject_squad_plan required Reject a plan. The feedback goes to the planner, which re-plans the same execution; the corrected plan is left waiting for approval and the result reports its task and wave counts.
cancel_squad_execution required Cancel an execution that has not finished.
steer_squad_execution required Send a standing instruction to a running, paused, or unapproved execution. It applies to every later matching turn; nothing already in flight is interrupted.
send_squad_agent_message required Send a message to one squad agent and run its turn. The reply streams into the squad's chat session rather than coming back as the tool result.
navigate_to_page none Navigate the application to a top-level page through the host router. A frontend tool: it executes in the WebView, not the backend.

A plugin advertises a tool only when the tool's name is in its manifest tools allowlist. The bundled Companion Chat plugin allowlists twelve of them; the squad tools added in issue #4581 and the autonomous-agent tools added in issue #4608 are not in that list, so a plugin that wants them adds their names to its own manifest.

Approval and prompt-injection posture

The mutating tools (load_model, unload_model, download_model, send_autonomous_message, decide_hermes_approval, and every squad tool that changes state: create_squad, submit_squad_request, approve_squad_plan, reject_squad_plan, cancel_squad_execution, steer_squad_execution, send_squad_agent_message) carry requires_approval: true. The SDK never runs one without an explicit per-call user approval, and denies by default when the plugin supplies no approval callback. This is the primary defense against indirect prompt injection: a companion that injects Memory Bank content into its system prompt is injecting text an attacker may have influenced, so a state-changing action must never auto-execute. See Deny-by-default approval.

The read-only tools are auto-approvable and run without a prompt, but their activity is still surfaced through the onToolCallStart / onToolResult callbacks.

Initiate-and-poll for long-running actions

load_model and download_model do not block the tool result until the operation finishes. They validate the request, start the operation in the background, and return immediately. This keeps a tool turn fast and avoids model or HTTP timeouts on a multi-minute download. The model observes progress by polling the read-only status tools:

  • get_inference_status reflects a model transitioning to loaded.
  • list_downloads reports download progress and completion.

download_model is per model, not per file. One call enqueues the whole file set of the chosen variant in a single request, so list_downloads shows several entries for one call and naming any one shard of a split model downloads all of them. Calling it once per file is both unnecessary and harmful: between two calls the download list holds a partial file set, which the completion notifier reads as a finished model and announces before the weights have arrived (issue #4493).

The bundled companion's system prompt encodes this behavior so the model reports that the action started and then polls, rather than waiting.

Local-first model recommendation

There is no dedicated "recommend a model" tool. Recommendation is an emergent behavior the model performs over grounded, fit-annotated candidates from two tools:

  • list_models carries a device-fit label for each already-downloaded model.
  • search_huggingface_models covers not-yet-downloaded models, each annotated with whether it fits this machine's memory and accelerator.

The companion's system prompt encodes a local-first ordering: check downloaded models first with list_models, recommend a suitable one whose fit is not "too large", and only call search_huggingface_models when nothing local fits. A proposed Hugging Face model must be downloaded before it can be loaded, and the model is told to say so.

Offline and air-gapped deployments

Two tools require network access: search_huggingface_models and download_model. An air-gapped enterprise deployment is supported without a separate mode. The enterprise tool policy can deny those two tools individually, and because the advertised tool set is the intersection of the manifest allowlist, the host catalog, and the enterprise policy (recomputed every turn), a deployment that denies them leaves the plugin advertising only the local tools. Recommendation and loading then operate entirely on already-downloaded models, and no download is ever proposed or attempted. On a plain network failure, a network-requiring tool fails with a descriptive tool error rather than hanging. No plugin code change is needed for either case.

Enterprise tool policy

Every tool executes through the host's built-in execute path, which runs the enterprise tool-policy gate on every call (Tauri, REST, and registry-fallback paths alike). A tool an administrator has denied is filtered out of the advertised set, and even a model that names it anyway receives a structured policy-denied result instead of execution. Plugin-initiated calls inherit this automatically because they ride the same execute path; no plugin-side policy logic exists or is needed.

Runtime availability

The model-oriented backend tools (list_models, get_inference_status, list_downloads, get_token_usage_stats, load_model, unload_model, download_model, search_huggingface_models) need a Tauri application handle or process-global desktop state: the inference pool, the download manager, the statistics manager. They are listed in the host's single headless-capability gate, which sets available_in_headless: false. The SDK loop reads that flag from the live catalog, so in a headless or browser context these tools are never advertised to the model, and the turn degrades to plain chat if nothing else is available. navigate_to_page is a frontend tool that executes in the WebView and is likewise marked non-headless.

The squad tools are the exception, and were not always. Until issue #4581 they reached squad storage through the application handle too. They now reach the squad subsystem through a process-global handle that both the desktop app and the headless Management API install at startup, the same shape the Data Hub tools use, so available_in_headless is true for all thirteen and they work over POST /api/v1/tools/execute and the MCP endpoint.

Both runtimes do the same work since issue #4954: submit_squad_request runs the planner and, with autoApprove, spawns run_squad_execution, and approve_squad_plan spawns it for a plan that was waiting. Each tool result still reports what happened (plannerStarted, executorStarted) rather than leaving the caller to assume work began. plannerStarted answers whether a planner actually decomposed the request, not whether the runtime called the submission path: run_planner_decomposition degrades to a one-task-per-agent split when the router is down, the planner agent has no usable model, or the planner reply creates no task, and a submission that landed on that split reports plannerStarted: false with plannerDegradedReason naming the cause (issue #4966). The reason stays on the execution, so get_squad_execution carries it on every later poll as well.

The autonomous-agent tools also use process-global runtime handles installed by both desktop and headless bootstrap. Read-only provider, gateway, channel, message, and Hermes approval-list tools are headless-available. Two write-like tools add a runtime scope check on headless transports: send_autonomous_message requires autonomous_message_send or Admin, and decide_hermes_approval requires container_write or Admin. The tools stay advertised over MCP and POST /api/v1/tools/execute; a caller missing the extra scope receives an audited policy-denied tool result.

Data Hub tools (category Data)

The five Data Hub tools are not AppControl tools, but a plugin reaches them the same way: put their names in the manifest tools allowlist and use the host-managed loop. No separate plugin primitive exists.

Tool Approval Purpose
search_data none Search the user's curated document store and return ranked matches with a snippet and each document's handle (D42).
read_data none Read one document by handle: the curated card by default, or the body in full or by section.
list_data none List documents, and the available collections when called without filters.
write_data required Create a note, or update an existing document's annotation card. Every write is recorded as a revision.
delete_data required Move a document to the trash. A soft delete, restorable from the Data page.

Three properties differ from the AppControl catalog:

  • They are headless-available. They reach the store through a process-global handle both the desktop app and the headless Management API publish at startup, so available_in_headless is true and they work over POST /api/v1/tools/execute.
  • Scope is enforced server-side. A collection named in the model's arguments is resolved by the store, and every returned document is filtered against the resolved scope. A collection flagged sensitive is never reachable from a tool call, even when the model names it explicitly, and its name is omitted from list_data output. An agent profile may additionally pin a run to specific collections; the pin narrows and never widens.
  • The body of an existing document cannot be rewritten. It is regenerated from the immutable original by the conversion pipeline, so a tool edit there would be silently discarded. Write to the card instead, or create a new note.

write_data and delete_data carry requires_approval: true for the same prompt-injection reason as the mutating AppControl tools: document text is untrusted model input, so it must not be able to silently rewrite or delete the store.

See Also