Running Agents¶
Everything you need to spawn Claude agents through Stromboli's API.
Basic usage¶
Send a prompt, get a response:
curl -X POST localhost:8080/run \
-H "Content-Type: application/json" \
-d '{"prompt": "Hello, Claude!"}'
{
"id": "run-abc123",
"status": "completed",
"output": "Hello! How can I help?",
"session_id": "550e8400-e29b-41d4-a716-446655440000"
}
Mount a project directory¶
Give Claude access to your code:
curl -X POST localhost:8080/run \
-d '{
"prompt": "Analyze the code structure",
"workdir": "/workspace",
"podman": {
"volumes": ["/home/user/myproject:/workspace"]
}
}'
workdir— working directory inside the containervolumes— mount host paths into the container (host:container[:options])
Use :ro for read-only access when the agent only needs to analyze, not modify:
Volume allowlist
In production, only paths listed in STROMBOLI_AGENT_ALLOWED_VOLUMES can be mounted. See security overview.
Claude options¶
Control Claude's behavior per-request:
curl -X POST localhost:8080/run \
-d '{
"prompt": "Review this code",
"claude": {
"model": "sonnet",
"system_prompt": "You are a senior Go developer",
"max_budget_usd": 1.00,
"allowed_tools": ["Read", "Grep", "Glob"],
"output_format": "json"
}
}'
| Option | Type | Description |
|---|---|---|
model |
string | sonnet, opus, haiku |
system_prompt |
string | Replace the default system prompt |
append_system_prompt |
string | Append to the system prompt |
max_budget_usd |
float | Max API cost for this run |
max_turns |
int | Max agentic turns (0 = unlimited) |
allowed_tools |
[]string | Whitelist specific tools |
disallowed_tools |
[]string | Blacklist specific tools |
output_format |
string | text, json, stream-json |
dangerously_skip_permissions |
bool | Skip permission prompts |
Container options¶
Set resource limits and timeouts:
curl -X POST localhost:8080/run \
-d '{
"prompt": "Run heavy analysis",
"podman": {
"memory": "2g",
"cpus": "2",
"timeout": "30m"
}
}'
| Option | Type | Description |
|---|---|---|
memory |
string | Memory limit (512m, 2g) |
cpus |
string | CPU limit (0.5, 2) |
timeout |
string | Max runtime (5m, 1h) |
cpu_shares |
int | CPU shares (relative weight, default 1024) |
image |
string | Custom container image |
volumes |
[]string | Volume mounts (host:container[:options]) |
secrets_env |
map | Secrets as env vars |
Async execution¶
For long-running tasks, use async mode to avoid HTTP timeouts:
# Start the job
curl -X POST localhost:8080/run/async \
-d '{"prompt": "Refactor the entire codebase", "workdir": "/workspace"}'
# {"job_id": "job-abc123", "session_id": "550e8400-..."}
# Check status
curl localhost:8080/jobs/job-abc123
Add a webhook_url to get notified when the job completes:
curl -X POST localhost:8080/run/async \
-d '{
"prompt": "Long running task",
"webhook_url": "https://your-server.com/webhook"
}'
Streaming output¶
Get real-time output via Server-Sent Events:
data: {"type":"output","content":"Hello! I'm analyzing..."}
data: {"type":"output","content":"Found 3 files..."}
data: {"type":"done","session_id":"..."}
Working directory¶
The workdir parameter sets where Claude starts inside the container. If the path doesn't exist, Stromboli creates it automatically (configurable via STROMBOLI_AGENT_WORKDIR_AUTO_CREATE).
Tips:
- Use absolute paths (
/workspace, not./workspace) - Make sure
workdirmatches where your volume is mounted - Mount specific project directories, not entire home folders
What's next¶
- Sessions — Resume conversations across requests
- Secrets — Inject tokens for GitHub, GitLab, etc.
- Custom images — Use Python, Node, Go, or any glibc image
- Lifecycle hooks — Install deps, start services before Claude runs
- Compose environments — Multi-service stacks with databases