peek_bag_samples
Read up to a requested number of recent messages from a topic in recorded ROS bag files (MCAP, rosbag2 SQLite, ROS 1 .bag) for post-mortem analysis.
Instructions
Peek up to count samples from a recorded bag file. Unlike peek_dds_samples (live DDS) and sample_messages (live ROS 2 graph), this reads offline bag content for post-mortem analysis. Supported formats: MCAP (.mcap), ROS 2 rosbag2 SQLite (.db3), ROS 1 legacy chunked binary (.bag), detected from the file extension. Returns a SampleResult in the same shape as peek_dds_samples: each sample's payload carries a _decode_status annotation (full / partial / raw). count defaults to 5 and is silently clamped to 50. Requires the rosbags library (pip install topicforge[bags]) and the ROS 2 side of the runtime: on a DDS-only setup it raises an error. The mock backend returns fixture samples on canned bag paths. Bags that embed no message definitions (rosbag2 .db3 from Humble) are decoded with the type definitions of the bag's recorded distro, or Humble when it records none; note says which. Arrays over 4096 elements are cut and note lists the fields. Read-only by architecture: nothing writes to the bag file. Raises an MCP error when the bag path does not exist, the topic is not present in the bag, or rosbags is not installed.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Path to a bag: a file ending in `.mcap` or `.db3`, or a `rosbag2_*` directory. `peek_bag_samples` also reads ROS 1 `.bag` files; `analyze_bag` does not (`ros2 bag info` cannot open them). Leading/trailing whitespace is stripped. Null bytes and otherwise malformed filesystem paths are rejected. Existence and bag format are validated by the live adapter (mock mode accepts any well-formed path). | |
| count | No | Maximum number of recent messages to return. Defaults to 5; silently clamped to 50 (the hard cap that keeps tool output bounded; read it from `health_check.max_sample_count`). Negative values raise an error. The returned `SampleResult.count` reflects the actual number of samples produced: it can be lower than the request (empty topic, timeout, mock fixture shorter than requested). | |
| topic | Yes | Fully qualified ROS2 topic name starting with `/`, e.g. `/cmd_vel` or `/camera/image_raw`. Each `/`-separated segment must start with a letter or underscore and contain only letters, digits, and underscores; everything else (whitespace, quotes, shell metacharacters, `//`, trailing `/`) is rejected before reaching the `ros2` CLI. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| note | No | Why `samples` is empty or limited, when the cause is not obvious (for example payload decoding is disabled for DDS user topics). `None` when there is nothing to add. | |
| count | Yes | Number of samples actually returned. May be 0 (no publisher active in live mode, or empty mock fixture), less than the requested count (topic yielded fewer messages within the timeout), or capped by the the silent maximum of 50: request `count > 50` and you will receive at most 50 without warning. | |
| topic | Yes | Topic the samples were taken from, echoed from the request. | |
| samples | Yes | The sampled messages, ordered as received from the backend. | |
| mode_effective | Yes | Runtime mode the adapter served this response in: `live` (real ROS2 introspection) or `mock` (deterministic fixtures). Lets a caller tell a real graph from a demo one without calling `health_check`. |