About Lootbox
Lootbox is an MCP server in the Productivity category: lootbox gives your coding assistant superpowers.
Install
git clone https://github.com/jx-codes/lootboxThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about Lootbox
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
5 checks have not been run yet.
README
Shameless Promo
Starting a new project? Get dev help
Lootbox - Code Mode for LLMs
Code mode doesn't replace MCP - it orchestrates it.
Example: Fetch Jira issues, filter high-priority, store in KV
- MCP: 4 sequential tool calls
- Code mode: 1 script that calls 4 tools
The script is reusable. Now you have a "get-high-priority-jira" tool. It's tools all the way up.
That's what Lootbox does.
What it is
Lootbox is inspired by "Code Mode" - LLMs write TypeScript code to call APIs rather than using tool invocation. This leverages what LLMs are already good at: writing real code with types and IntelliSense. The repository includes example tools for key-value storage, SQLite, knowledge graphs, GraphQL, and filesystem operations that you can copy to your project.
https://blog.cloudflare.com/code-mode/
Why Code Mode?
- LLMs are better at writing code than using artificial tool-calling syntax
- Real-world TypeScript is abundant in training data vs. contrived tool examples
- Code execution allows chaining multiple API calls without token overhead
- Type safety and IntelliSense provide better developer experience
Prerequisites
- Deno 2.x or later
- Git (for cloning the repository)
Quick Install
curl -fsSL https://raw.githubusercontent.com/jx-codes/lootbox/main/install.sh | bash
This installs lootbox to ~/.deno/bin/.
Or build from source:
git clone https://github.com/jx-codes/lootbox
cd lootbox
deno task compile
Quick Start
1. Start Server
lootbox server
2. Initialize Project
lootbox init # Creates .lootbox/ in current directory
The server starts with:
- WebSocket endpoint at
ws://localhost:3000/ws - Web UI at
http://localhost:3000/ui - OpenAPI docs at
http://localhost:3000/doc
3. Discover Available Tools
# List all available tool namespaces
lootbox tools
# Get TypeScript type definitions for specific namespaces
lootbox tools types kv,sqlite,memory
# List available scripts with examples
lootbox scripts
4. Create Your Tools
Create TypeScript files in .lootbox/tools/:
// .lootbox/tools/myapi.ts
export async function processData(args: {
items: string[];
threshold: number;
}): Promise<{ processed: number; results: string[] }> {
const results = args.items.filter((item) => item.length > args.threshold);
return { processed: results.length, results };
}
5. Execute Scripts
# Execute inline code
lootbox exec 'console.log(await tools.kv.get({key: "test"}))'
# Execute from file
lootbox script.ts
# Execute from stdin
cat script.ts | lootbox
Example Tools
The repository includes example tools that demonstrate common use cases. You can copy these to your own .lootbox/tools/ directory:
Location in Repository: .lootbox/tools/
To use: Copy the desired tool files from the repository's .lootbox/tools/ directory to your project's .lootbox/tools/ directory.
Usage Example (After Copying Tools)
// Using example tools (after copying to your .lootbox/tools/)
const kvResult = await tools.kv.set({
key: "user:1",
value: { name: "Alice" },
});
const userData = await tools.kv.get({ key: "user:1" });
// SQLite queries
await tools.sqlite.execute({
sql: "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)",
});
await tools.sqlite.query({
sql: "SELECT * FROM users WHERE name = ?",
params: ["Alice"],
});
// Knowledge graph
await tools.memory.createEntities({
entities: [
{ name: "Alice", type: "person", properties: { age: 30 } },
{ name: "Bob", type: "person", properties: { age: 25 } },
],
});
await tools.memory.createRelations({
relations: [{ from: "Alice", to: "Bob", type: "knows" }],
});
// GraphQL
const result = await tools.graphql.query({
endpoint: "https://api.example.com/graphql",
query: "{ user(id: 1) { name email } }",
});
Script Management
Lootbox includes a script management system for creating reusable, documented scripts.
Scripts Directory
Scripts are stored in .lootbox/scripts/ and can be organized in subdirectories.
Creating Scripts
# Create a new script from template
lootbox scripts init process-data
# This creates .lootbox/scripts/process-data.ts with template
Script Format
Scripts support JSDoc comments for documentation and examples:
/**
* Process and format tags from JSON input
* @example echo '{"tags": ["typescript", "deno"]}' | lootbox memory/tags.ts
* @example echo '{"tags": ["a", "b"], "filter": "a"}' | lootbox memory/tags.ts
*/
const input = stdin().json();
if (!input || typeof input !== "object") {
console.error(
JSON.stringify({
error: "Invalid input. Expected JSON object",
})
);
throw new Error("Invalid input");
}
// Your script logic here
console.log(JSON.stringify(result, null, 2));
Running Scripts
Use lootbox scripts to list all available scripts with descriptions and examples from JSDoc.
# Scripts auto-resolve from .lootbox/scripts/
lootbox process-data.ts
# Subdirectories work too
lootbox memory/tags.ts
# Pipe data to scripts
echo '{"tags": ["a", "b"]}' | lootbox memory/tags.ts
stdin() Helper
When piping data to scripts, use the stdin() helper function:
Methods:
.text()- Returns trimmed text content.json()- Returns parsed JSON object or null if invalid.lines()- Returns array of non-empty, trimmed lines.raw()- Returns raw input without processing
Example:
// Process JSON input
const data = stdin().json();
console.log(data);
// Process text lines
const lines = stdin().lines();
lines.forEach((line) => console.log(line.toUpperCase()));
// Get raw text
const raw = stdin().raw();
Configuration
Create lootbox.config.json in your project directory:
{
"port": 3000,
"serverUrl": "ws://localhost:3000/ws",
"lootboxRoot": ".lootbox",
"lootboxDataDir": "./data",
"mcpServers": {
// WIP
}
}
Configuration Options:
port- Server port (default: 3000)serverUrl- Override WebSocket URL for custom host/protocol (optional, derived from port if not specified)lootboxRoot- Directory containing tools/, workflows/, scripts/ subdirectories (default:.lootbox)lootboxDataDir- Directory for runtime data storage (optional, defaults to~/.local/share/lootboxon Linux/Mac,%LOCALAPPDATA%\lootboxon Windows)mcpServers- External MCP server configurations (optional)
Directory Resolution (priority order):
- Explicit
--lootbox-rootflag lootboxRootfrom config file- Local
.lootbox/directory (if exists) - Global
~/.lootbox/directory
CLI Flags:
--port <number>- Custom server port--lootbox-root <path>- Custom tools directory--lootbox-data-dir <path>- Custom data directory--server <url>- Custom server URL for execution
CLI Command Reference
Execution
lootbox script.ts- Execute TypeScript filelootbox -e 'code'orlootbox exec 'code'- Execute inline codecat script.ts | lootbox- Execute from stdin
Tools & Scripts Discovery
lootbox tools- List all tool namespaces (local + MCP)lootbox tools types <namespaces>- Get TypeScript types (comma-separated)lootbox scripts- List available scripts with exampleslootbox scripts init <name>- Create new script from template
Server & Init
lootbox server- Start server (default port 3000)lootbox server --port <port> --lootbox-root <dir> --lootbox-data-dir <dir>- Start with custom settingslootbox init- Create.lootbox/directory structure
Help
lootbox --help- Human-friendly helplootbox --llm-help- LLM-focused command referencelootbox --config-help- Configuration documentationlootbox --version- Show version number
MCP Server Integration
Integrate external MCP servers alongside local tools. MCP tools are namespaced with mcp_{servername} prefix.
Configuration
{
"mcpServers": {
// WIP may not work properly with all mcp servers
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
}
}
}
Usage
Access MCP tools with mcp_{servername} namespace prefix:
// Filesystem MCP server
await tools.mcp_filesystem.read_file({ path: "/etc/hosts" });
await tools.mcp_filesystem.list_directory({ path: "/tmp" });
// GitHub MCP server
await tools.mcp_github.create_issue({
repo: "owner/repo",
title: "Bug Report",
body: "Description...",
});
// Mix MCP tools with local tools
const data = await tools.kv.get({ key: "config" });
await tools.mcp_github.create_issue({
repo: "owner/repo",
title: data.value.title,
});
Discovery
MCP server namespaces appear alongside local tools when running lootbox tools, prefixed with mcp_ (e.g., mcp_filesystem, mcp_github).
Workflows
Execute multi-step workflows with Handlebars templating, loops, and session tracking.
Commands:
lootbox workflow start <file>- Start workflowlootbox workflow step- Execute/show current steplootbox workflow step --end-loop="reason"- End loop early (after min iterations)lootbox workflow status- Check current positionlootbox workflow reset- Reset to beginninglootbox workflow abort --abort="reason"- Abort with reason
Workflow File Format (YAML)
Workflows are YAML files located in .lootbox/workflows/ or current directory.
Basic Structure:
steps:
- title: Step 1 - Setup
prompt: |
Initialize the project structure.
- title: Step 2 - Implementation
prompt: |
Implement the core features.
- title: "Loop: Testing (iteration {{loop}}/{{totalSteps}})"
loop:
min: 2
max: 5
prompt: |
Run tests and fix issues.
{{#if (eq loop 1)}}
This is the first iteration.
{{else}}
This is iteration {{loop}}.
{{/if}}
Handlebars Templating
Workflows support Handlebars templates with built-in helpers:
Template Variables:
{{step}}- Current step number (1-based){{totalSteps}}- Total number of steps{{loop}}- Current loop iteration (only in loop steps, 1-based)
Helpers:
{{eq a b}}- Equal comparison{{ne a b}}- Not equal{{lt a b}}- Less than{{gt a b}}- Greater than{{lte a b}}- Less than or equal{{gte a b}}- Greater than or equal
Example with Conditionals:
steps:
- title: "Step {{step}} of {{totalSteps}}"
prompt: |
{{#if (eq step 1)}}
This is the first step.
{{else if (eq step totalSteps)}}
This is the final step.
{{else}}
This is an intermediate step.
{{/if}}
Loop Mechanics
Loop steps repeat with configurable min/max iterations. When max iterations reached, automatically advances to next step.
- title: "Review Loop ({{loop}}/{{max}})"
loop:
min: 2 # Minimum iterations before --end-loop allowed
max: 5 # Maximum iterations (auto-advances)
prompt: |
Review the code. Current iteration: {{loop}}
Session Tracking
Each workflow run has a unique session ID for tracking workflow events:
- Session ID generated on
workflow start - Persisted in
.lootbox-workflow.jsonstate file - Used for workflow logging and analytics
- Visible with
lootbox workflow status
Workflow State
Workflow state stored in .lootbox-workflow.json includes:
- Current step index
- Loop iteration count
- Session ID
- Workflow file path
State automatically managed - deleted on completion or abort.
Tool Requirements
All tools must follow these patterns:
// ✅ Correct - with single parameter (object)
export async function functionName(args: ArgsType): Promise<ReturnType> {
// Implementation
}
// ✅ Correct - no parameters
export async function getInfo(): Promise<InfoResult> {
return { version: "0.0.54" };
}
// ✅ Correct - with TypeScript interfaces
export interface CreateArgs {
name: string;
value: number;
}
export interface CreateResult {
success: boolean;
id: string;
}
export async function create(args: CreateArgs): Promise<CreateResult> {
return { success: true, id: "123" };
}
// ❌ Wrong - not exported
async function privateFunction(args: any) {}
// ❌ Wrong - multiple parameters
export function wrongSignature(x: number, y: string) {}
Requirements:
- Must be exported using
exportkeyword - Must have 0 or 1 parameter only
- If 1 parameter, it must be an object type
- Multiple positional parameters are not supported
- Should use TypeScript interfaces for type safety
- Should be async (return Promise) for consistency
Best Practices:
- Export TypeScript interfaces for args and results
- Use JSDoc comments for function documentation
- Keep functions focused on single responsibility
- Handle errors with clear error messages
- Return structured objects, not primitives
See the "Example Tools" section above for reference implementations (kv, sqlite, memory, graphql).
HTTP API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Server health check |
/namespaces |
GET | List available tool namespaces and MCP servers |
/types |
GET | All TypeScript type definitions for all tools |
/types/:namespaces |
GET | Types for specific namespaces (comma-separated) |
/client.ts |
GET | Generated TypeScript client with type definitions |
/ui |
GET | Interactive status dashboard (HTML) |
/doc |
GET | OpenAPI/Swagger documentation (HTML) |
/ws |
WS | WebSocket endpoint for script execution |
Examples
# Get all namespaces
curl http://localhost:3000/namespaces
# Get types for specific namespaces
curl http://localhost:3000/types/kv,sqlite,memory
# Get all types
curl http://localhost:3000/types
# Download TypeScript client
curl http://localhost:3000/client.ts > client.ts
# Health check
curl http://localhost:3000/health
Development
Development Mode
Development mode enables hot-reloading and debugging:
# Start server in development mode (MODE=development)
deno task start
# This enables:
# - Automatic restarts on file changes
# - Verbose logging
# - Development-specific features
Building
# Build UI (required before compile)
deno task ui:build
# Compile standalone binary
deno task compile
# UI development server
deno task ui:dev
# UI preview mode
deno task ui:preview
Code Quality
# Format code
deno task fmt
# Lint code
deno task lint
Production Mode
# Start in production mode (no auto-reload)
deno task start:prod
# Or run compiled binary
./lootbox server
Architecture
┌─────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Clients │ │ lootbox │ │ Tools │
│ │ │ │ │ │
│ • Web UI │◄────────►│ • Auto-discover │◄────────►│ • .lootbox/tools│
│ • CLI │ WS │ • Type gen │ Load │ • MCP Servers │
│ • LLM/MCP │ HTTP │ • Sandboxing │ │ │
└─────────────┘ └─────────────────┘ └─────────────────┘
Key Features:
- WebSocket RPC server with auto-discovery
- Sandboxed script execution with timeout
- Full TypeScript type safety
- MCP server integration
Technical Details
Worker-Based Execution
- Fast Startup: Workers stay warm, eliminating cold-start overhead
Script Sandboxing
- Isolated Execution: User scripts run in separate Deno processes
- Limited Permissions: Scripts only have
--allow-netaccess - 10-Second Timeout: Automatic termination for long-running scripts
- Injected Client:
toolsobject automatically available
Type System
- AST Analysis: Uses
ts-morphto extract TypeScript types - Namespace Prefixing: Prevents conflicts (e.g.,
Kv_GetArgs) - JSDoc Support: Extracts documentation comments
- Selective Generation: Filter types by namespace
Security Considerations
Local-First Design: Lootbox runs on your local machine in trusted environments.
- Tool Functions: Run with
--allow-all- only include trusted code - User Scripts: Sandboxed with
--allow-netonly - No Authentication: Designed for localhost use
- MCP Servers: External processes with configurable permissions
Inspiration
This project implements ideas from:
- Cloudflare's "Code Mode: the better way to use MCP"
- Model Context Protocol (MCP)
License
MIT License - See LICENSE file for details.
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.