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

# Overview

> Install typed command-line programs beside your mounts and let agents act on services by name.

Mounts make a service readable as files; CLIs make it actionable as a
program. A CLI is a typed program tree (`CLISpec`) installed on the
workspace by name and separate from the mounts: an account CLI
initializes from its own config, consults no mount, and takes no operand
path. `git` is the credential-free tier, so it takes no config at all and
reads the repository `-C` names through the mount ops. The shell
dispatches a line to a CLI when its first word matches an installed
name.

```python theme={null}
from mirage import Workspace
from mirage.commands.cli.builtin.himalaya import HIMALAYA

ws = Workspace({"/mail": EmailVFS(config)})
ws.register_cli("himalaya", HIMALAYA, config.model_dump())

await ws.shell("himalaya envelope list --unseen --max 5")
```

The config is a mapping, validated through the CLI's config model, or an
instance of that model, taken as it is. Anything else is refused at install
time.

In YAML the same install rides the `clis:` section:

```yaml theme={null}
mounts:
  /mail:
    vfs: email
    config: { ... }
clis:
  himalaya:
    cli: himalaya
    config: { ... }
```

Every level of the tree answers `--help`, unknown verbs fail with git's
wording (exit 1), and missing required flags fail with argparse's
wording (exit 2). Two installs under different head words are two
accounts.

## Authoring your own CLI

The [custom CLI authoring guide](/python/cli/custom) covers the complete
lifecycle: a runnable multi-account example, typed and script CLIs, code and
YAML registration, constructor validation, snapshots and credentials, the
`CLISpec` / `Option` / `Operand` reference, and an agent authoring checklist.

Installed CLIs are self-discovering through `man`, `--help`, `type`, and
`which`: each has an executable file under `/usr/bin`, the directory `$PATH`
names, so `which linear` prints `/usr/bin/linear`. Installation remains a
host-side API, so an agent can use and inspect the programs it was given but
cannot uninstall them.

These are read-only virtual command stubs. Agents can use `cat`, `grep`,
`head`, and `file` to inspect them. For example, `cat /usr/bin/linear`
shows which kind of command runs and points to `linear --help`; it does
not expose the implementation, account configuration, or credentials.
Use `linear --help` or `man linear` for the command's interface.

`ls -l`, `stat -c %s`, and `wc -c` report the stub's actual UTF-8 byte
length, not the installed program's size or a zero-byte placeholder.
Executing `/usr/bin/linear` dispatches the registered command with the
same arguments and command policy checks. Only programs visible to the
session are listed; shell-only builtins such as `cd` have no file.

The virtual program directory is fixed at `/usr/bin`: changing `PATH`
does not change Mirage's command catalog or lookup order. Host and remote
runtimes use their own executable search paths; the default virtual
`PATH` is not exported to them.

## Builtin CLIs

| Program | Acts on | Vocabulary |
| - | - | - |
| [himalaya](/python/cli/himalaya) | IMAP/SMTP mail | pimalaya/himalaya (`envelope`, `message`) |
| [gws](/python/cli/gws) | Google Workspace | official Google Workspace CLI |
| [slack](/python/cli/slack) | Slack | OpenClaw Slack actions (`send-message`, …) |
| [discord](/python/cli/discord) | Discord | OpenClaw Discord actions (`send`, `poll`, …) |
| [ntn](/python/cli/ntn) | Notion | official Notion CLI (`pages`, `datasources`) |
| [linear](/python/cli/linear) | Linear | noun/verb (`issue create`, `team list`) |
| [airtable](/python/cli/airtable) | Airtable | noun/verb (`record update`, `comment add`) |
| [gh](/python/cli/gh) | GitHub | repositories, issues, pull requests, releases, Actions, API |
| [git](/python/cli/git) | git repositories | git (`status`, `log`, `add`, `commit`) |

Reading stays on the mount (`cat`, `grep`, `jq` over the virtual
files); acting goes through the CLI. The mounted tree's
`<name>__<id>` path segments supply the IDs the CLI flags take.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.