---
title: "Workspace CLI | AgentRQ Docs"
url: https://agentrq.com/docs/workspace-cli
description: "agentrq-ws drives an AgentRQ workspace from the command line — every workspace tool, file attachments without base64, and the .mcp.json the agent already uses."
---

[Docs](https://agentrq.com/docs/) / Reference / Workspace CLI

Workspace CLI

# Workspace CLI

`agentrq-ws` is everything an agent can do in a workspace, from a shell, without spending an agent's tokens to do it. It reads the `.mcp.json` in the current directory — the same file the agent working there uses — so inside a workspace checkout there is nothing to configure.

Why it exists, and what the base64 round-trip costs an agent without it, is the subject of [MCP Attachment Base64 Cost: Why AgentRQ Has a Workspace CLI](https://agentrq.com/blog/base64-cost-of-mcp-attachments).

## Install

Nothing to install: `npx` fetches it on demand, and it has no runtime dependencies. Node 20.6 or newer.

Run it once, or keep it

```
npx @agentrq/agentrq-ws@latest help

npm install -g @agentrq/agentrq-ws
agentrq-ws help
```

The package is [@agentrq/agentrq-ws](https://www.npmjs.com/package/@agentrq/agentrq-ws) on npm, Apache-2.0, and its source is in [cli/agentrq-ws](https://github.com/agentrq/agentrq/tree/main/cli/agentrq-ws).

Inside a workspace checkout

```
cd ~/code/my-workspace
agentrq-ws workspace
```

## Commands

Twenty-nine commands over the workspace's seven MCP tools. Each tool takes an `action` and a `payload`, and the Tool column names the action a command calls. Against an older server, a command falls back to the tool name that server had, such as createTask. Every command takes `--help`, and so does every family: `agentrq-ws task --help` lists the task commands, `agentrq-ws attachment get -h` explains that one.

| Command | What it does | Tool |
| --- | --- | --- |
| `workspace` | Show the workspace title and mission | workspace get |
| `task get <taskId>` | Fetch a task, with `--conversation` for its history | task get |
| `task next` | Take the next not-started task — this dequeues the queue | task get |
| `task create <title>` | Create a task | task create |
| `task status <taskId> <status>` | Set a task's status | task updateStatus |
| `reply <taskId> <text>` | Send a message to a task | task reply |
| `task help [action]` | The server's help for its `task` tool: every action, or one action's payload | task help |
| `attachment get <id>` | Download an attachment to a file, through its link | task getAttachment |
| `memory load [name]` | Read a workspace memory, the index by default | memory load |
| `memory save [name]` | Replace a workspace memory | memory save |
| `memory delete [name]` | Delete a workspace memory | memory delete |
| `skill search [q]` | Find the skills this workspace can use, by name or description | skills search |
| `skill load <uri>` | Read a skill file — `skill://<name>` reads its `SKILL.md` | skills load |
| `skill save <uri>` | Replace a file of one of this workspace's skills | skills save |
| `skill delete <uri>` | Delete a skill, or one of its files | skills delete |
| `pano save [id] --title … --markdown …` | Create a Pano doc, or replace one, and print its id; `--file` sends a file the markdown links, `--ttl-days` and `--color` set its life and post-it | pano save |
| `pano read <id>` | Read a Pano doc, `--comments`/`--attachments` adding those; `--out DIR` writes its markdown and downloads its files instead, printing only their paths | pano read |
| `pano comment <id> <text>` | Comment on a Pano doc | pano comment |
| `pano attach <id> --file PATH…` | Attach files to a Pano doc; they need no link | pano attach |
| `pano delete <id>` | Delete a Pano doc | pano delete |
| `pano help [action]` | The server's help for its `pano` tool: every action, or one action's payload | pano help |
| `event publish <name>` | Publish a named event | workspace publishEvent |
| `ask <taskId> <message>` | Ask the human a question and wait | task elicit |
| `site-tools` | List the websites shared with this workspace, and their tools' names and descriptions | siteTools search |
| `site-tool <site> <tool>` | Show one shared website's tool in full, with its input schema | siteTools getDefinition |
| `call-site-tool <site> <tool>` | Run a shared website's tool in the human's Chrome, with `--task` and `--args` | siteTools call |
| `tools` | List the tools this workspace server offers | tools/list |
| `tools help [tool\|tool.action]` | The server's help: every tool, one tool's actions, or one action's payload with an example | help |
| `call <tool>` | Call any tool directly with JSON arguments, such as `'{"action": "help"}'` | any |

task next Claims Work

It is a separate verb rather than a bare `task get` on purpose: it mutates the queue, and a command that silently claims work is a bad surprise.

Statuses accepted by `task status`: `notstarted`, `ongoing`, `completed`, `rejected`, `cron`, `blocked`.

## Attachments Never Become Your Problem

The underlying tools speak base64 in both directions. This CLI does not. Uploading takes a path — the filename, media type and encoding are worked out for you, in this process rather than in an agent's context.

Uploading

```
agentrq-ws reply 0isnjTCkpW5 "Build is green — log attached" --attach ./run.log
agentrq-ws task create "Review the design" --body @brief.md --attach ./mock.png
```

Downloading writes a file and prints where it went. With no `--out` it lands in the OS temp directory; `--out` takes a directory (keeping the attachment's own name) or a full path (renaming it).

Downloading

```
$ agentrq-ws attachment get 0isp9dJxr85 --task 0isnjTCkpW5
/tmp/agentrq-ws-help.txt

$ agentrq-ws attachment get 0isp9dJxr85 --task 0isnjTCkpW5 --out ~/Downloads
$ agentrq-ws attachment get 0isp9dJxr85 --task 0isnjTCkpW5 --out ./report.pdf
```

Why --task Is Required

An attachment belongs to a task. The CLI asks `task getAttachment` for the attachment's public link, downloads it, and saves the file under the name a human gave it. An older attachment with no link arrives the same way, from its content.

## Long Text

Anywhere prose is expected — `--body`, `--content`, `--payload`, and a reply's text — `@path` reads a file and `-` reads stdin.

Files and pipes

```
agentrq-ws task create "Post-mortem" --body @notes.md
git log --oneline -20 | agentrq-ws reply 0isnjTCkpW5 -
agentrq-ws memory save release-notes.md --content @CHANGELOG.md
```

## Asking the Human Something

Two shapes: a form, or a link to go and do something. Both block until the human answers or the timeout elapses — `--timeout` seconds, one hour by default and at most. The mode is inferred from which of the two you gave.

ask

```
agentrq-ws ask 0isnjTCkpW5 "Which branch should I release from?" \
  --field branch:string:"Branch name" --field sign:boolean:"Sign the tag?"

agentrq-ws ask 0isnjTCkpW5 "Approve the deploy, then confirm" --url https://example.com/approve
```

`--field name:type:description` builds the form schema; types are `string`, `number`, `integer` and `boolean`, because the protocol restricts an elicitation to a flat object of primitives. `--schema @file` covers anything the shorthand cannot say.

## Choosing a Server

The nearest `.mcp.json` at or above the working directory is used — the CLI walks up the way `git` looks for a repository, because an agent's working directory is often a subdirectory of the one holding the config. When that file defines several servers, name one.

Picking one of several

```
agentrq-ws workspace --server agentrq-workspace
agentrq-ws workspace --config ../other/.mcp.json
```

| Variable | Effect |
| --- | --- |
| `AGENTRQ_WS_URL` | Use this server URL and ignore `.mcp.json` entirely |
| `AGENTRQ_WS_SERVER` | Which server in `.mcp.json` to use |

An ambiguous config is an error that lists the names rather than a guess: connecting to the wrong server would act on the wrong workspace.

## Output and Exit Codes

Commands print the server's text. `--json` prints the raw result instead, for piping into `jq`.

Piping

```
agentrq-ws tools --json | jq -r '.[].name'
```

Failures print one line and exit non-zero. A stack trace means a bug in the CLI, not a mistake in the command. Piping into a reader that stops early, such as `| head`, exits zero — closing the pipe is the reader's decision.

## Related Pages

[Why It Exists The base64 round-trip, and what it costs an agent](https://agentrq.com/blog/base64-cost-of-mcp-attachments) [Workspace MCP The tools underneath every command here](https://agentrq.com/docs/mcp-tools) [Workspaces Where the .mcp.json and its token come from](https://agentrq.com/docs/workspaces)
