> ## 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.

# Containers

## Overview

The `ContainersClient` lets you run temporary containers inside a room. Use it for one-off jobs, debugging, image management, or testing code in the same room environment that deployed services use.

## CLI commands

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

```bash bash theme={null}
meshagent room container --help
meshagent room container image list --room myroom
meshagent room container image pull --room myroom --tag meshagent/cli:default
meshagent room container run --room myroom --image meshagent/cli:default
meshagent room container list --room myroom
```

## Why use the Containers API?

* Pull and manage images without leaving the room context.
* Run short-lived workloads or exploratory commands on demand.
* Inspect logs or open an interactive terminal in a running container.

## How it works

Containers are room-scoped workloads. You can pull images, run a container, stream logs, exec into it, stop it, and delete its metadata when you are done. Deployed Room Services and Project Services rely on the same underlying container infrastructure, but the Containers API gives you direct, on-demand control.

## Permissions and grants

The Containers API is controlled by the `containers` grant on the participant token.

In practice:

* `use_containers` is the main switch for container operations
* `pull` and `run` can be narrowed to specific image names or prefixes
* `logs` controls access to container log streaming

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

## API reference

Use the methods below to manage room images, start and inspect containers, and clean up container state. The SDKs also expose image-transfer helpers such as `push_image`, `load` / `load_image`, `save_image`, build helpers such as `build`, `list_builds`, `cancel_build`, `delete_build`, and `get_build_logs`, and service helpers such as `run_service`.

### `list_images()`

* **Description**: List images currently available to the room (built or pulled previously).
* **Parameters**: None.
* **Returns**: `list[Image]` summary records including `id`, `preferred_ref`, `references`, `labels`, `created_at`, `updated_at`, and `target_media_type`.

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

  ```

  ```python Python theme={null}
  images = await room.containers.list_images()
  for image in images:
      print(image.preferred_ref, image.id)

  ```
</CodeGroup>

### `inspect_image(image_id)`

* **Description**: Inspect a room image by ID and return detailed content metadata from the container runtime.
* **Parameters**:
  * `image_id`: Image ID from `list_images()`.
* **Returns**: `ImageInspection` including the image summary, target descriptor, selected manifest, manifests, config descriptor, layers, and `content_size`.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room container image inspect \
    --room myroom \
    --image-id sha256:abc123

  ```

  ```python Python theme={null}
  inspection = await room.containers.inspect_image(image_id="sha256:abc123")
  print(inspection.image.preferred_ref, inspection.content_size)
  for layer in inspection.layers:
      print(layer.digest, layer.size)

  ```
</CodeGroup>

### `delete_image(image)`

* **Description**: Delete an unused image from the room.
* **Parameters**:
  * `image`: Tag or digest string to delete.
* **Returns**: `None`.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room container image delete \
    --room myroom \
    --image chatbot:old

  ```

  ```python Python theme={null}
  await room.containers.delete_image(image="chatbot:old")

  ```
</CodeGroup>

### `pull_image(tag, credentials=None)`

* **Description**: Pull an image into the room. Supports passing registry credentials when needed.
* **Parameters**:
  * `tag`: Image reference (e.g. `myrepo/app:latest`).
  * `credentials`: Optional list of `DockerSecret` credentials for private registries.
* **Returns**: `None` once the pull completes.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room container image pull \
    --room myroom \
    --tag registry.example.com/agents/chatbot:0.2

  ```

  ```python Python theme={null}
  await room.containers.pull_image(tag="registry.example.com/agents/chatbot:0.2")

  ```
</CodeGroup>

### `run(image, ...)`

* **Description**: Start a container in the room.
* **Parameters** (all optional except `image`):
  * `image`: Container image to run.
  * `command`: Override the default command (`str`).
  * `env`: Environment variables injected as `dict[str, str]`.
  * `mount_path`, `mount_subpath`: Mount configuration when using storage.
  * `role`, `participant_name`: Launch on behalf of a specific room identity.
  * `ports`: Port mappings `{container_port: host_port}`.
  * `credentials`: Registry secrets for the image.
  * `name`: Friendly name for the container.
  * `template`: Runtime defaults to apply. `"none"` (default) applies no template defaults; `"agent"` mounts room storage at `/data` and injects MeshAgent/OpenAI/Anthropic/SMTP proxy environment variables using a token for the container name with role `agent`.
