### Start Sandstorm API Server via CLI Source: https://context7.com/tomascupr/sandstorm/llms.txt Shows how to start the Sandstorm FastAPI server using the `ds serve` command. It covers starting with default settings, specifying a custom port, enabling development mode with auto-reloading, and provides an example for production deployment using Gunicorn. ```bash # Start with defaults (0.0.0.0:8000) ds serve # Custom port ds serve --port 3000 # Development mode with auto-reload ds serve --reload # Production deployment with Gunicorn pip install gunicorn gunicorn sandstorm.main:app \ --worker-class uvicorn.workers.UvicornWorker \ --workers 4 \ --bind 0.0.0.0:8000 \ --timeout 600 ``` -------------------------------- ### Install and Run Basic CLI Agent Query Source: https://context7.com/tomascupr/sandstorm/llms.txt Installs the Sandstorm CLI from PyPI and demonstrates a basic agent query to find trending GitHub repositories. It also shows how to set required API keys and provides examples for specifying models, increasing timeouts, and handling complex tasks with more conversation turns. ```bash # Install from PyPI pip install duvo-sandstorm # Set required API keys export ANTHROPIC_API_KEY=sk-ant-... export E2B_API_KEY=e2b_... # Basic query (query is the default command) ds "Find the top 10 trending Python repos on GitHub and summarize each in one sentence" # Specify model and increase timeout ds "Analyze this entire codebase for security vulnerabilities" --model opus --timeout 600 # Increase max conversation turns for complex tasks ds "Build a data pipeline that scrapes, transforms, and visualizes stock data" --max-turns 30 # Output raw JSON for piping to other tools ds "Parse this API and generate OpenAPI spec" --json-output | jq '.structured_output' # Override API keys inline ds "hello world" --anthropic-api-key sk-ant-... --e2b-api-key e2b_... ``` -------------------------------- ### Content Brief Generation Examples (Bash) Source: https://github.com/tomascupr/sandstorm/blob/main/examples/content-brief/README.md Demonstrates various use cases for the sandstorm CLI's content brief generation, including briefs for landing pages, SEO articles, thought leadership pieces, and product comparison pages. Each example uses a natural language prompt to guide the brief creation. ```bash # Landing page brief ds "Brief for a landing page targeting enterprise DevOps teams evaluating AI coding tools" # SEO-focused article ds "Create a brief for 'how to implement rate limiting in Node.js' targeting mid-level developers" # Thought leadership ds "Brief for a LinkedIn article about why most AI agent frameworks will fail" # Product comparison ds "Content brief for a comparison page: our product vs Competitor X for data pipeline orchestration" ``` -------------------------------- ### Python Client Example for Sandstorm API Source: https://github.com/tomascupr/sandstorm/blob/main/README.md Provides a Python example using the `httpx` and `httpx-sse` libraries to interact with the Sandstorm `/query` endpoint. It demonstrates sending a prompt and iterating over Server-Sent Events (SSE) for the response. ```python import httpx from httpx_sse import connect_sse with httpx.Client() as client: with connect_sse( client, "POST", "https://your-sandstorm-host/query", json={ "prompt": "Scrape the top 50 HN stories, cluster by topic, save to output/hn.csv" }, ) as events: for sse in events.iter_sse(): print(sse.data) ``` -------------------------------- ### Dockerize and Run Sandstorm Application Source: https://github.com/tomascupr/sandstorm/blob/main/README.md This Dockerfile sets up a Python 3.12 environment, copies the project files, installs dependencies, exposes port 8000, and defines the command to serve the application. The subsequent bash commands build the Docker image and run it, mapping port 8000. It requires Docker to be installed. ```dockerfile FROM python:3.12-slim WORKDIR /app COPY . . RUN pip install --no-cache-dir . # or: pip install duvo-sandstorm EXPOSE 8000 CMD ["ds", "serve", "--host", "0.0.0.0", "--port", "8000"] ``` ```bash docker build -t sandstorm . docker run -p 8000:8000 --env-file .env sandstorm ``` -------------------------------- ### Deploy Sandstorm with Gunicorn for Production Source: https://github.com/tomascupr/sandstorm/blob/main/docs/deployment.md Installs Gunicorn and runs the Sandstorm application with multiple Uvicorn workers for concurrent request handling. This is recommended for production environments. Adjust --workers based on CPU cores and --timeout for longest agent runs. ```bash pip install gunicorn gunicorn sandstorm.main:app \ --worker-class uvicorn.workers.UvicornWorker \ --workers 4 \ --bind 0.0.0.0:8000 \ --timeout 600 ``` -------------------------------- ### Run Sandstorm Development Server Source: https://github.com/tomascupr/sandstorm/blob/main/docs/deployment.md Starts the Sandstorm application using its built-in server for development or simple deployments. It listens on all network interfaces on port 8000. ```bash ds serve --host 0.0.0.0 --port 8000 ``` -------------------------------- ### Docker Deployment Configuration for Sandstorm Source: https://context7.com/tomascupr/sandstorm/llms.txt Provides a Dockerfile to build a Sandstorm container image and example commands to build and run the container. It installs dependencies, exposes the necessary port, and sets the entry point. ```dockerfile FROM python:3.12-slim WORKDIR /app COPY . . RUN pip install --no-cache-dir duvo-sandstorm EXPOSE 8000 CMD ["ds", "serve", "--host", "0.0.0.0", "--port", "8000"] ``` ```bash # Build and run docker build -t sandstorm . docker run -p 8000:8000 --env-file .env sandstorm ``` -------------------------------- ### Run Competitive Analysis (Bash) Source: https://github.com/tomascupr/sandstorm/blob/main/examples/competitive-analysis/README.md Execute a competitive analysis by providing a query to the 'ds' command. This example compares Vercel, Netlify, and Cloudflare Pages as deployment platforms. ```bash cd examples/competitive-analysis ds "Compare Vercel, Netlify, and Cloudflare Pages as deployment platforms" ``` -------------------------------- ### POST /query (TypeScript Client) Source: https://context7.com/tomascupr/sandstorm/llms.txt This example shows how to consume the SSE stream from the /query endpoint using a TypeScript client in Node.js or a browser environment. ```APIDOC ## POST /query (TypeScript Client) ### Description Consumes the SSE stream from the Sandstorm API's `/query` endpoint using `fetch` in TypeScript. It reads the response body chunk by chunk and parses SSE events. ### Method POST ### Endpoint http://localhost:8000/query ### Parameters #### Query Parameters None #### Request Body - **prompt** (string) - Required - The user's prompt or instruction. - **model** (string) - Optional - The specific model to use (e.g., "sonnet"). - **timeout** (integer) - Optional - The timeout in seconds for the request. ### Request Example ```json { "prompt": "Fetch recent arxiv papers on LLM agents, extract findings, write a lit review", "model": "sonnet", "timeout": 600 } ``` ### Response #### Success Response (200) - **event.type** (string) - The type of the SSE event. - **event** (object) - The parsed SSE event data. #### Response Example ```json { "type": "message", "content": "Processing request..." } ``` ``` -------------------------------- ### Quick Start Content Brief Generation (Bash) Source: https://github.com/tomascupr/sandstorm/blob/main/examples/content-brief/README.md Initiates the content brief generation process for a blog post about serverless vs containers. It utilizes the 'ds' command-line tool, likely part of the sandstorm project, to process the natural language prompt. ```bash cd examples/content-brief ds "Create a content brief for a blog post about serverless vs containers in 2025" ``` -------------------------------- ### Run Security Audit (Bash) Source: https://github.com/tomascupr/sandstorm/blob/main/examples/security-auditor/README.md Executes a security audit on specified Python and requirements files using the 'ds' command. This is a quick start example for initiating a basic audit. ```bash cd examples/security-auditor ds "Run a security audit on this codebase" -f /path/to/src/auth.py -f /path/to/requirements.txt ``` -------------------------------- ### Upload Files to Sandbox via CLI Source: https://context7.com/tomascupr/sandstorm/llms.txt Demonstrates how to upload local files to the Sandstorm sandbox for the AI agent to process using the `-f` flag. Examples include uploading single files, multiple files for comparison, and source code for review. It notes that files are uploaded to `/home/user/{filename}` and only text files are supported via CLI. ```bash # Upload a single file for analysis ds "Analyze this data and find outliers, create visualizations" -f data.csv # Upload multiple files for comparison ds "Compare these configurations and highlight differences" -f prod.json -f staging.json # Upload source code for review ds "Review this code for bugs and security issues" -f src/main.py -f src/utils.py -f src/config.py # Files are uploaded to /home/user/{filename} in the sandbox # Only text files are supported via CLI; use the API for binary files ``` -------------------------------- ### Run Multiple Agents Concurrently with Python Source: https://github.com/tomascupr/sandstorm/blob/main/docs/deployment.md Demonstrates how to run multiple agents concurrently using Python's asyncio and httpx libraries. Each agent request is sent to the Sandstorm server, which spins up an independent E2B sandbox for each prompt. ```python import asyncio import httpx from httpx_sse import aconnect_sse async def run_agent(client: httpx.AsyncClient, prompt: str): async with aconnect_sse( client, "POST", "http://localhost:8000/query", json={"prompt": prompt}, ) as events: async for sse in events.aiter_sse(): print(sse.data) async def main(): prompts = [ "Scrape the top 50 YC companies and save as CSV", "Analyze Python dependency security for requests==2.31.0", "Fetch today's arxiv papers on LLM agents and write a summary", "Build a SQLite DB of US national parks from NPS.gov", ] async with httpx.AsyncClient(timeout=600) as client: await asyncio.gather(*[run_agent(client, p) for p in prompts]) asyncio.run(main()) ``` -------------------------------- ### Execute Code Reviewer (Bash) Source: https://github.com/tomascupr/sandstorm/blob/main/examples/code-reviewer/README.md Initiates a code review for bugs and security issues using the 'ds' command with a specified file. This is the basic command to start a review. ```bash cd examples/code-reviewer ds "Review this code for bugs and security issues" -f /path/to/your/file.py ``` -------------------------------- ### Sample Content Brief Output (JSON) Source: https://github.com/tomascupr/sandstorm/blob/main/examples/content-brief/README.md An example of a structured content brief generated by the tool. It includes title options, target audience, keywords, recommended word count, an outline with key points, competitor analysis with identified gaps, a unique angle suggestion, and a call-to-action. ```json { "title_options": [ "Serverless vs Containers in 2025: When to Use Each (and When to Use Both)", "The Serverless vs Containers Debate Is Over — Here's What Won", "Serverless or Containers? A Decision Framework for Modern Teams" ], "target_audience": "Backend developers and DevOps engineers evaluating architecture options for new projects", "primary_keyword": "serverless vs containers", "secondary_keywords": [ "serverless architecture", "container orchestration", "AWS Lambda vs ECS", "when to use serverless", "kubernetes alternatives" ], "search_intent": "commercial", "recommended_word_count": 2500, "outline": [ { "heading": "The State of Serverless and Containers in 2025", "subpoints": ["Market adoption numbers", "Key shifts since 2023"], "key_points": [ "Serverless adoption has grown 40% YoY", "Container orchestration complexity is driving serverless migration" ] }, { "heading": "When Serverless Wins", "subpoints": ["Event-driven workloads", "Variable traffic", "Small teams"], "key_points": [ "Cost efficiency for bursty workloads", "Zero ops overhead for teams under 10 engineers" ] }, { "heading": "When Containers Win", "subpoints": ["Long-running processes", "GPU workloads", "Complex networking"], "key_points": [ "Predictable performance for latency-sensitive apps", "Required for ML inference and GPU workloads" ] } ], "competitor_content": [ { "title": "Serverless vs Containers: A Comprehensive Guide", "url": "https://example.com/serverless-vs-containers", "angle": "Technical comparison with code examples", "gap": "No cost analysis or decision framework — just feature comparison" } ], "unique_angle": "Focus on the decision framework rather than the technology comparison — help readers choose based on their team size, traffic patterns, and ops capacity", "cta_suggestion": "Download our serverless readiness assessment checklist" } ``` -------------------------------- ### Configure API Keys for Sandstorm Source: https://github.com/tomascupr/sandstorm/blob/main/README.md Demonstrates how to set API keys for different services like Anthropic and E2B in a `.env` file. It also shows how to send requests to the Sandstorm API, with an option to override API keys per request. ```bash # .env -- set once, forget about it ANTHROPIC_API_KEY=sk-ant-... E2B_API_KEY=e2b_... # Then just send prompts: curl -N -X POST https://your-sandstorm-host/query \ -d '{"prompt": "Crawl docs.stripe.com/api and generate an OpenAPI spec as YAML"}' # Or override per-request: curl -N -X POST https://your-sandstorm-host/query \ -d '{"prompt": "...", "anthropic_api_key": "sk-ant-other", "e2b_api_key": "e2b_other"}' ``` -------------------------------- ### Configure MCP Servers Source: https://github.com/tomascupr/sandstorm/blob/main/README.md Shows how to attach external tools or services via MCP (Model Context Protocol) in the `sandstorm.json` configuration. This includes options for stdio, HTTP, and SSE servers. ```json { "mcp_servers": { "sqlite": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-sqlite", "/home/user/data.db"] }, "remote-api": { "type": "sse", "url": "https://api.example.com/mcp/sse", "headers": { "Authorization": "Bearer your-token" } } } } ``` -------------------------------- ### POST /query Source: https://github.com/tomascupr/sandstorm/blob/main/README.md This endpoint initiates a query to the Sandstorm service. It creates a fresh E2B sandbox, runs the provided prompt with agent tools, and streams back results as SSE events. The sandbox is destroyed upon completion. ```APIDOC ## POST /query ### Description Initiates a query to the Sandstorm service, creating an isolated E2B sandbox to run a prompt with agent tools. Results are streamed back via SSE, and the sandbox is ephemeral. ### Method POST ### Endpoint /query ### Parameters #### Query Parameters None #### Request Body - **prompt** (string) - Required - The prompt to be executed by the agent. - **files** (object) - Optional - A key-value map of file paths and their content to be uploaded into the sandbox before execution. - **key** (string) - File path within the sandbox (e.g., `logs/app.log`). - **value** (string) - File content. - **output_format** (object) - Optional - Configuration for structured output. - **type** (string) - Required - The type of output format (e.g., `json_schema`). - **schema** (object) - Required - The JSON schema for validation. - **agents** (object) - Optional - Configuration for defining and using subagents. - **mcp_servers** (object) - Optional - Configuration for attaching external tools via MCP. - **key** (string) - Name of the MCP server. - **value** (object) - Configuration for the MCP server (type, command, args, url, headers, env). - **skills_dir** (string) - Optional - Path to the directory containing Claude Code Skills. ### Request Example ```json { "prompt": "Parse these server logs, find error spikes, and write an incident report", "files": { "logs/app.log": "2024-01-15T10:23:01Z ERROR [auth] connection pool exhausted\n...", "logs/deploys.json": "[{\"sha\": \"a1b2c3\", \"ts\": \"2024-01-15T10:20:00Z\"}]" }, "output_format": { "type": "json_schema", "schema": { "type": "object", "properties": { "summary": { "type": "string" }, "items": { "type": "array", "items": { "type": "object" } } }, "required": ["summary", "items"] } } } ``` ### Response #### Success Response (200) - **stream** (boolean) - Indicates if the response is a stream of Server-Sent Events. - **data** (object) - SSE event data. The structure depends on the event type (e.g., `content`, `tool_code`, `error`). #### Response Example (SSE Stream) ``` event: content data: {"type": "text", "text": "Analyzing logs..."} event: tool_code data: {"type": "code", "tool_code": "import subprocess\nsubprocess.run(['grep', 'ERROR', 'logs/app.log'])"} event: content data: {"type": "text", "text": "Found error spikes."} ``` ``` -------------------------------- ### GET /health Source: https://github.com/tomascupr/sandstorm/blob/main/README.md Check the health status of the Sandstorm service. ```APIDOC ## GET /health ### Description Check the health status of the Sandstorm service. ### Method GET ### Endpoint /health ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```bash curl https://your-sandstorm-host/health ``` ### Response #### Success Response (200) - **status** (string) - Indicates the health status of the service. #### Response Example ```json { "status": "ok" } ``` ``` -------------------------------- ### Compare Specific Products (Bash) Source: https://github.com/tomascupr/sandstorm/blob/main/examples/competitive-analysis/README.md Compare specific products within a category, like SaaS billing platforms, using the 'ds' command. ```bash # Compare specific products ds "Compare Stripe, Paddle, and LemonSqueezy for SaaS billing" ``` -------------------------------- ### Focus on Niche Comparison (Bash) Source: https://github.com/tomascupr/sandstorm/blob/main/examples/competitive-analysis/README.md Direct the analysis to a niche market, such as backend-as-a-service platforms for startups, using the 'ds' command. ```bash # Focus on a niche ds "Compare Supabase, Firebase, and Neon as backend-as-a-service for startups" ``` -------------------------------- ### Execute Agent Tasks via API POST /query Source: https://context7.com/tomascupr/sandstorm/llms.txt Demonstrates how to use the `/query` endpoint of the Sandstorm API to run agent tasks. It shows basic queries, configuring models and timeouts, uploading files via the request body, and passing API keys per request for multi-tenancy. The response format as an SSE stream with different event types is also illustrated. ```bash # Basic query curl -N -X POST http://localhost:8000/query \ -H "Content-Type: application/json" \ -d '{"prompt": "Create a Python script that fetches weather data and saves it as JSON"}' # With model and timeout configuration curl -N -X POST http://localhost:8000/query \ -H "Content-Type: application/json" \ -d '{ "prompt": "Scrape the top 50 HN stories, cluster by topic, save to output/hn.csv", "model": "opus", "max_turns": 25, "timeout": 600 }' # With file uploads (files written to /home/user/{path}) curl -N -X POST http://localhost:8000/query \ -H "Content-Type: application/json" \ -d '{ "prompt": "Parse these server logs, find error spikes, and write an incident report", "files": { "logs/app.log": "2024-01-15T10:23:01Z ERROR [auth] connection pool exhausted\n2024-01-15T10:23:02Z ERROR [auth] timeout waiting for connection", "logs/deploys.json": "[{\"sha\": \"a1b2c3\", \"ts\": \"2024-01-15T10:20:00Z\"}]" } }' # Multi-tenant: pass API keys per request curl -N -X POST http://localhost:8000/query \ -H "Content-Type: application/json" \ -d '{ "prompt": "Analyze this repository", "anthropic_api_key": "sk-ant-customer-key", "e2b_api_key": "e2b_customer-key" }' # Response: SSE stream with event types: system, assistant, user, result, error # event: message # data: {"type": "assistant", "message": {"content": [{"type": "text", "text": "Creating script..."}]}} # data: {"type": "result", "subtype": "success", "num_turns": 5, "cost_usd": 0.0234} ``` -------------------------------- ### Code Reviewer Configuration (JSON) Source: https://github.com/tomascupr/sandstorm/blob/main/examples/code-reviewer/README.md Defines the configuration for the code reviewer agent, specifying the system prompt, model, allowed tools, and output format. This configuration guides the reviewer's behavior and output. ```json { "system_prompt": "Expert code reviewer persona", "model": "sonnet", "allowed_tools": ["Read", "Glob", "Grep"], "output_format": "JSON schema with findings array" } ``` -------------------------------- ### Configure OpenRouter Environment Variables Source: https://github.com/tomascupr/sandstorm/blob/main/README.md Sets up the necessary environment variables to use OpenRouter with the Sandstorm project. This involves specifying the base URL for the OpenRouter API and providing an API key. ```bash ANTHROPIC_BASE_URL=https://openrouter.ai/api OPENROUTER_API_KEY=sk-or-... ANTHROPIC_DEFAULT_SONNET_MODEL=anthropic/claude-sonnet-4 # or any model ID ``` -------------------------------- ### Define Claude Code Skills for Domain Knowledge Source: https://context7.com/tomascupr/sandstorm/llms.txt Adds reusable domain knowledge via Claude Code Skills. Skills are defined in Markdown files within the `.claude/skills/` directory. This example shows a checklist for OWASP Top 10 vulnerabilities. ```markdown # OWASP Top 10 Security Audit Checklist ## A01:2021 — Broken Access Control - [ ] Missing authorization checks on endpoints - [ ] Insecure direct object references (IDOR) - [ ] CORS misconfiguration allowing unauthorized origins ## A03:2021 — Injection - [ ] SQL injection via string concatenation - [ ] Command injection via os.system(), subprocess.shell=True - [ ] XSS via unescaped user input in templates ``` -------------------------------- ### Sandstorm Architecture Overview Source: https://github.com/tomascupr/sandstorm/blob/main/README.md Illustrates the request flow from a client to the Sandstorm service, through an E2B sandbox, and back to the client via SSE stream. It highlights the tools and capabilities available within the sandbox. ```text Client --POST /query--> FastAPI --> E2B Sandbox (isolated VM) <---- SSE stream <---- stdout <-- runner.mjs --> query() from Agent SDK |-- Bash, Read, Write, Edit |-- Glob, Grep, WebSearch, WebFetch '-- subagents, MCP servers, structured output ``` -------------------------------- ### Query Sandstorm Agent with Model Alias Source: https://github.com/tomascupr/sandstorm/blob/main/docs/openrouter.md Example of sending a query to the Sandstorm agent using a model alias (e.g., 'sonnet') which is then routed through OpenRouter to a configured model. This demonstrates the agent's ability to use tool use, file access, and streaming with various models. ```bash curl -N -X POST http://localhost:8000/query \ -H "Content-Type: application/json" \ -d '{"prompt": "Analyze this CSV and build a chart", "model": "sonnet"}' ``` -------------------------------- ### Fetch and Process Data with TypeScript Source: https://github.com/tomascupr/sandstorm/blob/main/README.md This snippet demonstrates how to make a POST request to a Sandstorm host to query for information, stream the response using a TextDecoder, and log the output. It requires the 'fetch' API and assumes a running Sandstorm instance. ```typescript const res = await fetch("https://your-sandstorm-host/query", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ prompt: "Fetch recent arxiv papers on LLM agents, extract findings, write a lit review", }), }); const reader = res.body!.getReader(); const decoder = new TextDecoder(); while (true) { const { done, value } = await reader.read(); if (done) break; console.log(decoder.decode(value)); } ``` -------------------------------- ### Configure Alternative AI Providers via Environment Variables Source: https://context7.com/tomascupr/sandstorm/llms.txt Sets up alternative AI providers by configuring specific environment variables. Supports Anthropic (default), Google Vertex AI, Amazon Bedrock, Microsoft Azure/Foundry, and custom API proxies. ```bash # Anthropic (default) ANTHROPIC_API_KEY=sk-ant-... # Google Vertex AI CLAUDE_CODE_USE_VERTEX=1 CLOUD_ML_REGION=us-central1 ANTHROPIC_VERTEX_PROJECT_ID=your-project-id GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json # Amazon Bedrock CLAUDE_CODE_USE_BEDROCK=1 AWS_REGION=us-east-1 AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=... # Microsoft Azure / Foundry CLAUDE_CODE_USE_FOUNDRY=1 AZURE_FOUNDRY_RESOURCE=your-resource AZURE_API_KEY=... # Custom API proxy ANTHROPIC_BASE_URL=https://your-proxy.com/api ANTHROPIC_AUTH_TOKEN=your-token ``` -------------------------------- ### POST /query Source: https://github.com/tomascupr/sandstorm/blob/main/README.md Submit a prompt to the Sandstorm agent for processing. This endpoint supports various configuration options and API keys, and returns results as a server-sent event stream. ```APIDOC ## POST /query ### Description Submit a prompt to the Sandstorm agent for processing. This endpoint supports various configuration options and API keys, and returns results as a server-sent event stream. ### Method POST ### Endpoint /query ### Parameters #### Query Parameters None #### Request Body - **prompt** (string) - Required - The task for the agent (min 1 char) - **anthropic_api_key** (string) - Optional - Anthropic key (falls back to env) - **openrouter_api_key** (string) - Optional - OpenRouter key (falls back to env) - **e2b_api_key** (string) - Optional - E2B key (falls back to env) - **model** (string) - Optional - Overrides `sandstorm.json` model - **max_turns** (integer) - Optional - Overrides `sandstorm.json` max_turns - **timeout** (integer) - Optional - Sandbox lifetime in seconds (Default: 300) - **files** (object) - Optional - Files to upload (`{path: content}`) ### Request Example ```json { "prompt": "Scrape the top 50 HN stories, cluster by topic, save to output/hn.csv", "anthropic_api_key": "sk-ant-...", "model": "claude-3-opus-20240229" } ``` ### Response #### Success Response (200) - **Content-Type**: `text/event-stream` #### Response Example ``` type: system data: {"tools": ["Bash", "Read"], "model": "claude-3-opus-20240229", "session_id": "abc123xyz"} type: assistant data: {"content": "Okay, I will scrape the top 50 HN stories, cluster them by topic, and save the results to output/hn.csv.", "tool_calls": []} type: user data: {"tool_results": [{"tool_name": "Bash", "tool_input": "curl -s https://news.ycombinator.com/ | grep -o ']*>\K[^<]+' | head -n 50 > hn_titles.txt", "output": ""}]} type: result data: {"total_cost_usd": 0.0005, "num_turns": 2, "structured_output": null} ``` ``` -------------------------------- ### Upload Files via cURL Request Source: https://github.com/tomascupr/sandstorm/blob/main/README.md Demonstrates how to send files along with a prompt in a POST request to the Sandstorm `/query` endpoint using cURL. The files are made available within the sandbox environment. ```bash curl -N -X POST https://your-sandstorm-host/query \ -d '{ "prompt": "Parse these server logs, find error spikes, and write an incident report", "files": { "logs/app.log": "2024-01-15T10:23:01Z ERROR [auth] connection pool exhausted\n...", "logs/deploys.json": "[{\"sha\": \"a1b2c3\", \"ts\": \"2024-01-15T10:20:00Z\"}]" } }' ``` -------------------------------- ### Run Sandstorm Docker Image with Environment Variables Source: https://context7.com/tomascupr/sandstorm/llms.txt This command demonstrates how to run the Sandstorm Docker container, exposing port 8000 and setting necessary API keys as environment variables. It specifies the 'sandstorm' image to be used. ```bash docker run -p 8000:8000 \ -e ANTHROPIC_API_KEY=sk-ant-... \ -e E2B_API_KEY=e2b_... \ sandstorm ``` -------------------------------- ### POST /query (Asynchronous Python Client) Source: https://context7.com/tomascupr/sandstorm/llms.txt This endpoint demonstrates how to use an asynchronous Python client to send multiple prompts concurrently and process their SSE responses. ```APIDOC ## POST /query (Asynchronous Python Client) ### Description Sends multiple prompts to the Sandstorm API concurrently using an asynchronous HTTP client and processes the Server-Sent Events (SSE) stream for each. ### Method POST ### Endpoint http://localhost:8000/query ### Parameters #### Query Parameters None #### Request Body - **prompt** (string) - Required - The user's prompt or instruction. ### Request Example ```json { "prompt": "Scrape the top 50 YC companies and save as CSV" } ``` ### Response #### Success Response (200) - **data** (string) - The data received from the SSE stream. #### Response Example ``` Scraping YC companies... Saving to companies.csv ``` ``` -------------------------------- ### MCP Server Configuration Fields Source: https://github.com/tomascupr/sandstorm/blob/main/README.md Provides a table detailing the fields available for configuring MCP servers, including their types, descriptions, and applicable server types (stdio, http, sse). ```text | Field | Type | Description | |-------|------|-------------| | `type` | `string` | `"stdio"`, `"http"`, or `"sse"` | | `command` | `string` | Command for stdio servers | | `args` | `string[]` | Command arguments | | `url` | `string` | URL for HTTP/SSE servers | | `headers` | `object` | Auth headers for remote servers | | `env` | `object` | Environment variables | ``` -------------------------------- ### Sample Competitive Analysis Output (JSON) Source: https://github.com/tomascupr/sandstorm/blob/main/examples/competitive-analysis/README.md A sample JSON output demonstrating the structured format for competitive analysis, including competitor profiles, a comparison matrix, and market insights. ```json { "market_segment": "Cloud deployment platforms for frontend developers", "competitors": [ { "name": "Vercel", "website": "https://vercel.com", "positioning": "Frontend cloud platform for building and deploying web applications", "target_audience": "Frontend developers and teams using Next.js and React", "key_features": [ "Automatic CI/CD from Git", "Edge Functions", "Preview deployments", "Built-in analytics" ], "pricing_model": "Freemium with per-seat Pro plan at $20/month", "strengths": [ "Best-in-class Next.js integration", "Fast global edge network", "Excellent developer experience" ], "weaknesses": [ "Vendor lock-in with Next.js optimizations", "Costs scale quickly with traffic", "Limited backend capabilities" ] } ], "comparison_matrix": [ { "feature": "Free tier bandwidth", "Vercel": "100 GB", "Netlify": "100 GB", "Cloudflare": "Unlimited" }, { "feature": "Edge functions", "Vercel": "Yes", "Netlify": "Yes", "Cloudflare": "Yes (Workers)" }, { "feature": "Build minutes (free)", "Vercel": "6000/mo", "Netlify": "300/mo", "Cloudflare": "500/mo" } ], "market_insights": "The deployment platform market is consolidating around edge-first architectures. Cloudflare's unlimited bandwidth on the free tier is disrupting pricing norms, while Vercel maintains dominance in the React/Next.js ecosystem through deep framework integration.", "recommendations": [ "Startups with Next.js apps should default to Vercel for the best DX", "Cost-sensitive projects benefit from Cloudflare Pages' generous free tier", "Teams needing form handling and identity should evaluate Netlify's integrated services" ] } ``` -------------------------------- ### Configure OpenRouter Integration via Environment Variables Source: https://context7.com/tomascupr/sandstorm/llms.txt Sets up integration with OpenRouter to use various third-party models. Environment variables define the base URL, API key, and map SDK model aliases to specific OpenRouter model identifiers. ```bash # .env configuration for OpenRouter ANTHROPIC_BASE_URL=https://openrouter.ai/api OPENROUTER_API_KEY=sk-or-... ANTHROPIC_DEFAULT_SONNET_MODEL=anthropic/claude-sonnet-4 # Remap SDK model aliases to any OpenRouter model ANTHROPIC_DEFAULT_SONNET_MODEL=qwen/qwen3-max-thinking ANTHROPIC_DEFAULT_OPUS_MODEL=deepseek/deepseek-r1 ANTHROPIC_DEFAULT_HAIKU_MODEL=qwen/qwen3-30b-a3b ``` -------------------------------- ### POST /query Source: https://context7.com/tomascupr/sandstorm/llms.txt The main endpoint for running agent tasks. It accepts a prompt and optional configurations, returning a Server-Sent Events (SSE) stream with real-time agent output. ```APIDOC ## POST /query ### Description This endpoint allows you to run AI agent tasks by providing a prompt and optional configurations. It returns a Server-Sent Events (SSE) stream that provides real-time output from the agent. ### Method POST ### Endpoint /query ### Parameters #### Query Parameters None #### Request Body - **prompt** (string) - Required - The user's query or instruction for the AI agent. - **model** (string) - Optional - The AI model to use (e.g., 'opus'). - **max_turns** (integer) - Optional - The maximum number of conversation turns allowed for the task. - **timeout** (integer) - Optional - The maximum time in seconds the agent has to complete the task. - **files** (object) - Optional - A dictionary where keys are file paths within the sandbox and values are file content (string). - **path/to/file** (string) - Content of the file. - **anthropic_api_key** (string) - Optional - Override the Anthropic API key for this request. - **e2b_api_key** (string) - Optional - Override the E2B API key for this request. ### Request Example ```json { "prompt": "Scrape the top 50 HN stories, cluster by topic, save to output/hn.csv", "model": "opus", "max_turns": 25, "timeout": 600, "files": { "logs/app.log": "2024-01-15T10:23:01Z ERROR [auth] connection pool exhausted\n2024-01-15T10:23:02Z ERROR [auth] timeout waiting for connection", "logs/deploys.json": "[{\"sha\": \"a1b2c3\", \"ts\": \"2024-01-15T10:20:00Z\"}]" }, "anthropic_api_key": "sk-ant-customer-key", "e2b_api_key": "e2b_customer-key" } ``` ### Response #### Success Response (SSE Stream) - **event: message** - Contains messages from the AI agent. - **data: {"type": "assistant", "message": {"content": [{"type": "text", "text": "..."}]}}** - **event: result** - Contains the final result of the agent's task. - **data: {"type": "result", "subtype": "success", "num_turns": 5, "cost_usd": 0.0234}** - **event: error** - Contains error information if the task fails. #### Response Example (SSE Stream) ``` event: message data: {"type": "assistant", "message": {"content": [{"type": "text", "text": "Creating script..."}]}} event: result data: {"type": "result", "subtype": "success", "num_turns": 5, "cost_usd": 0.0234} ``` ``` -------------------------------- ### Sample Code Reviewer Output (JSON) Source: https://github.com/tomascupr/sandstorm/blob/main/examples/code-reviewer/README.md Demonstrates the structured JSON output format for code review findings. It includes summary statistics and detailed information for each identified issue. ```json { "summary": "Found 3 issues across 2 files. One critical SQL injection vulnerability in the auth module requires immediate attention.", "findings": [ { "severity": "critical", "category": "security", "file": "src/auth.py", "line": 45, "title": "SQL injection via string formatting", "description": "User input is interpolated directly into a SQL query using f-string formatting, allowing an attacker to execute arbitrary SQL.", "suggestion": "Use parameterized queries: cursor.execute('SELECT * FROM users WHERE email = %s', (email,))" }, { "severity": "warning", "category": "bug", "file": "src/auth.py", "line": 72, "title": "Unchecked None return value", "description": "get_user() can return None when the user is not found, but the return value is accessed without a null check on line 73.", "suggestion": "Add a guard clause: if user is None: raise UserNotFoundError(user_id)" }, { "severity": "info", "category": "maintainability", "file": "src/utils.py", "line": 12, "title": "Broad exception catch", "description": "Catching bare Exception hides bugs and makes debugging harder.", "suggestion": "Catch specific exceptions: except (ValueError, KeyError) as e:" } ], "stats": { "files_reviewed": 2, "total_findings": 3, "critical_count": 1, "warning_count": 1 } } ``` -------------------------------- ### Docker Deployment Source: https://context7.com/tomascupr/sandstorm/llms.txt Deploy Sandstorm as a container to any platform. This involves creating a Dockerfile to build the image and then using docker commands to build and run the container. ```APIDOC ## Docker Deployment ### Description Deploy Sandstorm as a container to any platform. This involves creating a Dockerfile to build the image and then using docker commands to build and run the container. ### Method N/A (Deployment) ### Endpoint N/A (Deployment) ### Parameters #### Dockerfile - **FROM** (string) - Specifies the base image. - **WORKDIR** (string) - Sets the working directory inside the container. - **COPY** (string) - Copies files from the host to the container. - **RUN** (string) - Executes commands during the image build process. - **EXPOSE** (string) - Informs Docker that the container listens on the specified network ports at runtime. - **CMD** (string) - Provides default commands for an executing container. ### Dockerfile Example ```dockerfile FROM python:3.12-slim WORKDIR /app COPY . . RUN pip install --no-cache-dir duvo-sandstorm EXPOSE 8000 CMD ["ds", "serve", "--host", "0.0.0.0", "--port", "8000"] ``` ### Build and Run Commands - **docker build** - Builds a Docker image from a Dockerfile. - **docker run** - Runs a Docker container from an image. ### Build and Run Example ```bash # Build and run docker build -t sandstorm . docker run -p 8000:8000 --env-file .env sandstorm ``` ### Response N/A (Deployment) ``` -------------------------------- ### Structure for Skills Directory Source: https://github.com/tomascupr/sandstorm/blob/main/README.md Illustrates the expected directory structure for organizing Claude Code Skills. Each skill is a subfolder containing a `SKILL.md` file. ```text .claude/skills/ code-review/ SKILL.md data-analyst/ SKILL.md ``` -------------------------------- ### Provider Configuration Source: https://context7.com/tomascupr/sandstorm/llms.txt Configure alternative AI providers (Google Vertex AI, Amazon Bedrock, Microsoft Azure/Foundry) or a custom API proxy using environment variables. ```APIDOC ## Provider Configuration ### Description Configure alternative AI providers (Google Vertex AI, Amazon Bedrock, Microsoft Azure/Foundry) or a custom API proxy using environment variables. ### Method N/A (Configuration) ### Endpoint N/A (Configuration) ### Parameters #### Environment Variables (Configuration) - **ANTHROPIC_API_KEY** (string) - Required for Anthropic default provider. - **CLAUDE_CODE_USE_VERTEX** (boolean) - Set to `1` to use Google Vertex AI. - **CLOUD_ML_REGION** (string) - Required for Vertex AI - The region for Vertex AI. - **ANTHROPIC_VERTEX_PROJECT_ID** (string) - Required for Vertex AI - Your Google Cloud project ID. - **GOOGLE_APPLICATION_CREDENTIALS** (string) - Required for Vertex AI - Path to your service account key file. - **CLAUDE_CODE_USE_BEDROCK** (boolean) - Set to `1` to use Amazon Bedrock. - **AWS_REGION** (string) - Required for Bedrock - The AWS region. - **AWS_ACCESS_KEY_ID** (string) - Required for Bedrock - Your AWS access key ID. - **AWS_SECRET_ACCESS_KEY** (string) - Required for Bedrock - Your AWS secret access key. - **CLAUDE_CODE_USE_FOUNDRY** (boolean) - Set to `1` to use Microsoft Azure / Foundry. - **AZURE_FOUNDRY_RESOURCE** (string) - Required for Foundry - Your Azure Foundry resource name. - **AZURE_API_KEY** (string) - Required for Foundry - Your Azure API key. - **ANTHROPIC_BASE_URL** (string) - Optional - Use for a custom API proxy. - **ANTHROPIC_AUTH_TOKEN** (string) - Optional - Auth token for a custom API proxy. ### Request Example (Environment Variables) ```bash # Anthropic (default) ANTHROPIC_API_KEY=sk-ant-... # Google Vertex AI CLAUDE_CODE_USE_VERTEX=1 CLOUD_ML_REGION=us-central1 ANTHROPIC_VERTEX_PROJECT_ID=your-project-id GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json # Amazon Bedrock CLAUDE_CODE_USE_BEDROCK=1 AWS_REGION=us-east-1 AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=... # Microsoft Azure / Foundry CLAUDE_CODE_USE_FOUNDRY=1 AZURE_FOUNDRY_RESOURCE=your-resource AZURE_API_KEY=... # Custom API proxy ANTHROPIC_BASE_URL=https://your-proxy.com/api ANTHROPIC_AUTH_TOKEN=your-token ``` ### Response N/A (Configuration) ```