A3S Docs
A3S Code

Built-in Tools

13 built-in tools (14 with sandbox) for file operations, shell execution, search, web access, git worktree, and subagent delegation

Built-in Tools

A3S Code ships with 13 built-in tools (14 with the sandbox feature) covering file operations, shell execution, search, web access, git worktree, and subagent delegation. All tools execute in-process via native Rust implementations.

Tool Reference

Prop

Type

File Operations

read

Read file contents with line numbers. Supports offset and limit for large files.

{
  "file_path": "src/main.rs",
  "offset": 0,
  "limit": 100
}

write

Create or overwrite a file. Automatically creates parent directories.

{
  "file_path": "src/config.rs",
  "content": "pub struct Config {\n    pub port: u16,\n}\n"
}

edit

Replace a specific string in a file. Useful for targeted modifications.

{
  "file_path": "src/main.rs",
  "old_string": "fn main() {",
  "new_string": "fn main() -> Result<()> {"
}

patch

Apply a unified diff patch. Best for complex multi-line edits.

{
  "file_path": "src/lib.rs",
  "diff": "--- a/src/lib.rs\n+++ b/src/lib.rs\n@@ -1,3 +1,4 @@\n+use anyhow::Result;\n use std::io;\n"
}

grep

Search file contents using ripgrep patterns. Supports regex, globs, and context lines.

{
  "pattern": "fn.*async",
  "path": "src/",
  "glob": "*.rs",
  "context": 2
}

glob

Find files matching a glob pattern.

{
  "pattern": "src/**/*.rs"
}

ls

List directory contents with file sizes and types.

{
  "path": "src/"
}

Shell

bash

Execute shell commands. Commands run in the session's workspace directory.

{
  "command": "cargo test --lib -- test_name"
}

Security: Use Permission System to control bash access:

policy.deny("bash(rm -rf:*)");  // Block destructive commands
policy.ask("bash(*)");          // Require confirmation for all bash

Web

web_fetch

Fetch content from a URL. Returns text content extracted from HTML.

{
  "url": "https://docs.rs/tokio/latest/tokio/"
}

Search the web using multiple search engines.

{
  "query": "rust async trait object",
  "engine": "google"
}

Direct Tool Execution

Call tools directly on the session without going through the LLM:

// Convenience wrappers
let content = session.read_file("src/main.rs").await?;
let output = session.bash("cargo test --lib").await?;
let files = session.glob("**/*.rs").await?;
let matches = session.grep("fn main").await?;

// Generic tool call with JSON args
let result = session.tool("edit", serde_json::json!({
    "file_path": "src/main.rs",
    "old_string": "fn main() {",
    "new_string": "fn main() -> Result<()> {"
})).await?;
println!("[{}] {}", result.exit_code, result.output);
// Convenience wrappers
const content = await session.readFile('src/main.rs');
const output = await session.bash('cargo test --lib');
const files = await session.glob('**/*.rs');
const matches = await session.grep('fn main');

// Generic tool call
const result = await session.tool('edit', {
  file_path: 'src/main.rs',
  old_string: 'fn main() {',
  new_string: 'fn main() -> Result<()> {',
});
console.log(`[${result.exitCode}] ${result.output}`);
# Convenience wrappers
content = session.read_file("src/main.rs")
output = session.bash("cargo test --lib")
files = session.glob("**/*.rs")
matches = session.grep("fn main")

# Generic tool call with dict args
result = session.tool("edit", {
    "file_path": "src/main.rs",
    "old_string": "fn main() {",
    "new_string": "fn main() -> Result<()> {"
})
print(f"[{result['exit_code']}] {result['output']}")

Git

git_worktree

Manage Git worktrees for parallel workspace isolation. Supports status, create, list, and remove subcommands.

{
  "command": "create",
  "branch": "feature-auth",
  "path": "/repo/wt-feature-auth"
}

See Git Worktree Example for full multi-language examples.

Subagent Delegation

task

Delegate work to a specialized child agent. The child agent runs in its own session with its own conversation history. See Subagents for details.

{
  "description": "Write unit tests for the auth module",
  "prompt": "Create comprehensive tests for src/auth.rs covering all edge cases"
}

Sandbox (Optional)

sandbox

Execute commands in an isolated A3S Box MicroVM. Requires the sandbox Cargo feature.

a3s-code-core = { version = "0.7", features = ["sandbox"] }

Two modes of operation:

Transparent Routing — When SandboxConfig is set on the session, the bash tool silently routes through the sandbox:

use a3s_code_core::{SessionOptions, SandboxConfig};

let session = agent.session(".", Some(
    SessionOptions::new().with_sandbox(SandboxConfig {
        image: "ubuntu:22.04".into(),
        memory_mb: 512,
        network: false,
        ..SandboxConfig::default()
    })
))?;

// bash commands run inside the MicroVM sandbox
let result = session.send("Run the test suite", None).await?;

Explicit sandbox Tool — With the feature enabled, a sandbox tool is registered so the LLM can choose to use it explicitly. The workspace is mounted at /workspace inside the sandbox.

Prop

Type

File Version History

All file-modifying tools (write, edit, patch) automatically capture a snapshot before making changes. You can:

  • View the diff between versions
  • Restore any previous version
  • Track all modifications made during a session

The file history maintains up to 500 snapshots per session.

Extending with Custom Tools

Beyond built-in tools, A3S Code supports external tool integration via:

  • MCP — Connect external tool servers via Model Context Protocol (JSON-RPC 2.0, stdio + HTTP+SSE)
  • Custom Tool Trait — Implement the Tool trait in Rust and register with ToolRegistry

See MCP for external tool integration examples.

API Reference

Tool input/output schemas

read

Prop

Type

write

Prop

Type

edit

Prop

Type

patch

Prop

Type

grep

Prop

Type

glob

Prop

Type

ls

Prop

Type

bash

Prop

Type

web_fetch

Prop

Type

web_search

Prop

Type

task

Prop

Type

batch

Prop

Type

git_worktree

Prop

Type

Custom Tool trait (Rust)

use a3s_code_core::tools::{Tool, ToolOutput};
use async_trait::async_trait;

#[async_trait]
impl Tool for MyTool {
    fn name(&self) -> &str { "my_tool" }
    fn description(&self) -> &str { "Does something useful" }
    fn parameters(&self) -> serde_json::Value { /* JSON Schema */ }
    async fn execute(&self, args: serde_json::Value) -> anyhow::Result<ToolOutput> {
        Ok(ToolOutput::success("result"))
    }
}

session.register_tool(Arc::new(MyTool));

On this page