MCAP: The File Format for Robotics and Physical AI Recordings

Nov 4, 2026
•
12 min read
MCAP (pronounced "em-cap") is an open source container file format for timestamped, multimodal data such as camera frames, LiDAR point clouds, inertial measurement unit (IMU) readings, and robot state. It is the default recording format in Robot Operating System 2 (ROS 2). This guide covers how an MCAP file is structured, how MCAP relates to rosbag and to training formats such as LeRobot, how to open and inspect MCAP files, and how teams search, curate, and annotate MCAP recordings at scale.

What is MCAP?

MCAP is a modular container file format for recording timestamped publish and subscribe messages in any serialization format. A robot or vehicle publishes streams of messages on named topics, such as /camera/front/image, /lidar/points, and /joint_states, and an MCAP file records every message from every topic, in time order, in a single file. Each message carries a nanosecond timestamp, and the file embeds the schema needed to decode every message type, so the file can be read without the software that wrote it.
MCAP was created by Foxglove and is maintained as an MIT-licensed open source project, with the specification, reference libraries, and the mcap command-line tool published at mcap.dev. It is the default storage format for rosbag2, the recording tool in ROS 2, and it is also widely used outside ROS by teams that log Protobuf, FlatBuffers, or JSON messages from custom robotics stacks.
MCAP exists because robotics logging used to be fragmented. Teams on ROS 1 recorded .bag files, which are hard to read outside the ROS ecosystem. Early ROS 2 recorded to a SQLite-based format that was not fully self-contained, so third-party tools struggled to decode it. Teams outside ROS often invented their own binary formats. MCAP gives all of them one self-describing container that can hold many streams in many encodings, survives interrupted recordings, and supports fast indexed reads.
In the physical AI data lifecycle, MCAP is the recording layer. Robots and vehicles write MCAP at capture. Engineers replay MCAP files to see what happened, search and curate across many recordings to find the moments that matter, annotate the episodes worth learning from, and export the best of them into training formats. The multimodal data guide covers that full lifecycle.

At a glance

  • MCAP is an open container format that stores timestamped messages from many sensors and software topics in one file, with their schemas embedded.
  • MCAP is append-only, so a recording interrupted by a crash or power loss can usually be recovered, and it supports an optional index for fast seeking.
  • MCAP is serialization-agnostic: ROS 1, ROS 2 Common Data Representation (CDR), Protobuf, FlatBuffers, JSON, and other encodings can share one file.
  • MCAP is a recording format, not a training format. Teams curate MCAP recordings and export the episodes worth training on into formats such as LeRobotDataset.

MCAP tutorials and guides from the Voxel51 blog

These posts cover MCAP recordings from opening a file to building a training set. Each section below links to more.

Core concepts in MCAP

MCAP borrows its vocabulary from robotics middleware and file formats. These terms anchor the rest of this guide.
  • MCAP: an open container file format for timestamped, multimodal robotics data, and the ROS 2 default.
  • Message: one timestamped record of data on a channel, such as a single camera frame or IMU reading. Each message carries a log time and a publish time in nanoseconds.
  • Channel: a stream of messages on one topic with one encoding, such as /lidar/points encoded as ROS 2 CDR.
  • Schema: the definition of a message type, embedded in the file so readers can decode messages without outside dependencies.
  • Chunk: a block of messages written together, optionally compressed with zstd or lz4, and indexed by time.
  • Summary section: optional index records at the end of the file that let readers find channels, chunks, attachments, and statistics without scanning the whole file.
  • rosbag: the ROS 1 recording format (.bag), which many teams now convert to MCAP.
  • rosbag2: the ROS 2 recording tool, which writes MCAP by default and supports SQLite (.db3) as an alternative storage plugin.
  • ROS 2: the robotics middleware widely used across research and industry, which records to MCAP by default.
  • MCAP annotation: labeling objects, events, and time ranges directly on MCAP recordings.

How is an MCAP file structured?

