neuron-explorer
Qwen3.5‑4B 전용 조향형 뉴런 탐색기, 모든 MLP 뉴런을 밀어 결과를 보관·탐색
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기A cloud sandbox for coding agents, on your own server. Start a run from the dashboard, from any agentic IDE (Cursor, Claude Code, Codex, VS Code), or from a script — it runs in an isolated KVM microVM and streams back live.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Sandbox as a service for coding agents — hosted with a free trial, or self-host for free.
Delegate the task. Keep the control.
Hand a coding task to an autonomous agent running inside a throwaway
microsandbox microVM. Watch it work live, answer the
one question it stops to ask, and get a pull request back.
Start a run from the dashboard, from your coding agent, or from a script — same sandbox,
same fleet, same live view. Sign up on a hosted controller, or self-host in five minutes; either way,
your machines, GitHub accounts and MCP servers are yours alone.README 전문 보기 ↗Sandbox as a service for coding agents — hosted with a free trial, or self-host for free.
Hand a coding task to an autonomous agent running inside a throwaway microsandbox microVM. Watch it work live, answer the one question it stops to ask, and get a pull request back.
Start a run from the dashboard, from your coding agent, or from a script — same sandbox, same fleet, same live view. Sign up on a hosted controller, or self-host in five minutes; either way, your machines, GitHub accounts and MCP servers are yours alone.
Sign up / live console · Self-host · Status · Security model · Architecture · Lifecycle
Works with Cursor · Claude Code · Codex · VS Code · Windsurf · Zed · Cline · Claude web · CI — anything that speaks MCP over stdio or Streamable HTTP. And nothing at all, if you use the dashboard.
Handing a task to an autonomous agent usually means one of two bad trades: run it on your own machine
and hope it doesn't rm -rf something, or run it in a container and pretend a shared kernel is a
boundary. Agent Sandbox takes the third option — one hardware-isolated microVM per run, on
hardware you own — and then solves the parts that make running agents unattended actually usable:
| Problem | What Agent Sandbox does |
|---|---|
| "Is this safe to run unattended?" | Every run is its own KVM guest kernel. A fork bomb or rm -rf / ends at the VM boundary. |
| "It went quiet for 10 minutes." | NDJSON tool events stream to a live log — watch, the fleet monitor, and SSE in the console. |
| "It guessed instead of asking." | The agent writes a question and a PreToolUse hook denies every further tool call until you answer. It cannot barrel on. |
| "What is it doing right now?" | ask runs a second, read-only agent in the same box that reads the diff and log — the driver is never paused. |
| "I don't want to paste tokens everywhere." | GitHub access is resolved per repo from a login-keyed store; on-demand secrets are injected for one step and never stored. |
| "A prompt injection could exfiltrate my keys." | A deterministic guard hook denies control-plane edits, credential exfiltration and runtime reconfiguration — no model in the loop. |
| "I'm away from my desk and it's blocked." | The dashboard is a full control plane, not a log viewer: start runs, answer questions, queue follow-ups, tear boxes down — from a phone. |
The sandbox is the product; how you reach it is your choice. All three paths hit the same orchestrator, produce the same box, and show up in the same fleet view.
| Start it | Best for | |
|---|---|---|
| 🖥️ Dashboard | Open the console, pick repos, type the task, hit send. Nothing installed. | Kicking off work from anywhere — including a phone — and answering a box that's blocked. |
| 🧩 Your coding agent | delegate this: <task> in Cursor, Claude Code, Codex, VS Code, Windsurf, Zed… | Handing off what you're already looking at — the local entry ships your uncommitted working tree. |
| ⚙️ A script / CI | POST /delegate.json (or /mcp) with a bearer token. | Automation: nightly chores, an issue-triage bot, a pipeline step. |
| 💬 A PR comment | Comment /agent <ask> on any pull request in any repo your GitHub account can push to. No webhook, no setup. | Driving a PR from GitHub itself — "add a test for this", "why does CI fail?", "review it". The agent works on the PR's branch, replies on the PR, and keeps listening (how it works). |
Once a run exists, every surface can drive it: watch the live log, ask a read-only co-pilot what
it's doing, queue a follow-up, answer its question, pin the box, or tear it down.
Hosted: open the controller's landing page → Get started → name, username, password → you are on the dashboard. Add a GitHub account under Integrations (yours alone), type a task, send.
Self-hosted, single operator: deploy (below), open https://<ASB_DOMAIN>/dashboard, paste your
MCP_HTTP_TOKEN once. To let several people in, see Multi-user mode.
The composer picks up the repos you name — "fix the flaky retry test in packages/queue" attaches the repo it refers to automatically, so the agent starts with the checkout it was clearly asked about instead of hunting for it. You can also pick repos explicitly, or run with no repo at all.
git clone https://github.com/HatriGt/agent-sandbox.git
cd agent-sandbox
npm ci && npm run build
cp .env.example .env # set VPS_SSH to a host that has microsandbox installed
Hosted: in the dashboard go to Account → Connect an IDE. It mints a personal API key and shows the exact config for Claude Code, Cursor, VS Code and Windsurf with the key filled in, plus a Test connection button. That is all you need — skip the rest of this step.
Local stdio entry (self-hosters who want to ship an uncommitted working tree): register it with
your IDE's MCP config (~/.cursor/mcp.json, .vscode/mcp.json, Windsurf's mcp_config.json,
claude mcp add — see Connect your IDE):
{ "mcpServers": { "agent-sandbox": {
"type": "stdio",
"command": "node",
"args": ["/absolute/path/agent-sandbox/dist/index.js"],
"env": { "WORKSPACE_DIR": "${workspaceFolder}" }
} } }
Now say "delegate this: add tests for the parser" in your agent chat. The local entry rsyncs your working tree — uncommitted changes included — so you can hand off work that isn't pushed anywhere.
curl -X POST https://<ASB_DOMAIN>/delegate.json \
-H "Authorization: Bearer $MCP_HTTP_TOKEN" \
-H "Content-Type: application/json" \
-d '{"task":"bump deps and open a PR","repos":[{"repo":"owner/name"}]}'
Every console action has a route behind it (/fleet.json, /watch.sse, /ask.json,
/resume.json, /teardown.json), so anything the dashboard can do, a script can do.
[!IMPORTANT] The HTTP entry refuses to start without
MCP_HTTP_TOKEN; that token is the deployment's root identity. In multi-user mode people sign in with their own accounts and personal API keys, and the operator token stays in.envas break-glass. Readdocs/security.mdbefore exposing a controller to the internet.
delegate · status · resume · monitor · watch · ask · …Runtime: microsandbox (msb, libkrun/KVM microVMs).
Orchestration: a small TypeScript MCP server with two entry points that share the same tools:
| Entry | Transport | Use it for | Client |
|---|---|---|---|
dist/index.js | stdio (your IDE spawns it) | "delegate THIS" — your local working tree incl. uncommitted changes | Any MCP client on your machine — Cursor, VS Code, Windsurf, Zed, Claude Code, Cline… |
dist/http.js | Streamable HTTP + bearer token | "delegate a git repo/branch" from anywhere — and it serves the dashboard | The web console, any remote MCP client, a phone, CI |
We benchmarked microsandbox, OpenSandbox, SmolVM, and CubeSandbox on the target VPS
(see docs/eval-summary.md). microsandbox won for this use case: real microVM isolation
(hardware boundary), sub-second boot, right-sized RAM, and — critically for v0.6.9 — a
self-contained CLI with the whole delegate wishlist built in:
| Need | microsandbox v0.6.9 feature |
|---|---|
| Ship repo + local changes | --copy-dir SRC:DST, -v/--volume, msb cp |
| Inject git/npm creds | -e KEY=val, --secret-conf (keyring/env secrets) |
| Egress control (creds-proxy-grade) | --net public/private/host, --no-net, --net-rule allow@<target>, DNS controls |
| Run Claude Code + MCP | any OCI image; Claude Code CLI + MCP servers run in-box |
| Use ccproxy for the model | -e ANTHROPIC_BASE_URL=https://your-ccproxy.example.com (verified) |
| Auto-teardown | --idle-timeout, --max-duration |
| Resume / continue | msb exec, msb ssh into a running box |
| Checkpoints / fast restore | msb snapshot, msb run --from-snapshot |
| Status / preview | -p HOST:GUEST port forward |
The egress/secret features mean we get the credential-injection-proxy pattern (that Cleanroom and iron-proxy sell as separate products) natively.
Dashboard Your IDE Any MCP Script / CI
(HTTP+token) (stdio, MCP) client (HTTP) (HTTP+token)
│ │ │ │
│ local working tree │ git clone │
│ (rsync, uncommitted) │ │
└────────────────┴────────┬───────┴─────────────────┘
▼
handlers (shared) → msb on the VPS host
▼
microsandbox microVM (libkrun/KVM)
• repo copied in (local tree OR fresh clone)
• git/npm creds injected (short-lived)
• Claude Code runs the task → commit/PR
• model calls → ccproxy
▼
live log · fleet view · ask · resume · follow-ups · teardown
Both entries register identical tools (src/handlers.ts) backed by the same side-effecting deps
(src/deps.ts), and the dashboard's JSON routes call those same handlers — so a run started in the
browser and a run started from your IDE are the same object, visible and drivable from either.
delegate · status · resume · teardown · pool_status · monitor · watch · ask · gh_token_add.
delegate takes source (local ships your working tree; git clones owner/repo@ref on the VPS),
task, optional ref, optional allowDomains, and repos:[{repo,ref?}] for a cross-repo task (each
lands in /workspace/<name> in one box). Missing required info is asked back, not failed.
Fleet monitor. monitor (no args; or npm run monitor) shows the whole fleet in one call — how
many sandboxes are up and what each is doing: role (session / claimed-pool / free-pool), run state
(running / waiting-for-answer / done / idle), the task text, uptime, and CPU/MEM. Only running boxes
count as "up"; auto-stopped boxes are noted separately. status is one session; monitor is all of
them at a glance.
Watch one box live. watch(session) returns a rich snapshot of a single box — run state, task,
resources, and a tail of the agent's log (what it's doing right now). For a terminal live-stream that
redraws every ~2s, run npm run watch -- <session> on the VPS.
Ask a running box — without stopping it. ask(session, question) runs a second, read-only
co-pilot agent inside the same box and answers you from what it reads: the workspace, git diff,
and the driver's live log. The driver agent keeps working, is never paused, and never sees the
exchange — so you can ask "what has it changed so far?", "why is it stuck?", "is it about to do
something dumb?" mid-run. watch gives you the raw log; ask gives you the log interpreted.
Three things keep the lanes apart (see src/ask.ts):
/ask. If it shared the repo workdir, an ask turn would become the most recent session there
and the next resume would continue the co-pilot's conversation instead of the driver's./ask, outside /workspace — the repo tree stays
clean, monitor/watch never show ask chatter, and nothing lands in a PR.PreToolUse hook (ask-ro.js) denies the edit tools and mutating
shell in this lane. Both in-box hooks self-select on the ASK_LANE env flag: the driver's ask-gate
skips when it's set (so a pending question doesn't freeze the co-pilot — exactly when you most want
to ask what it's stuck on), and the read-only gate skips when it isn't. The gate is generated from
the same predicate the tests exercise, and the shipped file is run under node in the suite.ask can only look, never steer: to change what the driver does, answer its question with resume.
Follow-ups continue the same co-pilot thread unless you pass newThread:true. One turn is capped by
ASK_TIMEOUT_MS (default 45s, under the client's request timeout); ASK_MODEL points the co-pilot at
a cheaper/faster alias than the driver's (the co-pilot mostly reads a log and summarizes — it does not
need the driver's model).
Three surfaces, one lane: the ask MCP tool, an Ask panel in each dashboard row (under that box's
terminal — POSTs to /ask.json), and a CLI. With no question the CLI reads them from stdin, one per
line, so you can hold a conversation with the co-pilot while the driver works:
# in the deployed setup the built dist lives in the container, not on the host
ssh <vps> "docker exec agent-sandbox npm run ask -- <session> 'what has it changed so far?'"
ssh -t <vps> "docker exec -i agent-sandbox npm run ask -- <session>" # interactive, stdin
Web dashboard — a full control plane, not a log viewer. The HTTP entry serves the console at
/dashboard (and a public landing page at /). It is a first-class way to use the product, not
just to observe it: start a run (repo picker, or let the composer infer the repo from the task
text), stream each box live over SSE, ask the read-only co-pilot, queue follow-ups, answer a
blocked agent, pin a box so it is never reaped, browse and download the files a run produced, and
manage GitHub accounts and MCP servers under Integrations. It works on a phone, which is the point —
a run you started this morning can be unblocked from wherever you are.
Open https://<ASB_DOMAIN>/dashboard, paste MCP_HTTP_TOKEN once into the token gate; the browser
keeps it and sends it as a bearer header on every call (?token= is not accepted). See
docs/security.md and web/DESIGN.md.
Reactive GitHub auth — no default account. There is no baked GitHub token or git identity. Access
is resolved per repo from a login-keyed store on the VPS: on the first delegation to a repo no
stored account can reach, delegate asks for a githubToken; it's probed (login + orgs + access),
stored, and reused. Each repo's commit identity + push token + gh come from the account that has
access to that repo (works for local too — owner read from the origin remote). status shows
run:waiting when the agent asks a question; you answer with resume.
On-demand secrets (ask-then-resume). If a task needs a credential it doesn't have (a token for a
private repo it can't reach, a DB URL, an API key), the agent is instructed to stop and name the
exact env var instead of failing or faking. You then call resume with secrets, injected as env
for that step only — never stored, gone on teardown:
resume({
session: "box-abc",
message: "Use the token I provided to clone and continue.",
secrets: { "GITHUB_TOKEN": "ghp_…", "DB_URL": "postgres://…" }
})
delegate is interactive and blocking: one call ships the repo, launches the agent, and waits —
it does not fire-and-forget. It returns only at a real boundary: the run finished (run:done), the
box paused to ask a question (run:waiting), or the wait cap elapsed with the box still working
(run:running — an explicit "reconnect via status"). The wait window is bounded (WAIT_TIMEOUT_MS,
default 50s) so the call always returns under the MCP client's request timeout instead of hanging
to a -32001.
delegate ──► launch, then wait to a boundary:
┌────────────────────────────────────────────────────────────────────┐
│ waitForBoundary (≤ WAIT_TIMEOUT_MS) │
│ ├─ done → return result ────────────────────────────┼──► report PR/result to user
│ ├─ waiting(question) → return the QUESTION as text ──────────────┼──► calling agent answers it
│ │ (from context) OR asks the user via its │ (from context) or asks
│ │ OWN native question UI, then resume(...) │ the user, then resume()
│ └─ still running → return "reconnect via status" ────────────┼──► status() to keep waiting
└────────────────────────────────────────────────────────────────────┘
Client-driven question loop (why not native elicitation). The spec-intended mechanism is MCP
Elicitation (a server→client elicitation/create request sent before the final result). We
implemented it, but Cursor auto-declines a server-initiated elicitation for a token-bearing
delegate/status/resume call before the user ever sees a card — the server gets
action=decline instantly and the call then hangs to -32001. So native elicitation is disabled
(canElicit() returns false; one-line re-enable if a future Cursor build renders it). Instead the
wait loop hands the pending question back as text, and the calling agent does the
turn-taking with its own reliable UI: it answers the question itself when it can from repo/task
context, otherwise prompts the user via its native question UI (e.g. AskQuestion), then calls
resume({session, message}). Repeat until run:done. resume also auto-starts a box that
idle-stopped while waiting; status reconnects and resumes the same loop. The tool descriptions
carry this as an imperative protocol so the calling agent never ends its turn on a run:waiting.
Live output (stream-json terminal). The in-box agent runs with
claude -p --output-format stream-json --verbose, whose NDJSON events are piped through a small
formatter (~/.claude/stream-fmt.js, installed on every claim) that appends readable lines to the
agent log as work happens — assistant text, → Tool: <arg> calls, and indented results. Plain
claude -p buffers and flushes only at the end; this makes watch/monitor/the dashboard terminal
genuinely live during a run.
Ask-and-stop is enforced. Writing a question to the channel doesn't by itself stop a headless
agent, so a PreToolUse hook (ask-gate.sh, installed at bootstrap) denies every further tool
call while /workspace/.agent.question exists. The agent writes its question as its last action and
its turn ends — it can't self-answer or work around a pending question until you resume with the
answer.
The in-box agent reaches back through one channel (/workspace/.agent.question → run:waiting)
whenever it hits something it shouldn't guess through:
resume secrets),npm install / build / test / auth, a 401/403 from a package
registry or API, a missing scope. It reports the exact failure and what unblocks it, and does not
quietly skip the step or declare success. You (or the calling agent) answer, resume, and it picks up.So a delegate/resume call returns only when it truly finishes (run:done), is genuinely blocked
and waiting on you (run:waiting), or the wait cap elapsed (explicit "still working, reconnect via
status") — never a silent "I'll report back later".
agent-sandbox registers standard MCP tools over two standard transports, so wiring it up is the same three lines everywhere — only the config file's location and key name differ per client.
{ "mcpServers": { "agent-sandbox": {
"type": "stdio",
"command": "node",
"args": ["/absolute/path/agent-sandbox/dist/index.js"],
"env": { "WORKSPACE_DIR": "${workspaceFolder}" }
} } }
Where that goes:
| Client | Config |
|---|---|
| Cursor | ~/.cursor/mcp.json (or .cursor/mcp.json in the project) |
| VS Code / Copilot agent mode | .vscode/mcp.json — uses servers instead of mcpServers |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| Claude Code | claude mcp add agent-sandbox -- node /absolute/path/dist/index.js |
| Zed | settings.json → context_servers |
| Cline / Roo | the extension's MCP settings JSON |
WORKSPACE_DIR is what lets you say "delegate this" with no repo argument — it tells the server
which project is open. ${workspaceFolder} is a VS Code-family variable, so Cursor, VS Code and
Windsurf expand it for you. In any client that doesn't, set an absolute path instead, or just name the
repo — the server asks for it rather than guessing. (The remote entry always names a repo: the VPS
cannot see your machine.)
{ "mcpServers": { "agent-sandbox-remote": {
"url": "https://<ASB_DOMAIN>/mcp",
"headers": { "Authorization": "Bearer <MCP_HTTP_TOKEN>" }
} } }
Same URL and bearer header for every remote client — an IDE on another machine, Claude web, a phone, or a CI job that shells out to an MCP client. Nothing about the transport is editor-specific.
[!NOTE] Cursor is the most heavily exercised client today, which is why one Cursor-specific quirk is documented below (its Auto-review auto-declines server-initiated MCP elicitation). The workaround — handing the pending question back as plain text for the calling agent to answer — is client-agnostic and is the path all clients take, so no client depends on native elicitation.
src/ MCP orchestrator: handlers (shared) + stdio entry (index.ts) + HTTP entry (http.ts)
+ git-source, delegate-input, deps, http-auth, msb/pool/ssh/sync
+ ask.ts (read-only co-pilot lane: gate predicate + in-box hook + prompt)
test/ unit tests (node:test via tsx) — run `npm test`
docs/ status (start here), architecture, lifecycle, runbook, security — see docs/README.md
Dockerfile HTTP controller image (Dokploy)
compose.yaml Dokploy app: Traefik route ${ASB_DOMAIN} → :8787
Actively developed and deployed. The orchestrator ships a ~300-case unit suite (npm test) covering the
handlers, the guard predicates, the auth guard, the response security headers, the lifecycle/pool
logic and the stream formatter — all pure, so they run in CI with no VPS. Both entries (stdio + HTTP)
are live, and the web console runs against a real fleet.
Next up: real user authentication (replacing the single shared bearer token), rate limiting on the
token check, and egress deny-by-default for RFC1918 ranges. See docs/remote-mcp-plan.md for the
phase breakdown and Known gaps for what is deliberately not
solved yet.
Prereq: a VPS with microsandbox (msb) installed
and Docker + a Traefik reverse proxy (e.g. Dokploy). Then, from a machine that can SSH to the VPS:
VPS_SSH_ALIAS=<your-vps-ssh> ./setup.sh
That one script: verifies msb on the VPS, creates + authorizes a dedicated SSH key, pulls the
private key into deploy/ (gitignored), scaffolds .env with a generated MCP_HTTP_TOKEN and
the container→host SSH settings, and builds. Then:
.env: ASB_DOMAIN, ANTHROPIC_BASE_URL/ANTHROPIC_MODEL (your proxy), and optionally
NPM_TOKEN. No GH_TOKEN/GIT_AUTHOR_* — GitHub access is reactive and resolved per repo from
the login-keyed store (delegate asks for a token on first use).ASB_DOMAIN → your VPS../compose.yaml), or on the VPS
docker compose up -d --build.The container drives msb on the VPS host over SSH (msb needs KVM on the host), reaching it
as host.docker.internal. Everything site-specific lives in .env; the repo ships no secrets.
AUTH_MODE=saas # accounts, sessions, ownership, per-user integrations
SIGNUP=open # public "Create an account"; omit for invite-only
ADMIN_GITHUB_LOGINS=… # who becomes admin when signing in with GitHub (optional)
GITHUB_OAUTH_CLIENT_ID / GITHUB_OAUTH_CLIENT_SECRET # optional "Continue with GitHub"
What you get:
USER_MAX_BOXES concurrent machines per user, 60 mutating requests/minute
per caller, sign-in throttling.TRIAL_DAYS=7 starts every new account on a free trial; when it lapses the account keeps
its history but cannot start or resume machines until an admin marks it pro (or extends the
trial). Unset for self-hosting: no clock. BILLING_URL is where Upgrade points.Step-by-step: docs/self-hosting.md. Design, threat model and roadmap:
docs/saas-design.md.
Every run is a KVM microVM, so the host is protected by hardware regardless of what the agent does.
The interesting threat is therefore not escape but a prompt-injected agent exfiltrating the
credentials the box legitimately holds — so the defences that matter are deterministic, not
model-mediated: a PreToolUse guard hook denylist, a read-only lane for ask, allow-listed tools,
per-repo credential resolution, and a strict CSP around the console.
docs/security.md documents the full model, including an honest
Known gaps section.
Found a vulnerability? Please report it privately — see SECURITY.md. Do not open a public issue.
Contributions are welcome. CONTRIBUTING.md covers the dev loop (npm run build,
npm test), the testing conventions (pure units, no VPS required) and what a good PR looks like.
Apache-2.0 © 2026 Ajeeth Kumar Ravichandran.