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

# Zas agent reference: MCP tools and error codes

> Every tool the Zas MCP server exposes, every error code it can answer, the files it writes on disk, and the settings that change where it points.

Everything the `zas-agent` MCP server exposes, in one page.

|                   |                                                                             |
| ----------------- | --------------------------------------------------------------------------- |
| Package           | [`zas-agent`](https://www.npmjs.com/package/zas-agent) on npm               |
| MCP registry name | `io.github.soke1556/zas-agent`                                              |
| Transport         | stdio                                                                       |
| Runtime           | Node.js 22 or newer                                                         |
| Source            | [github.com/soke1556/zas-agent](https://github.com/soke1556/zas-agent), MIT |

## Commands

```text theme={null}
zas-agent [--profile <name>]                serve the MCP tools over stdio
zas-agent pair [--profile <name>]           pair this agent with a Zas account
               [--kind claude_code|codex|other] [--host <name>] [--no-open]
zas-agent telemetry [on|off]                say what this machine reports, or change it
zas-agent --version
```

With no command it serves the MCP tools, which is what a harness starts it for.

## Tools

`channel` takes a channel name or a channel id. A name has to match exactly one granted channel. With exactly one grant, every tool that takes `channel` can leave it out except `zas_list_items` and `zas_get_item`, which always name theirs.

### `zas_status`

Says whether this machine is paired, and lists the channels this agent may send to or read from. Also prints the package version, the profile, and the telemetry state. No arguments.

### `zas_pair`

Pairs this machine with a Zas account. The first call returns a URL for you to open; a later call says whether you approved. In a profile that is already paired, approval replaces the old agent.

| Argument | Type             | Notes                                                                          |
| -------- | ---------------- | ------------------------------------------------------------------------------ |
| `code`   | string, optional | The code the pairing page shows when the browser could not reach this machine. |

### `zas_send_file`

Sends a file from this machine into a granted channel. Returns the item id, or a job id when the upload takes longer than a minute.

| Argument          | Type              | Notes                                                                                             |
| ----------------- | ----------------- | ------------------------------------------------------------------------------------------------- |
| `path`            | string, required  | Absolute or relative path of the file.                                                            |
| `channel`         | string, optional  | Name or id. Optional with exactly one grant.                                                      |
| `title`           | string, optional  | Label for the item. Defaults to the file name.                                                    |
| `expires_in_days` | integer, optional | How many whole days the item lives for, at least 1. Left out, it takes the account's normal life. |

A channel in Directo mode refuses this tool with `direct_mode`. Use `zas_send_direct` there.

<Warning>
  This sends any file the process can read, secrets included. See [Recommendations](/en/agents/recommendations).
</Warning>

### `zas_send_note`

Sends a note: plain text, or a code snippet with its language.

| Argument          | Type              | Notes                                                   |
| ----------------- | ----------------- | ------------------------------------------------------- |
| `text`            | string, required  | The body of the note.                                   |
| `channel`         | string, optional  | Name or id. Optional with exactly one grant.            |
| `title`           | string, optional  | Label. Defaults to the first line.                      |
| `lang`            | string, optional  | Language for highlighting, for example `ts` or `py`.    |
| `secret`          | boolean, optional | Hide the body behind a cover until the reader opens it. |
| `expires_in_days` | integer, optional | How many whole days the item lives for, at least 1.     |

### `expires_in_days`

Both sending tools take it, and it only ever shortens an item's life. A request longer than the plan grants is answered with the plan's number rather than refused, so asking for 100 days gives you five. The floor is one whole day, because the countdown ring counts whole days.

It is worth setting for output that is stale tomorrow: a build log, a test run, a screenshot of a fix.

### `zas_send_direct`

Sends a file through [Directo](/en/concepts/direct): a live, device-to-device transfer into a granted channel that is in Directo mode. Nothing is stored. Somebody has to press **Receive** on another device within ten minutes. The call waits a minute and then returns a job id to check with `zas_jobs`.

| Argument  | Type             | Notes                                        |
| --------- | ---------------- | -------------------------------------------- |
| `path`    | string, required | Absolute or relative path of the file.       |
| `channel` | string, optional | Name or id. Optional with exactly one grant. |

A channel that is not in Directo mode refuses this tool with `not_direct_mode`.

### `zas_receive_direct`

Receives a file sent through Directo, straight onto this machine. It waits for the offer, takes it, and writes the file to disk. Only for a channel in Directo mode, and only with a grant that includes **reading**, because it writes onto the machine.

| Argument  | Type             | Notes                                                                                            |
| --------- | ---------------- | ------------------------------------------------------------------------------------------------ |
| `channel` | string, optional | Name or id. Optional with exactly one grant.                                                     |
| `dest`    | string, optional | Where to write the file. A directory means "inside it". Defaults to a fresh temporary directory. |

It never overwrites an existing file. The wait for an offer alone can take ten minutes, so the call returns a job id after a minute.

### `zas_send_direct_fallback`

After a `zas_send_direct` job failed in flight, delivers the same file through reliable delivery instead. Zas encrypts the file on this machine and stores only that encrypted copy for up to 24 hours; it uses none of your space, and the device that claimed the offer can download it later.

| Argument | Type             | Notes                                        |
| -------- | ---------------- | -------------------------------------------- |
| `job`    | string, required | The job id the failed Directo send reported. |

<Note>
  This stops being Directo: the encrypted bytes pass through storage. The tool's own description tells the model to ask you first, because it is your choice, not the model's.
</Note>

### `zas_receive_direct_fallback`

After a `zas_receive_direct` job failed in flight, downloads the encrypted copy the sender chose to store. It works only if the person sending picked reliable delivery for that transfer. The file is decrypted on this machine and written to the same destination.

| Argument | Type             | Notes                                   |
| -------- | ---------------- | --------------------------------------- |
| `job`    | string, required | The job id the failed receive reported. |

### `zas_list_items`

Lists the most recent items in a channel. Needs a grant that includes reading.

| Argument  | Type              | Notes                    |
| --------- | ----------------- | ------------------------ |
| `channel` | string, required  | Name or id.              |
| `limit`   | integer, optional | 1 to 50. Defaults to 20. |

### `zas_get_item`

Fetches one item. A note comes back as text; a file is written to disk.

| Argument  | Type             | Notes                                                                                          |
| --------- | ---------------- | ---------------------------------------------------------------------------------------------- |
| `channel` | string, required | Name or id.                                                                                    |
| `id`      | string, required | Item id, as `zas_list_items` reports it.                                                       |
| `dest`    | string, optional | Where to write a file. A directory means "inside it". Defaults to a fresh temporary directory. |

It never overwrites an existing file. A name that is taken gets a suffix, and the path it answers with is the one it actually wrote.

### `zas_jobs`

Lists the sends and Directo transfers this server started, newest first, with the phase each one reached and how it ended. A `job_id` from a long send is redeemed here, and a finished job keeps its result.

## Error codes

The agent answers in a closed set. Anything a route says that is not in this set collapses to `upload_failed` or `network`, so no raw server string ever reaches a terminal, and no stack trace does either.

### Pairing and identity

| Code                   | What it means                                                      |
| ---------------------- | ------------------------------------------------------------------ |
| `not_paired`           | This machine is not paired yet.                                    |
| `identity_corrupt`     | The identity file on disk is damaged.                              |
| `agent_revoked`        | The owner revoked this agent.                                      |
| `agent_forbidden`      | Only the account owner can do that.                                |
| `pairing_expired`      | The pairing expired. Pair again.                                   |
| `pairing_cancelled`    | The owner cancelled the pairing.                                   |
| `pairing_not_approved` | Nobody has approved this pairing yet.                              |
| `pairing_claimed`      | This pairing was already claimed.                                  |
| `claim_mismatch`       | The code does not match.                                           |
| `agent_limit`          | The account cannot take another agent.                             |
| `grant_limit`          | The plan allows fewer channels per agent than this pairing grants. |
| `feature_disabled`     | Agents are not enabled for this account yet.                       |
| `sign_in_failed`       | Zas did not accept this agent session.                             |
| `bad_signature`        | Zas rejected this agent's signature. Pair again.                   |
| `missing_token`        | The session token is missing. Pair again.                          |

### Channels and grants

| Code              | What it means                                             |
| ----------------- | --------------------------------------------------------- |
| `grant_missing`   | This agent has no access to that channel.                 |
| `send_forbidden`  | This agent cannot send to that channel.                   |
| `read_forbidden`  | This agent cannot read that channel.                      |
| `direct_mode`     | That channel is in Directo mode. Use `zas_send_direct`.   |
| `not_direct_mode` | That channel is not in Directo mode. Use `zas_send_file`. |
| `key_stale`       | The channel key changed. Open Zas to refresh it.          |

### Sending and reading

| Code             | What it means                                                                                     |
| ---------------- | ------------------------------------------------------------------------------------------------- |
| `quota_exceeded` | The account reached its storage limit.                                                            |
| `rate_limited`   | Too many sends in a row.                                                                          |
| `file_too_big`   | The file is over the plan limit.                                                                  |
| `duplicate`      | That item is already in the channel.                                                              |
| `not_found`      | That item is not in the channel.                                                                  |
| `not_yours`      | That item was not sent by this agent. It can only change its own items.                           |
| `stale`          | That item changed while this agent was working on it. Read it again and retry.                    |
| `not_a_note`     | That item is a file, not a note. Only its title can change; use `zas_replace_file` for the bytes. |
| `not_a_file`     | That item is a note, not a file. Use `zas_edit_item`.                                             |
| `item_shared`    | That item has a public share. The owner removes the share first.                                  |
| `invalid_cap`    | That file is no longer available.                                                                 |
| `write_failed`   | The file could not be saved to the destination.                                                   |
| `upload_failed`  | The upload failed.                                                                                |
| `oprf_failed`    | Zas did not answer correctly while preparing the file.                                            |

### Directo

| Code                   | What it means                                                                |
| ---------------------- | ---------------------------------------------------------------------------- |
| `not_claimed`          | Nobody received the file within ten minutes. The offer was withdrawn.        |
| `no_offer`             | Nobody offered a file through Directo while this call waited.                |
| `offer_taken`          | Another device received that file first.                                     |
| `direct_cancelled`     | The offer was cancelled from the other side.                                 |
| `direct_failed`        | The Directo transfer failed in flight. A fallback tool can still deliver it. |
| `direct_not_failed`    | That job is not a Directo transfer that failed in flight.                    |
| `file_changed`         | The file changed since the Directo offer. Send it again.                     |
| `webrtc_unavailable`   | The WebRTC engine (`node-datachannel`) could not be loaded on this machine.  |
| `fallback_unavailable` | Reliable delivery is not available right now.                                |

### Everything else

| Code       | What it means                      |
| ---------- | ---------------------------------- |
| `network`  | Zas cannot be reached.             |
| `internal` | Something failed inside the agent. |

## Files on disk

One directory per profile, so one machine can hold a Claude Code agent and a Codex agent without either reading the other's keys.

| OS           | Path                                |
| ------------ | ----------------------------------- |
| macOS, Linux | `~/.zas/agent/PROFILE/`             |
| Windows      | `%USERPROFILE%\.zas\agent\PROFILE\` |

| File                | What it holds                                                                                                                                                      |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `identity.json`     | The agent uid, the owner uid, the name and the two key pairs. Back it up like a private key, or delete it and pair again.                                          |
| `pending.json`      | A pairing not claimed yet. Removed on completion, expiry or cancellation.                                                                                          |
| `grants.json`       | A one-minute cache of the agent's channels and their sealed keys. The channel name stays encrypted here. Disposable.                                               |
| `fingerprints.json` | Hashes of what an identical send produced in the last ten minutes, so a retried call answers without touching the network. Hashes only, never a title. Disposable. |

One file sits a level up, in `~/.zas/agent/` itself, because it is a choice about the machine rather than about one identity:

| File            | What it holds                                                                                       |
| --------------- | --------------------------------------------------------------------------------------------------- |
| `settings.json` | The telemetry choice for this machine, and whether the first-run notice has been shown. Disposable. |

Every file is written through a temporary file and renamed into place, so a crash mid-write cannot leave half a file behind.

On macOS and Linux the directory is created `0700` and every file `0600`. On Windows those bits have no effect: the files carry the permissions of the user profile they live in, and the package sets no others.

<Note>
  Deleting the directory makes the machine forget the agent. It does **not** revoke it. That happens in **Settings → Agents → Revoke**.
</Note>

## Telemetry

The agent reports the pairing funnel and one `agent.tool_call` event per tool call, so Zas can see which tools work and which fail. It is on by default and it prints a notice the first time.

**What it never sends:** file names, titles, note bodies, channel names, paths, or item content.

Three ways to turn it off, in the order they are read:

| Switch                    | Effect                                               |
| ------------------------- | ---------------------------------------------------- |
| `ZAS_AGENT_TELEMETRY=off` | Off for this process. `on` forces it on.             |
| `DO_NOT_TRACK=1`          | Off. The cross-vendor switch, honoured for off only. |
| `zas-agent telemetry off` | Off for this machine, remembered in `settings.json`. |

`zas-agent telemetry` with no setting prints the current state and which of the three decided it. `zas_status` prints the same line.

## Settings

| Setting               | Default                | What it changes                                                                                                           |
| --------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `--profile NAME`      | `claude-code`          | Which identity directory this process uses. Letters, digits, `.`, `_` and `-`, up to 64, and it may not start with a dot. |
| `--kind`              | from the profile name  | The harness shown in the approval list: `claude_code`, `codex` or `other`.                                                |
| `--host NAME`         | the machine's hostname | The host shown in the approval list.                                                                                      |
| `--no-open`           | off                    | Do not open the browser during pairing. The link is printed either way.                                                   |
| `ZAS_NO_OPEN`         | unset                  | Same as `--no-open`.                                                                                                      |
| `ZAS_AGENT_HOME`      | `~/.zas/agent`         | Where the profile directories live.                                                                                       |
| `ZAS_AGENT_TELEMETRY` | unset                  | `off` or `on`, for this process.                                                                                          |
| `DO_NOT_TRACK`        | unset                  | `1` turns telemetry off.                                                                                                  |
| `ZAS_WEB_BASE`        | `https://zas.red`      | The web app the pairing URL points at.                                                                                    |
| `ZAS_API_BASE`        | `https://zas.red/api`  | The API.                                                                                                                  |

Only `--profile`, `ZAS_AGENT_HOME` and the telemetry switches are worth setting by hand. The rest exist so the package can be pointed at a test deployment.

## Numbers

|                                         | Value                                             |
| --------------------------------------- | ------------------------------------------------- |
| Agents, free plan                       | 5, revoked included                               |
| Channels per agent, free plan           | 5, ever-granted                                   |
| Agents, without an account              | None                                              |
| Agents per member, organization default | 2, range 0 to 10                                  |
| Channels per agent, in an organization  | No cap; channel membership governs reach          |
| Hard ceiling, any account               | 10                                                |
| Largest stored file                     | Your plan's stored limit, 50 MB on the free plan  |
| Largest file the agent will read        | 5 GiB                                             |
| Largest Directo transfer                | Your plan's Directo limit, 10 GB on the free plan |
| Shortest item life an agent may ask for | 1 day                                             |
| Session token life                      | 1 hour, re-signed automatically                   |
| Pairing waits for approval              | 10 minutes                                        |
| Approved pairing waits for its claim    | 5 minutes                                         |

## Where to go next

<CardGroup cols={2}>
  <Card title="Connect an agent" icon="plug" href="/en/agents/connect">
    Pairing, the harness commands and the failure modes.
  </Card>

  <Card title="Limits" icon="book" href="/en/reference/limits">
    Every limit Zas enforces, agents included.
  </Card>

  <Card title="FAQ" icon="circle-question" href="/en/reference/faq">
    Short answers to the usual questions.
  </Card>

  <Card title="Recommendations" icon="lightbulb" href="/en/agents/recommendations">
    Safe practice, and the warning about secrets.
  </Card>
</CardGroup>
