docs/src/tool-registry.md
Rama main · réplica de lectura del repositorio original.
# Tool Registry
The tool registry manages all tools available to the agent during a
conversation. It tracks where each tool comes from, which audience may use it,
and supports filtering by both properties.
## Tool Sources
Every registered tool has a `ToolSource` that identifies its origin:
- **`Builtin`** — tools shipped with the binary (exec, web_fetch, etc.)
- **`Mcp { server }`** — tools provided by an MCP server, tagged with the
server name
- **`Wasm { component_hash }`** — tools provided by a WASM component
This replaces the previous convention of identifying MCP tools by their
`mcp__` name prefix, providing type-safe filtering instead of string matching.
## Registration
Every entry also has a `ToolAudience`:
- **`Trusted`** — authenticated owner and authorized operator turns
- **`Public`** — eligible for explicitly configured untrusted origins such as
webhook payloads
Registration is fail-closed. Built-in tools are trusted-only by default, and
all MCP and WASM tools are trusted-only. A reviewed built-in must explicitly use
`register_public` to become public. Tool descriptions and third-party metadata
cannot grant public access.
Public registration does not grant a tool to messaging-channel guests or
shared rooms. Those turns receive an additional deny-all request policy. A
webhook also receives no tools unless its configuration explicitly opts in.
```rust
// Trusted-only built-in tool (the default)
registry.register(Box::new(MyTool::new()));
// Built-in reviewed as safe for untrusted input
registry.register_public(Box::new(PublicTool::new()));
// Trusted-only MCP tool, tagged with server name
registry.register_mcp(Box::new(adapter), "github".into());
```
Duplicate names are rejected rather than overwritten. Intentional wrappers use
`replace`, which preserves the original source and audience metadata.
## Filtering
When MCP tools are disabled for a session, the registry can produce a filtered
copy:
```rust
// Type-safe: filters by ToolSource::Mcp variant
let no_mcp = registry.clone_without_mcp();
// Remove all MCP tools in-place (used during sync)
let removed_count = registry.unregister_mcp();
// Keep only tools explicitly reviewed for public use
let public = registry.clone_for_audience(ToolAudience::Public);
```
## Schema Output
`list_schemas()` includes source metadata in every tool schema:
```json
{
"name": "exec",
"description": "Execute a command",
"parameters": { ... },
"source": "builtin",
"audience": "trusted"
}
```
```json
{
"name": "mcp__github__search",
"description": "Search GitHub",
"parameters": { ... },
"source": "mcp",
"mcpServer": "github",
"audience": "trusted"
}
```
The source and audience fields are available to the UI for diagnostics. The
audience is enforced by registry filtering before model tool schemas are built;
it is not an instruction that the model is expected to follow.
## Lazy Registry Mode
By default every LLM turn includes full JSON schemas for all registered tools.
With many MCP servers this can burn 15,000+ tokens per turn. **Lazy mode**
replaces all tool schemas with a single `tool_search` meta-tool that the model
uses to discover and activate tools on demand.
### Configuration
```toml
[tools]
registry_mode = "lazy" # default: "full"
```
### How it works
1. The model receives only `tool_search` in its tool list.
2. `tool_search(query="memory")` returns name + description pairs (max 15), no schemas.
3. `tool_search(name="memory_search")` returns the full schema and **activates** the tool.
4. On the next iteration the model calls `memory_search` directly — standard pipeline, hooks fire normally.
The runner re-computes schemas each iteration, so activated tools appear
immediately. The iteration limit is tripled in lazy mode to account for the
extra discovery round-trips.
### When to use
- Many MCP servers connected (50+ tools)
- Long conversations where input token cost matters
- Sub-agent runs that only need a few specific tools
In **full** mode (default), all schemas are sent every turn — no behavioral change from before this feature.