File size: 10,868 Bytes
db14e6b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 | ---
title: MatrixLab Sandbox
emoji: 🧪
colorFrom: blue
colorTo: purple
sdk: docker
app_port: 7860
license: apache-2.0
short_description: MatrixLab HF backend for AI repo testing and debugging
---
# MatrixLab HF Backend (Space)
This Hugging Face Space is a **microservice frontend** for MatrixLab.
The Space home page (`/`) is the **Matrix CLI Console** — and **only** the
console. Because this runs inside a real Hugging Face Space, HF already renders
the page chrome (owner/repo, App·Files·Community tabs, the **Running** badge,
Settings/Restart), so MatrixLab does **not** duplicate that navigation or the
running/online status. The app is one console, one status pill, one input. The
legacy ZIP-verification UI moved to **`/verify`**.
Trialing a server is a first-class command rather than a separate toggle:
`matrix mcp test [name]` (or the **Test in sandbox** chip) starts a real
ephemeral `/mcp/*` session, streams the lifecycle, and prints a verdict.
It supports these modes:
1. **MatrixLab Space UI** (`/`) — Matrix CLI Console + one-click sandbox testing.
2. **Upload ZIP** (`/verify`) for static verification (syntax/security/basic tests).
3. **Remote GitHub execution** through MatrixLab Runner using environment bootstrap + cached task runs.
## Matrix CLI Console & the embeddable sandbox button
The page lives under `app/static/space/`:
- `index.html` — loads React (CDN) + the components below.
- `hf-theme.css`, `fx.jsx` (digital rain / typewriter), `data.jsx` (catalog + CLI engine).
- `hf-console.jsx` — the Matrix CLI Console (the whole in-Space UI).
- `hf-space.jsx` — a thin shell that renders **only** the console (no duplicated
HF chrome).
- **`sandbox.jsx`** — the reusable sandbox client (`window.MatrixLabSandbox`) plus
**`<SandboxButton>`** / `mountSandboxButton`.
Inside the Space there is **no separate "enable sandbox" toggle** — `matrix mcp
test` runs the real flow directly (the Space *is* the sandbox server). The
`<SandboxButton>` / `mountSandboxButton` export is still shipped so **matrixhub.io**
can embed a one-click toggle elsewhere (see "Embedding the button" below).
### Embedding the button in matrixhub.io (later)
`sandbox.jsx` is intentionally self-contained so the marketplace can drop the
button in with one call. It exposes `window.MatrixLabSandbox` (a framework-agnostic
client) and `window.mountSandboxButton`:
```html
<div id="sbx"></div>
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<script src="https://ruslanmv-matrixlab.hf.space/static/space/sandbox.jsx"></script>
<script>
// Point at the Space (or your own proxy) and embed the toggle.
MatrixLabSandbox.configure({ baseUrl: "https://ruslanmv-matrixlab.hf.space" });
mountSandboxButton(document.getElementById("sbx"), {
onChange: (on) => console.log("sandbox enabled:", on),
});
</script>
```
Programmatic use (no button):
```js
MatrixLabSandbox.configure({ baseUrl: "https://ruslanmv-matrixlab.hf.space" });
await MatrixLabSandbox.run(
{ entity_id: "mcp_server:filesystem",
start_command: "npx -y @modelcontextprotocol/server-filesystem /tmp" },
(ev) => console.log(ev.step, ev.status, ev.message) // { step, status, message, data }
);
```
Notes for cross-origin (matrixhub.io) embedding:
- The Space enforces its own `MATRIXLAB_SANDBOX_TOKEN` server-side. For browser
embedding, prefer a **MatrixHub backend proxy** (set `baseUrl` to the proxy) so
no token is exposed; or supply `getToken: async () => "<short-lived>"`.
- Enable CORS on the proxy/Space for the marketplace origin.
## Production Goal
Use this Space as a backend entrypoint for testing and debugging AI/code repos, including:
- `https://github.com/ruslanmv/gitpilot`
- `https://github.com/ruslanmv/agent-generator`
- `https://github.com/ruslanmv/RepoGuardian`
The Space sends workload requests to MatrixLab Runner (`MATRIXLAB_RUNNER_URL`), which executes in isolated containers.
## Environment Variables
Set these in HF Space settings:
- `MATRIXLAB_RUNNER_URL` (required): e.g. `https://your-runner.example.com`
- `MATRIXLAB_RUNNER_TIMEOUT_S` (optional, default `120`)
## API
### Health
```bash
GET /health
```
### List repo profiles
```bash
GET /profiles
```
### Run GitHub repo task through MatrixLab Runner
```bash
POST /repo/run
Content-Type: application/json
{
"environment_id": "gitpilot-main",
"profile": "gitpilot",
"repo_url": "https://github.com/ruslanmv/gitpilot",
"default_branch": "main",
"branch": "main",
"force_rebuild": false
}
```
Profiles:
- `gitpilot`
- `agent-generator`
- `repoguardian`
- `custom` (provide your own `repo_url` + scripts)
### ZIP verification mode (local in Space)
```bash
POST /runs # upload zip multipart
GET /runs
GET /runs/{id}
```
## Local Run
```bash
cd hf
docker build -t matrixlab-hf-space .
docker run -p 7860:7860 -e MATRIXLAB_RUNNER_URL=http://host.docker.internal:8000 matrixlab-hf-space
```
## Notes
- This Space is intentionally lightweight and acts as control-plane API/UI.
- Containerized build/test execution happens in MatrixLab Runner.
- For production, put authentication + rate-limiting in front of `/repo/run`.
- For organization-wide maintenance sweeps, use `tools/matrix_maintainer.py` with `configs/agent_matrix_repos.json`.
---
## MatrixHub MCP 10-minute sandbox mode
This Space can also run as a short-lived MCP server test worker for MatrixHub.io.
### Flow
1. MatrixHub.io user clicks **Test MCP Server**.
2. MatrixHub backend validates the MatrixHub entity manifest.
3. Backend restarts/wakes this Hugging Face Space if needed.
4. Backend calls `POST /mcp/sessions` with a curated install/start command.
5. The Space starts the MCP server over `stdio`, sends `initialize`, then `tools/list`.
6. MatrixHub proxies tool tests through this Space for up to 600 seconds.
7. The Space kills the MCP process and deletes `/tmp` session data.
8. MatrixHub backend may call Hugging Face `pause_space()` after the session expires.
### Recommended Space secrets
- `MATRIXLAB_SANDBOX_TOKEN`: bearer token required by `/mcp/*` write/read APIs.
- `MATRIXLAB_MCP_MAX_TTL_SECONDS`: default `600`.
- `MATRIXLAB_MCP_MAX_SESSIONS`: default **`auto`** — derive a safe concurrent cap
from the instance specs (see Concurrency below). Set an integer to pin it.
## Concurrency — parallel sandboxes per HF instance
MatrixLab is the **main sandbox server**: each session is an independent
subprocess with its own workdir, event stream, and TTL, so the worker runs many
sandboxes in parallel. The cap is `MATRIXLAB_MCP_MAX_SESSIONS`.
With `MATRIXLAB_MCP_MAX_SESSIONS=auto` (default) the worker reads the
**actual instance specs** (cgroup-aware RAM + CPU count) and picks
`min(cpu × 2, (usable_RAM_MB) / MATRIXLAB_MCP_MB_PER_SESSION)`, capped at
`MATRIXLAB_MCP_MAX_SESSIONS_CEILING` (default 32). `usable_RAM` reserves ~1.5 GB
for the OS/uvicorn; `MATRIXLAB_MCP_MB_PER_SESSION` defaults to 700 MB.
`GET /mcp/health` reports live capacity and the detected specs:
```json
{ "active_sessions": 0, "max_sessions": 10, "available_slots": 10,
"max_ttl_seconds": 600,
"instance": { "cpu": 8, "total_mem_mb": 32768, "mb_per_session": 700 } }
```
Reference mapping (700 MB/session, ~1.5 GB reserved):
| HF hardware | vCPU | RAM | `auto` cap | Notes |
|------------------------|------|-------|-----------|--------------------------------|
| CPU Basic | 2 | 16 GB | ~4 | mem-bound headroom; demos |
| CPU Upgrade | 8 | 32 GB | ~16→**10+**| comfortably serves 10 parallel |
| CPU Upgrade (pinned) | 8 | 32 GB | set `=10` | explicit, predictable |
To force exactly 10 parallel sandboxes:
```text
MATRIXLAB_MCP_MAX_SESSIONS=10
```
Verify on a running worker:
```bash
BASE=$SPACE_URL N=10 python hf/scripts/sandbox_concurrency_smoke.py
# requested 10 · admitted 10 · running 10/10 · with tools 10 → RESULT: PASS
```
When full, `POST /mcp/sessions` returns `429` so callers can queue/retry.
### Start a session
```bash
curl -X POST "$SPACE_URL/mcp/sessions" \
-H "Authorization: Bearer $MATRIXLAB_SANDBOX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"entity_id": "filesystem-demo",
"runtime": "node",
"start_command": "npx -y @modelcontextprotocol/server-filesystem /tmp",
"transport": "stdio",
"ttl_seconds": 600
}'
```
### Poll status
```bash
curl -H "Authorization: Bearer $MATRIXLAB_SANDBOX_TOKEN" \
"$SPACE_URL/mcp/sessions/$SESSION_ID"
```
### List tools
```bash
curl -H "Authorization: Bearer $MATRIXLAB_SANDBOX_TOKEN" \
"$SPACE_URL/mcp/sessions/$SESSION_ID/tools"
```
### Call a tool
```bash
curl -X POST "$SPACE_URL/mcp/sessions/$SESSION_ID/tools/call" \
-H "Authorization: Bearer $MATRIXLAB_SANDBOX_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"example_tool","arguments":{}}'
```
### MVP safety constraints
This HF mode is a compatibility sandbox, not hardened isolation. For the free MVP, use only curated MatrixHub entries and keep these defaults:
- TTL max: 600 seconds
- Max sessions: 1 per free Space
- No user secrets
- No arbitrary shell scripts
- Allow only `npx`, `uvx`, `pipx`, `python`, `python3`, and `node` commands
- Block `curl | bash`, `wget | bash`, `sudo`, `docker`, package-manager installs, and shell chaining
---
## MatrixHub 10-minute MCP sandbox worker
This Space also exposes a MatrixHub-facing MCP sandbox API. It is designed to be
called by the MatrixHub backend controller when a user clicks **Test in sandbox**.
### Required Space secrets
```text
MATRIXLAB_SANDBOX_TOKEN=<random shared secret>
MATRIXLAB_MCP_MAX_TTL_SECONDS=600
MATRIXLAB_MCP_MAX_SESSIONS=1
MATRIXLAB_MCP_INSTALL_TIMEOUT_SECONDS=120
MATRIXLAB_MCP_STARTUP_TIMEOUT_SECONDS=45
MATRIXLAB_MCP_RPC_TIMEOUT_SECONDS=20
```
### Worker endpoints
```text
GET /mcp/health
POST /mcp/sessions
GET /mcp/sessions/{session_id}
GET /mcp/sessions/{session_id}/events
GET /mcp/sessions/{session_id}/tools
POST /mcp/sessions/{session_id}/tools/call
DELETE /mcp/sessions/{session_id}
```
### Example direct test
```bash
curl -X POST "$SPACE_URL/mcp/sessions" \
-H "Authorization: Bearer $MATRIXLAB_SANDBOX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"entity_id": "mcp_server:filesystem",
"runtime": "node",
"start_command": "npx -y @modelcontextprotocol/server-filesystem /tmp",
"transport": "stdio",
"ttl_seconds": 600
}'
```
Then stream events:
```bash
curl -N "$SPACE_URL/mcp/sessions/$SESSION_ID/events" \
-H "Authorization: Bearer $MATRIXLAB_SANDBOX_TOKEN"
```
This worker is for curated compatibility testing only. Do not pass production
secrets into it and do not expose it directly to browsers.
|