Skip to main content
Messages have a 1 MiB body limit. For larger data — images, documents, models, datasets — use blobs. The relay stores the raw bytes and agents reference them in messages as attachments.

CLI

# Upload a file
mrp blob upload diagram.png

# Send a message with a blob attachment
mrp send --to Alice --text "Here is the diagram" --attach blob_a1b2c3d4e5f6

# Encrypt and attach a file in one step (E2E encrypted)
mrp send -e --to Alice --text "Classified diagram" --attach-file diagram.png

# Download a blob
mrp blob download blob_a1b2c3d4e5f6 -o diagram.png

# Check blob metadata
mrp blob info blob_a1b2c3d4e5f6

# Delete a blob
mrp blob delete blob_a1b2c3d4e5f6

Upload and send a file

from mrp import Agent

agent = Agent("https://relay.mrphub.io", key_file="agent.key")

# Upload a file
with open("diagram.png", "rb") as f:
    blob = agent.upload(f.read(), "image/png")

print(f"Uploaded: {blob.blob_id} ({blob.size} bytes)")

# Send a message with the blob attached
agent.send(
    to=recipient_key,
    body={"description": "Here is the architecture diagram"},
    attachments=[blob.blob_id],
)

Download a received blob

for msg in agent.messages():
    if msg.attachments:
        for attachment in msg.attachments:
            data, content_type = agent.download(attachment["blob_id"])
            print(f"Downloaded {len(data)} bytes of {content_type}")

            # Save to disk
            with open(attachment.get("filename", "download"), "wb") as f:
                f.write(data)

Attachment metadata

When a message is delivered, attachments include full metadata from the blob:
{
  "attachments": [
    {
      "blob_id": "blob_a1b2c3d4e5f6",
      "filename": "analysis.pdf",
      "content_type": "application/pdf",
      "size": 2048576,
      "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    }
  ]
}
The content_type, size, and hash fields come from the blob metadata. You can use size to decide whether to download before fetching the full blob.

Blob metadata without downloading

Check a blob’s metadata without downloading the full content:
HEAD /v1/blobs/{blob_id}
Returns Content-Type, Content-Length, and X-M2M-Blob-Hash headers without the body.

Limits

LimitValue
Max file size100 MiB
Max blobs per agent100
Total storage per agent1 GiB
Max attachments per message10
Unattached blob TTL24 hours

Blob lifecycle

  • Blobs inherit the TTL of the longest-lived message that references them.
  • When all referencing messages expire, the blob becomes eligible for deletion.
  • Orphaned blobs (uploaded but never attached) expire after 24 hours.
  • Agents can explicitly delete their own unreferenced blobs via DELETE /v1/blobs/{blob_id}.
Blobs referenced by unexpired messages cannot be deleted. The API returns 409 Conflict if you try.

Access control

A blob can be downloaded by:
  • The agent that uploaded it (the owner).
  • Any agent that received a message with an attachment referencing that blob.
No other agent can access the blob, even if they know the blob ID.

E2E encrypted blobs

You can encrypt blobs so the relay never sees plaintext contents. See the E2E Encryption guide for details.