An MCAP file is a sequence of records between two sets of magic bytes. Every record starts with a one-byte opcode and a length, so a reader can skip any record it doesn't understand. The file has five parts: a header, a data section, an optional summary section, an optional summary offset section, and a footer.
The summary section is what makes MCAP fast to read. In an indexed file, it repeats the schemas and channels, lists every chunk with its time range and byte offset, and can include statistics such as message counts per channel. A reader that wants the camera frames from second 42 reads the footer, jumps to the summary, finds the chunk that covers second 42, and decompresses only that chunk. This is also what lets tools read just the parts they need from an MCAP file in cloud storage, without downloading the whole file.
RecordWhat it holdsWhere it lives
HeaderThe profile (such as ros2) and the library that wrote the fileStart of file
SchemaA message type definition, such as sensor_msgs/msg/PointCloud2Data section, repeated in summary
ChannelA topic, its message encoding, and its schemaData section, repeated in summary
MessageOne timestamped message on a channelData section, usually inside chunks
ChunkA batch of records, optionally compressed with zstd or lz4Data section
Message indexTimestamps and offsets of messages inside a chunkAfter each chunk
AttachmentAn auxiliary file, such as calibration data or a mapData section
MetadataArbitrary key-value pairs, such as hardware infoData section
Data endMarks the end of the data section, with an optional checksumEnd of data section
Chunk, attachment, and metadata indexesWhere each chunk, attachment, and metadata record sits in the fileSummary section
StatisticsMessage, channel, and chunk counts, plus start and end timesSummary section
FooterOffsets to the summary sectionEnd of file
The records in an MCAP file, with what each one holds and where it lives in the file.
The append-only design is deliberate. A recorder writes records front to back and never goes back to edit earlier bytes, and the summary is written last. If a robot loses power mid-recording, the file is missing its summary and footer but the chunks already written are intact.

Encodings, schemas, and profiles

MCAP doesn't care how a message is serialized. Each channel declares a message encoding, and each schema declares a schema encoding, and readers use those to pick a decoder. That is why one MCAP file can hold ROS 2 sensor messages next to Protobuf messages from a custom service.
Message encodingTypical schema encodingCommon source
cdrros2msg or ros2idlROS 2
ros1ros1msgROS 1 recordings converted to MCAP
protobufprotobuf (a FileDescriptorSet)Custom stacks and many autonomous vehicle logging pipelines
flatbufferflatbufferPerformance-sensitive custom stacks
jsonjsonschema, or nonePrototyping and lightweight telemetry
Common MCAP message encodings, with their typical schema encodings and sources.
The MCAP registry lists several more. Profiles add framework rules on top. A file with the ros2 profile must use CDR messages, ROS 2 schemas, and record each channel's quality of service settings, so ROS 2 tools can play it back faithfully.
Encoding mismatches are a common reason an MCAP file writes cleanly and plays back broken. A schema named after a well-known message type but written with the wrong encoding passes every structural check and only fails when a viewer tries to decode it. What actually breaks when you author MCAP by hand walks through that bug and five others.

MCAP and ROS 2

MCAP became the default storage format for rosbag2 with the ROS 2 Iron release in 2023, replacing SQLite. Recording with ros2 bag record writes MCAP unless you choose another storage plugin. MCAP bags written by rosbag2 carry their message schemas, so tools can decode them without the original ROS workspace. From Iron on, SQLite (.db3) bags embed message definitions too.
Two practical details matter for ROS 2 teams. First, compression: rosbag2 can compress whole files or individual messages, but compressed files lose their index. MCAP's own chunk compression keeps files compressed and indexable. The simplest way to use it is a storage preset such as zstd_fast or zstd_small, and a storage configuration file gives finer control. The fastwrite preset writes messages unchunked and without a message index, which is fast to write but can't be seeked or read by topic efficiently until the file is post-processed. Second, conversion: older .bag and .db3 recordings convert to MCAP with the mcap command-line interface (CLI) or ros2 bag convert (see the FAQ below).
mcap convert recording.bag recording.mcap
ros2 bag record -a -s mcap --storage-preset-profile zstd_fast

