SpadeBox is a set of sandboxed tools and a JS runtime for AI agents, written in Rust with JavaScript and Python bindings. Focus on your domain-specific tools and harness — give your agent SpadeBox for the rest.
| Category | Tools |
|---|---|
| Files | read_file, write_file, edit_file, move, grep, glob |
| Network | fetch |
| Code execution | js_repl, js_exec |
Features
- Lightweight sandboxing: SpadeBox uses the
cap-stdcrate for file system sandboxing, and domain allowlisting for HTTP requests. The JS engine is based on boa, and uses the same sandboxing policies. - Configurable: Pick only the tools you need for your application: files, network, or code execution, or any combination of those.
- No
bashtool: SpadeBox has been designed to work well even without abashtool. The tools are designed to cover all the basic operations an agent needs without having to shell-out. If you would like your agent to usebashyou can provide your ownbashtool in addition to SpadeBox. - Native function in JS runtime: Expose native functions to the SpadeBox JS runtime to allow your agents to programmatically interact with your application. Compatible with all supported host language bindings.
- Secret management for HTTP requests: Register credentials for specific HTTP domains and get a token that can be safely shared with your agent. Spadebox replaces the token by the actual secret within HTTP requests to the target domain.
- Default limits to preserve context: SpadeBox's tools try to safeguard your agent context, with default limits to tool outputs and HTML-to-markdown conversion.
Usage
JavaScript
import { SpadeBox } from "@spadebox/spadebox";
const sb = new SpadeBox()
.enableFiles("/workspace")
.enableHttp()
.allow("api.example.com", ["GET", "POST"])
.enableJs();
const tools = sb.tools(); // pass to your LLM as available tools
// dispatch a tool call coming from the model
const result = await sb.callTool("read_file", JSON.stringify({ path: "src/main.rs" }));
Rust
use spadebox_core::{Sandbox, DomainRule, HttpVerb, enabled_tools, call_tool};
let mut sandbox = Sandbox::new();
sandbox
.enable_fs("/workspace")?
.enable_http()
.allow(DomainRule::new("api.example.com", vec![HttpVerb::Get, HttpVerb::Post])?)
.enable_js();
let tools = enabled_tools(&sandbox); // pass to your LLM as available tools
// dispatch a tool call coming from the model
let result = call_tool(&sandbox, "read_file", r#"{"path":"src/main.rs"}"#.into()).await?;
Python
from spadebox import SpadeBox
sb = (SpadeBox()
.enable_files("/workspace")
.enable_http()
.allow("api.example.com", ["GET", "POST"])
.enable_js())
tools = sb.tools() # pass to your LLM as available tools
# dispatch a tool call coming from the model
result = sb.call_tool("read_file", '{"path": "src/main.rs"}')
MCP
# filesystem tools only
spadebox-mcp --files /workspace
# HTTP tools only (allow specific domains and verbs)
spadebox-mcp --allow "api.example.com:GET,POST" --allow "*.cdn.example.com:GET"
# JavaScript REPL only
spadebox-mcp --js
# all tools
spadebox-mcp --files /workspace --allow "api.example.com:GET" --js