> ## Documentation Index
> Fetch the complete documentation index at: https://docs.openhome.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect to OpenClaw

> Give your OpenHome agent the ability to control your computer through OpenClaw — full setup, SDK reference, and example abilities.

OpenClaw lets your OpenHome agent control your local machine through voice — launch apps, monitor system status, manage files, run developer workflows, and more. The Ability sends a command through OpenHome's `exec_local_command()` call; the OpenClaw client executes it on your machine; the result comes back as a spoken response.

For a short task-oriented quickstart, see [Getting Started → OpenClaw](/guides/getting-started/openclaw). This page is the full reference.

## What you can build

* Application launcher and manager
* System monitoring and diagnostics
* File and folder automation
* Development environment controller
* Custom workflow automations
* Smart home integration via computer
* Screenshot and screen recording tools
* Clipboard and text manipulation

## Setup

### 1. Install OpenClaw

OpenClaw must be installed and configured on your local machine with an LLM API key.

```bash theme={"system"}
npm install -g openclaw@latest
openclaw onboard --install-daemon
```

During onboarding you'll be prompted for an LLM API key (OpenAI, Anthropic, etc.). OpenClaw uses this key to interpret natural-language commands.

### 2. Download the OpenClaw client

[Download for your OS](https://drive.google.com/drive/folders/10qK75I-bFB2D98YJ6dH3tQFsvEk44Y7-):

* **Windows** — `.exe` installer
* **macOS** — `.dmg` or `.app`
* **Linux** — AppImage or `.deb`

### 3. Run the client

<Steps>
  <Step title="Launch">
    * **Windows** — run the `.exe`, allow permissions if prompted
    * **macOS** — if blocked, go to System Settings → Privacy & Security → **Open Anyway**
    * **Linux** — `chmod +x` and run, grant required permissions
  </Step>

  <Step title="Get your OpenHome API key">
    Copy it from [Dashboard → Settings → API Keys](https://app.openhome.com/dashboard/settings).
  </Step>

  <Step title="Connect">
    Paste the key into the OpenClaw client, click **Connect**. Wait for the *"welcome"* message in the logs — that confirms a live connection.
  </Step>
</Steps>

### 4. Add the OpenClaw Ability

Install the OpenClaw Ability from the [Abilities library](https://app.openhome.com/dashboard/abilities) on your Agent. This is the template you'll customize for your use case.

## The `exec_local_command()` API

One function carries every command from the Ability to the OpenClaw client.

```python theme={"system"}
async def exec_local_command(
    self,
    command: str | dict,
    target_id: str | None = None,
    timeout: float = 10.0,
)
```

**Parameters:**

* `command` *(str | dict, required)* — inquiry or command for OpenClaw
* `target_id` *(str | None)* — target device identifier (default: `"laptop"`)
* `timeout` *(float)* — max seconds to wait for a response (default: `10.0`)

**Returns:** `str` — response from OpenClaw (success message, error, or command output).

### Usage

```python theme={"system"}
# Basic
response = await self.capability_worker.exec_local_command(user_inquiry)

# Long-running command — longer timeout
response = await self.capability_worker.exec_local_command(
    "compile large project",
    timeout=30.0,
)

# Specific target device
response = await self.capability_worker.exec_local_command(
    "check battery status",
    target_id="laptop",
)
```

## How it works

1. User speaks a computer-control command
2. OpenHome captures voice as text
3. Ability sends the command to your local OpenClaw client via `exec_local_command()`
4. OpenClaw executes on your computer
5. OpenClaw returns the result (success / failure / output)
6. An LLM converts the technical output into a natural spoken response (max \~15 words)
7. OpenHome speaks the result

## Example abilities

### 1. Development environment controller

```python theme={"system"}
# Trigger: "start coding session"
# Opens IDE, starts local servers, opens documentation
async def first_function(self):
    commands = [
        "open Visual Studio Code",
        "start local dev server on port 3000",
        "open browser to localhost:3000",
    ]
    for cmd in commands:
        await self.capability_worker.exec_local_command(cmd)
    await self.capability_worker.speak("Development environment is ready.")
    self.capability_worker.resume_normal_flow()
```

### 2. System health monitor

```python theme={"system"}
# Trigger: "check system health"
async def first_function(self):
    metrics = [
        ("CPU usage", "get cpu usage"),
        ("Memory usage", "get memory usage"),
        ("Disk space", "get disk usage"),
        ("Battery level", "get battery level"),
    ]
    report = []
    for name, cmd in metrics:
        response = await self.capability_worker.exec_local_command(cmd)
        report.append(f"{name}: {response}")
    await self.capability_worker.speak(", ".join(report))
    self.capability_worker.resume_normal_flow()
```

### 3. Smart screenshot

```python theme={"system"}
# Trigger: "take screenshot of active window"
async def first_function(self):
    user_inquiry = await self.capability_worker.wait_for_complete_transcription()

    if "full screen" in user_inquiry.lower():
        cmd = "screenshot fullscreen save to ~/Desktop"
    elif "active window" in user_inquiry.lower():
        cmd = "screenshot active window save to ~/Desktop"
    else:
        cmd = "screenshot selection save to ~/Desktop"

    response = await self.capability_worker.exec_local_command(cmd, timeout=15.0)
    await self.capability_worker.speak(f"Screenshot saved: {response}")
    self.capability_worker.resume_normal_flow()
```

### 4. App manager with confirmation

```python theme={"system"}
# Trigger: "close all browsers"
async def first_function(self):
    response = await self.capability_worker.exec_local_command("list open browsers")

    if "none" in response.lower():
        await self.capability_worker.speak("No browsers are open.")
        self.capability_worker.resume_normal_flow()
        return

    await self.capability_worker.speak(f"Found: {response}. Close all?")
    confirmation = await self.capability_worker.user_response()

    if "yes" in confirmation.lower():
        await self.capability_worker.exec_local_command("close all browsers")
        await self.capability_worker.speak("All browsers closed.")
    else:
        await self.capability_worker.speak("Cancelled.")

    self.capability_worker.resume_normal_flow()
```

## Best practices

### 1. Define clear trigger words

Specific, unambiguous triggers beat generic ones:

* ✅ `start development session`, `launch dev environment`, `open my coding setup`
* ❌ `start`, `go`, `do it`

Avoid trigger phrases that collide with other Abilities.

### 2. Validate before executing

```python theme={"system"}
DANGEROUS_COMMANDS = ["rm -rf", "format", "delete system", "shutdown -h now"]

if any(danger in user_inquiry.lower() for danger in DANGEROUS_COMMANDS):
    await self.capability_worker.speak("I can't execute that for safety reasons.")
    return
```

### 3. Confirm destructive actions

```python theme={"system"}
if "restart" in user_inquiry.lower() or "shutdown" in user_inquiry.lower():
    confirmed = await self.capability_worker.run_confirmation_loop(
        "This will restart your computer. Are you sure?"
    )
    if not confirmed:
        await self.capability_worker.speak("Cancelled.")
        return
```

### 4. Tune timeouts

```python theme={"system"}
# Default is fine for quick commands
response = await self.capability_worker.exec_local_command("open Chrome")

# Long-running — bump the timeout
response = await self.capability_worker.exec_local_command(
    "compile entire project",
    timeout=60.0,
)
```

### 5. Format responses for voice

Don't just echo raw OpenClaw output. Parse and shape:

```python theme={"system"}
response = await self.capability_worker.exec_local_command("get battery level")
# Raw: "Battery: 73% (charging, 2:15 remaining)"
# Spoken: "Battery is at 73 percent."
battery = extract_percentage(response)
await self.capability_worker.speak(f"Battery is at {battery} percent.")
```

Keep spoken output to **1 sentence, 15 words or less**.

### 6. Handle errors and timeouts

```python theme={"system"}
try:
    response = await self.capability_worker.exec_local_command(user_inquiry, timeout=15.0)
    if "error" in response.lower() or "failed" in response.lower():
        await self.capability_worker.speak("That command didn't work. Try something else.")
    else:
        # process success
        ...
except asyncio.TimeoutError:
    await self.capability_worker.speak("That took too long. It might still be running.")
except Exception as e:
    self.worker.editor_logging_handler.error(f"Command failed: {e}")
    await self.capability_worker.speak("Something went wrong. Check the logs.")
```

### 7. Chain commands for workflows

```python theme={"system"}
workflow = [
    ("Opening calendar", "open Calendar app"),
    ("Starting video", "open Zoom"),
    ("Opening notes", "open Notes app"),
]
for description, command in workflow:
    await self.capability_worker.speak(description)
    await self.capability_worker.exec_local_command(command)
    await asyncio.sleep(1)

await self.capability_worker.speak("Ready for your meeting.")
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="OpenClaw client won't connect">
    * Verify your API key is correct (from Dashboard → Settings → API Keys)
    * Check the daemon is running: `openclaw status`
    * Restart the OpenClaw client app
    * Check the client logs for error messages
  </Accordion>

  <Accordion title="Commands time out or fail">
    * Increase timeout: `exec_local_command(command, timeout=20.0)`
    * Check daemon status: `openclaw status`
    * Verify the command is valid for your OS
    * Review OpenClaw client logs
  </Accordion>

  <Accordion title="Permission errors on macOS">
    * System Settings → Privacy & Security → find the blocked app → **Open Anyway**
    * Grant Accessibility and Automation permissions when prompted
  </Accordion>

  <Accordion title="Commands not executing">
    * Confirm the client shows *"Connected"*
    * Test a safe command first: *"what time is it"*
    * Verify the Ability is registered on your Agent
    * Review OpenClaw client logs
  </Accordion>
</AccordionGroup>

## Security & privacy

<Warning>
  OpenClaw runs with **your user permissions** on the local machine. Commands execute exactly as if you typed them in a terminal.
</Warning>

* Commands run locally — not sent to external servers (the LLM used by OpenClaw may receive the natural-language text for command generation)
* Your OpenHome API key authenticates the OpenHome → OpenClaw connection
* **Always add validation** for user-provided input
* **Use confirmation prompts** for destructive operations (restart, delete, format)
* Review all permissions carefully when installing the client

## Architecture

```
Voice Input → OpenHome Ability → exec_local_command()
                                        ↓
                                 OpenClaw Client
                                   (via WebSocket)
                                        ↓
                                 OpenClaw Daemon
                                  (with LLM API)
                                        ↓
                                Local System Execution
                                  (apps, files, etc.)
                                        ↓
                        Response ← AI Formatting ← Template
```

## Resources

* **OpenClaw template** on GitHub: [openhome-dev/abilities/templates/OpenClaw](https://github.com/openhome-dev/abilities/tree/dev/templates/OpenClaw)
* **OpenClaw CLI help:** `openclaw --help`
* **Check status:** `openclaw status`
* **Quick start checklist:** [Getting Started → OpenClaw](/guides/getting-started/openclaw)
* **Lightweight alternative:** [Local Connect](/building-abilities/local-connect)
