Skip to content

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).

ToolDescription
read_fileRead file contents within allowed root
shellExecute allowlisted shell commands
glob_searchFind files by glob pattern
content_searchSearch file contents with regex
memory_storeStore entries in agent memory
memory_recallRecall entries from agent memory
memory_forgetRemove entries from agent memory
image_infoExtract image metadata
docx_readRead DOCX file contents
pdf_readRead PDF file contents
screenshotCapture screen screenshots
task_planCreate and manage task plans
process_toolExecute external processes
subagent_spawnSpawn background sub-agents
subagent_listList running sub-agents
subagent_manageManage sub-agent lifecycle
cli_discoveryDiscover CLI capabilities
proxy_configQuery proxy configuration
delegate_coordination_statusCheck delegate coordination status
sop_listList Standard Operating Procedures
sop_statusCheck SOP execution status
sop_advanceAdvance SOP to next step
sop_approveApprove SOP step
sop_executeExecute an SOP
hardware_board_infoQuery hardware board information
hardware_memory_mapRead hardware memory map
hardware_memory_readRead hardware memory
wasm_moduleLoad WASM modules
wasm_tool_execExecute WASM tool
ToolDescriptionConfig
write_fileWrite file contents within allowed root[security.write_file]
file_editEdit files with search/replaceEnabled with write_file
apply_patchValidate and apply structured patchesEnabled with write_file
git_operationsGit operations (status, diff, log, etc.)enable_git
http_requestMake HTTP requests to allowed domains[http_request]
web_fetchFetch and convert web pages to markdown[web_fetch]
url_validationValidate URLs against access policy[url_access]
web_searchSearch the web via DuckDuckGo/Brave/etc[web_search]
browserBrowser automation and screenshot[browser]
browser_openOpen URLs in system browser[browser]
cron_addAdd a cron schedule[cron]
cron_listList cron schedules[cron]
cron_removeRemove a cron schedule[cron]
cron_updateUpdate a cron schedule[cron]
cron_pausePause a cron schedule[cron]
cron_resumeResume a cron schedule[cron]
scheduleSchedule one-time tasks[cron]
composioComposio integrationenable_composio
pushoverPushover notificationsenable_pushover
ToolDescriptionCondition
agents_ipcInter-process communication between agentsenable_agents_ipc (default: true)
mcpModel Context Protocol bridge[security.mcp]
model_routing_configQuery model routing configurationWhen router is configured
delegateSpawn sub-agent with scoped toolsWhen [agents.*] configured

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,
}

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. unless allow_sensitive_file_reads is true
  • Size cap — 64 KiB per read (configurable)
[security.read_file]
allowed_root = "." # workspace root
max_read_bytes = 65536 # 64 KiB
allow_binary = false

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_file protections 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 = true
allowed_root = "."
max_write_bytes = 65536 # 64 KiB

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 Patch

Security: Validates patch structure before any file modification. Rejects malformed envelopes.


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_commands can 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:

Terminal window
# Allowed — semicolon is inside single quotes
echo 'hello;world'
# Blocked — unquoted semicolon is shell injection
echo hello;world
# Blocked — backtick is always forbidden
echo `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 = 8
max_arg_length = 128
max_output_bytes = 8192
forbidden_chars = ";&|><$`\n\r"

All network tools share the URL Access Policy for SSRF prevention.

[url_access]
block_private_ip = true # blocks 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
allow_loopback = false # blocks 127.0.0.0/8
enforce_domain_allowlist = false
domain_allowlist = []
domain_blocklist = []

Private IP ranges blocked:

RangeDescription
10.0.0.0/8Private Class A
172.16.0.0/12Private Class B
192.168.0.0/16Private Class C
169.254.0.0/16Link-local
100.64.0.0/10Carrier-grade NAT
0.0.0.0/8Unspecified
240.0.0.0/4Reserved
fc00::/7IPv6 unique local
fe80::/10IPv6 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.

Performs HTTP requests (GET, POST, PUT, DELETE) to allowed domains.

Input: <METHOD> <URL> [JSON_BODY]

GET https://api.example.com/data
POST 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 = true
allowed_domains = ["api.example.com", "*.internal.dev"]
max_response_size = 1000000 # 1 MB
timeout_secs = 30

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.

