Tools & Plugins
AgentZero ships with 50+ built-in tools and supports extension via WASM plugins, process plugins, MCP servers, and skills. Every tool enforces fail-closed security — capabilities are denied unless explicitly enabled. All tools implement input_schema() for structured tool-use APIs (Anthropic tool_use, OpenAI function calling).
Built-in Tools
Section titled “Built-in Tools”Always Enabled
Section titled “Always Enabled”| Tool | Description |
|---|---|
read_file | Read file contents within allowed root |
shell | Execute allowlisted shell commands |
glob_search | Find files by glob pattern |
content_search | Search file contents with regex |
memory_store | Store entries in agent memory |
memory_recall | Recall entries from agent memory |
memory_forget | Remove entries from agent memory |
image_info | Extract image metadata |
docx_read | Read DOCX file contents |
pdf_read | Read PDF file contents |
screenshot | Capture screen screenshots |
task_plan | Create and manage task plans |
process_tool | Execute external processes |
subagent_spawn | Spawn background sub-agents |
subagent_list | List running sub-agents |
subagent_manage | Manage sub-agent lifecycle |
cli_discovery | Discover CLI capabilities |
proxy_config | Query proxy configuration |
delegate_coordination_status | Check delegate coordination status |
sop_list | List Standard Operating Procedures |
sop_status | Check SOP execution status |
sop_advance | Advance SOP to next step |
sop_approve | Approve SOP step |
sop_execute | Execute an SOP |
hardware_board_info | Query hardware board information |
hardware_memory_map | Read hardware memory map |
hardware_memory_read | Read hardware memory |
wasm_module | Load WASM modules |
wasm_tool_exec | Execute WASM tool |
Policy-Gated (Disabled by Default)
Section titled “Policy-Gated (Disabled by Default)”| Tool | Description | Config |
|---|---|---|
write_file | Write file contents within allowed root | [security.write_file] |
file_edit | Edit files with search/replace | Enabled with write_file |
apply_patch | Validate and apply structured patches | Enabled with write_file |
git_operations | Git operations (status, diff, log, etc.) | enable_git |
http_request | Make HTTP requests to allowed domains | [http_request] |
web_fetch | Fetch and convert web pages to markdown | [web_fetch] |
url_validation | Validate URLs against access policy | [url_access] |
web_search | Search the web via DuckDuckGo/Brave/etc | [web_search] |
browser | Browser automation and screenshot | [browser] |
browser_open | Open URLs in system browser | [browser] |
cron_add | Add a cron schedule | [cron] |
cron_list | List cron schedules | [cron] |
cron_remove | Remove a cron schedule | [cron] |
cron_update | Update a cron schedule | [cron] |
cron_pause | Pause a cron schedule | [cron] |
cron_resume | Resume a cron schedule | [cron] |
schedule | Schedule one-time tasks | [cron] |
composio | Composio integration | enable_composio |
pushover | Pushover notifications | enable_pushover |
Conditionally Registered
Section titled “Conditionally Registered”| Tool | Description | Condition |
|---|---|---|
agents_ipc | Inter-process communication between agents | enable_agents_ipc (default: true) |
mcp | Model Context Protocol bridge | [security.mcp] |
model_routing_config | Query model routing configuration | When router is configured |
delegate | Spawn sub-agent with scoped tools | When [agents.*] configured |
Tool Trait
Section titled “Tool Trait”All tools implement the core Tool trait:
#[async_trait]pub trait Tool: Send + Sync { fn name(&self) -> &'static str; fn description(&self) -> &'static str { "" } fn input_schema(&self) -> Option<serde_json::Value> { None } async fn execute(&self, input: &str, ctx: &ToolContext) -> anyhow::Result<ToolResult>;}The input_schema() method returns a JSON Schema describing expected input parameters. When provided, this enables structured tool-use APIs (Anthropic tool_use, OpenAI function calling) and input validation before execution. All 50+ built-in tools implement this method.
The ToolContext carries workspace-scoped security state:
pub struct ToolContext { pub workspace_root: String, pub allow_sensitive_file_reads: bool, pub allow_sensitive_file_writes: bool,}File Tools
Section titled “File Tools”read_file
Section titled “read_file”Reads text file contents with full path-safety enforcement.
Input: Relative file path (e.g., src/main.rs)
Security controls:
- Path traversal prevention — rejects
..components and absolute paths - Canonicalization — resolves symlinks and validates the final path stays within
allowed_root - Hard-link guard (B7) — blocks files with multiple hard links to prevent symlink attacks
- Binary detection — rejects files containing null bytes or non-UTF8 content
- Sensitive file detection — blocks
.env,.aws/credentials,.ssh/id_rsa,.gnupg/,credentials.json, etc. unlessallow_sensitive_file_readsis true - Size cap — 64 KiB per read (configurable)
[security.read_file]allowed_root = "." # workspace rootmax_read_bytes = 65536 # 64 KiBallow_binary = falsewrite_file
Section titled “write_file”Writes text files with the same path-safety enforcement as read_file.
Input: JSON payload:
{ "path": "src/output.txt", "content": "file contents here", "overwrite": false, "dry_run": false}Security controls:
- Disabled by default — requires explicit
enabled = true - All
read_fileprotections apply (path traversal, canonicalization, hard-link guard, sensitive file detection) - Existence check — errors if file exists and
overwrite: false - Dry-run mode — preview capability without writing to disk
Output: dry_run={bool} path={path} bytes={count} overwrite={bool}
[security.write_file]enabled = trueallowed_root = "."max_write_bytes = 65536 # 64 KiBapply_patch
Section titled “apply_patch”Validates and applies structured patches using a strict envelope format.
Input: Patch content with BEGIN/END markers:
*** Begin Patch*** Update File: src/main.rs@@ ... patch content ...*** End PatchSecurity: Validates patch structure before any file modification. Rejects malformed envelopes.
Shell Tool
Section titled “Shell Tool”Executes shell commands with allowlist-driven security. Only explicitly permitted commands can run.
Input: Command string (e.g., ls -la src/)
Security controls:
- Command allowlist — only commands listed in
allowed_commandscan execute - Default allowlist:
ls,pwd,cat,echo - Quote-aware validation — metacharacters (
; & | > < $) are forbidden when unquoted, but allowed inside single/double quotes - Always forbidden — backtick (
`) and null byte are blocked even inside quotes - Argument limits — max 8 arguments of 128 bytes each
- Output truncation — stdout/stderr capped at 8 KiB with truncation notice
Output: status={code}\nstdout:\n...\nstderr:\n...
Examples:
# Allowed — semicolon is inside single quotesecho 'hello;world'
# Blocked — unquoted semicolon is shell injectionecho hello;world
# Blocked — backtick is always forbiddenecho `whoami`Shell tokenizer: The command parser performs quote-aware tokenization supporting single quotes (no interpretation), double quotes (with escape handling), and backslash escapes. Each character’s quoting context is tracked for policy validation.
[security]allowed_commands = ["ls", "pwd", "cat", "echo", "grep", "find", "git"]
[security.shell]max_args = 8max_arg_length = 128max_output_bytes = 8192forbidden_chars = ";&|><$`\n\r"Network Tools
Section titled “Network Tools”All network tools share the URL Access Policy for SSRF prevention.
URL Access Policy
Section titled “URL Access Policy”[url_access]block_private_ip = true # blocks 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16allow_loopback = false # blocks 127.0.0.0/8enforce_domain_allowlist = falsedomain_allowlist = []domain_blocklist = []Private IP ranges blocked:
| Range | Description |
|---|---|
10.0.0.0/8 | Private Class A |
172.16.0.0/12 | Private Class B |
192.168.0.0/16 | Private Class C |
169.254.0.0/16 | Link-local |
100.64.0.0/10 | Carrier-grade NAT |
0.0.0.0/8 | Unspecified |
240.0.0.0/4 | Reserved |
fc00::/7 | IPv6 unique local |
fe80::/10 | IPv6 link-local |
DNS rebinding protection: Domain names are resolved to IP addresses and checked against the private IP blocklist. This prevents attackers from registering a domain, then changing DNS to point to an internal IP.
http_request
Section titled “http_request”Performs HTTP requests (GET, POST, PUT, DELETE) to allowed domains.
Input: <METHOD> <URL> [JSON_BODY]
GET https://api.example.com/dataPOST https://api.example.com/items {"name": "item1"}Security pipeline:
Input → URL Parse → Scheme Check (http/https only) →Policy Check (blocklist) → IP Resolution → Private IP Check →DNS Rebinding Check → Domain Allowlist Check → Execute[http_request]enabled = trueallowed_domains = ["api.example.com", "*.internal.dev"]max_response_size = 1000000 # 1 MBtimeout_secs = 30web_fetch
Section titled “web_fetch”Fetches content from URLs and returns the response body.
Input: URL string
Output: status={code}\n{body}
Security: Same URL access policy as http_request. Automatic response truncation at 64 KiB default.
web_search
Section titled “web_search”Searches the web via configurable provider.
[web_search]enabled = trueprovider = "duckduckgo" # duckduckgo, brave, perplexity, exa, jinamax_results = 5timeout_secs = 15Agent Tools
Section titled “Agent Tools”delegate
Section titled “delegate”Spawns a sub-agent with scoped tools. Prevents infinite delegation chains.
Input:
{ "agent": "researcher", "prompt": "Find the latest Rust async runtime benchmarks"}Security controls:
- Depth limiting —
max_depthprevents infinite delegation chains - Tool blocklist — the
delegatetool itself is forbidden in sub-agent tool lists (prevents recursion) - Scoped tool access — each delegate configuration specifies its own
allowed_tools
Per-agent configuration:
[agents.researcher]provider = "https://api.openai.com/v1"model = "gpt-4"max_depth = 2agentic = truemax_iterations = 10allowed_tools = ["read_file", "web_search", "memory"]agents_ipc
Section titled “agents_ipc”Inter-process communication between agents with encrypted storage.
Operations:
| Operation | Input | Description |
|---|---|---|
send | {"op":"send","from":"a1","to":"a2","payload":"msg"} | Send message between agents |
recv | {"op":"recv","to":"agent_name"} | Receive pending messages |
list | {"op":"list","to":"?","from":"?","limit":"?"} | List messages with filters |
clear | {"op":"clear","to":"?","from":"?"} | Clear messages |
Security: All IPC data is encrypted at rest using EncryptedJsonStore. Messages include timestamps for audit trail.
model_routing
Section titled “model_routing”Queries the model routing configuration to determine which provider/model handles a request.
Operations:
| Operation | Description |
|---|---|
list_routes | Returns all model route hints |
list_embedding_routes | Returns all embedding route hints |
resolve_hint | Find route by hint name |
classify_query | Classify query to appropriate hint |
route_query | Complete routing decision for query |
Autonomy Levels
Section titled “Autonomy Levels”Tools are gated by the autonomy policy, which controls what requires user approval:
| Level | Read Tools | Write Tools | Network Tools |
|---|---|---|---|
ReadOnly | Auto-approve | Blocked | Blocked |
Supervised | Auto-approve | Requires approval | Requires approval |
Full | Auto-approve | Auto-approve | Auto-approve |
Read tools (auto-approved): read_file, glob, search, memory_read
Write tools (gated): write_file, shell, apply_patch, browser, http_request
Forbidden paths (all levels): /etc, /root, /proc, /sys, ~/.ssh, ~/.gnupg, ~/.aws
[autonomy]level = "supervised"workspace_only = trueforbidden_paths = ["/etc", "/root", "/proc", "/sys"]auto_approve = ["read_file", "memory"]always_ask = ["shell", "write_file"]allow_sensitive_file_reads = falseallow_sensitive_file_writes = falseWASM Plugins
Section titled “WASM Plugins”AgentZero runs plugins in a sandboxed WASM environment with WASI capabilities, strict resource limits, and SHA-256 integrity verification. Plugins implement the same Tool trait as native tools — the agent loop treats them identically.
Four Extension Mechanisms
Section titled “Four Extension Mechanisms”| Mechanism | Isolation | Overhead | Use Case |
|---|---|---|---|
| WASM plugins | Sandboxed (memory + CPU + capability-gated) | ~1-5ms (cached) | Third-party tools, community plugins |
| FFI plugins | Host process (not sandboxed) | Native | Embedding in Swift/Kotlin/Python/Node.js apps |
| Process plugins | Full (OS process) | ~5-50ms | Any-language tools via stdin/stdout JSON |
| MCP servers | Full (separate process) | Network | Tool server interoperability |
Writing a Plugin (10 Lines)
Section titled “Writing a Plugin (10 Lines)”use agentzero_plugin_sdk::prelude::*;
declare_tool!("my_tool", execute);
fn execute(input: ToolInput) -> ToolOutput { let req: serde_json::Value = serde_json::from_str(&input.input) .unwrap_or_default(); let name = req["name"].as_str().unwrap_or("world"); ToolOutput::success(format!("Hello, {name}!"))}Build: cargo build --target wasm32-wasip1 --release
For a complete example with typed input, az_log host calls, ToolOutput::with_warning, and WASI filesystem access, see the reference notepad plugin at plugins/agentzero-plugin-reference/notepad/.
See the Plugin Authoring Guide for the full walkthrough.
Plugin Discovery
Section titled “Plugin Discovery”Plugins are auto-discovered from three locations (later overrides earlier):
| Path | Scope | Hot-Reload |
|---|---|---|
~/.local/share/agentzero/plugins/ | Global (user-wide) | No |
$PROJECT/.agentzero/plugins/ | Project-specific | No |
./plugins/ | Current working directory (development) | Yes |
Plugin Lifecycle
Section titled “Plugin Lifecycle”agentzero plugin new --id my-tool --scaffold rust # Scaffold projectagentzero plugin test --manifest manifest.json --wasm plugin.wasm --execute # Testagentzero plugin package --manifest manifest.json --wasm plugin.wasm # Packageagentzero plugin install --package my-tool.tar # Install from fileagentzero plugin install my-tool # Install from registryagentzero plugin list # List installedagentzero plugin enable <id> / disable <id> # Toggle stateagentzero plugin search <query> # Search registryagentzero plugin remove --id my-tool # RemoveSecurity Controls
Section titled “Security Controls”[runtime.wasm]fuel_limit = 1000000 # execution budgetmemory_limit_mb = 64 # max memorymax_module_size_mb = 50 # max .wasm file sizeallow_workspace_read = falseallow_workspace_write = falseallowed_hosts = [] # network access allowlist
[runtime.wasm.security]require_workspace_relative_tools_dir = truereject_symlink_modules = truereject_symlink_tools_dir = truecapability_escalation_mode = "deny"module_hash_policy = "warn" # warn or enforceWASM Isolation Policy
Section titled “WASM Isolation Policy”- Network: disabled by default
- Filesystem write: disabled by default
- WASI capabilities: granted per-plugin via manifest + policy
- Bounded execution: epoch-based CPU timeout (default: 30s)
- Bounded memory: configurable max memory (default: 256MB)
- Capability validation: undeclared imports fail at load time (not runtime)
- SHA-256 integrity: verified on every install and load
For the full ABI specification, host callbacks, and manifest schema, see the Plugin API Reference.
Skills
Section titled “Skills”Skills are higher-level composable behaviors built on top of tools.
# List installed skillsagentzero skill list
# Install a skillagentzero skill install --name my-skill --source local
# Test a skillagentzero skill test --name my-skill
# Remove a skillagentzero skill remove --name my-skillMCP (Model Context Protocol)
Section titled “MCP (Model Context Protocol)”MCP tool servers can be integrated when enabled. Servers must be explicitly allowlisted.
[security.mcp]enabled = trueallowed_servers = ["filesystem", "github"]Connection Caching
Section titled “Connection Caching”MCP server connections are cached in an McpSession for the lifetime of the tool instance. The first call to a server spawns the subprocess and caches the stdin/stdout handles. Subsequent calls reuse the existing connection, avoiding process startup overhead on every tool invocation.
Tool schemas from each server’s tools/list response are also cached and used for structured tool definitions. If a connection error occurs, the session is cleared and retried once automatically.
Security Defaults Summary
Section titled “Security Defaults Summary”| Component | Setting | Default |
|---|---|---|
read_file max size | max_read_bytes | 64 KiB |
write_file max size | max_write_bytes | 64 KiB |
write_file enabled | enabled | false |
shell max args | max_args | 8 |
shell max arg length | max_arg_length | 128 bytes |
shell max output | max_output_bytes | 8 KiB |
web_fetch max size | max_bytes | 64 KiB |
| WASM fuel limit | fuel_limit | 1,000,000 |
| WASM memory limit | memory_limit_mb | 64 MB |
| Private IP blocking | block_private_ip | true |
| Loopback access | allow_loopback | false |
| Sensitive files | allow_sensitive_file_reads | false |