MCAP vs. rosbag and other formats

MCAP is often compared with formats that do different jobs. rosbag and SQLite-based rosbag2 are the recording formats teams are moving off. HDF5 and LeRobotDataset are formats teams train on.
MCAProsbag (.bag)rosbag2 SQLite (.db3)HDF5LeRobotDataset
LayerRecording containerRecording containerRecording containerGeneral array storageTraining dataset
SerializationAny (ROS, Protobuf, FlatBuffers, JSON, and more)ROS 1 onlyROS 2 CDRArrays, not messagesParquet tables and MP4 video
Self-describingYes, schemas embeddedYes, message definitions embeddedOnly from Iron onPartly, through attributesYes, schema in metadata files
Random accessOptional index in the summaryIndex at end of fileDatabase queriesYesYes, by episode and frame
Interrupted recordingRecoverable, append-onlyReindexable with rosbag reindexDepends on the SQLite journalCan be left unreadableNot a recording format
Typical useROS 2 and custom robotics logging, replay, and curationLegacy ROS 1 systemsEarly ROS 2 systemsResearch datasets such as robomimicImitation learning and VLA training
MCAP compared with rosbag, rosbag2 SQLite, HDF5, and LeRobotDataset by layer, serialization, self-description, random access, recovery, and typical use.
ROS 1 reached end of life with Noetic in May 2025, which is why many teams are converting their .bag archives now.
To train a robot policy, teams usually export curated episodes from MCAP into a training format such as LeRobotDataset or RLDS. The LeRobot guide covers that side.

How to open and inspect an MCAP file

There are three common ways to look inside an MCAP file, and each answers a different question.

Open an MCAP file from the command line

The mcap CLI reports what a file contains and pulls data out of it. mcap info summarizes the profile, duration, compression, and every channel with its message count and rate. mcap cat prints messages from chosen topics, and can decode ROS 1, Protobuf, and JSON messages into JSON lines or CSV. mcap doctor checks the file's structure, and mcap recover rebuilds a damaged file. The CLI can also read files directly from S3, Google Cloud Storage, Azure, or HTTP using the summary index.
mcap info recording.mcap
mcap cat recording.mcap --topics /joint_states
mcap doctor recording.mcap

Read an MCAP file in Python and other languages

Reference libraries read and write MCAP in several languages, including Python, C++, Go, Rust, Swift, and TypeScript. In Python, the mcap package reads raw messages, and mcap-ros1-support, mcap-ros2-support, and mcap-protobuf-support decode ROS 1, ROS 2, and Protobuf payloads. Reading a ROS 2 topic takes a few lines:
from mcap.reader import make_reader
from mcap_ros2.decoder import DecoderFactory

with open("recording.mcap", "rb") as f:
    reader = make_reader(f, decoder_factories=[DecoderFactory()])
    for schema, channel, message, ros_msg in reader.iter_decoded_messages(topics=["/joint_states"]):
        print(message.log_time, ros_msg.position)

View an MCAP file in a browser: an MCAP viewer without ROS

Many robotics visualization tools open .mcap files, and synchronized playback puts every camera, point cloud, and plotted signal on one timeline, so you can scrub to the moment something went wrong and see every sensor at once. Voxel51 opens MCAP files in the browser with nothing to install: upload a file to a free workspace and every camera and sensor stream plays back together. This is the fastest way to understand a single recording. To work across hundreds or thousands of recordings, the next section matters more.

Searching and curating MCAP data at scale

