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.