# The mehen command line

`mehen` is the command line on every machine an agent works from, and `mehen mcp` serves the core operations as [MCP tools](https://docs.mehen.dev/reference/mcp.md); their inputs, output shapes, timeouts and body limits differ where those pages say so. No command and no tool returns a secret value, except the real values a human allowed into a `mehen run` child, which go to that child only. The command sections below are generated from the command table `mehen` itself is built from, so they match `mehen <command> --help` for the version in the footer.

## By task

| Task | CLI | MCP tool |
| --- | --- | --- |
| Which workspaces is this machine in? | `mehen status` | `vault_status` |
| Why is it not working? | `mehen doctor` | `vault_doctor` |
| Enrol it in a workspace | `mehen enrol --workspace <slug>` (prints the ask and exits), then `mehen wait enr_...` | `vault_wait` (to finish) |
| Which workspace does this checkout use? | `mehen workspace show` | |
| Is `mehen` current? | `mehen update --check --json` (a release build with a trusted key updates itself) | |
| What may I name as a provider? | `mehen templates [<id>]` | `vault_templates` |
| What credentials exist? | `mehen ls` | `vault_list` |
| Is this key set and right? | `mehen show <slug>` | `vault_show` |
| Will this request be allowed? | `mehen check <slug> <METHOD> <url>` | `vault_check` |
| Ask a human for a new credential | `mehen request <kind> --name <slug> --provider <template> --reason <why> [--home private\|project\|workspace]` | `vault_request` |
| Connect an OAuth account | `mehen connect <provider> --name <slug> --reason <why> [--expect <account>] [--request-client]` | `vault_connect` |
| Wait for an intake, connection, approval or enrolment | `mehen wait <id>` | `vault_wait` |
| Which links are still open? | `mehen pending [<id>]` | `vault_pending` |
| Call an HTTP API | `mehen fetch <slug> <METHOD> <url> [--project <prj_id> --env <name>]` | `vault_fetch` |
| Run a project command | `mehen run [--env <name>] -- <cmd>` | |
| Check a project's variables | `mehen env check` | `vault_env` with `check` |
| Pull the brake | `mehen freeze` | |
| The short guide | `mehen guide` | |

## Output and `--json`

`--json` works on every command except `mehen run`, `mehen env set`, `mehen init` and `mehen mcp`. With it, results go to stdout as one JSON object per line, and errors go to stdout as an error object (see [Errors and exit codes](https://docs.mehen.dev/reference/errors.md)). Without it, results go to stdout and anything meant for a person reading along goes to stderr. Use `--json` whenever a program reads the output; it may also come before the command (`mehen --json status`).

The standard commands accept `--no-qr`, which turns off the terminal QR code for one run; `mehen mcp`, `mehen run`, `mehen env` and `mehen init` do not, so set `MEHEN_QR=0` when a run's approval block must not draw one. `--workspace <slug or id>` is accepted by every command, before or after it, and picks which of this machine's enrolments acts ([Several workspaces on one machine](https://docs.mehen.dev/guides/several-workspaces.md)). `mehen run --help`, `mehen env --help` and `mehen init --help` print the usage and exit 0.

`--timeout` on `wait`, `request` and `connect` takes `0` (check once), a number of seconds, or `30s`, `10m`, `2h`, up to 24 hours. The default is 10 minutes.

## Environment variables

The variables `mehen` reads:

| Variable | Meaning |
| --- | --- |
| `MEHEN_SESSION` | A label for your session (1 to 120 letters, digits, `.`, `:`, `_` or `-`), shown to the human in the details of intake, connect and approval pages and written to the audit log. Set it; a harness that draws cards from your calls usually sets it for you. It grants nothing. |
| `MEHEN_ENV` | Picks an unprotected environment for `mehen run` and `mehen env` when there is no `--env`. Never a protected one. |
| `MEHEN_VAULT_URL` | The vault to enrol with when it is not `https://app.mehen.dev`. Once a workspace is selected, a value naming another origin is `workspace_mismatch`. |
| `MEHEN_HOME` | Where this machine's Mehen state lives: one directory per workspace under it, with its config, device key, key scope and ledger. Default `~/.config/mehen`. A different `MEHEN_HOME` is a different machine to the vault. Set by the harness or the human; leave it as it is. |
| `MEHEN_WORKSPACES` | Which workspaces this agent may use, comma-separated slugs or `tn_` ids; unset means all. It only narrows: anything outside is `workspace_not_allowed`. Set by the harness; only the human widens it. |
| `MEHEN_WORKSPACE` | The same as `--workspace <slug or id>`: which workspace acts. |
| `MEHEN_MANAGED_CONTEXT` | Set by an agent launcher on a managed host, with the pinned workspace directory; never set it yourself. |
| `MEHEN_NO_AUTO_UPDATE` | `1` switches off the background update and the automatic update when the vault asks for a newer `mehen`. |
| `MEHEN_QR` | `0` turns the terminal QR code off; `light` or `dark` picks its colours when the terminal does not say. |
| `NO_COLOR`, `FORCE_COLOR`, `TERM` | Colour is used only on a terminal, never with `NO_COLOR` set or `TERM=dumb`; `FORCE_COLOR` forces it on. Colour never carries meaning on its own. |

## Exit codes

These are Mehen's own exit codes. `mehen run` returns the child's exit code after a successful start; it is not limited to this table. [Errors and exit codes](https://docs.mehen.dev/reference/errors.md#exit-codes) says what to do with each, and names every error code.

| Exit | Meaning |
| --- | --- |
| `0` | OK |
| `1` | Error |
| `2` | Usage |
| `3` | Approval required |
| `4` | A human must act |
| `5` | Refused by rule |
| `6` | Identity |
| `7` | Transient |

## Commands

In the order `mehen --help` lists them. Standard commands accept the global flags `--json`, `--help`, `--no-qr`, `--workspace`. `run`, `env`, `init` and `mcp` have the command-specific exceptions described under [Output and `--json`](#output-and---json) and in their usage.

| Command | What it does |
| --- | --- |
| [`setup`](#setup) | register the Mehen MCP server and skills in your installed agents, at user level |
| [`update`](#update) | check for or install a signed Mehen release and refresh managed skills |
| [`enrol`](#enrol) | enrol this machine in a workspace: prints the link a human accepts in the browser, then mehen wait finishes it; the key is kept across attempts |
| [`status`](#status) | show every workspace this machine is in, or one with --workspace |
| [`whoami`](#whoami) | same as mehen status |
| [`doctor`](#doctor) | check in one go: every workspace on this machine, its key, the vaults, the clock, identity, session label, frozen, and what to do next |
| [`ls`](#ls) | list the items this machine may use |
| [`show`](#show) | show an item's public metadata (never its value) |
| [`templates`](#templates) | list the credential templates and OAuth providers an agent may name (no network) |
| [`check`](#check) | evaluate an item's base policy locally (advisory, not permission to send) |
| [`request`](#request) | ask a human for a credential (prints the link for them) |
| [`connect`](#connect) | ask a human to connect an OAuth account (prints the link for them) |
| [`wait`](#wait) | wait for an intake (int_), approval (apr_), connection (con_), enrolment (enr_) or policy proposal (pol_) |
| [`pending`](#pending) | list the asks still waiting for a human, or show one again (mehen pending [<id>\|<slug>]) |
| [`policy`](#policy) | read policy or stop access; preview and propose are unavailable in this release |
| [`fetch`](#fetch) | make an HTTP request with an item's credential, through the vault |
| [`revoke`](#revoke) | revoke this workspace's device key and forget it locally |
| [`freeze`](#freeze) | freeze the whole workspace: every use is refused until a human unfreezes it |
| [`guide`](#guide) | how agents use the vault: references, intake, next, exit codes |
| [`version`](#version) | print the mehen version and the commit it was built from |
| [`run`](#run) | run a command with the project's variables (mehen run [--env <env>] -- <command>) |
| [`env`](#env) | list, check or set the project's variables (mehen env ls\|check\|set) |
| [`init`](#init) | create the project and write mehen.toml |
| [`workspace`](#workspace) | list, show, forget or bind a checkout to this machine's workspaces (mehen workspace list\|show\|forget\|bind) |
| [`mcp`](#mcp) | serve the vault tools over MCP on stdio |

## `setup`

Register the Mehen MCP server and skills in your installed agents, at user level.

```
mehen setup [--agent <name>]... [--workspaces <a,b>] [--mcp-file <path>] [--remove] [--dry-run] [--force] [--reset-env] [--print [--format json|toml]]
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--agent` |  | a value; repeatable |
| `--workspaces` |  | a value |
| `--mcp-file` |  | a value |
| `--dry-run` |  | nothing (a switch) |
| `--remove` |  | nothing (a switch) |
| `--force` |  | nothing (a switch) |
| `--reset-env` |  | nothing (a switch) |
| `--print` |  | nothing (a switch) |
| `--format` |  | a value |

Examples:

```sh
mehen setup --json
mehen setup --agent codex --dry-run
mehen setup --workspaces acme --agent claude-code
mehen setup --mcp-file /path/to/mcp.json
mehen setup --print --format toml
mehen setup --remove
```

- Agents: claude-code, codex, cursor, pi, gemini, opencode, vscode, claude-desktop. Reload or restart afterwards.
- One `mehen` server per agent, always `mehen mcp`, serving every workspace this machine may use. The entry carries MEHEN_WORKSPACES when this shell is restricted or --workspaces narrows it (never wider than this shell), and MEHEN_HOME for a root other than ~/.config/mehen.
- --mcp-file writes mcpServers.mehen into any JSON MCP client's file. --print renders the entry and writes nothing.
- Symlinked and foreign skills and entries are left alone unless --force, which needs the human's agreement and still refuses unsafe files; read every entry's status and reason. Settings are backed up once; --remove only undoes entries still owned by setup, and the skills stay while another entry remains.
- Exit 1 when a skill or an agent file failed; 2 when every agent was skipped.

## `update`

Check for or install a signed Mehen release and refresh managed skills.

```
mehen update [--check] [--force] [--version <v>] [--rollback]
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--check` |  | nothing (a switch) |
| `--force` |  | nothing (a switch) |
| `--version` |  | a value |
| `--rollback` |  | nothing (a switch) |
| `--background` |  | nothing (a switch) |

Examples:

```sh
mehen update --check --json
mehen update --json
mehen update --rollback --json
```

- Installs only a release signed by a key this build trusts, newer than the one running, after a smoke test of the new binary; the previous binary is kept for --rollback.
- --check only reports. --force installs the signed release named even when it is not newer. No sudo; the installed binary's directory must be writable. Exit 0 also when another update holds the lock.

## `enrol`

Enrol this machine in a workspace: prints the link a human accepts in the browser, then mehen wait finishes it; the key is kept across attempts.

```
mehen enrol --workspace <slug> [--name <machine-name>] [--team <team-slug>] [--backend secure-enclave|software] [--fresh-key] [--wait] [--no-renew] [--connect <code>]
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--name` |  | a value |
| `--team` |  | a value |
| `--backend` |  | a value |
| `--fresh-key` |  | nothing (a switch) |
| `--wait` |  | nothing (a switch) |
| `--no-renew` |  | nothing (a switch) |
| `--connect` |  | a value |

Examples:

```sh
mehen enrol --workspace acme --name my-laptop
mehen enrol --workspace acme --name ci-runner --team ci --backend software --json
```

- The slug is on the workspace's Connect an agent page. Your own machine: you accept it yourself with your passkey. --team: an owner or admin admits it as the team's machine.
- Prints the link and exits 0: relay it, then run `mehen wait enr_...` until it is accepted; it keeps the link alive while it waits. --wait waits here instead.
- Each workspace gets its own slot under the config root (MEHEN_HOME, default ~/.config/mehen); running it again resumes the same attempt with the same key.

## `status`

Show every workspace this machine is in, or one with --workspace.

```
mehen status [--workspace <slug or id>]
```

No flags of its own; the global flags apply.

Examples:

```sh
mehen status
mehen status --json
mehen status --workspace acme
```

- Lists every workspace slot this machine may use (active, pending, ended with the key kept, corrupt, and MEHEN_WORKSPACES entries not enrolled yet), each active one checked with the vault; a failing check is reported, never deleted. Exit 0.
- With --workspace (or MEHEN_WORKSPACE): that one workspace's status; not enrolled is exit 6 with next.command mehen enrol --workspace <slug>. When something else is wrong, mehen doctor checks everything at once.

## `whoami`

Same as mehen status.

```
mehen whoami
```

No flags of its own; the global flags apply.

Examples:

```sh
mehen whoami --json
```

- Lists every workspace slot this machine may use (active, pending, ended with the key kept, corrupt, and MEHEN_WORKSPACES entries not enrolled yet), each active one checked with the vault; a failing check is reported, never deleted. Exit 0.
- With --workspace (or MEHEN_WORKSPACE): that one workspace's status; not enrolled is exit 6 with next.command mehen enrol --workspace <slug>. When something else is wrong, mehen doctor checks everything at once.

## `doctor`

Check in one go: every workspace on this machine, its key, the vaults, the clock, identity, session label, frozen, and what to do next.

```
mehen doctor
```

No flags of its own; the global flags apply.

Examples:

```sh
mehen doctor
mehen doctor --json
```

- Exits 0 when no check failed, else with the exit code of the first failure. Works before enrolment. The checks never migrate, write or delete anything: strays under the config root are named, not removed. As after any command, the background updater may run afterwards when a check for a new release is due.

## `ls`

List the items this machine may use.

```
mehen ls [--tag <tag>] [--kind <kind>] [--provider <provider>]
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--tag` |  | a value |
| `--kind` |  | a value |
| `--provider` |  | a value |

Examples:

```sh
mehen ls
mehen ls --kind api-key --json
mehen ls --provider openai
```

## `show`

Show an item's public metadata (never its value).

```
mehen show <item>
```

No flags of its own; the global flags apply.

Examples:

```sh
mehen show openai-personal
mehen show gmail-personal --json
```

- Never the value: for each secret field, whether it is set, its length, a well-known prefix and a fingerprint.

## `templates`

List the credential templates and OAuth providers an agent may name (no network).

```
mehen templates [<id>]
```

No flags of its own; the global flags apply.

Examples:

```sh
mehen templates
mehen templates google-gmail --json
```

## `check`

Evaluate an item's base policy locally (advisory, not permission to send).

```
mehen check <item> <METHOD> <URL> [-H 'Name: value']... [-d @file|-|text]
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--header` | `-H` | a value; repeatable |
| `--data` | `-d` | a value |

Examples:

```sh
mehen check openai-personal GET https://api.openai.com/v1/models
mehen check gmail-personal POST https://gmail.googleapis.com/gmail/v1/users/me/messages/send -d @message.json --json
```

- Exits 0 (base allow), 3 (base approval) or 5 (base refusal).
- Fetches the item's public metadata from the vault and evaluates its base binding and policy locally. It sends no request upstream and creates no approval. Its answer is advisory, not permission to send; live scope, protection, policy floors and grants can change the result.

## `request`

Ask a human for a credential (prints the link for them).

```
mehen request <kind> --name <slug> --reason <why> [--provider <template>] [--home private|project|workspace] [--project <prj_id>] [--tag <tag>]... [--host <host>]... [--path <glob>]... [--header <name> --format "Bearer {key}"] [--wait] [--new] [--timeout <duration>]
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--name` |  | a value |
| `--home` |  | a value |
| `--project` |  | a value |
| `--provider` |  | a value |
| `--reason` |  | a value |
| `--tag` |  | a value; repeatable |
| `--host` |  | a value; repeatable |
| `--path` |  | a value; repeatable |
| `--header` |  | a value |
| `--format` |  | a value |
| `--wait` |  | nothing (a switch) |
| `--new` |  | nothing (a switch) |
| `--timeout` |  | a value |

Examples:

```sh
mehen request api-key --name openai-personal --provider openai --reason 'run the nightly evals against the OpenAI API' --json
mehen request api-key --name snyk --host api.snyk.io --header Authorization --format 'token {key}' --reason 'scan this repo'\''s dependencies'
mehen request api-key --name openai-team --provider openai --home project --project prj_3kQ9vXyZ7 --reason 'run the evals for this project'
```

- Prints the ask block for the human; the value goes into the vault page, never through you. mehen templates lists the providers.
- Naming a credential this machine can already reach asks the human to rotate it instead: --home and --provider must match it, only its secret fields are replaced, and its binding and policy stay.
- Without --provider, the item holds every request for a human's approval unless the human lets reads through on the page.
- --home says who the credential belongs to: private (only the owner, the default), project (needs --project or the checkout's mehen.toml) or workspace. The human may change it on the page.

## `connect`

Ask a human to connect an OAuth account (prints the link for them).

```
mehen connect <provider> --name <slug> --reason <why> [--client <oauth-client-item>] [--home private|project|workspace] [--project <prj_id>] [--scopes a,b] [--expect <account>] [--request-client] [--client-tag <tag>]... [--wait] [--new] [--timeout <duration>]
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--client` |  | a value |
| `--name` |  | a value |
| `--home` |  | a value |
| `--project` |  | a value |
| `--scopes` |  | a value; repeatable |
| `--expect` |  | a value |
| `--reason` |  | a value |
| `--request-client` |  | nothing (a switch) |
| `--client-tag` |  | a value; repeatable |
| `--wait` |  | nothing (a switch) |
| `--new` |  | nothing (a switch) |
| `--timeout` |  | a value |

Examples:

```sh
mehen connect google-gmail --name gmail-personal --expect you@example.com --reason 'read and draft replies in your inbox' --request-client --json
mehen connect github-oauth --name github-personal --scopes read:user,repo --reason 'open pull requests for you'
```

- With no OAuth client in the vault it exits 4 (client_missing) with the mehen request to run; --request-client asks for the client first, in one chain.
- --home as for mehen request: private by default, project with --project or the checkout's mehen.toml, or workspace.

## `wait`

Wait for an intake (int_), approval (apr_), connection (con_), enrolment (enr_) or policy proposal (pol_).

```
mehen wait <id> [--timeout <duration>] [--json [--events]]
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--timeout` |  | a value |
| `--events` |  | nothing (a switch) |

Examples:

```sh
mehen wait int_3kQ9vXyZ7 --timeout 10m
mehen wait apr_7Hq2 --json --events
```

- A human who has not acted by the timeout is exit 4 (timeout) with the ask handed back: relay it again and wait again. Ctrl-C leaves the link valid.

## `pending`

List the asks still waiting for a human, or show one again (mehen pending [<id>|<slug>]).

```
mehen pending [<id>|<slug>]
```

No flags of its own; the global flags apply.

Examples:

```sh
mehen pending
mehen pending apr_7Hq2 --json
```

## `policy`

Read policy or stop access; preview and propose are unavailable in this release.

```
mehen policy show <item> | preview --file <path|-> | propose --file <path|-> | propose --item <slug> --policy-mode <relaxed|yolo> (--session|--device) --host <host> --method <METHOD> --path <pattern> --anchor-path <path> --reason <text> | cancel <pol_id> | stop <pov_id|gnt_id>
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--file` |  | a value; repeatable |
| `--new` |  | nothing (a switch) |
| `--session` |  | nothing (a switch) |
| `--device` |  | nothing (a switch) |
| `--item` |  | a value; repeatable |
| `--policy-mode` |  | a value; repeatable |
| `--action` |  | a value; repeatable |
| `--host` |  | a value; repeatable |
| `--method` |  | a value; repeatable |
| `--path` |  | a value; repeatable |
| `--anchor-path` |  | a value; repeatable |
| `--reason` |  | a value; repeatable |
| `--for` |  | a value; repeatable |
| `--until` |  | a value; repeatable |

Examples:

```sh
mehen policy show example-key
mehen policy preview --file proposal.json
mehen policy propose --file - --json
mehen policy stop pov_example
```

- Preview and propose are retained in the command surface but are refused by the current workspace server (forbidden: Policy widening is not available yet). No access changes before a human's passkey decision.
- Choose --session with MEHEN_SESSION set, or --device for access shared by any program on this device. No run scope or automatic renewal.
- --for accepts seconds, 10m or 2h. --until requires an ISO timestamp with timezone. They are mutually exclusive.
- File preview is PolicyPreviewRequest; file propose is PolicyPropose, including preview's baseDigest and slotRevision. --new replaces only your pending proposal.

## `fetch`

Make an HTTP request with an item's credential, through the vault.

```
mehen fetch <item> <METHOD> <URL> [-H 'Name: value']... [-d @file|-|text] [--project <prj_id> --env <name>] [--approval apr_...] [--fail] [-o <file>] [--select <path>] [-i] [--max-time <duration>]   (or mehen fetch --run <run> <METHOD> <URL>)
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--header` | `-H` | a value; repeatable |
| `--project` |  | a value |
| `--env` |  | a value |
| `--data` | `-d` | a value |
| `--run` |  | a value |
| `--approval` |  | a value |
| `--fail` |  | nothing (a switch) |
| `--output` | `-o` | a value |
| `--select` |  | a value |
| `--include` | `-i` | nothing (a switch) |
| `--max-time` |  | a value |

Examples:

```sh
mehen fetch openai-personal GET https://api.openai.com/v1/models --select data.0.id
mehen fetch openai-personal POST https://api.openai.com/v1/responses -H 'Content-Type: application/json' -d @body.json
mehen fetch github-work GET https://api.github.com/repos/acme/app/tarball -o app.tar.gz --max-time 2m
mehen fetch stripe-prod GET https://api.stripe.com/v1/balance --project prj_3kQ9vXyZ7 --env prod
```

- The response body goes to stdout as the vault returns it; the status and Mehen-Item go to stderr. Any upstream status exits 0 unless --fail.
- The vault may already have decompressed or scrubbed the body and removed response headers; it is not a byte-for-byte copy of the original upstream response.
- Never set an auth header yourself: the vault injects the credential where the item says.
- --project and --env name the project environment the credential is used for; a protected, team or guest credential needs them. They never change the workspace.

## `revoke`

Revoke this workspace's device key and forget it locally.

```
mehen revoke [--workspace <slug or id>]
```

No flags of its own; the global flags apply.

Examples:

```sh
mehen revoke
mehen revoke --workspace acme
```

- Irreversible for this key: a human must accept a new enrolment before this machine can use the workspace again. Only the selected workspace is revoked; other workspaces' keys stay.
- The slot is removed when the vault revokes the device or says it was revoked already; any other answer leaves it, and `mehen workspace forget --slot <path>` retires it without the vault.

## `freeze`

Freeze the whole workspace: every use is refused until a human unfreezes it.

```
mehen freeze
```

No flags of its own; the global flags apply.

Examples:

```sh
mehen freeze
```

- For an emergency, such as a leaked key or an agent acting strangely. Only a human with a passkey can unfreeze.

## `guide`

How agents use the vault: references, intake, next, exit codes.

```
mehen guide
```

No flags of its own; the global flags apply.

Examples:

```sh
mehen guide
```

## `version`

Print the mehen version and the commit it was built from.

```
mehen version
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--extract-helper` |  | a value |

Examples:

```sh
mehen version --json
```

- --json prints { version, commit, build, helper }; commit and build are null when mehen runs from source.

## `run`

Run a command with the project's variables (mehen run [--env <env>] -- <command>).

```
mehen run [--env <env>] [--approval <id>] [--] <command> [args...]
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--env` |  | see the usage |
| `--approval` |  | see the usage |

Global flags: see the exceptions above; the usage lists what this command accepts.

## `env`

List, check or set the project's variables (mehen env ls|check|set).

```
mehen env ls [--env <env>] [--json] | mehen env check [--env <env>] [--json] | mehen env set <NAME> --env <env> [--item <slug> [--field <field>]] [--plain <value>]
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--env` |  | see the usage |
| `--json` |  | see the usage |
| `--item` |  | see the usage |
| `--field` |  | see the usage |
| `--plain` |  | see the usage |

Global flags: see the exceptions above; the usage lists what this command accepts.

## `init`

Create the project and write mehen.toml.

```
mehen init [--slug <slug>] [--env <name>]...
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--slug` |  | see the usage |
| `--env` |  | see the usage |

Global flags: see the exceptions above; the usage lists what this command accepts.

## `workspace`

List, show, forget or bind a checkout to this machine's workspaces (mehen workspace list|show|forget|bind).

```
mehen workspace list [--check] | show | forget (<slug or id> | --slot <path>) | bind
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--check` |  | see the usage |
| `--slot` |  | see the usage |

Examples:

```sh
mehen workspace list --json
mehen workspace show
mehen workspace forget acme
mehen workspace bind
```

- list shows every workspace slot on this machine (active, pending, ended with the key kept, corrupt, and MEHEN_WORKSPACES entries not enrolled yet) without talking to the vault; --check asks each vault whether the enrolment still works and records a renamed workspace's new slug and name.
- show says which workspace --workspace, MEHEN_WORKSPACE, the checkout's mehen.toml or the only enrolment picks here, and why.
- forget retires one slot on this machine only (its key, config and ledger, or a pending enrolment); the device stays on the devices page until an owner revokes it. --slot <path> names a duplicate or unreadable slot.
- bind finds which enrolled workspace holds the checkout's project and writes workspace and vault into mehen.toml; it refuses when none or several do.
- --json prints one JSON object per line on stdout, errors included. More: mehen guide.

## `mcp`

Serve the vault tools over MCP on stdio.

```
mehen mcp [--workspace <slug or id>]
```

| Flag | Short | Takes |
| --- | --- | --- |
| `--workspace` |  | see the usage |

Global flags: see the exceptions above; the usage lists what this command accepts.

- Speaks MCP over stdin and stdout; a host (Claude Desktop, Cursor, pi) starts it as a command.
- The tools share core operations and enforcement with the mehen commands, and never return a secret value. Their inputs, output shapes, timeouts and body limits differ: vault_fetch, for one, returns at most 256 KiB of body text.
- Tools: vault_status, vault_doctor, vault_templates, vault_list, vault_show, vault_check, vault_request, vault_connect, vault_fetch, vault_env, vault_wait, vault_pending, vault_policy (policy widening is not available on the server in this release; propose and preview are refused).
- One server spans every workspace MEHEN_WORKSPACES allows under the config root (MEHEN_HOME; every one when it is unset), including one enrolled while it runs. Every tool but vault_templates takes an optional workspace (slug or id); with more than one workspace, a call names one unless the checkout's mehen.toml binds it. vault_status lists them.
- --workspace (or MEHEN_WORKSPACE) pins the server to one workspace, and a call naming another is refused. A workspace's enrolment is latched on first use: if it changes on disk while the server runs, that workspace is refused until the agent restarts; the others keep working.
- Enrol this machine first with mehen enrol --workspace <slug>; until it is accepted only vault_status, vault_doctor, vault_templates, vault_pending and vault_wait (for the enr_ id mehen enrol started) answer.
