sandbox
Summary: This server is the Agent Governance Gateway's MCP interface — it lets an agent request privileged actions (shell, file, network) that a human must approve and that execute outside the sandbox, and check on those requests.
run_privileged— request a shell command to run outside the sandbox; a human approves and the captured stdout/stderr is returned (agent never gets root itself).request_path_access— request a read or write outside the sandbox folder; the sandbox performs it on the agent's behalf (modeisread/write, withcontentfor writes).fetch_url— fetch a URL through the sandbox; network access is gated and the body is returned after human approval.check_request— poll the outcome of an escalation (from MCP or a Claude Code hook), optionally waiting N seconds.sandbox_status— inspect the sandbox root, triggers, and pending escalations.
Every action is mediated by human approval and audit rather than granting the agent the capability directly.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@sandboxRunsudo apt-get updateand show the output."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Agent Governance Gateway
Authorization and runtime governance for AI coding agents. Every Claude Code tool call is intercepted, classified and recorded. Codex, Cursor and Windsurf are governed only through the gateway's MCP tools; their built-in shell and file tools are not intercepted. Risky actions go to a named human, who runs them outside the agent. Everything is signed and audited.
An AI agent having a capability is not the same as it having authority.
What it does
Intercepts every tool call (shell, file, web and MCP) via Claude Code hooks and an MCP server, and returns allow / observe / escalate / deny with an itemized, explainable risk score.
Keeps the agent unprivileged: approved commands run in a broker outside the agent. For third-party MCP calls the sandbox can't make itself, a human approves the exact call and the agent's identical retry is allowed once.
Dual control: critical actions (e.g. a command that sends
.envout) need two approvals by different reviewers with different keys, each signed.Detects intent, not just keywords (optional, local): a small distilled classifier plus jev-os zero-shot checks scan what the agent reads for prompt injection, sentence by sentence. On a hit, even allowlisted shell and network actions need a human.
Governance-as-code: plain-language clauses ("no moving money without human review") mapped to EU AI Act / GDPR / SR 11-7 references, checked on shell commands and on MCP/WebFetch calls, with a
testcommand that measures each clause before you trust it.Governance records: versioned policies with second-reviewer change control and drift protection, a signed evidence pack for auditors, oversight metrics with approval-fatigue detection, and dev/staging/prod plus data-classification rules.
Operations: every tool call is audited, with secrets scrubbed from output and logs. Denials and critical actions raise alerts (local log plus an optional webhook). Per-class rate limits stop an agent that loops, and audit retention is tiered at 90 days, 1 year or 7 years.
Design rule: models may only raise scrutiny. Deterministic rules stay in charge, so a fooled model means an extra approval, never an open door.
Related MCP server: @looppause/mcp
Results (measured, laptop CPU)
Prompt injection in what the agent reads, held-out sets (caught, false alarms):
Set | Keyword rules (before) | jev-os checks | Shipped (jev-os OR student) |
Injections in repo files (600) | 60/309, 39/291 | 86/309, 8/291 | 256/309, 14/291 |
deepset, genuine attacks | 0/39, 0/56 | 26/39, 1/56 | 31/39, 1/56 |
neuralchemy (942 texts) | 156/552, 3/390 | 324/552, 86/390 | 525/552, 96/390 |
Governance on MCP/WebFetch calls: 16/20 violations caught, 0/24 benign calls flagged (frozen test set).
Red team: 10 of 113 evasive attacks still get through, all plain-sounding instructions with no AI wording. That case is left to the authorization layer.
AIUC-1 (the AI agent standard, July 2026 release): 5 of 51 requirements supported, 16 partial, 30 not covered, self-assessed with the gap for each (mapping). Most of the 30 are organizational processes a runtime tool can't supply.
Every adoption decision used a rule written before the test run; two candidates that missed their rule were not shipped. Full numbers, method and limits: the write-up.
Security of the gateway itself
CI runs Semgrep, Gitleaks, Trivy and a ZAP API scan on every push, with SARIF upload and a severity gate. Fixed along the way: an unauthenticated HTTP API that let anyone approve and run commands, an endpoint that would pull and run any Docker image, and every real 500 ZAP found. See SECURITY.md.
Tech
Python 3.12 · FastAPI · MCP · Claude Code hooks · ONNX Runtime · Pydantic · PyNaCl (Ed25519) · pytest (679 tests collected, 18 Oct 2026)
Quick start
pip install -e ".[dev]"
sandbox init . --claude --mcp # connect a folder
sandbox watch . # approve escalations in another terminalUseful commands: sandbox verify (audit chains), sandbox explain <id>, sandbox alerts, sandbox oversight, sandbox retention, sandbox export-evidence --out pack.zip, sandbox policy history.
To send alerts to Slack, Teams or any collector, set SANDBOX_ALERT_WEBHOOK to its incoming-webhook URL.
Guided walkthrough: python demo/call_demo.py runs 12 scenes through the real gateway, from normal work to a poisoned README, .env theft stopped by dual control, governance clauses on a Stripe call, a tampered log and an evidence pack. The agent is scripted to act as if it were fooled; everything else is the real gateway. Start jevos serve first for the governance scene. For a live session with the real Claude Code, python demo/live_setup.py builds the same project with hooks connected, and python demo/try.py preset steal-env (or any tool call you name) sends one call through the gateway while you approve or deny it in sandbox watch.
Optional intent-aware layer: pip install -e ".[semantic]", then jevos serve and sandbox semantic enable .
Docs
Write-up: intent-aware authorization · Full details · Threat model · Governance-as-code · Evidence pack · Data and environment · Compliance mapping · AIUC-1 mapping · Benchmarks
Compliance mappings show design intent, not certification. No software is "compliant" on its own; organisations are.
Licence
Everything outside ee/ is licensed under the MIT License. The ee/ directory is the home of the self-hosted control plane and is licensed under the Elastic License 2.0. Today it holds an early skeleton (health and readiness endpoints and a database test harness). The web UI at ee/web/ is part of ee/ and so is under the Elastic License 2.0 as well.
The connector (everything outside ee/) never imports ee/. The import-linter contract in ee/.importlinter forbids it, and CI runs it (lint-imports --config ee/.importlinter).
Available Tools
5 toolscheck_requestA
Retrieve the outcome of an escalation (from MCP OR the hook).
Use this after run_privileged returns 'pending', or to pick up a request the Claude Code hook raised.
| Name | Required | Description | Default |
|---|---|---|---|
| request_id | Yes | ||
| wait_seconds | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. Yet it never explains the polling semantics implied by wait_seconds — what happens on timeout, whether it blocks, what states the outcome can be in, or the return shape. For a polling-type tool this is a notable gap given there is no annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the purpose front-loaded ahead of the usage trigger. No filler. It only loses a point because the second clause ('or to pick up a request the Claude Code hook raised') could arguably have been folded into the first, though it does add the sibling/hook context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given it has an output schema and only two parameters (one with a meaningful default), the description covers the core purpose and when to call it competently. But it leaves out the wait_seconds timeout/blocking behavior and the possible outcome states — information an agent polling after a pending escalation would reasonably need before calling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, but it adds no parameter meaning at all. request_id and wait_seconds are never explained beyond their raw schema definition (an ID string and a defaulted integer). The description's mention of 'the request' hints at request_id but provides no semantics like what a valid ID looks like or what wait_seconds controls.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource — 'Retrieve the outcome of an escalation' — with an explicit scope qualifier ('from MCP OR the hook'). It differentiates itself from its sibling run_privileged by the triggering mechanism it responds to, so an agent can tell exactly what this tool is for.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use context: 'after run_privileged returns pending, or to pick up a request the Claude Code hook raised.' This is clear and actionable, though it stops short of stating when-not-to-use or naming an alternative for older/unresolved requests.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_urlA
Fetch a URL through the sandbox. A human approves; you get the body.
Network access is gated — the sandbox performs the fetch outside your context so you never make the request directly.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| reason | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that a human approves each request and that the sandbox performs the fetch outside the agent's context, providing key behavioral context. However, it does not cover all potential behaviors like failure scenarios or rejection handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, with two short paragraphs that front-load the primary purpose and add key behavioral context without unnecessary words. Every sentence contributes value, making it well-structured and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with only two parameters, and the description covers the main flow (fetch, approval, body). However, it omits the purpose of the 'reason' parameter, which is significant given zero schema descriptions. The output schema likely covers return format, but the missing parameter explanation creates a gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, but it fails to explain the 'reason' parameter or any URL constraints. It implicitly mentions the URL but adds no meaningful detail beyond what the schema already shows (just types). The optional reason parameter is left unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool fetches a URL through the sandbox, specifying both the verb and resource. It is distinct from siblings like run_privileged and request_path_access, making its purpose unambiguous and easy to differentiate.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when needing to fetch a URL and mentions human approval, but it does not explicitly state when to use this tool versus alternatives or specify exclusions. The guidance is implied rather than explicit, leaving some ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
request_path_accessA
Request a file operation OUTSIDE the sandbox folder.
A human approves; the sandbox performs the read or write on your behalf
(you never receive the capability). mode is "read" or "write"; for
"write", pass the file content in content.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | read | |
| path | Yes | ||
| reason | No | ||
| content | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It discloses critical behavioral traits: a human must approve, the sandbox performs the read/write on the agent's behalf, and the agent never receives the capability. This covers the most important asynchronous and security implications. It does not mention whether the operation is blocking or how to check approval status, but the core behavior is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no redundancy. The first sentence states the purpose upfront, and the second explains the approval process and parameter usage. Every word earns its place, and the structure is optimized for quick comprehension.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having an output schema, the description is fairly complete for a tool that requires human approval. It covers the main flow (request, approval, sandbox performs) and key parameters (mode, content). It does not mention that the operation is asynchronous or that the agent should poll check_request for status, but given the sibling tools and the output schema, this is a moderate gap. Overall, it's adequate but not exhaustive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for parameter meaning. It does explain 'mode' (valid values 'read' or 'write') and 'content' (used with write mode), which adds value. However, it does not clarify 'path' (though it's implied as the target file) or 'reason' (its purpose), leaving those parameters ambiguous. While partial compensation, the coverage gaps prevent a higher score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: requesting a file operation outside the sandbox folder. It specifies the verb 'Request' and the resource 'a file operation', and the scope 'OUTSIDE the sandbox folder' differentiates it from siblings like run_privileged, fetch_url, check_request, and sandbox_status, which have distinct purposes. The distinction is explicit and leaves no ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: this tool is for file operations that need to happen outside the sandbox. It implies that for operations inside the sandbox, this tool is not needed. However, it does not explicitly name alternatives or state when not to use it; rather, it relies on the reader to infer that other tools like run_privileged or fetch_url are for different resource types. This is clear context but no exclusions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_privilegedA
Request a privileged shell command. A human approves; you get the output.
The command runs OUTSIDE the sandbox on your behalf — you never receive root yourself. Returns the captured stdout/stderr on approval.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | No | ||
| command | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full responsibility. It discloses critical behaviors: human approval is required, the command runs outside the sandbox, the agent never receives root, and output is captured on approval. This is substantial transparency, though it omits what happens on rejection, timeouts, or any safety caveats—more than enough to earn a 4 but not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The core action is front-loaded ('Request a privileged shell command'), and the second sentence adds essential behavioral context. Every clause earns its place; it is a model of conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having an output schema, the description misses critical operational details an agent needs: what happens if approval is denied, is the request asynchronous (the term 'Request' implies a wait, but it is not stated), what is the expected latency, and how does the 'reason' parameter factor into approval. It also does not mention safety or restrictions on the command. These gaps are significant for a privileged, human-in-the-loop tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description does not shed any light on the parameters. It never mentions 'command' or 'reason' by name, nor explains expected syntax, purpose of reason, or any parameter-specific guidance. With zero schema coverage, the description must compensate but fails entirely.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Request') and resource ('a privileged shell command'), and the second sentence adds the key differentiator: it runs outside the sandbox. This distinguishes it from siblings like fetch_url (network) and request_path_access (file access), so an agent can tell it apart without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It is clear the tool is for running privileged shell commands that require human approval, but it does not explicitly state when to prefer it over alternatives or when not to use it. There is no mention of 'use this when sandbox is insufficient' or 'instead of sandbox_status'. The context is implied but not made explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sandbox_statusA
Show the sandbox root, triggers, and any pending escalations.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. The verb 'Show' implies a non-mutating, read-only operation, which is useful implicit disclosure. However, it doesn't explicitly state that it has no side effects, requires no auth, or how escalations are represented. For a status tool this is acceptable but leaves room for more explicit guarantees.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with zero waste. The verb leads, and each listed item (root, triggers, pending escalations) earns its place by describing distinct output facets. Nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter status tool with an output schema present, the description is largely complete — it states exactly what the status covers. Minor gaps exist (e.g., no mention of when status is current or whether it reflects a snapshot), but these are not material for an agent deciding to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and an empty input schema with 100% coverage, so there is nothing for the description to add. Per the baseline for a 0-param tool, a 4 is appropriate — no parameter documentation burden exists.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource — 'Show the sandbox root, triggers, and any pending escalations.' The verb 'Show' signals a read-only status operation, and the listed content (root, triggers, escalations) is concrete. It does not explicitly contrast with siblings, but the domain is distinct enough from run_privileged, request_path_access, fetch_url, and check_request that an agent can infer the purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus the siblings. It does not state prerequisites, conditions, or exclusions. For example, it doesn't clarify that this should be called before requesting access or that it's the safe inspection entry point. The agent must infer usage purely from the name and the sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v1.0.0- First observed
check_request - First observed
fetch_url - First observed
request_path_access - First observed
run_privileged - First observed
sandbox_status
TDQS
Scored across 5 tools
Each tool targets a distinct capability: shell execution, file access, network fetch, request status, and sandbox overview. There is no overlap in purpose, and descriptions clearly delineate boundaries.
Most tools follow a verb_noun pattern (run_privileged, request_path_access, fetch_url, check_request), but sandbox_status breaks the pattern by being noun_noun. The deviation is minor and the intent remains clear.
With 5 tools, the server is well-scoped for its purpose of gated external operations. Each tool earns its place without redundancy or excess.
The surface covers all core operations (run, file, fetch) and provides status retrieval via check_request and sandbox_status. No obvious dead ends or missing lifecycle steps for the stated escalation workflow.
Maintenance
Related MCP Connectors
Set up human approval for your AI agents' tool calls.
Preventive human-approval write-gate for AI agents: writes commit only after a human approves.
Give any AI agent a way to ask a person — for approval, a decision, an answer or a review.
Human-in-the-loop approval for agent actions, with verifiable action-bound receipts.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides a human approval gate for AI agents, enabling interactive inline cards for approving, editing, or rejecting actions before they are executed.MIT
- AlicenseNot gradedqualityDmaintenancePauses AI agent execution and routes approval requests to humans via Slack or email, with cryptographically signed proof of the human's decision.17 npmMIT
- AlicenseAqualityDmaintenanceEnables AI agents to securely use real secrets (API keys, database passwords) by requiring human approval for each release, ensuring secrets never enter the model's context.2Apache 2.0
- AlicenseNot gradedqualityCmaintenanceGates agent tool execution with human approval, audit trails, and replay-resistant permits, enabling safe use of tools in agent loops.MIT