interven-computer-use
Govern Anthropic Computer Use tool calls through Interven before they run on your host.
Computer Use tools — computer_* (mouse/keyboard/screenshot), bash_* (shell),
text_editor_* (file edits) — execute locally and never touch HTTP. The
only place to govern them is the agent's own loop: after messages.create
returns tool_use blocks and before you execute them. IntervenGuard sits
exactly there. Each tool call is scanned through Interven's policy + risk engine,
and the decision is mapped back into Computer Use's allow/deny model.
Install (30 seconds)
pip install interven-computer-use
export INTERVEN_API_KEY=iv_live_... # from https://app.intervensecurity.com/signup
Use
Wrap the tool-execution step of your loop. The guard scans, then either runs your executor (ALLOW/SANITIZE) or returns a synthetic error block (DENY/REQUIRE_APPROVAL):
import anthropic
from interven_computer_use import IntervenGuard
client = anthropic.Anthropic()
guard = IntervenGuard() # reads INTERVEN_API_KEY from env
def run_tool(block):
# your existing executor: screenshot, run bash, edit a file, ...
return execute_computer_use_tool(block.name, block.input)
messages = [{"role": "user", "content": "Open the terminal and run `whoami`."}]
while True:
response = client.beta.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
tools=[
{"type": "computer_20250124", "name": "computer",
"display_width_px": 1280, "display_height_px": 800},
{"type": "bash_20250124", "name": "bash"},
{"type": "text_editor_20250124", "name": "str_replace_editor"},
],
betas=["computer-use-2025-01-24"],
messages=messages,
)
tool_results = []
for block in response.content:
if block.type == "tool_use":
# One line of governance — scan + execute-or-block:
tool_results.append(guard.guard_tool_use(block, execute=run_tool))
if not tool_results:
break # no tools requested — Claude is done
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
Prefer to make the decision yourself? Call guard.check(block) and inspect the
Verdict (.proceed, .decision, .reason, .approval_url, .trace_id).
Decision mapping
| Interven decision | What the guard does |
|---|---|
| ALLOW | Runs your execute and returns its real tool_result. |
| SANITIZE | Runs the tool (a pure-local action — a mouse click, a keystroke — can't be redacted), logs the event for audit, and writes a warning to stderr. |
| DENY | Skips execution. Returns a tool_result with is_error=True and a reason string Claude sees and reacts to. |
| REQUIRE_APPROVAL | Skips execution. Returns is_error=True with an "approval pending" message + the Console approval URL. After an analyst approves, Claude's retry on the next turn lands inside the approval grace window and auto-allows. |
A blocked call returns a standard Computer Use tool_result block:
{ "type": "tool_result", "tool_use_id": "tu_…", "content": "Interven DENY (…). Trace: …", "is_error": true }
Configuration
| Env var | Default | Purpose |
|---|---|---|
INTERVEN_API_KEY |
required | Your iv_live_* key. Sign up at https://app.intervensecurity.com/signup |
INTERVEN_GATEWAY |
https://api.intervensecurity.com |
Gateway base URL. Override only when self-hosting. |
INTERVEN_TIMEOUT_MS |
5000 |
Per-scan timeout in milliseconds. |
INTERVEN_FAIL_CLOSED |
(unset) | Set to 1 to block when a scan fails. Default is fail-open. |
INTERVEN_CONSOLE_URL |
https://app.intervensecurity.com |
Base URL used to build approval links. |
All of these can also be passed to the constructor:
guard = IntervenGuard(
api_key="iv_live_...",
gateway="https://interven.your-company.internal",
timeout=10.0,
fail_closed=True,
agent_name="ops-desktop-agent",
)
Failure mode
If /v1/scan is unreachable (network down, gateway 5xx, timeout, missing key),
the guard fails open by default: the tool runs and a warning is written to
stderr, so a partial outage doesn't freeze the agent. Set
INTERVEN_FAIL_CLOSED=1 (or fail_closed=True) to block instead — choose this
when enforcement matters more than availability.
What gets scanned
Every tool_use block you pass to guard_tool_use / check is scanned — not
just the three built-in families — so a custom tool your agent calls is governed
too. The guard infers a category (computer / bash / text_editor /
other) from the tool name and includes it in the scan so policies can match on
it. No tool args are executed before the decision returns.
License
MIT
Metadata
Release files for interven-computer-use 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| interven_computer_use-0.1.1.tar.gz | 11.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| interven_computer_use-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.5 kB
Release files / interven_computer_use-0.1.1.tar.gz
| Download URL | interven_computer_use-0.1.1.tar.gz |
|---|---|
| Size | 11.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cb12ba82683ea8ba093a1b42e4b53b3e12c07f7a7e05c817bee0c6de8cba612c
|
|
BLAKE2b-256 checksum How to use checksums |
d6fba87c29ac77e21f79b98d397a531e8e994b7b88f70784bad23027990cb1d5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / interven_computer_use-0.1.1-py3-none-any.whl
| Download URL | interven_computer_use-0.1.1-py3-none-any.whl |
|---|---|
| Size | 10.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
65067157b41f2acb20fd91d75c7167ec294b18133e7df7e302136ca324f2bdf2
|
|
BLAKE2b-256 checksum How to use checksums |
5bd05894638dac52762f1bfda430b3b472d01376aa6e4b48a2b273eb69916f48
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|