Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nearai/ironclaw/llms.txt

Use this file to discover all available pages before exploring further.

IronClaw provides a powerful, security-first tool system that allows agents to interact with external services, execute code, manage data, and extend their capabilities through custom tools.

Architecture

The tool system is built on three pillars:
┌─────────────────────────────────────────────────────────────────────────────┐
│                          IronClaw Tool System                                │
│                                                                              │
│   Built-in Tools ──────▶ Core functionality (HTTP, shell, files, memory)   │
│   (Rust native)                                                              │
│                                                                              │
│   WASM Tools ──────────▶ Sandboxed extensions with capability control       │
│   (Sandboxed)           • Fuel metering   • Memory limits                   │
│                         • Allowlists      • Credential injection             │
│                                                                              │
│   MCP Servers ─────────▶ External tool providers via JSON-RPC               │
│   (External process)    • Pre-built servers  • Any language                 │
└─────────────────────────────────────────────────────────────────────────────┘

Tool Trait

All tools implement the Tool trait defined in src/tools/tool.rs:
#[async_trait]
pub trait Tool: Send + Sync {
    /// Get the tool name.
    fn name(&self) -> &str;

    /// Get a description of what the tool does.
    fn description(&self) -> &str;

    /// Get the JSON Schema for the tool's parameters.
    fn parameters_schema(&self) -> serde_json::Value;

    /// Execute the tool with the given parameters.
    async fn execute(
        &self,
        params: serde_json::Value,
        ctx: &JobContext,
    ) -> Result<ToolOutput, ToolError>;

    /// Whether this tool requires user approval.
    fn requires_approval(&self, _params: &serde_json::Value) -> ApprovalRequirement {
        ApprovalRequirement::Never
    }

    /// Where this tool should execute (Orchestrator or Container).
    fn domain(&self) -> ToolDomain {
        ToolDomain::Orchestrator
    }

    /// Per-invocation rate limit configuration.
    fn rate_limit_config(&self) -> Option<ToolRateLimitConfig> {
        None
    }
}
Location: src/tools/tool.rs:178-266

Tool Domains

Tools are separated by execution domain for security:
DomainDescriptionExamplesRisk
OrchestratorSafe for main processecho, time, json, http, memory_*Low
ContainerMust run in sandboxshell, read_file, write_file, apply_patchHigh
Location: src/tools/tool.rs:64-74 Orchestrator tools run in the main agent process and have no filesystem access. Container tools run inside Docker containers with isolated filesystems.

Tool Registry

The ToolRegistry manages all available tools and provides registration methods for different tool types. Location: src/tools/registry.rs:74-87
pub struct ToolRegistry {
    tools: RwLock<HashMap<String, Arc<dyn Tool>>>,
    builtin_names: RwLock<HashSet<String>>,
    credential_registry: Option<Arc<SharedCredentialRegistry>>,
    secrets_store: Option<Arc<dyn SecretsStore>>,
    rate_limiter: RateLimiter,
}

Registration Methods

// Register built-in tools (echo, time, json, http, web_fetch)
registry.register_builtin_tools();

// Register container tools (shell, file operations)
registry.register_container_tools();

// Register memory tools (requires workspace)
registry.register_memory_tools(workspace);

// Register job management tools
registry.register_job_tools(context_manager, scheduler, ...);

// Register WASM tool from bytes
registry.register_wasm(WasmToolRegistration {
    name: "my_tool",
    wasm_bytes: &bytes,
    runtime: &runtime,
    capabilities: caps,
    ..Default::default()
}).await?;
Locations:
  • Built-in: src/tools/registry.rs:210-224
  • Container: src/tools/registry.rs:236-242
  • Memory: src/tools/registry.rs:274-285
  • WASM: src/tools/registry.rs:470-539

Protected Tool Names

Certain built-in tools cannot be shadowed by dynamic registrations to prevent security bypasses:
const PROTECTED_TOOL_NAMES: &[&str] = &[
    "echo", "time", "json", "http", "shell",
    "read_file", "write_file", "list_dir", "apply_patch",
    "memory_search", "memory_write", "memory_read", "memory_tree",
    "create_job", "list_jobs", "job_status", "cancel_job",
    "build_software", "tool_search", "tool_install", "tool_auth",
    "web_fetch", "message", ...
];
Location: src/tools/registry.rs:36-72

Approval Requirements

Tools can specify when they need user approval:
pub enum ApprovalRequirement {
    Never,                    // No approval needed
    UnlessAutoApproved,       // Needs approval unless session auto-approve enabled
    Always,                   // Always requires explicit approval
}
Location: src/tools/tool.rs:13-21 Example from ShellTool:
fn requires_approval(&self, params: &serde_json::Value) -> ApprovalRequirement {
    let command = params.get("command")
        .and_then(|v| v.as_str())
        .unwrap_or("");
    
    if is_destructive(command) {
        ApprovalRequirement::Always
    } else {
        ApprovalRequirement::UnlessAutoApproved
    }
}

Rate Limiting

Tools can specify per-user rate limits:
pub struct ToolRateLimitConfig {
    pub requests_per_minute: u32,
    pub requests_per_hour: u32,
}

impl Default for ToolRateLimitConfig {
    fn default() -> Self {
        Self {
            requests_per_minute: 60,
            requests_per_hour: 1000,
        }
    }
}
Location: src/tools/tool.rs:31-62 Read-only tools (echo, time, json, file_read) return None for rate limits. Write/external tools (shell, http, file_write) return sensible limits.

Tool Output

Tools return structured output with metadata:
pub struct ToolOutput {
    pub result: serde_json::Value,
    pub cost: Option<Decimal>,
    pub duration: Duration,
    pub raw: Option<String>,
}

impl ToolOutput {
    pub fn success(result: serde_json::Value, duration: Duration) -> Self;
    pub fn text(text: impl Into<String>, duration: Duration) -> Self;
    pub fn with_cost(mut self, cost: Decimal) -> Self;
    pub fn with_raw(mut self, raw: impl Into<String>) -> Self;
}
Location: src/tools/tool.rs:101-147

Schema Validation

All tool parameter schemas are validated at registration time:
pub fn validate_tool_schema(schema: &serde_json::Value, path: &str) -> Vec<String>
Location: src/tools/tool.rs:314-378 Rules enforced:
  1. Top-level must have "type": "object"
  2. Top-level must have "properties" as an object
  3. Every key in "required" must exist in "properties"
  4. Nested objects follow the same rules recursively
  5. Array properties should have "items" defined
Properties without a "type" field are allowed (freeform/any-type), used by tools like json and http for OpenAI compatibility.

Extension Points

The tool system provides multiple extension points:

1. Built-in Tools (Rust)

Create new Rust tools by implementing the Tool trait. See: Built-in Tools Reference

2. WASM Tools (Sandboxed)

Build sandboxed tools in Rust that compile to WebAssembly. See: WASM Tool System

3. MCP Servers (External)

Connect to external tool servers using the Model Context Protocol. See: MCP Integration

4. Software Builder (LLM-driven)

Use the build_software tool to create new tools using AI. See: Building Custom Tools

Next Steps

Built-in Tools

Explore the complete reference of built-in tools

WASM Tools

Learn about the sandboxed WASM tool system

MCP Integration

Connect external tool servers via MCP

Build Tools

Create custom tools using the builder

Build docs developers (and LLMs) love