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

# Workspaces

> Team workspaces, their members and invitations.

15 tools. Each one is also a REST route and a CLI command, from the same definition: the same input, the same output, the same errors.

| Tool                                                      | What it does                          | Kind                                                  |
| --------------------------------------------------------- | ------------------------------------- | ----------------------------------------------------- |
| [`get_workspace`](#get_workspace)                         | One workspace                         | Read · idempotent · no outside service                |
| [`list_workspace_members`](#list_workspace_members)       | Who is in a workspace                 | Read · idempotent · no outside service                |
| [`list_workspaces`](#list_workspaces)                     | The workspaces you are in             | Read · idempotent · no outside service                |
| [`accept_workspace_invite`](#accept_workspace_invite)     | Accept an invitation into a workspace | Write · idempotent · no outside service               |
| [`create_workspace`](#create_workspace)                   | Start a team workspace                | Write · no outside service                            |
| [`delete_workspace`](#delete_workspace)                   | Delete a team workspace               | Write · destructive · idempotent · no outside service |
| [`invite_workspace_member`](#invite_workspace_member)     | Seat someone, by handle or by email   | Write · no outside service                            |
| [`join_workspace`](#join_workspace)                       | Join a workspace by its link          | Write · idempotent · no outside service               |
| [`leave_workspace`](#leave_workspace)                     | Leave a workspace                     | Write · destructive · idempotent · no outside service |
| [`remove_workspace_member`](#remove_workspace_member)     | Take someone's seat away              | Write · destructive · idempotent · no outside service |
| [`revoke_workspace_invite`](#revoke_workspace_invite)     | Cancel a pending invitation           | Write · destructive · idempotent · no outside service |
| [`set_workspace_join_link`](#set_workspace_join_link)     | Switch the join link on or off        | Write · idempotent · no outside service               |
| [`set_workspace_member_role`](#set_workspace_member_role) | Change someone's role                 | Write · idempotent · no outside service               |
| [`transfer_workspace`](#transfer_workspace)               | Hand a team over                      | Write · no outside service                            |
| [`update_workspace`](#update_workspace)                   | Rename or re-address a workspace      | Write · idempotent · no outside service               |

## get\_workspace

**One workspace.**

As you see it: your role, its address, its plan. Not found unless you are in it.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Read · idempotent · no outside service                                          |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `GET https://api.doers.sh/v2/workspaces/{workspaceId}`                          |
| CLI       | `doers workspaces get`                                                          |
| Touches   | `user`, `workspaceMembers`, `workspaces`                                        |
| Operation | `getWorkspace`                                                                  |

### Input

| Field                | Type   | Required | Default | Allowed values | Description          |
| -------------------- | ------ | -------- | ------- | -------------- | -------------------- |
| `workspaceId` (path) | string | yes      |         | UUID           | Identifier of a row. |

### Output

<Accordion title="Output fields">
  | Field                      | Type           | Allowed values             | Description                                                                                                                                                             |
  | -------------------------- | -------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `workspace`                | object         |                            |                                                                                                                                                                         |
  | `workspace.id`             | string         |                            |                                                                                                                                                                         |
  | `workspace.name`           | string         |                            |                                                                                                                                                                         |
  | `workspace.address`        | string \| null |                            | The segment under the site's root: the owner's handle for a personal workspace, the team's own slug otherwise. `null` while a personal workspace's owner has no handle. |
  | `workspace.logo`           | string \| null |                            |                                                                                                                                                                         |
  | `workspace.timezone`       | string \| null |                            | IANA name; `null` means each person's own.                                                                                                                              |
  | `workspace.isPersonal`     | boolean        |                            | Minted at signup, named after the person, never handed over.                                                                                                            |
  | `workspace.role`           | string         | `owner`, `admin`, `member` | Ascending. `owner` is not grantable: it is what owning the workspace means.                                                                                             |
  | `workspace.plan`           | string         | `free`, `pro`, `team`      | The owner's plan, read when asked; it is what pays the seats.                                                                                                           |
  | `workspace.whoCanInvite`   | string         | `admins`, `everyone`       | Who may invite into the workspace: its admins, or everyone in it.                                                                                                       |
  | `workspace.newAreasShared` | boolean        |                            | New areas open to everyone in the workspace, at view.                                                                                                                   |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "get_workspace",
      "arguments": {
        "workspaceId": "21a3230e-0377-4a58-8ff1-b3709a9e2328"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "Acme · owner · free"
        }
      ],
      "structuredContent": {
        "workspace": {
          "id": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
          "name": "Acme",
          "address": "Notes for the Acme launch.",
          "logo": "Notes for the Acme launch.",
          "timezone": "Europe/Paris",
          "isPersonal": true,
          "role": "owner",
          "plan": "free",
          "whoCanInvite": "admins",
          "newAreasShared": true
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces get --workspace-id 21a3230e-0377-4a58-8ff1-b3709a9e2328
  ```
</CodeGroup>

## list\_workspace\_members

**Who is in a workspace.**

The owner, everyone seated, the seats the plan holds, and whether you may invite. Pending invitations are listed to the owner and the admins only (they carry a link that grants a seat) and never with their link.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Read · idempotent · no outside service                                          |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `GET https://api.doers.sh/v2/workspaces/{workspaceId}/members`                  |
| CLI       | `doers workspaces list-workspace-members`                                       |
| Touches   | `user`, `workspaceInvites`, `workspaceMembers`, `workspaces`                    |
| Operation | `listWorkspaceMembers`                                                          |

### Input

| Field                | Type   | Required | Default | Allowed values | Description          |
| -------------------- | ------ | -------- | ------- | -------------- | -------------------- |
| `workspaceId` (path) | string | yes      |         | UUID           | Identifier of a row. |

### Output

<Accordion title="Output fields">
  | Field                  | Type           | Allowed values             | Description                                                                   |
  | ---------------------- | -------------- | -------------------------- | ----------------------------------------------------------------------------- |
  | `owner`                | object         |                            |                                                                               |
  | `owner.id`             | string         |                            |                                                                               |
  | `owner.username`       | string \| null |                            |                                                                               |
  | `owner.name`           | string \| null |                            |                                                                               |
  | `owner.email`          | string \| null |                            |                                                                               |
  | `owner.image`          | string \| null |                            |                                                                               |
  | `owner.role`           | string         | `owner`, `admin`, `member` | Ascending. `owner` is not grantable: it is what owning the workspace means.   |
  | `owner.joinedAt`       | number         |                            | When they sat down; for the owner, the workspace's birth.                     |
  | `members`              | object\[]      |                            |                                                                               |
  | `members[].id`         | string         |                            |                                                                               |
  | `members[].username`   | string \| null |                            |                                                                               |
  | `members[].name`       | string \| null |                            |                                                                               |
  | `members[].email`      | string \| null |                            |                                                                               |
  | `members[].image`      | string \| null |                            |                                                                               |
  | `members[].role`       | string         | `owner`, `admin`, `member` | Ascending. `owner` is not grantable: it is what owning the workspace means.   |
  | `members[].joinedAt`   | number         |                            | When they sat down; for the owner, the workspace's birth.                     |
  | `invites`              | object\[]      |                            |                                                                               |
  | `invites[].id`         | string         |                            |                                                                               |
  | `invites[].email`      | string         |                            |                                                                               |
  | `invites[].role`       | string         | `admin`, `member`          |                                                                               |
  | `invites[].invitePath` | string         |                            | Where to send them. Carries the token, so treat it as one.                    |
  | `invites[].createdAt`  | number         |                            | Epoch milliseconds.                                                           |
  | `seats`                | object \| null |                            | `null` unless the owner holds a team plan.                                    |
  | `seats.included`       | integer        | 0 to 9007199254740991      |                                                                               |
  | `seats.used`           | integer        | 0 to 9007199254740991      |                                                                               |
  | `canInvite`            | boolean        |                            |                                                                               |
  | `joinLinkOn`           | boolean        |                            | Whether the join link is on; the link itself is shown once, when switched on. |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "list_workspace_members",
      "arguments": {
        "workspaceId": "21a3230e-0377-4a58-8ff1-b3709a9e2328"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "2 in it · 3/3 seats · 1 invited"
        }
      ],
      "structuredContent": {
        "owner": {
          "id": "4c102969-7ee3-4871-8d3a-14a2add817c4",
          "username": "ada",
          "name": "Acme",
          "email": "ada@acme.example",
          "image": "https://acme.example/ada.png",
          "role": "owner",
          "joinedAt": 1790069400000
        },
        "members": [
          {
            "id": "e31ab643-c44f-4a0e-8824-b59d1194d60d",
            "username": "ada",
            "name": "Acme",
            "email": "ada@acme.example",
            "image": "https://acme.example/ada.png",
            "role": "owner",
            "joinedAt": 1790069400000
          }
        ],
        "invites": [
          {
            "id": "5014f9af-3a68-4fdd-84a7-75c1c4c532ee",
            "email": "ada@acme.example",
            "role": "admin",
            "invitePath": "Acme/Weekly review",
            "createdAt": 1790069400000
          }
        ],
        "seats": {
          "included": 3,
          "used": 3
        },
        "canInvite": true,
        "joinLinkOn": true
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces list-workspace-members --workspace-id 21a3230e-0377-4a58-8ff1-b3709a9e2328
  ```
</CodeGroup>

## list\_workspaces

**The workspaces you are in.**

Your own personal workspace first (every account has one from signup) then every team you own or sit in, oldest first, each with your role and the plan its owner holds.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Read · idempotent · no outside service                                          |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `GET https://api.doers.sh/v2/workspaces`                                        |
| CLI       | `doers workspaces list`                                                         |
| Touches   | `user`, `workspaceMembers`, `workspaces`                                        |
| Operation | `listWorkspaces`                                                                |

### Input

This tool takes no arguments.

### Output

<Accordion title="Output fields">
  | Field                         | Type           | Allowed values             | Description                                                                                                                                                             |
  | ----------------------------- | -------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `workspaces`                  | object\[]      |                            |                                                                                                                                                                         |
  | `workspaces[].id`             | string         |                            |                                                                                                                                                                         |
  | `workspaces[].name`           | string         |                            |                                                                                                                                                                         |
  | `workspaces[].address`        | string \| null |                            | The segment under the site's root: the owner's handle for a personal workspace, the team's own slug otherwise. `null` while a personal workspace's owner has no handle. |
  | `workspaces[].logo`           | string \| null |                            |                                                                                                                                                                         |
  | `workspaces[].timezone`       | string \| null |                            | IANA name; `null` means each person's own.                                                                                                                              |
  | `workspaces[].isPersonal`     | boolean        |                            | Minted at signup, named after the person, never handed over.                                                                                                            |
  | `workspaces[].role`           | string         | `owner`, `admin`, `member` | Ascending. `owner` is not grantable: it is what owning the workspace means.                                                                                             |
  | `workspaces[].plan`           | string         | `free`, `pro`, `team`      | The owner's plan, read when asked; it is what pays the seats.                                                                                                           |
  | `workspaces[].whoCanInvite`   | string         | `admins`, `everyone`       | Who may invite into the workspace: its admins, or everyone in it.                                                                                                       |
  | `workspaces[].newAreasShared` | boolean        |                            | New areas open to everyone in the workspace, at view.                                                                                                                   |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "list_workspaces",
      "arguments": {}
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "- [21a3230e-0377-4a58-8ff1-b3709a9e2328] Acme · owner · personal"
        }
      ],
      "structuredContent": {
        "workspaces": [
          {
            "id": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
            "name": "Acme",
            "address": "Notes for the Acme launch.",
            "logo": "Notes for the Acme launch.",
            "timezone": "Europe/Paris",
            "isPersonal": true,
            "role": "owner",
            "plan": "free",
            "whoCanInvite": "admins",
            "newAreasShared": true
          }
        ]
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces list
  ```
</CodeGroup>

## accept\_workspace\_invite

**Accept an invitation into a workspace.**

Accepts a link, but **only** for the account carrying the address it was sent to; forwarded, it grants nothing. Refused when every seat has been taken since it was sent.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                         |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `POST https://api.doers.sh/v2/workspaces/invites/accept`                        |
| CLI       | `doers workspaces accept-workspace-invite`                                      |
| Touches   | `user`, `workspaceInvites`, `workspaceMembers`, `workspaces`                    |
| Operation | `acceptWorkspaceInvite`                                                         |

### Input

| Field   | Type   | Required | Default | Allowed values      | Description                       |
| ------- | ------ | -------- | ------- | ------------------- | --------------------------------- |
| `token` | string | yes      |         | 1 to 200 characters | *No description in the registry.* |

### Output

<Accordion title="Output fields">
  | Field         | Type   | Allowed values             | Description                                                                 |
  | ------------- | ------ | -------------------------- | --------------------------------------------------------------------------- |
  | `workspaceId` | string |                            |                                                                             |
  | `role`        | string | `owner`, `admin`, `member` | Ascending. `owner` is not grantable: it is what owning the workspace means. |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "accept_workspace_invite",
      "arguments": {
        "token": "acme-example-token"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: you are owner in 21a3230e-0377-4a58-8ff1-b3709a9e2328."
        }
      ],
      "structuredContent": {
        "workspaceId": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
        "role": "owner"
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces accept-workspace-invite acme-example-token
  ```
</CodeGroup>

## create\_workspace

**Start a team workspace.**

You become its owner. The address follows the handle rules and must be free among both handles and workspaces. Your personal workspace is not created this way: it exists.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · no outside service                                                      |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `POST https://api.doers.sh/v2/workspaces`                                       |
| CLI       | `doers workspaces create`                                                       |
| Touches   | `user`, `workspaceMembers`, `workspaces`                                        |
| Operation | `createWorkspace`                                                               |

### Input

| Field  | Type   | Required | Default | Allowed values      | Description                                                                         |
| ------ | ------ | -------- | ------- | ------------------- | ----------------------------------------------------------------------------------- |
| `name` | string | yes      |         | 1 to 200 characters | *No description in the registry.*                                                   |
| `slug` | string | yes      |         |                     | The team's segment under the site's root. Handle rules; one namespace with handles. |

### Output

<Accordion title="Output fields">
  | Field                      | Type           | Allowed values             | Description                                                                                                                                                             |
  | -------------------------- | -------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `workspace`                | object         |                            |                                                                                                                                                                         |
  | `workspace.id`             | string         |                            |                                                                                                                                                                         |
  | `workspace.name`           | string         |                            |                                                                                                                                                                         |
  | `workspace.address`        | string \| null |                            | The segment under the site's root: the owner's handle for a personal workspace, the team's own slug otherwise. `null` while a personal workspace's owner has no handle. |
  | `workspace.logo`           | string \| null |                            |                                                                                                                                                                         |
  | `workspace.timezone`       | string \| null |                            | IANA name; `null` means each person's own.                                                                                                                              |
  | `workspace.isPersonal`     | boolean        |                            | Minted at signup, named after the person, never handed over.                                                                                                            |
  | `workspace.role`           | string         | `owner`, `admin`, `member` | Ascending. `owner` is not grantable: it is what owning the workspace means.                                                                                             |
  | `workspace.plan`           | string         | `free`, `pro`, `team`      | The owner's plan, read when asked; it is what pays the seats.                                                                                                           |
  | `workspace.whoCanInvite`   | string         | `admins`, `everyone`       | Who may invite into the workspace: its admins, or everyone in it.                                                                                                       |
  | `workspace.newAreasShared` | boolean        |                            | New areas open to everyone in the workspace, at view.                                                                                                                   |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "create_workspace",
      "arguments": {
        "name": "Acme",
        "slug": "acme"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: Acme at /Notes for the Acme launch.."
        }
      ],
      "structuredContent": {
        "workspace": {
          "id": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
          "name": "Acme",
          "address": "Notes for the Acme launch.",
          "logo": "Notes for the Acme launch.",
          "timezone": "Europe/Paris",
          "isPersonal": true,
          "role": "owner",
          "plan": "free",
          "whoCanInvite": "admins",
          "newAreasShared": true
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces create --name Acme --slug acme
  ```
</CodeGroup>

## delete\_workspace

**Delete a team workspace.**

Owner only. Everything filed in it goes with it. A personal workspace cannot be deleted; deleting the account is what removes it.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · destructive · idempotent · no outside service                           |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `DELETE https://api.doers.sh/v2/workspaces/{workspaceId}`                       |
| CLI       | `doers workspaces delete`                                                       |
| Touches   | `user`, `workspaceMembers`, `workspaces`                                        |
| Operation | `deleteWorkspace`                                                               |

### Input

| Field                | Type   | Required | Default | Allowed values | Description          |
| -------------------- | ------ | -------- | ------- | -------------- | -------------------- |
| `workspaceId` (path) | string | yes      |         | UUID           | Identifier of a row. |

### Output

<Accordion title="Output fields">
  | Field     | Type    | Allowed values | Description |
  | --------- | ------- | -------------- | ----------- |
  | `deleted` | boolean |                |             |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "delete_workspace",
      "arguments": {
        "workspaceId": "21a3230e-0377-4a58-8ff1-b3709a9e2328"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: deleted."
        }
      ],
      "structuredContent": {
        "deleted": true
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces delete --workspace-id 21a3230e-0377-4a58-8ff1-b3709a9e2328
  ```
</CodeGroup>

## invite\_workspace\_member

**Seat someone, by handle or by email.**

`target` is a handle or an email address. A matching account sits down at once and takes a seat; an address that matches nobody produces an invitation link to send them. Only while a seat is spare, and only for those the workspace lets invite.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · no outside service                                                      |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `POST https://api.doers.sh/v2/workspaces/{workspaceId}/members`                 |
| CLI       | `doers workspaces invite-workspace-member`                                      |
| Touches   | `user`, `workspaceInvites`, `workspaceMembers`, `workspaces`                    |
| Operation | `inviteWorkspaceMember`                                                         |

### Input

| Field                | Type   | Required | Default    | Allowed values      | Description                       |
| -------------------- | ------ | -------- | ---------- | ------------------- | --------------------------------- |
| `workspaceId` (path) | string | yes      |            | UUID                | Identifier of a row.              |
| `target`             | string | yes      |            | 1 to 254 characters | *No description in the registry.* |
| `role`               | string | no       | `"member"` | `admin`, `member`   | *No description in the registry.* |

### Output

<Accordion title="Output fields">
  Returns `object`.
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "invite_workspace_member",
      "arguments": {
        "workspaceId": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
        "target": "Notes for the Acme launch.",
        "role": "admin"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: ada is owner."
        }
      ],
      "structuredContent": {
        "kind": "member",
        "member": {
          "id": "e31ab643-c44f-4a0e-8824-b59d1194d60d",
          "username": "ada",
          "name": "Acme",
          "email": "ada@acme.example",
          "image": "https://acme.example/ada.png",
          "role": "owner",
          "joinedAt": 1790069400000
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces invite-workspace-member --workspace-id 21a3230e-0377-4a58-8ff1-b3709a9e2328 --target "Notes for the Acme launch." --role admin
  ```
</CodeGroup>

## join\_workspace

**Join a workspace by its link.**

Sits you down as a member while the link is on and a seat is spare.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                         |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `POST https://api.doers.sh/v2/workspaces/join`                                  |
| CLI       | `doers workspaces join`                                                         |
| Touches   | `user`, `workspaceInvites`, `workspaceMembers`, `workspaces`                    |
| Operation | `joinWorkspace`                                                                 |

### Input

| Field   | Type   | Required | Default | Allowed values      | Description                       |
| ------- | ------ | -------- | ------- | ------------------- | --------------------------------- |
| `token` | string | yes      |         | 1 to 200 characters | *No description in the registry.* |

### Output

<Accordion title="Output fields">
  | Field         | Type   | Allowed values             | Description                                                                 |
  | ------------- | ------ | -------------------------- | --------------------------------------------------------------------------- |
  | `workspaceId` | string |                            |                                                                             |
  | `role`        | string | `owner`, `admin`, `member` | Ascending. `owner` is not grantable: it is what owning the workspace means. |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "join_workspace",
      "arguments": {
        "token": "acme-example-token"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: you are owner in 21a3230e-0377-4a58-8ff1-b3709a9e2328."
        }
      ],
      "structuredContent": {
        "workspaceId": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
        "role": "owner"
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces join acme-example-token
  ```
</CodeGroup>

## leave\_workspace

**Leave a workspace.**

Your tasks stay with the team. The owner cannot leave: hand the workspace over first.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · destructive · idempotent · no outside service                           |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `POST https://api.doers.sh/v2/workspaces/{workspaceId}/leave`                   |
| CLI       | `doers workspaces leave`                                                        |
| Touches   | `user`, `workspaceInvites`, `workspaceMembers`, `workspaces`                    |
| Operation | `leaveWorkspace`                                                                |

### Input

| Field                | Type   | Required | Default | Allowed values | Description          |
| -------------------- | ------ | -------- | ------- | -------------- | -------------------- |
| `workspaceId` (path) | string | yes      |         | UUID           | Identifier of a row. |

### Output

<Accordion title="Output fields">
  | Field  | Type    | Allowed values | Description |
  | ------ | ------- | -------------- | ----------- |
  | `left` | boolean |                |             |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "leave_workspace",
      "arguments": {
        "workspaceId": "21a3230e-0377-4a58-8ff1-b3709a9e2328"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: left."
        }
      ],
      "structuredContent": {
        "left": true
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces leave --workspace-id 21a3230e-0377-4a58-8ff1-b3709a9e2328
  ```
</CodeGroup>

## remove\_workspace\_member

**Take someone's seat away.**

Owner or admin. Their tasks stay in the workspace; their seat is free at once. Not found when they held none.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · destructive · idempotent · no outside service                           |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `DELETE https://api.doers.sh/v2/workspaces/{workspaceId}/members/{username}`    |
| CLI       | `doers workspaces remove-workspace-member`                                      |
| Touches   | `user`, `workspaceInvites`, `workspaceMembers`, `workspaces`                    |
| Operation | `removeWorkspaceMember`                                                         |

### Input

| Field                | Type   | Required | Default | Allowed values | Description                       |
| -------------------- | ------ | -------- | ------- | -------------- | --------------------------------- |
| `workspaceId` (path) | string | yes      |         | UUID           | Identifier of a row.              |
| `username` (path)    | string | yes      |         |                | *No description in the registry.* |

### Output

<Accordion title="Output fields">
  | Field     | Type    | Allowed values | Description |
  | --------- | ------- | -------------- | ----------- |
  | `removed` | boolean |                |             |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "remove_workspace_member",
      "arguments": {
        "workspaceId": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
        "username": "ada"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: removed."
        }
      ],
      "structuredContent": {
        "removed": true
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces remove-workspace-member --workspace-id 21a3230e-0377-4a58-8ff1-b3709a9e2328 --username ada
  ```
</CodeGroup>

## revoke\_workspace\_invite

**Cancel a pending invitation.**

Owner or admin. The link stops working immediately.

|           |                                                                                   |
| --------- | --------------------------------------------------------------------------------- |
| Kind      | Write · destructive · idempotent · no outside service                             |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`)   |
| REST      | `POST https://api.doers.sh/v2/workspaces/{workspaceId}/invites/{inviteId}/revoke` |
| CLI       | `doers workspaces revoke-workspace-invite`                                        |
| Touches   | `user`, `workspaceInvites`, `workspaceMembers`, `workspaces`                      |
| Operation | `revokeWorkspaceInvite`                                                           |

### Input

| Field                | Type   | Required | Default | Allowed values | Description          |
| -------------------- | ------ | -------- | ------- | -------------- | -------------------- |
| `workspaceId` (path) | string | yes      |         | UUID           | Identifier of a row. |
| `inviteId` (path)    | string | yes      |         | UUID           | Identifier of a row. |

### Output

<Accordion title="Output fields">
  | Field     | Type    | Allowed values | Description |
  | --------- | ------- | -------------- | ----------- |
  | `revoked` | boolean |                |             |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "revoke_workspace_invite",
      "arguments": {
        "workspaceId": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
        "inviteId": "5014f9af-3a68-4fdd-84a7-75c1c4c532ee"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: invitation cancelled."
        }
      ],
      "structuredContent": {
        "revoked": true
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces revoke-workspace-invite --workspace-id 21a3230e-0377-4a58-8ff1-b3709a9e2328 --invite-id 5014f9af-3a68-4fdd-84a7-75c1c4c532ee
  ```
</CodeGroup>

## set\_workspace\_join\_link

**Switch the join link on or off.**

Owner or admin. Switching it on mints a fresh link, returned **once**; switching it off stops the old one at once. Anyone holding the link sits down as a member while a seat is spare.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                         |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `PUT https://api.doers.sh/v2/workspaces/{workspaceId}/join-link`                |
| CLI       | `doers workspaces set-workspace-join-link`                                      |
| Touches   | `user`, `workspaceInvites`, `workspaceMembers`, `workspaces`                    |
| Operation | `setWorkspaceJoinLink`                                                          |

### Input

| Field                | Type    | Required | Default | Allowed values | Description                       |
| -------------------- | ------- | -------- | ------- | -------------- | --------------------------------- |
| `workspaceId` (path) | string  | yes      |         | UUID           | Identifier of a row.              |
| `enabled`            | boolean | yes      |         |                | *No description in the registry.* |

### Output

<Accordion title="Output fields">
  | Field      | Type           | Allowed values | Description                                        |
  | ---------- | -------------- | -------------- | -------------------------------------------------- |
  | `joinPath` | string \| null |                | Where to send people. Shown once; `null` when off. |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "set_workspace_join_link",
      "arguments": {
        "workspaceId": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
        "enabled": true
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: join link on: Acme/Weekly review"
        }
      ],
      "structuredContent": {
        "joinPath": "Acme/Weekly review"
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces set-workspace-join-link --workspace-id 21a3230e-0377-4a58-8ff1-b3709a9e2328 --enabled true
  ```
</CodeGroup>

## set\_workspace\_member\_role

**Change someone's role.**

Owner or admin. The owner has no role to change: handing over is its own operation.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                         |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `PATCH https://api.doers.sh/v2/workspaces/{workspaceId}/members/{username}`     |
| CLI       | `doers workspaces set-workspace-member-role`                                    |
| Touches   | `user`, `workspaceInvites`, `workspaceMembers`, `workspaces`                    |
| Operation | `setWorkspaceMemberRole`                                                        |

### Input

| Field                | Type   | Required | Default | Allowed values    | Description                       |
| -------------------- | ------ | -------- | ------- | ----------------- | --------------------------------- |
| `workspaceId` (path) | string | yes      |         | UUID              | Identifier of a row.              |
| `username` (path)    | string | yes      |         |                   | *No description in the registry.* |
| `role`               | string | yes      |         | `admin`, `member` | *No description in the registry.* |

### Output

<Accordion title="Output fields">
  | Field             | Type           | Allowed values             | Description                                                                 |
  | ----------------- | -------------- | -------------------------- | --------------------------------------------------------------------------- |
  | `member`          | object         |                            |                                                                             |
  | `member.id`       | string         |                            |                                                                             |
  | `member.username` | string \| null |                            |                                                                             |
  | `member.name`     | string \| null |                            |                                                                             |
  | `member.email`    | string \| null |                            |                                                                             |
  | `member.image`    | string \| null |                            |                                                                             |
  | `member.role`     | string         | `owner`, `admin`, `member` | Ascending. `owner` is not grantable: it is what owning the workspace means. |
  | `member.joinedAt` | number         |                            | When they sat down; for the owner, the workspace's birth.                   |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "set_workspace_member_role",
      "arguments": {
        "workspaceId": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
        "username": "ada",
        "role": "admin"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: now owner."
        }
      ],
      "structuredContent": {
        "member": {
          "id": "e31ab643-c44f-4a0e-8824-b59d1194d60d",
          "username": "ada",
          "name": "Acme",
          "email": "ada@acme.example",
          "image": "https://acme.example/ada.png",
          "role": "owner",
          "joinedAt": 1790069400000
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces set-workspace-member-role --workspace-id 21a3230e-0377-4a58-8ff1-b3709a9e2328 --username ada --role admin
  ```
</CodeGroup>

## transfer\_workspace

**Hand a team over.**

Owner only, to someone already in the workspace, by handle. You stay as an admin. A personal workspace is never handed over.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · no outside service                                                      |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `POST https://api.doers.sh/v2/workspaces/{workspaceId}/transfer`                |
| CLI       | `doers workspaces transfer`                                                     |
| Touches   | `user`, `workspaceMembers`, `workspaces`                                        |
| Operation | `transferWorkspace`                                                             |

### Input

| Field                | Type   | Required | Default | Allowed values | Description                       |
| -------------------- | ------ | -------- | ------- | -------------- | --------------------------------- |
| `workspaceId` (path) | string | yes      |         | UUID           | Identifier of a row.              |
| `username`           | string | yes      |         |                | *No description in the registry.* |

### Output

<Accordion title="Output fields">
  | Field                      | Type           | Allowed values             | Description                                                                                                                                                             |
  | -------------------------- | -------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `workspace`                | object         |                            |                                                                                                                                                                         |
  | `workspace.id`             | string         |                            |                                                                                                                                                                         |
  | `workspace.name`           | string         |                            |                                                                                                                                                                         |
  | `workspace.address`        | string \| null |                            | The segment under the site's root: the owner's handle for a personal workspace, the team's own slug otherwise. `null` while a personal workspace's owner has no handle. |
  | `workspace.logo`           | string \| null |                            |                                                                                                                                                                         |
  | `workspace.timezone`       | string \| null |                            | IANA name; `null` means each person's own.                                                                                                                              |
  | `workspace.isPersonal`     | boolean        |                            | Minted at signup, named after the person, never handed over.                                                                                                            |
  | `workspace.role`           | string         | `owner`, `admin`, `member` | Ascending. `owner` is not grantable: it is what owning the workspace means.                                                                                             |
  | `workspace.plan`           | string         | `free`, `pro`, `team`      | The owner's plan, read when asked; it is what pays the seats.                                                                                                           |
  | `workspace.whoCanInvite`   | string         | `admins`, `everyone`       | Who may invite into the workspace: its admins, or everyone in it.                                                                                                       |
  | `workspace.newAreasShared` | boolean        |                            | New areas open to everyone in the workspace, at view.                                                                                                                   |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "transfer_workspace",
      "arguments": {
        "workspaceId": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
        "username": "ada"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: handed over; you are owner."
        }
      ],
      "structuredContent": {
        "workspace": {
          "id": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
          "name": "Acme",
          "address": "Notes for the Acme launch.",
          "logo": "Notes for the Acme launch.",
          "timezone": "Europe/Paris",
          "isPersonal": true,
          "role": "owner",
          "plan": "free",
          "whoCanInvite": "admins",
          "newAreasShared": true
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces transfer --workspace-id 21a3230e-0377-4a58-8ff1-b3709a9e2328 --username ada
  ```
</CodeGroup>

## update\_workspace

**Rename or re-address a workspace.**

Renaming is the owner's; the address, the logo, the time zone and who may invite are an admin's too. A personal workspace keeps its owner's handle as its address and cannot be given another.

|           |                                                                                 |
| --------- | ------------------------------------------------------------------------------- |
| Kind      | Write · idempotent · no outside service                                         |
| Auth      | Bearer token: a personal API token (`pc_…`) or an OAuth access token (`pcat_…`) |
| REST      | `PATCH https://api.doers.sh/v2/workspaces/{workspaceId}`                        |
| CLI       | `doers workspaces update`                                                       |
| Touches   | `user`, `workspaceMembers`, `workspaces`                                        |
| Operation | `updateWorkspace`                                                               |

### Input

| Field                | Type           | Required | Default | Allowed values       | Description                                                                         |
| -------------------- | -------------- | -------- | ------- | -------------------- | ----------------------------------------------------------------------------------- |
| `workspaceId` (path) | string         | yes      |         | UUID                 | Identifier of a row.                                                                |
| `name`               | string         | no       |         | 1 to 200 characters  | *No description in the registry.*                                                   |
| `slug`               | string         | no       |         |                      | The team's segment under the site's root. Handle rules; one namespace with handles. |
| `logo`               | string \| null | no       |         | URL                  | A square picture; `null` removes it.                                                |
| `timezone`           | string \| null | no       |         |                      | *No description in the registry.*                                                   |
| `whoCanInvite`       | string         | no       |         | `admins`, `everyone` | Who may invite into the workspace: its admins, or everyone in it.                   |
| `newAreasShared`     | boolean        | no       |         |                      | *No description in the registry.*                                                   |

### Output

<Accordion title="Output fields">
  | Field                      | Type           | Allowed values             | Description                                                                                                                                                             |
  | -------------------------- | -------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `workspace`                | object         |                            |                                                                                                                                                                         |
  | `workspace.id`             | string         |                            |                                                                                                                                                                         |
  | `workspace.name`           | string         |                            |                                                                                                                                                                         |
  | `workspace.address`        | string \| null |                            | The segment under the site's root: the owner's handle for a personal workspace, the team's own slug otherwise. `null` while a personal workspace's owner has no handle. |
  | `workspace.logo`           | string \| null |                            |                                                                                                                                                                         |
  | `workspace.timezone`       | string \| null |                            | IANA name; `null` means each person's own.                                                                                                                              |
  | `workspace.isPersonal`     | boolean        |                            | Minted at signup, named after the person, never handed over.                                                                                                            |
  | `workspace.role`           | string         | `owner`, `admin`, `member` | Ascending. `owner` is not grantable: it is what owning the workspace means.                                                                                             |
  | `workspace.plan`           | string         | `free`, `pro`, `team`      | The owner's plan, read when asked; it is what pays the seats.                                                                                                           |
  | `workspace.whoCanInvite`   | string         | `admins`, `everyone`       | Who may invite into the workspace: its admins, or everyone in it.                                                                                                       |
  | `workspace.newAreasShared` | boolean        |                            | New areas open to everyone in the workspace, at view.                                                                                                                   |
</Accordion>

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "update_workspace",
      "arguments": {
        "workspaceId": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
        "name": "Acme",
        "slug": "acme"
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "content": [
        {
          "type": "text",
          "text": "OK: Acme."
        }
      ],
      "structuredContent": {
        "workspace": {
          "id": "21a3230e-0377-4a58-8ff1-b3709a9e2328",
          "name": "Acme",
          "address": "Notes for the Acme launch.",
          "logo": "Notes for the Acme launch.",
          "timezone": "Europe/Paris",
          "isPersonal": true,
          "role": "owner",
          "plan": "free",
          "whoCanInvite": "admins",
          "newAreasShared": true
        }
      }
    }
  }
  ```

  ```bash CLI theme={null}
  doers workspaces update --workspace-id 21a3230e-0377-4a58-8ff1-b3709a9e2328 --name Acme --slug acme
  ```
</CodeGroup>
