Open-source runtime for general-purpose AI agents in isolated sandboxes.
Project description
Sandstorm
Claude Agent SDK, or any LLM, as a sandboxed agent in your Slack, on your infra.
CLI, HTTP API, Python client, Slack bot, and TypeScript client over the same runtime. Fresh E2B sandbox per thread, streaming, file uploads, replay, and OpenTelemetry traces out of the box.
Why this exists
Anthropic shipped Claude Managed Agents (April 2026): great sandbox, Anthropic-infra only, Claude-only. Vercel shipped Slack Agent Skill + Chat SDK: great Slack wizard, Vercel-only, TypeScript-only. Neither runs on your infrastructure; neither gives you other LLMs; neither emits to your observability backend.
Sandstorm is the intersection. Self-hosted, multi-provider, Slack-native,
observable. The shortest path from pip install to a production agent that
runs on your terms.
Who it's for
- Teams who want Claude-style agents in Slack but can't send runtime traffic to Anthropic or Vercel.
- Engineers on GPT-5 / Gemini / DeepSeek / Qwen / Kimi / Grok who still want the Claude Agent SDK's tool + skill + sandbox story.
- Anyone running Langfuse / Phoenix / Langsmith who refuses to operate blind because their agent vendor keeps telemetry in a closed console.
What a run looks like
$ ds init research-brief && cd research-brief
$ ds "Research Acme's competitors, crawl their sites and recent news, and write a one-page briefing PDF with sources."
[tool: WebFetch] competitor product pages + recent coverage
[tool: WebSearch] launches, pricing, positioning, buyer signals
[tool: Write] briefing.pdf
[tool: Write] reports/sources.md
--- Result: success | turns: 14 | cost: $0.0731 ---
artifacts:
- briefing.pdf
- reports/sources.md
Same prompt from Slack:
you: @Sandstorm research Acme's competitors and post the briefing here
bot: (paused thread sandbox resumed)
🔧 WebFetch
🔧 WebSearch
🔧 Write
Acme's top three competitors are ...
[briefing.pdf uploaded]
Model: sonnet | Turns: 14 | Cost: $0.0731 | Duration: 47.2s
Three things only OSS can do
- Self-host: runs on your Railway/Fly/K8s/Docker. Data stays in your network. E2B is available self-hosted; Anthropic's Managed Agents are Anthropic-infra only.
- Every LLM: Anthropic direct, OpenRouter (GPT-5, Gemini, DeepSeek, Qwen, Kimi, Grok), Vertex AI, Bedrock, Azure Foundry, any OpenAI-compatible base URL.
- Your observability: OTel export to Langfuse, Phoenix/Arize, Langsmith, or any OTLP backend. No vendor console.
Sandstorm vs the closed alternatives
| Feature | Sandstorm | Claude Managed Agents | Vercel Slack Agent Skill | claude-code-slack-bot |
|---|---|---|---|---|
| Self-hosted | ✅ | ❌ | ❌ | ✅ (local) |
| Sandboxed per thread | ✅ | ✅ | ✅ | ❌ |
| Slack in the box | ✅ | ❌ | ✅ | ✅ |
| Multi-provider (not just Claude) | ✅ | ❌ | ✅ | ❌ |
| OTel traces to any backend | ✅ | ❌ | ❌ | ❌ |
| OSS license | MIT | Proprietary | Apache templates | MIT |
| Ships a TypeScript client | ✅ | ✅ | ✅ | ❌ |
| Session resume + replay | ✅ | ✅ | ❌ | ❌ |
Full side-by-side in docs/comparison.md; "when should I pick each?" in docs/faq-vs-managed-agents.md.
60-second quickstart
pip install duvo-sandstorm
ds doctor # verify creds before running anything
ds init research-brief
cd research-brief
ds "Research Acme's competitors, crawl their sites, write a one-page brief with sources"
ds doctor is the fastest way to catch a missing ANTHROPIC_API_KEY / E2B_API_KEY /
Slack scope before your first real query.
In Slack
pip install "duvo-sandstorm[slack]"
ds slack setup # interactive, opens Slack app install in your browser
ds slack start # Socket Mode (dev), use --http for production
Once installed:
@Sandstorm review PR 123 in owner/repo: agent picks up context, runs tests, posts review/remember shipping address is Berlin: personal memory/team-remember shipping address is Berlin: workspace-wide memory (v0.9.1)/channel-remember on-call rotation: channel-scoped memory (v0.9.1)/cancel: stop the most recent in-flight run in this channel (v0.9.1)/model claude-haiku-4-5-20251001: per-thread model override- Reaction triggers: add an emoji to any message to fire an agent (v0.9.1, see docs/triggers.md)
- App Home tab shows memories, active runs, channel defaults, and triggers (v0.9.1)
Thread continuity is real: each thread keeps its own paused E2B sandbox, so uploaded files, generated outputs, and installed packages survive across messages, even across server restarts. See docs/memory.md.
Triggers (v0.9.1)
Fire agent runs from cron schedules, inbound webhooks, or Slack reactions:
"triggers": [
{"name": "standup", "type": "cron", "schedule": "0 9 * * MON-FRI", "prompt": "Post standup"},
{"name": "issue-triage", "type": "webhook", "path": "/triggers/gh",
"secret": "${GH_SECRET}", "prompt": "Triage: {{body.issue.title}}"},
{"name": "summarize-on-robot", "type": "reaction", "emoji": "robot_face",
"prompt": "Summarize {{message.text}}"}
]
Sub-hourly cron supported (Claude Code Routines enforces a 1-hour minimum). See docs/triggers.md and docs/managed-agents-interop.md for the MA interop patterns.
Pick a starter
| Starter | Use when… | Aliases |
|---|---|---|
general-assistant |
One flexible agent for mixed workflows | |
research-brief |
Research a topic, compare options, support a decision | competitive-analysis |
document-analyst |
Review transcripts, reports, PDFs, or decks | |
support-triage |
Triage tickets into priorities, owners, next actions | issue-triage |
api-extractor |
Crawl docs and draft an API summary + OpenAPI spec | docs-to-openapi |
security-audit |
Structured security review with sub-agents and an OWASP skill | |
code-review |
Review GitHub PRs with the GitHub MCP, inline comments, CI logs | pr-review |
ds init --list for the current catalog.
Add toolpacks
ds add --list # bundled: linear, notion, firecrawl, exa, github
ds add linear
ds add github
For any MCP server not in the bundled catalog, ds add --custom wires it in
one command without hand-editing sandstorm.json (v0.9.1):
ds add --custom hubspot --package @hubspot/mcp-server --env PRIVATE_APP_ACCESS_TOKEN
ds add --custom zapier --package mcp-remote --arg https://mcp.zapier.app/mcp --env ZAPIER_MCP_TOKEN
ds add --custom postgres --runtime uvx --package postgres-mcp --env DATABASE_URI
See docs/custom-mcps.md for npm / mcp-remote / uvx patterns and the trust-boundary note on running arbitrary MCP packages inside your sandbox.
Replay a run with a different model
ds replay <run_id> --model claude-haiku-4-5-20251001 --budget 0.05
Forks the original agent session so the replay starts with identical context but on a fresh branch. A fast, cheap way to A/B compare models or reproduce bug-report runs. Reports cost Δ, latency Δ, and turn-count Δ as a markdown table. Details in docs/replay.md.
Install extras
pip install duvo-sandstorm # CLI + server
pip install "duvo-sandstorm[client]" # Async Python client
pip install "duvo-sandstorm[slack]" # Slack bot
pip install "duvo-sandstorm[telemetry]" # OpenTelemetry
TypeScript client: npm install @duvo/sandstorm-client (see clients/typescript).
Deploy
- Railway: one-click template, 30-second deploy
- Docker:
Dockerfilein repo root,docker-compose.ymlfor local - Self-host:
pipx install duvo-sandstorm && ds serve - Langfuse-bundled local stack:
docker compose -f deploy/docker-compose.langfuse.yml up
Docs
- Getting started
- Comparison vs Managed Agents / Victor / others
- When to pick which (FAQ)
- Multi-LLM: GPT-5, Gemini, DeepSeek, Ollama, self-hosted
- Observability: Langfuse, Phoenix, Langsmith
- Memory:
/remember,/forget, persistence guarantees - Replay
- Python client · TypeScript client
- Configuration · API reference
- Slack bot · Deployment · OpenRouter
Community
If Sandstorm closes a gap for you, star the repo and open an issue or discussion with your use case. We read every one.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file duvo_sandstorm-0.9.1.tar.gz.
File metadata
- Download URL: duvo_sandstorm-0.9.1.tar.gz
- Upload date:
- Size: 534.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81e0f9790f7ef5fae8c1d35dec96a2482e10b32b8d36a0bda177ae2e474f82bc
|
|
| MD5 |
c51e490988a4bdc4ebe62d0b6f6c61ab
|
|
| BLAKE2b-256 |
42be9bebdac917841a667f5217c0285c819b40b5b3cc0d5263cd70f74b4e0e03
|
Provenance
The following attestation bundles were made for duvo_sandstorm-0.9.1.tar.gz:
Publisher:
publish.yml on tomascupr/sandstorm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
duvo_sandstorm-0.9.1.tar.gz -
Subject digest:
81e0f9790f7ef5fae8c1d35dec96a2482e10b32b8d36a0bda177ae2e474f82bc - Sigstore transparency entry: 1328318101
- Sigstore integration time:
-
Permalink:
tomascupr/sandstorm@9426707ea662c4bb5c421bf7b7129189b783fb80 -
Branch / Tag:
refs/tags/v0.9.1 - Owner: https://github.com/tomascupr
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9426707ea662c4bb5c421bf7b7129189b783fb80 -
Trigger Event:
release
-
Statement type:
File details
Details for the file duvo_sandstorm-0.9.1-py3-none-any.whl.
File metadata
- Download URL: duvo_sandstorm-0.9.1-py3-none-any.whl
- Upload date:
- Size: 137.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f3d40ddde4999cdb96a4234c4276aeb5127f28c42cf9cfbdc9e26daa9fad2dd
|
|
| MD5 |
20363090fc139778b753977c54ec7d03
|
|
| BLAKE2b-256 |
967730356989b66dca5b937b0754b522b187a9bd7573646a6bc3b86ce1001ca6
|
Provenance
The following attestation bundles were made for duvo_sandstorm-0.9.1-py3-none-any.whl:
Publisher:
publish.yml on tomascupr/sandstorm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
duvo_sandstorm-0.9.1-py3-none-any.whl -
Subject digest:
1f3d40ddde4999cdb96a4234c4276aeb5127f28c42cf9cfbdc9e26daa9fad2dd - Sigstore transparency entry: 1328318169
- Sigstore integration time:
-
Permalink:
tomascupr/sandstorm@9426707ea662c4bb5c421bf7b7129189b783fb80 -
Branch / Tag:
refs/tags/v0.9.1 - Owner: https://github.com/tomascupr
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9426707ea662c4bb5c421bf7b7129189b783fb80 -
Trigger Event:
release
-
Statement type: