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

# Use HoloDesktop CLI from an agent host

> Let Claude Code, Cursor, Codex, and other hosts hand desktop work to HoloDesktop CLI over MCP, ACP, or A2A.

export const Notice = ({kind = "note", title, children}) => {
  const kinds = {
    warning: {
      label: "User notice",
      icon: <>
          <path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" />
          <path d="M12 9v4" />
          <path d="M12 17h.01" />
        </>
    },
    gotcha: {
      label: "Gotcha",
      icon: <>
          <circle cx="12" cy="12" r="10" />
          <path d="M12 16v-4" />
          <path d="M12 8h.01" />
        </>
    },
    note: {
      label: "Note",
      icon: <>
          <circle cx="12" cy="12" r="10" />
          <path d="M12 16v-4" />
          <path d="M12 8h.01" />
        </>
    }
  };
  const k = kinds[kind];
  return <div className="notice my-6 rounded-xl border border-zinc-200 bg-white p-5 dark:border-zinc-800 dark:bg-zinc-950">
      <div className={`${kind === "warning" ? "not-prose flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wide text-red-400/80 dark:text-red-400/70" : kind === "gotcha" ? "not-prose flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wide text-amber-500/80 dark:text-amber-400/70" : "not-prose flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wide text-zinc-400 dark:text-zinc-500"}`}>
        <svg className="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          {k.icon}
        </svg>
        {k.label}
      </div>
      {title && <div className="not-prose mt-2 text-base font-semibold text-zinc-900 dark:text-zinc-100">{title}</div>}
      <div className="notice-body mt-3 text-sm leading-6 text-zinc-700 dark:text-zinc-300">{children}</div>
    </div>;
};

Coding assistants and agent hosts can delegate desktop work to HoloDesktop CLI. Three protocols are supported, all fronting the same local runtime:

| Protocol                 | Command                         | The host sees                            | Can cancel mid-run                      | Use it with                                                               |
| ------------------------ | ------------------------------- | ---------------------------------------- | --------------------------------------- | ------------------------------------------------------------------------- |
| [MCP](#connect-over-mcp) | `holo mcp` (stdio)              | One tool, `holo_desktop`                 | No, the call blocks until the task ends | Claude Code, Cursor, Codex, Grok Build, OpenCode                          |
| [ACP](#connect-over-acp) | `holo acp` (stdio)              | A sub-agent                              | Yes                                     | Hermes, OpenClaw, Zed, other [ACP](https://agentclientprotocol.com) hosts |
| [A2A](#connect-over-a2a) | `holo serve` (HTTP on loopback) | An [A2A](https://a2a-protocol.org) agent | Yes                                     | Your own agents and orchestrators                                         |

`holo install` also drops a [skill](/holo-desktop-cli/integrations/use-as-skill) where the host supports one, so the parent agent learns when to hand off to HoloDesktop CLI, not just how to reach it.

All three are beta. Host implementations are still moving, especially around cancellation of long-running desktop calls.

## Before you start

Run one task from the terminal to check that HoloDesktop CLI starts on this machine:

```bash theme={"system"}
holo run "Open TextEdit and write a short note saying HoloDesktop CLI is installed"
```

Hosts launch the CLI non-interactively, so they cannot complete browser login. For hosted mode, sign in first and restart the host afterwards:

```bash theme={"system"}
holo login
holo whoami
```

For local mode, the host process needs `HAI_AGENT_RUNTIME_BASE_URL` and `HAI_AGENT_RUNTIME_MODEL`. See [Local mode from hosts](/holo-desktop-cli/getting-started/hosted-or-local-models#local-mode-from-hosts) for where to put them, including GUI apps that do not inherit shell exports.

## Connect over MCP

List the hosts HoloDesktop CLI can install itself into, and whether each is detected on your machine:

```bash theme={"system"}
holo install list
```

| Host ID          | Host               |
| ---------------- | ------------------ |
| `claude-code`    | Claude Code        |
| `claude-desktop` | Claude Desktop     |
| `codex`          | Codex              |
| `cursor`         | Cursor             |
| `grok-build`     | Grok Build         |
| `opencode`       | OpenCode           |
| `openclaw`       | OpenClaw           |
| `hermes`         | Hermes             |
| `copilot`        | GitHub Copilot CLI |
| `antigravity`    | Antigravity        |

Install into one host, or into every detected host at once:

```bash theme={"system"}
holo install cursor
holo install
```

`holo install` either calls the host's own MCP CLI or updates its MCP config file. When possible it writes the absolute path to the `holo` executable, so GUI hosts do not depend on your shell `PATH`. Re-running it preserves extra keys such as `env`.

Claude Code registers the server at `local` scope, tied to the workspace you run the command from:

```bash theme={"system"}
cd /path/to/your/claude-code-workspace
holo install claude-code
```

Grok Build gets both the MCP server (in `~/.grok/config.toml`) and the bundled skill (under `~/.grok/skills/holo-desktop`). Check with `grok mcp list` and `grok inspect`.

For file-backed hosts such as Cursor, the installed entry looks like this. Add an `env` block for local mode:

```json theme={"system"}
{
  "mcpServers": {
    "holo": {
      "type": "stdio",
      "command": "/absolute/path/to/holo",
      "args": ["mcp"],
      "env": {
        "HAI_AGENT_RUNTIME_BASE_URL": "http://localhost:8000/v1",
        "HAI_AGENT_RUNTIME_MODEL": "holo3-1-35b-a3b"
      }
    }
  }
}
```

### What the host gets

The MCP server exposes one tool:

```text theme={"system"}
holo_desktop(task: str) -> str
```

<Notice kind="gotcha" title="The tool call blocks until the task ends">
  `holo_desktop` is a blocking call, not a background job. While it runs, HoloDesktop CLI owns one desktop task and keeps observing, clicking, and typing until the task completes or hits its safety budget.

  The CLI cancels the run on MCP `notifications/cancelled` and on stdio shutdown. Some hosts do not propagate cancellation consistently yet, so stopping a chat response may not stop the desktop run right away. Keep the CLI up to date and prefer short, specific tasks that finish or time out cleanly.
</Notice>

Each call should be a self-contained desktop task. The CLI does not see the host conversation, so the host has to include the app, workspace, account, person, and success condition.

Good task:

```text theme={"system"}
Open Slack in the Acme workspace and send a DM to Sarah Chen saying "on my way". Return "sent" after the message appears.
```

Too vague:

```text theme={"system"}
Tell Sarah.
```

## Connect over ACP

ACP host configuration differs by host. Point it at a stdio command that runs the ACP server:

```text theme={"system"}
command: holo
args: ["acp"]
```

From a source checkout, run it through `uv` instead:

```text theme={"system"}
command: uv
args: ["run", "holo", "acp"]
```

HoloDesktop CLI starts the desktop runtime locally and creates a desktop session for each task the host sends. ACP hosts can cancel an in-flight task, which is the main reason to pick it over MCP.

## Connect over A2A

For agents you build yourself, run HoloDesktop CLI as an [A2A](https://a2a-protocol.org) server:

```bash theme={"system"}
export HOLO_AUTH_TOKEN=$(openssl rand -hex 24)
holo serve
```

It listens on `127.0.0.1:18794` (change with `--port`), requires `Authorization: Bearer $HOLO_AUTH_TOKEN` on every request, and maps each A2A `contextId` to one desktop session, so a multi-turn conversation in your agent stays one session here. Pass `--base-url` and `--model` exactly as you would to `holo run` to use a local model.

## Stop a run

The host owns the conversation, so cancel the tool call or sub-agent session from the host. HoloDesktop CLI cancels the active runtime session when it receives the cancellation or when the stdio connection closes. `holo stop` from any terminal, or `Esc` twice, also works: in headless surfaces the double-`Esc` is watched by `holo guard`, which `holo install` registers with the OS. See [Stop a run](/holo-desktop-cli/getting-started/quickstart#stop-a-run).

Avoid `holo stop --force` here. Hosts spawn their runtime once at startup, so a force-kill leaves the host process alive but pointing at a dead runtime, and every later task fails until you restart the host.

## Check it worked

Restart the host after installation if it was already open. Then ask it to do a small, safe desktop task:

```text theme={"system"}
Open TextEdit and write a short note saying HoloDesktop CLI is connected. Return "done" when the note is visible.
```

If the host cannot find or start HoloDesktop CLI:

* run `holo install list` and confirm the host ID, then re-run `holo install <host-id>`;
* check that hosted mode has `HAI_API_KEY`, or local mode has `HAI_AGENT_RUNTIME_BASE_URL`, available to the host process;
* for a source checkout, check that the command path points at the checkout where `uv sync` succeeded;
* check `~/.holo/logs/` for runtime startup errors.

## Next steps

<CardGroup cols={2}>
  <Card title="Use as a skill" icon="graduation-cap" href="/holo-desktop-cli/integrations/use-as-skill">
    The guidance installed into hosts that support skills.
  </Card>

  <Card title="Debug a failed run" icon="bug" href="/holo-desktop-cli/how-to/debug-failed-run">
    When the CLI works in the terminal but not from the host.
  </Card>
</CardGroup>