Searches the web via configurable provider.

[web_search]
enabled = true
provider = "duckduckgo" # duckduckgo, brave, perplexity, exa, jina
max_results = 5
timeout_secs = 15

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 limitingmax_depth prevents infinite delegation chains
  • Tool blocklist — the delegate tool 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 = 2
agentic = true
max_iterations = 10
allowed_tools = ["read_file", "web_search", "memory"]

Inter-process communication between agents with encrypted storage.

Operations:

OperationInputDescription
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.

Queries the model routing configuration to determine which provider/model handles a request.

Operations:

OperationDescription
list_routesReturns all model route hints
list_embedding_routesReturns all embedding route hints
resolve_hintFind route by hint name
classify_queryClassify query to appropriate hint
route_queryComplete routing decision for query

Tools are gated by the autonomy policy, which controls what requires user approval:

LevelRead ToolsWrite ToolsNetwork Tools
ReadOnlyAuto-approveBlockedBlocked
SupervisedAuto-approveRequires approvalRequires approval
FullAuto-approveAuto-approveAuto-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 = true
forbidden_paths = ["/etc", "/root", "/proc", "/sys"]
auto_approve = ["read_file", "memory"]
always_ask = ["shell", "write_file"]
allow_sensitive_file_reads = false
allow_sensitive_file_writes = false

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.

MechanismIsolationOverheadUse Case
WASM pluginsSandboxed (memory + CPU + capability-gated)~1-5ms (cached)Third-party tools, community plugins
FFI pluginsHost process (not sandboxed)NativeEmbedding in Swift/Kotlin/Python/Node.js apps
Process pluginsFull (OS process)~5-50msAny-language tools via stdin/stdout JSON
MCP serversFull (separate process)NetworkTool server interoperability
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.

Plugins are auto-discovered from three locations (later overrides earlier):

PathScopeHot-Reload
~/.local/share/agentzero/plugins/Global (user-wide)No
$PROJECT/.agentzero/plugins/Project-specificNo
./plugins/Current working directory (development)Yes
Terminal window
agentzero plugin new --id my-tool --scaffold rust # Scaffold project
agentzero plugin test --manifest manifest.json --wasm plugin.wasm --execute # Test
agentzero plugin package --manifest manifest.json --wasm plugin.wasm # Package
agentzero plugin install --package my-tool.tar # Install from file
agentzero plugin install my-tool # Install from registry
agentzero plugin list # List installed
agentzero plugin enable <id> / disable <id> # Toggle state
agentzero plugin search <query> # Search registry
agentzero plugin remove --id my-tool # Remove
[runtime.wasm]
fuel_limit = 1000000 # execution budget
memory_limit_mb = 64 # max memory
max_module_size_mb = 50 # max .wasm file size
allow_workspace_read = false
allow_workspace_write = false
allowed_hosts = [] # network access allowlist
[runtime.wasm.security]
require_workspace_relative_tools_dir = true
reject_symlink_modules = true
reject_symlink_tools_dir = true
capability_escalation_mode = "deny"
module_hash_policy = "warn" # warn or enforce
  • 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 are higher-level composable behaviors built on top of tools.

Terminal window
# List installed skills
agentzero skill list
# Install a skill
agentzero skill install --name my-skill --source local
# Test a skill
agentzero skill test --name my-skill
# Remove a skill
agentzero skill remove --name my-skill

MCP tool servers can be integrated when enabled. Servers must be explicitly allowlisted.

[security.mcp]
enabled = true
allowed_servers = ["filesystem", "github"]

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.


ComponentSettingDefault
read_file max sizemax_read_bytes64 KiB
write_file max sizemax_write_bytes64 KiB
write_file enabledenabledfalse
shell max argsmax_args8
shell max arg lengthmax_arg_length128 bytes
shell max outputmax_output_bytes8 KiB
web_fetch max sizemax_bytes64 KiB
WASM fuel limitfuel_limit1,000,000
WASM memory limitmemory_limit_mb64 MB
Private IP blockingblock_private_iptrue
Loopback accessallow_loopbackfalse
Sensitive filesallow_sensitive_file_readsfalse