A remote agent orchestration and observability platform for controlling coding agents (Claude Code, Codex, etc.) running in isolated environments.
- Multi-Agent Support - Run Claude Code, Codex, or custom agents
- Flexible Deployment - Docker, Kubernetes, E2B, Firecracker, or bare metal pools
- Session Management - Long-lived work contexts with suspend/resume
- Workspace Persistence - Encrypted storage with S3/GCS sync
- Real-time Streaming - Live logs, permission requests, progress updates
- Port Forwarding - HTTP tunnels, desktop streaming (WebRTC), iOS/Android emulator
- Multi-tenant - Built for SaaS integration with tenant isolation
- Go 1.22+
- PostgreSQL 15+
- Docker (for local development)
# Clone repository
git clone https://github.com/chunlea/marionette.git
cd marionette
# Install dependencies
make deps
# Setup database
createdb marionette
make migrate
# Build binaries
make build
# Terminal 1: Start server
./bin/server --config configs/local.yaml
# Terminal 2: Start a Docker runner
./bin/agent --server localhost:9090 --token dev-token
# Terminal 3: Use CLI
./bin/mctl sessions create --agent claude --api-key $ANTHROPIC_API_KEY
./bin/mctl tasks create --session $SESSION_ID --prompt "Build a REST API"
./bin/mctl tasks logs --follow $TASK_ID
┌─────────────────────────────────────────────────────────────────────┐
│ Server (Go) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ SessionMgr │ │ TaskMgr │ │ RunnerMgr │ │ TunnelMgr │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Provider Registry (Docker, K8s, E2B, Pool, ...) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ :9090 gRPC │ :8080 Public API │ :8081 Admin UI │
└──────────────┼────────────────────┼─────────────────────────────────┘
│ │
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ Runner (isolated) │ │ Runner (pool) │
│ ┌────────────────┐ │ │ ┌────────────────┐ │
│ │marionette-agent│ │ │ │marionette-agent│ │
│ │ ┌────────────┐ │ │ │ └───────┬────────┘ │
│ │ │Claude Code │ │ │ │ │ │
│ │ └────────────┘ │ │ │ ┌───────▼────────┐ │
│ │ ┌────────────┐ │ │ │ │Sandbox (gVisor)│ │
│ │ │ /workspace │ │ │ │ │ Agent+Workspace│ │
│ │ └────────────┘ │ │ │ └────────────────┘ │
│ └────────────────┘ │ └──────────────────────┘
└──────────────────────┘
| Concept |
Description |
| Runner |
Execution environment (container, VM, or machine) |
| Session |
Long-lived work context binding Runner + Workspace |
| Task |
Unit of work (prompt) executed within a Session |
| Workspace |
Persistent /workspace directory |
| Agent |
AI coding agent (Claude Code, Codex, etc.) |
curl -X POST http://localhost:8080/api/v1/sessions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent": "claude",
"api_key": "sk-ant-xxx",
"labels": {"user": "alice", "project": "my-app"}
}'
curl -X POST http://localhost:8080/api/v1/sessions/$SESSION_ID/tasks \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "Build a REST API with authentication"}'
curl -N http://localhost:8080/api/v1/tasks/$TASK_ID/logs?follow=true \
-H "Authorization: Bearer $API_KEY"
# config.yaml - non-sensitive settings only
server:
api:
port: 8080
admin:
port: 8081
grpc:
port: 9090
providers:
default: docker
docker:
image: "ghcr.io/chunlea/marionette-runner:latest"
storage:
provider: local
local:
path: /var/marionette/storage
# .env - sensitive values (all prefixed with MARIONETTE_)
MARIONETTE_DATABASE_URL=postgres://localhost/marionette?sslmode=disable
MARIONETTE_MASTER_KEY=your-master-key
MARIONETTE_ENCRYPTION_KEY=your-encryption-key
# Sessions
mctl sessions list
mctl sessions create --agent claude --api-key $KEY
mctl sessions suspend $SESSION_ID
mctl sessions resume $SESSION_ID --api-key $KEY
mctl sessions terminate $SESSION_ID
# Tasks
mctl tasks create --session $SID --prompt "Fix the bug"
mctl tasks list --session $SID
mctl tasks logs --follow $TASK_ID
mctl tasks cancel $TASK_ID
# Runners
mctl runners list
mctl runners get $RUNNER_ID
mctl runners pause $RUNNER_ID
mctl runners resume $RUNNER_ID
# Tunnels
mctl tunnels create --session $SID --type http --port 3000
mctl tunnels list --session $SID
# Run tests
make test
# Run linter
make lint
# Generate protobuf
make proto
# Build Docker image
make docker-build
# Run with hot reload
make dev
| Variable |
Description |
Default |
MARIONETTE_CONFIG |
Config file path |
config.yaml |
MARIONETTE_DATABASE_URL |
PostgreSQL connection string |
- |
MARIONETTE_MASTER_KEY |
Master key for admin operations |
- |
MARIONETTE_ENCRYPTION_KEY |
Key for encrypting agent credentials |
- |
MARIONETTE_LOG_LEVEL |
Log level |
info |
MIT