One MCAP file is easy to replay. A fleet's worth is not. A robot team can record thousands of hours of MCAP across sites, robots, and software versions, and the questions that matter span all of it: how often does this failure happen, which recordings contain it, and which episodes are worth labeling or training on? Opening files one at a time doesn't answer those questions.
Curating MCAP data starts with indexing. Each recording, or each episode cut from a recording, becomes a searchable sample with its metadata, such as robot, site, task, and software version, plus events and tags on its timeline. Embeddings computed from the camera streams let engineers find visually similar moments that metadata misses, and segment-level embeddings narrow that to the exact few seconds inside a long recording. Natural-language search goes one step further: an engineer can ask for "episodes where the gripper misses the handle" across thousands of recordings and review what comes back.
Quality checks belong in the same pass. Dropped messages, drifting frame rates, channels on the wrong clock, and calibration that changed mid-session all corrupt training data quietly, so teams score recordings on those checks and watch the worst ones first. Voxel51's AV audit runs 80 such checks directly on raw MCAP before any recording reaches neural reconstruction.

Annotating MCAP data

MCAP annotation labels objects, events, and time ranges directly on recordings, without first extracting frames to a separate folder. Labels can be 2D boxes on camera messages, 3D cuboids on point cloud messages, tracks that follow an object across the recording, or temporal tags that mark when something happened, such as "gripper closed" or "hard braking." Because every stream shares one timeline, a label made in one sensor's view can be checked against every other sensor at the same moment.

From MCAP to training datasets

MCAP files record everything a robot logged, which is more than a policy trains on. Turning MCAP recordings into a training dataset means choosing which topics become observations and actions, cutting recordings into episodes, resampling streams that ran at different rates to one frame rate, and writing the result in a training format. Teams typically curate first and export only the episodes worth training on, because conversion multiplies whatever problems the recordings already have.
For robot learning, the most common target today is LeRobotDataset v3.0, which stores state and action data in Parquet and camera streams as MP4 video. Converting MCAP to LeRobot format is a curation decision as much as a file conversion.

Common MCAP problems and how to catch them

Most MCAP problems don't throw an error. The file writes, the validator passes, and something is still wrong. These are the ones teams hit most.
ProblemWhat it looks likeHow teams catch it
Missing summary or footerSlow reads or tools that can't open the file, often after a crashmcap doctor, then mcap recover
Wrong encoding for a schemaThe file writes cleanly but a viewer shows "encoding unsupported" on every topicCheck each schema's encoding before writing
Timestamp unit errorsOverflow errors, or messages at the wrong timeOne helper for splitting nanoseconds into seconds and remainder
Mixed clocksSome channels show 1970 on the timeline while others show the presentCompare each channel's timestamps against a plausible floor
Calibration or sign mistakesEverything decodes and plays, but projections are offNumeric assertions against a known reference
Common MCAP problems, what each one looks like, and how teams catch it.

MCAP across physical AI

A manipulation episode in MCAP typically holds wrist and fixed camera streams, joint states, gripper state, commanded actions, and transforms. Autonomous vehicle fleet logs often carry Protobuf messages from custom stacks. Drones built on ROS 2 record their flight data to it. The format is the same in every case, which is why tooling built around MCAP carries from one domain to the next. The physical AI guide covers each domain.

Try MCAP in your browser

You can run the opening and curation steps in this guide without writing code or installing anything. In the free tier of Voxel51, you can:
  1. Browse the 20+ demo datasets and add DROID, 1,000 robot episodes stored as MCAP with three synchronized cameras, or upload your own MCAP files. Each dataset, demo or your own, uses one of three free dataset slots.
  2. Play all three cameras in an episode on one timeline.
  3. Ask the Voxel51 Agent for moments in plain language, such as episodes where the robot is picking up clothes, and review what it finds.
  4. Tag the moments that matter and save them as a view your team can reopen.
Sign up with a work or .edu email, then start with the DROID demo. The tutorial on failure mining with segment-level embedding search runs the same find-and-save loop on DROID stored as MCAP, and Try Voxel51 free covers what the free tier includes.

Try Voxel51 for yourself

Frequently asked questions about MCAP

Have MCAP files to explore? Try Voxel51 for free · See Voxel51 Multimodal · Book a demo