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

# Queue

## Overview

The `QueuesClient` is the Room API for simple room-scoped work queues. Use it when one participant or service needs to hand off JSON work items to another participant or service asynchronously.

## CLI commands

Start with the CLI help, then use a few common commands:

```bash bash theme={null}
meshagent room queue --help
meshagent room queue list --room myroom
meshagent room queue size --room myroom --queue my-queue
meshagent room queue send --room myroom --queue my-queue --json '{"payload":"Hello World!"}'
meshagent room queue receive --room myroom --queue my-queue
meshagent room queue send-mail --room myroom --queue my-queue --from support@example.com --subject "Support request" --body "Please review this."
```

## Why use the Queues API?

* Decouple producers and consumers when work should happen later.
* Build lightweight background workflows without adding another queueing system.
* Coordinate multi-agent jobs where one participant produces work and another consumes it.

## How it works

A queue stores JSON messages until a consumer receives them. Senders and receivers can be different participants or services in the same room. SDKs can list, open, send, receive, drain, and close queues, while Python auto-creates queues during `send` or `receive` when `create=True`.

## Permissions and grants

The Queues API is controlled by the `queues` grant on the participant token.

In practice:

* `list` controls queue discovery
* `send` can be narrowed to specific queue names
* `receive` can be narrowed separately to specific queue names

See [API Scopes](../rest_api/api_scopes) and [Service YAML](../services/deployment/deploy_services).

## API reference

Use the methods below to inspect queues, send JSON work items, and receive them from another participant or service in the same room.

### `list()`

List the queues currently visible in the room.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room queue list \
    --room myroom

  ```

  ```python Python theme={null}
  queues = await room.queues.list()

  ```

  ```javascript NodeJs theme={null}
  const queues = await room.queues.list();

  ```

  ```typescript TypeScript theme={null}
  const queues = await room.queues.list();

  ```

  ```dart Dart theme={null}
  final queues = await room.queues.list();

  ```

  ```dotnet C# theme={null}
  var queues = await room.Queues.List();

  ```
</CodeGroup>

* **Returns**: An array of queue objects, each with a `name` and `size`.

### `open(name)`

Create or reopen a queue explicitly.

<Alert type="note">
  Python does not expose `open()` today. In Python, queues are created implicitly when you call `send(..., create=True)` or `receive(..., create=True)`.
</Alert>

<CodeGroup>
  ```javascript NodeJs theme={null}
  await room.queues.open("my-queue");

  ```

  ```typescript TypeScript theme={null}
  await room.queues.open("my-queue");

  ```

  ```dart Dart theme={null}
  await room.queues.open("my-queue");

  ```

  ```dotnet C# theme={null}
  await room.Queues.Open("my-queue");

  ```
</CodeGroup>

* **Parameters**:
  * `name`: Queue name.

### `send(name, message, create=True)`

Send one JSON message to a queue.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room queue send \
    --room myroom \
    --queue my-queue \
    --json '{"foo":"bar"}'

  ```

  ```python Python theme={null}
  await room.queues.send(name="my-queue", message={"foo": "bar"}, create=True)

  ```

  ```javascript NodeJs theme={null}
  await room.queues.send("my-queue", { foo: "bar" }, { create: true });

  ```

  ```typescript TypeScript theme={null}
  await room.queues.send("my-queue", { foo: "bar" }, { create: true });

  ```

  ```dart Dart theme={null}
  await room.queues.send("my-queue", {"foo": "bar"}, create: true);

  ```

  ```dotnet C# theme={null}
  var message = new Dictionary<string, object?> { ["payload"] = "Hello World!" };
  await room.Queues.Send("my-queue", message, create: true);

  ```
</CodeGroup>

* **Parameters**:
  * `name`: Queue name.
  * `message`: JSON-serializable payload.
  * `create`: When `true`, create the queue if it does not already exist.

### Queue size from the CLI

Use `meshagent room queue size` when you only need the current queue length:

```bash bash theme={null}
meshagent room queue size \
  --room myroom \
  --queue my-queue
```

### Send email-shaped work from the CLI

Use `meshagent room queue send-mail` when a queue consumer expects an email payload instead of a generic JSON work item:

```bash bash theme={null}
meshagent room queue send-mail \
  --room myroom \
  --queue my-queue \
  --from support@example.com \
  --subject "Support request" \
  --body "Please review this."
```

When the queue consumer is a MeshAgent queue channel, the payload can include turn-oriented fields such as:

* `prompt`: string or typed content items for the next turn
* `content`: typed content items that should be passed through directly
* `thread_id` or `path`: explicit thread path for the work item
* `model`, `instructions`, `tools`, `sender_name`: optional turn settings

