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
(checkout out the documentation for more)
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

