* **Returns**: Container ID string.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room container run \
    --room myroom \
    --image registry.example.com/agents/chatbot:0.2 \
    --env SYSTEM_PROMPT="Always respond with a fun fact." \
    --container-name chatbot-demo

  ```

  ```python Python theme={null}
  container_id = await room.containers.run(
      image="registry.example.com/agents/chatbot:0.2",
      env={"SYSTEM_PROMPT": "Always respond with a fun fact."},
      name="chatbot-demo",
  )
  print(f"Container launched: {container_id}")

  ```
</CodeGroup>

### `exec(container_id, ...)`

* **Description**: Attach an interactive command to an existing container and stream its output.
* **Parameters**:
  * `container_id`: Target container.
  * `command`: Optional command list; defaults to the container's shell.
  * `tty`: Request a TTY session (`True` for interactive).
  * `detach`: Leave the session running in the background (`True` by default).
* **Returns**: An exec-session object (`ExecSession` in Python) exposing helpers to read output, send input, resize the terminal, and await completion.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room container exec \
    --room myroom \
    --container-id "$CONTAINER_ID" \
    --command "bash"

  ```

  ```python Python theme={null}
  session = await room.containers.exec(
      container_id=container_id,
      command=["bash"],
      tty=True,
      detach=False,
  )

  async for chunk in session.stdout():
      print(chunk.decode(), end="")

  # (Optional) Send input; for example, list files then exit the shell
  await session.write(b'ls -la\n')
  await session.write(b'exit\n')  # end the interactive session

  status = await session.result
  print(f"Exec finished with status: {status}")

  ```
</CodeGroup>

The CLI streams a non-TTY exec session. Use the SDK directly when you need an explicit TTY session and terminal resize control.

### Image transfer helpers

In addition to pulling an image into a room, the CLI can push an image from the room to a registry, load an OCI archive from room storage, or save an image as an OCI archive:

```bash bash theme={null}
meshagent room container image push \
  --room myroom \
  --tag registry.example.com/agents/chatbot:0.2

meshagent room container image load \
  --room myroom \
  --archive-path /images/chatbot.tar

meshagent room container image save \
  --room myroom \
  --tag registry.example.com/agents/chatbot:0.2 \
  --archive-path /workspace/chatbot.tar \
  --mount-room-path /images:/workspace
```

### `logs(container_id, follow=False)`

* **Description**: Stream container logs and optionally follow until exit.
* **Parameters**:
  * `container_id`: Target container.
  * `follow`: `True` to keep streaming until the container exits.
* **Returns**: `LogStream[None]`, which you can iterate for log lines or await for completion.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room container log \
    --room myroom \
    --id "$CONTAINER_ID" \
    --follow

  ```

  ```python Python theme={null}
  stream = room.containers.logs(container_id=container_id, follow=True)

  async for line in stream.logs():
      print(line)

  await stream  # optional: wait for the request to finish

  ```
</CodeGroup>

### `list(all=False)`

* **Description**: List containers in the room, optionally including exited ones.
* **Parameters**:
  * `all`: `True` to include stopped containers.
* **Returns**: `list[RoomContainer]` with name, image, state, status, applicable manifest, and metadata about who started it.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room container list \
    --room myroom \
    --all \
    --output table

  ```

  ```python Python theme={null}
  containers = await room.containers.list(all=True)
  for container in containers:
      print(container.id, container.state, container.started_by.name)

  ```
</CodeGroup>

### `stop(container_id, force=False)`

* **Description**: Request a graceful stop (or force stop) of a running container.
* **Parameters**:
  * `container_id`: Target container.
  * `force`: Send a forceful termination signal when `True`.
* **Returns**: `None`.

<CodeGroup>
  ```bash CLI theme={null}
  meshagent room container stop \
    --room myroom \
    --id "$CONTAINER_ID"

  ```

  ```python Python theme={null}
  await room.containers.stop(container_id=container_id, force=False)

  ```
</CodeGroup>

### `delete(container_id)`

* **Description**: Remove container metadata after it has stopped. Useful for cleaning up history.
* **Parameters**:
  * `container_id`: Container to delete.
* **Returns**: `None`.

<CodeGroup>
  ```python Python theme={null}
  await room.containers.delete(container_id=container_id)

  ```
</CodeGroup>

## Related guides

* [Room API Overview](./overview)
* [Service YAML](../services/deployment/deploy_services)
* [MeshAgent Studio](../interfaces/meshagent_studio)