#### Structured agent payloads

For queue-backed MeshAgent agents, `prompt` and `content` can carry typed content instead of a plain string.

* Think of `prompt` as "text the agent should read".
* Think of `content` as "input items the agent should receive".
* Use `prompt` when you want a `room:///...` text file read from room storage and inlined into the turn as text before the turn starts.
* Use `content` when you want a `room:///...` file passed through as a file item in the turn input instead of being converted into text.
* `content` does not create or update room artifacts by itself. It only defines the turn input that the queue consumer receives.
* `prompt` can be plain text, typed content, or typed content that includes `room:///...` files. You only need a room file when you want to pull existing room content into the prompt.
* `thread_id` and `path` can use UTC time tokens such as `{YYYY}`, `{MM}`, `{DD}`, `{HH}`, `{mm}`, and `{SECOND}`.
* Legacy `prompt_file` payloads still work, but typed `prompt` items are the preferred format.

Examples:

1. Plain text prompt

```bash theme={null}
meshagent room queue send \
  --room myroom \
  --queue support-jobs \
  --json '{"prompt":"Summarize the current support backlog and highlight urgent issues."}'
```

This sends plain prompt text. No room file is involved.

2. Prompt that reads a room file and turns it into text

```bash theme={null}
meshagent room queue send \
  --room myroom \
  --queue support-jobs \
  --json '{"thread_id":"dataset://threads/support/{YYYY}/{MM}/{DD}/{HH}/{mm}/summary","prompt":[{"type":"file","url":"room:///prompts/support-summary.md"},{"type":"text","text":"Summarize the current support backlog and highlight urgent issues."}]}'
```

In this example, MeshAgent reads `room:///prompts/support-summary.md` from room storage and inserts that file's UTF-8 text into the turn before the agent runs.

3. Content that preserves the room file as a file input

```bash theme={null}
meshagent room queue send \
  --room myroom \
  --queue support-jobs \
  --json '{"content":[{"type":"file","url":"room:///docs/report.md"}]}'
```

In this example, MeshAgent keeps `room:///docs/report.md` as a file item in the turn input. It does not inline the file into prompt text, and it does not create a new room artifact.

### `receive(name, create=True, wait=True)`

Receive one JSON message from a queue.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room queue receive \
    --room myroom \
    --queue my-queue

  ```

  ```python Python theme={null}
  message = await room.queues.receive(name="my-queue", create=True, wait=True)

  ```

  ```javascript NodeJs theme={null}
  const message = await room.queues.receive("my-queue", { create: true, wait: true });

  ```

  ```typescript TypeScript theme={null}
  const message = await room.queues.receive("my-queue", { create: true, wait: true });

  ```

  ```dart Dart theme={null}
  final message = await room.queues.receive("my-queue", create: true, wait: true);

  ```

  ```dotnet C# theme={null}
  var received = await room.Queues.Receive("my-queue", create: true, wait: true);

  ```
</CodeGroup>

* **Parameters**:
  * `name`: Queue name.
  * `create`: When `true`, create the queue if it does not already exist.
  * `wait`: When `true`, wait until a message is available.
* **Returns**: A JSON payload, or `null` if the queue is empty and `wait=False`.

### `drain(name)`

Remove all messages from a queue.

<CodeGroup>
  ```python Python theme={null}
  await room.queues.drain(name="my-queue")

  ```

  ```javascript NodeJs theme={null}
  await room.queues.drain("my-queue");

  ```

  ```typescript TypeScript theme={null}
  await room.queues.drain("my-queue");

  ```

  ```dart Dart theme={null}
  await room.queues.drain("my-queue");

  ```

  ```dotnet C# theme={null}
  await room.Queues.Drain("my-queue");

  ```
</CodeGroup>

* **Parameters**:
  * `name`: Queue name.

### `close(name)`

Close a queue so it stops accepting sends or receives until reopened.

<CodeGroup>
  ```python Python theme={null}
  await room.queues.close(name="my-queue")

  ```

  ```javascript NodeJs theme={null}
  await room.queues.close("my-queue");

  ```

  ```typescript TypeScript theme={null}
  await room.queues.close("my-queue");

  ```

  ```dart Dart theme={null}
  await room.queues.close("my-queue");

  ```

  ```dotnet C# theme={null}
  await room.Queues.Close("my-queue");

  ```
</CodeGroup>

* **Parameters**:
  * `name`: Queue name.

### `Queue`

Queue objects returned by `list()` include:

* `name`: Queue name.
* `size`: Queue length at the time of retrieval.

## Related guides

* [Room API Overview](./overview)
* [Messaging API](./messaging)
* [Service YAML](../services/deployment/deploy_services)
