claude-computer-use
Automate computer tasks using Anthropic's computer use API — Claude controls mouse, keyboard, and screen. Use when automating GUI workflows, browser automation without CSS selectors, desktop app testing, or any task that requires seeing and interacting with a graphical interface.
What this skill does
# Claude Computer Use
## Overview
Claude's computer use capability lets the model see your screen (via screenshots) and control mouse and keyboard. Unlike Playwright or Selenium, it requires no selectors — Claude navigates visually, the same way a human would. It's ideal for legacy software, complex multi-app workflows, and tasks that are hard to automate programmatically.
**⚠️ Always run in a sandboxed environment (Docker, VM, or dedicated machine). Never run on a machine with access to sensitive accounts or production systems.**
## Setup
### Install Dependencies
```bash
pip install anthropic pillow pyautogui
# Linux: also install scrot or gnome-screenshot for screenshots
apt-get install -y scrot
```
### Environment
Use Docker for safety:
```dockerfile
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
python3 python3-pip \
xvfb x11vnc \
scrot \
chromium-browser \
&& pip install anthropic pillow pyautogui
ENV DISPLAY=:1
CMD ["Xvfb", ":1", "-screen", "0", "1280x800x24"]
```
```bash
docker build -t computer-use-sandbox .
docker run -d --name sandbox \
-e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
-p 5900:5900 \ # VNC to monitor what's happening
computer-use-sandbox
```
## Core Implementation
### Tool Definitions
The computer use beta provides three tools:
```python
TOOLS = [
{
"type": "computer_20241022", # Screen + mouse + keyboard
"name": "computer",
"display_width_px": 1280,
"display_height_px": 800,
"display_number": 1
},
{
"type": "bash_20241022", # Run shell commands
"name": "bash"
},
{
"type": "text_editor_20241022", # View and edit files
"name": "str_replace_editor"
}
]
```
### Take a Screenshot
```python
import subprocess
import base64
from pathlib import Path
def take_screenshot() -> str:
"""Take a screenshot and return as base64 PNG."""
path = "/tmp/screenshot.png"
subprocess.run(["scrot", path], check=True)
return base64.standard_b64encode(Path(path).read_bytes()).decode("utf-8")
def get_screenshot_block() -> dict:
"""Return an image content block for the API."""
return {
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": take_screenshot()
}
}
```
### Execute Computer Actions
```python
import pyautogui
import time
def execute_computer_action(action: dict) -> str:
"""Execute a computer action from Claude's tool use response."""
action_type = action["action"]
if action_type == "screenshot":
return take_screenshot()
elif action_type == "mouse_move":
pyautogui.moveTo(action["coordinate"][0], action["coordinate"][1])
return "Mouse moved"
elif action_type == "left_click":
pyautogui.click(action["coordinate"][0], action["coordinate"][1])
time.sleep(0.5)
return "Clicked"
elif action_type == "double_click":
pyautogui.doubleClick(action["coordinate"][0], action["coordinate"][1])
time.sleep(0.5)
return "Double-clicked"
elif action_type == "right_click":
pyautogui.rightClick(action["coordinate"][0], action["coordinate"][1])
return "Right-clicked"
elif action_type == "type":
pyautogui.write(action["text"], interval=0.02)
return "Typed text"
elif action_type == "key":
pyautogui.hotkey(*action["key"].replace("+", " ").split())
return f"Pressed {action['key']}"
elif action_type == "scroll":
direction = action.get("direction", "down")
clicks = action.get("clicks", 3)
pyautogui.scroll(-clicks if direction == "down" else clicks)
return f"Scrolled {direction}"
else:
return f"Unknown action: {action_type}"
def execute_bash(command: str) -> str:
"""Execute a bash command and return output."""
result = subprocess.run(
command, shell=True, capture_output=True, text=True, timeout=30
)
return result.stdout + result.stderr
```
### Full Action Loop
```python
import anthropic
client = anthropic.Anthropic()
def run_computer_use_agent(task: str, max_steps: int = 20) -> str:
"""
Run Claude computer use to complete a task.
Args:
task: Natural language description of what to do
max_steps: Safety limit on number of actions
Returns:
Claude's final response describing what was done
"""
# Start with screenshot so Claude sees current state
messages = [
{
"role": "user",
"content": [
{"type": "text", "text": task},
get_screenshot_block()
]
}
]
for step in range(max_steps):
print(f"\n[Step {step + 1}/{max_steps}]")
response = client.beta.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=4096,
tools=TOOLS,
messages=messages,
betas=["computer-use-2024-10-22"]
)
# Add Claude's response to history
messages.append({"role": "assistant", "content": response.content})
# Check if Claude is done
if response.stop_reason == "end_turn":
final_text = next(
(b.text for b in response.content if hasattr(b, "text")), ""
)
print(f"\n✅ Task complete: {final_text}")
return final_text
# Process tool uses
if response.stop_reason == "tool_use":
tool_results = []
for block in response.content:
if block.type != "tool_use":
continue
print(f" → Tool: {block.name}, Action: {block.input.get('action', block.name)}")
if block.name == "computer":
result = execute_computer_action(block.input)
# Always include a fresh screenshot after actions
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": [
{"type": "text", "text": result},
get_screenshot_block()
]
})
elif block.name == "bash":
output = execute_bash(block.input["command"])
print(f" ← Output: {output[:200]}")
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": output
})
elif block.name == "str_replace_editor":
# Handle file viewing/editing
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": "File operation completed"
})
messages.append({"role": "user", "content": tool_results})
return "Max steps reached without completion"
```
## Human-in-the-Loop
For sensitive tasks, add approval checkpoints:
```python
SENSITIVE_ACTIONS = ["left_click", "type", "key"]
REQUIRE_APPROVAL_FOR = ["submit", "delete", "purchase", "send"]
def execute_with_approval(action: dict, task_context: str) -> str:
"""Pause and ask for human approval on potentially dangerous actions."""
action_type = action.get("action", "")
text = action.get("text", "")
# Check if this looks like a high-risk action
is_risky = any(word in task_context.lower() for word in REQUIRE_APPROVAL_FOR)
if is_risky and action_type in SENSITIVE_ACTIONS:
print(f"\n⚠️ APPROVAL REQUIRED")
print(f" Action: {action_type}")
print(f" Details: {action}")
approval = input(" Approve? (y/n): ")
if approval.lower() != "y":
raise RuntimeError("Related in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.