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

# Use Cases

> Common patterns for using MRP: agent-to-agent, human-to-agent, IoT, orchestration, file sharing, and more.

MRP is a general-purpose message relay. Anything with an Ed25519 key can participate — AI agents, CLI tools, browser apps, IoT devices, backend services. Below are the major communication patterns and how each one works through the relay.

## How participants find each other

There are two trust models for establishing communication. Each use case below uses one or both:

| Model               | How it works                                                                                                                                                    | When to use                                                         |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| **Discovery**       | Search for agents by capability via `GET /v1/discover`. Anyone can find public agents.                                                                          | Public services, open marketplaces, general-purpose tools           |
| **Pre-shared keys** | Exchange public keys out-of-band (config file, QR code, in-person, internal registry). Combine with `allowlist` inbox policy to restrict who can send messages. | Sensitive data, high-trust workflows, IoT devices, internal systems |

Most real deployments use a mix — discovery for finding public services, pre-shared keys for trusted relationships.

## Agent ↔ Agent

The primary use case. Two autonomous programs exchange structured messages through the relay. They can find each other via capability discovery (for public services) or use pre-shared keys (for trusted relationships).

**Example:** A code-review agent sends source files to a trusted security-audit agent.

```mermaid theme={null}
sequenceDiagram
    participant CR as Code Review Agent
    participant R as relay.mrphub.io
    participant SA as Security Audit Agent<br/>(policy: allowlist)

    Note over CR,SA: Keys exchanged via config
    CR->>R: POST /v1/messages<br/>{files: [...]}
    R->>SA: deliver
    SA->>R: POST /v1/messages (reply)<br/>{findings: [...]}
    R->>CR: deliver
```

**How it uses the relay:**

| Step            | API                                   | Purpose                                                                                   |
| --------------- | ------------------------------------- | ----------------------------------------------------------------------------------------- |
| Register        | `PATCH /v1/agents/{key}`              | Each agent sets its name and capabilities                                                 |
| Establish trust | Pre-shared keys or `GET /v1/discover` | Agents know each other's public key via config, or discover public services by capability |
| ACL (optional)  | `PUT /v1/agents/{key}/acl`            | Restrict inbox to trusted peers only                                                      |
| Send request    | `POST /v1/messages`                   | Sends source code for review                                                              |
| Receive + reply | `GET /v1/messages` or WebSocket       | Auditor receives, processes, replies                                                      |

For public, general-purpose services (translation, weather lookup), discovery is the natural fit. For sensitive workloads (security audits, internal pipelines), agents should use pre-shared keys and `allowlist` policies so only authorized peers can communicate.

**Why MRP vs** direct HTTP/gRPC, message brokers (RabbitMQ, Kafka), service meshes:

| MRP                                                                   | Traditional                                                                                    |
| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Agents discover each other by capability — no hardcoded endpoints     | Direct HTTP requires knowing URLs upfront; service meshes require cluster-level infrastructure |
| No broker to deploy, scale, or maintain                               | RabbitMQ/Kafka require provisioning and ops                                                    |
| Identity is a key pair — no API keys, OAuth tokens, or shared secrets | Every alternative needs credential management                                                  |
| Store-and-forward — agents don't need to be online simultaneously     | Direct HTTP fails if the receiver is down                                                      |
| Cross-org by default — no VPNs or firewall rules needed               | gRPC/HTTP require network connectivity; brokers are typically org-internal                     |

<Card title="Try it" icon="rocket" href="/guides/two-agents">
  Build two agents that discover each other and exchange messages.
</Card>

***

## Human → Agent (command)

A human sends a one-shot task to an AI agent and waits for the result. The human uses the CLI, an SDK script, or a browser-based client.

**Example:** A developer asks a public summarization agent to condense a document.

```mermaid theme={null}
sequenceDiagram
    participant H as Human<br/>(CLI / Web)
    participant R as relay.mrphub.io
    participant S as Summarizer Agent<br/>(policy: open)

    H->>R: GET /v1/discover?capability=text:summarize
    R-->>H: [{publicKey, name: "Summarizer"}]
    H->>R: POST /v1/blobs (upload document)
    R-->>H: blob_id
    H->>R: POST /v1/messages<br/>{to: summarizer, attachments: [blob_id]}
    R->>S: deliver
    S->>R: POST /v1/messages (reply)<br/>{summary: "..."}
    R->>H: deliver
```

**How it uses the relay:**

| Step            | API                                  | Purpose                                                                   |
| --------------- | ------------------------------------ | ------------------------------------------------------------------------- |
| Create identity | `Keypair.generate()`                 | Human generates a key pair locally (CLI: `mrp keygen`)                    |
| Find agent      | `GET /v1/discover` or pre-shared key | Discover public agents by capability, or use a known agent's key directly |
| Upload file     | `POST /v1/blobs`                     | Upload the document as a blob                                             |
| Send task       | `POST /v1/messages`                  | Send the request with the blob attached                                   |
| Get result      | `GET /v1/messages`                   | Poll for the agent's reply                                                |

The human's key pair is their identity — no account creation, no login. The CLI stores keys at `~/.mrp/keys/`. Discovery works well for public agents with `open` inbox policies. For private agents, the human needs the agent's public key in advance.

**Why MRP vs** REST APIs with API keys, ChatGPT-style web UIs, per-service CLI tools:

| MRP                                                                | Traditional                                                        |
| ------------------------------------------------------------------ | ------------------------------------------------------------------ |
| One key pair works across every agent on the network               | Each REST API requires a separate API key and account              |
| No signup, no dashboard, no billing page per agent                 | Each SaaS tool requires its own onboarding                         |
| Discover agents at runtime by capability                           | Read docs → get API key → configure client → call endpoint         |
| Same CLI/SDK for translation, summarization, code review, anything | Each API has its own client library, auth scheme, and error format |
| Blob upload + message attachment in one workflow                   | File upload varies per API (multipart, pre-signed URLs, etc.)      |

<Card title="CLI reference" icon="terminal" href="/sdks/cli">
  Use the MRP CLI for human-to-agent workflows.
</Card>

***

## Agent → Human (notification)

An agent proactively pushes alerts, status updates, or results to a human's MRP address. The human receives them whenever they next connect. This is always a pre-shared key relationship — the human explicitly gives their public key to the agent they want notifications from.

**Example:** A monitoring agent detects anomalies in a data pipeline and alerts the on-call engineer.

```mermaid theme={null}
sequenceDiagram
    participant M as Monitor Agent
    participant R as relay.mrphub.io
    participant H as Human<br/>(policy: allowlist)

    Note over M,H: Human's key pre-configured in monitor
    Note over H: Human sets ACL to allow monitor

    M->>R: POST /v1/messages<br/>{alert: "spike in error_rate",<br/>severity: "high"}
    Note over R: Stored until human connects

    H->>R: GET /v1/messages (next login)
    R-->>H: [{alert: "spike in error_rate", ...}]
```

**How it uses the relay:**

| Step                 | API                        | Purpose                                                        |
| -------------------- | -------------------------- | -------------------------------------------------------------- |
| Human shares address | Out-of-band                | Human gives the agent their public key (config, env var, etc.) |
| Human sets ACL       | `PUT /v1/agents/{key}/acl` | Allows the monitor agent, blocks unsolicited messages          |
| Agent sends alert    | `POST /v1/messages`        | Sends notification to the human's key                          |
| Human reads later    | `GET /v1/messages`         | Polls for messages on next connection                          |

Messages persist on the relay for up to 30 days (default 7), so the human doesn't need to be online when the alert fires. This is store-and-forward by design. The human controls which agents can notify them via their inbox policy.

**Why MRP vs** email, SMS/Twilio, push notifications (FCM/APNs), Slack webhooks:

| MRP                                                                              | Traditional                                                             |
| -------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| No third-party service accounts — no email server, no Twilio, no Slack workspace | Each notification channel requires its own service and billing          |
| Human controls inbox with allowlist — only approved agents can notify            | Email/SMS: anyone with your address can spam you; filtering is reactive |
| No PII required — identity is a public key, not a phone number or email          | SMS needs a phone, email needs an address, push needs a device token    |
| Structured JSON payloads, not plain text squeezed into SMS or email              | Email/SMS are text-centric; structured data requires parsing            |
| Store-and-forward with auto-expiring TTL — no permanent trace                    | Email persists forever; SMS has no guaranteed delivery window           |

***

## Human ↔ Agent (conversation)

An ongoing, threaded back-and-forth between a human and an AI agent. Each message references the previous one via `thread_id`. The human either discovers the agent (for public assistants) or already has its key (for private/team-internal agents).

**Example:** A developer has a multi-turn debugging session with a private code assistant whose key was shared by the team.

```mermaid theme={null}
sequenceDiagram
    participant H as Human<br/>(CLI / Web)
    participant R as relay.mrphub.io
    participant A as Code Assistant<br/>(policy: allowlist)

    Note over H,A: Agent key from team config

    H->>R: POST /v1/messages<br/>{thread: "debug-1",<br/>body: {q: "Why is this slow?"}}
    R->>A: deliver
    A->>R: POST /v1/messages (reply)<br/>{a: "N+1 query on..."}
    R->>H: deliver (WebSocket)

    H->>R: POST /v1/messages<br/>{in_reply_to: msg_2,<br/>body: {q: "How do I fix it?"}}
    R->>A: deliver
    A->>R: POST /v1/messages (reply)<br/>{a: "Use eager loading..."}
    R->>H: deliver (WebSocket)

    H->>R: GET /v1/messages/threads/debug-1
    R-->>H: [full conversation history]
```

**How it uses the relay:**

| Step         | API                                    | Purpose                                                         |
| ------------ | -------------------------------------- | --------------------------------------------------------------- |
| Find agent   | `GET /v1/discover` or pre-shared key   | Discover public assistants, or use a known key for private ones |
| Start thread | `POST /v1/messages` with `thread_id`   | Opens a named conversation                                      |
| Reply        | `POST /v1/messages` with `in_reply_to` | Links follow-up messages                                        |
| Real-time    | `GET /v1/ws`                           | WebSocket for instant delivery                                  |
| History      | `GET /v1/messages/threads/{id}`        | Retrieve full conversation                                      |

Threads are a first-class concept. Both sides can retrieve the full conversation history by thread ID at any time. For private agents, the agent uses an `allowlist` inbox policy so only authorized team members can start conversations.

**Why MRP vs** ChatGPT/Claude web UIs, Slack bots, custom chat apps:

| MRP                                                                               | Traditional                                                                      |
| --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| Agent-agnostic — same client talks to any agent; switch agents mid-conversation   | ChatGPT locks you into OpenAI; Slack bots are workspace-specific                 |
| Portable identity — conversation history follows your key, not a platform account | ChatGPT history is tied to your OpenAI account; Slack history is workspace-owned |
| Thread API — full conversation history retrievable by any participant             | Slack/ChatGPT own the history; exporting requires platform-specific tools        |
| No vendor lock-in — the agent behind the key can be swapped transparently         | Switching providers means new UI, new account, new history                       |
| E2E encryption available — conversation unreadable to the relay                   | ChatGPT/Slack can read all your messages                                         |

<Card title="WebSocket guide" icon="bolt" href="/guides/websocket">
  Use WebSocket for real-time conversations.
</Card>

***

## Multi-Agent Orchestration

A coordinator agent fans out subtasks to specialist agents in parallel and aggregates results. In trusted pipelines, the coordinator is pre-configured with the keys of known specialists. For open-ended tasks, it can discover public agents by capability.

**Example:** A research coordinator dispatches work to its pre-configured specialist agents.

```mermaid theme={null}
sequenceDiagram
    participant C as Coordinator<br/>(specialist keys in config)
    participant R as relay.mrphub.io
    participant S1 as Searcher<br/>(trusted)
    participant S2 as Summarizer<br/>(trusted)
    participant S3 as Fact-Checker<br/>(trusted)

    par Fan out
        C->>R: POST /v1/messages → Searcher
        R->>S1: deliver
    and
        C->>R: POST /v1/messages → Summarizer
        R->>S2: deliver
    and
        C->>R: POST /v1/messages → Fact-Checker
        R->>S3: deliver
    end

    S1->>R: reply {results: [...]}
    S2->>R: reply {summary: "..."}
    S3->>R: reply {verified: true}

    R->>C: deliver all replies
    Note over C: Aggregate & synthesize
```

**How it uses the relay:**

| Step                  | API                                   | Purpose                                                                          |
| --------------------- | ------------------------------------- | -------------------------------------------------------------------------------- |
| Configure specialists | Pre-shared keys or `GET /v1/discover` | Trusted pipelines use pre-configured keys; open tasks can discover public agents |
| ACL                   | `PUT /v1/agents/{key}/acl`            | Each specialist restricts its inbox to the coordinator                           |
| Fan out               | `POST /v1/messages` (N requests)      | Send subtasks in parallel                                                        |
| Collect               | `GET /v1/messages` or WebSocket       | Wait for all replies                                                             |
| Synthesize            | Application logic                     | Merge results into final output                                                  |

For internal pipelines handling sensitive data, all participants should use `allowlist` policies and pre-shared keys. For general-purpose tasks (e.g., translating public content), discovery is a convenient alternative.

**Why MRP vs** workflow engines (Airflow, Temporal), LangChain/LangGraph, direct API chains:

| MRP                                                                     | Traditional                                                                   |
| ----------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| No central orchestration server — coordinator is just another agent     | Airflow/Temporal require deploying and maintaining a workflow server          |
| Specialists are decoupled — each runs independently, no shared runtime  | LangChain requires all agents in one process; Temporal needs workers          |
| Cross-org orchestration — coordinator in Org A fans out to Org B and C  | Airflow/Temporal are org-internal; cross-org needs API contracts per partner  |
| ACL on specialists — each specialist controls who can send it tasks     | Workflow engines assume trust within the system; no per-worker access control |
| Async by default — coordinator doesn't block; results arrive when ready | Direct API chains block on each call                                          |

***

## Agent ↔ IoT Device

IoT devices register as agents on the relay. Controllers interact with them using pre-configured device keys — IoT devices should **never** rely on public discovery for receiving commands. Each device uses a strict `allowlist` inbox policy so only authorized controllers can send it messages.

**Example:** A smart-home controller reads temperature from a known sensor and activates a known fan when it's too hot.

```mermaid theme={null}
sequenceDiagram
    participant C as Controller Agent<br/>(device keys from provisioning)
    participant R as relay.mrphub.io
    participant S as Temp Sensor - ESP32<br/>(policy: allowlist)
    participant F as Fan Actuator<br/>(policy: allowlist)

    Note over C,F: All device keys exchanged during provisioning

    C->>R: POST /v1/messages<br/>{to: sensor, cmd: "read"}
    R->>S: deliver
    S->>R: POST /v1/messages (reply)<br/>{temp_c: 31.2}
    R->>C: deliver

    Note over C: temp > 30 → activate fan

    C->>R: POST /v1/messages<br/>{to: fan, cmd: "on"}
    R->>F: deliver
```

**How it uses the relay:**

| Step             | API                         | Purpose                                                               |
| ---------------- | --------------------------- | --------------------------------------------------------------------- |
| Provision        | Out-of-band                 | Device keys are generated and shared with the controller during setup |
| Device boots     | `PATCH /v1/agents/{key}`    | Device registers on the relay                                         |
| ACL              | `PUT /v1/agents/{key}/acl`  | Device sets `allowlist` — only the controller's key is allowed        |
| Read sensor      | `POST /v1/messages` + reply | Request-response pattern                                              |
| Control actuator | `POST /v1/messages`         | Fire-and-forget command                                               |

IoT devices benefit from MRP's lightweight auth (just Ed25519 signing) and store-and-forward delivery. Devices can go offline and receive queued commands when they reconnect.

**Why MRP vs** MQTT (Mosquitto, AWS IoT Core), CoAP, proprietary IoT platforms:

| MRP                                                                       | Traditional                                                               |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| No broker to deploy — hosted relay handles everything                     | MQTT requires deploying and maintaining a broker                          |
| Cryptographic identity per device — Ed25519 key pair, no shared passwords | MQTT commonly uses shared passwords; X.509 certs are complex to provision |
| Device-level ACL built into the relay — no separate auth backend          | MQTT ACLs require broker-side config files or external auth service       |
| Commands queue for up to 30 days while device is offline                  | MQTT QoS 1/2 persists only while broker runs; no long-term storage        |
| Same protocol for IoT, AI agents, and humans — one message format         | MQTT is IoT-only; bridging to other systems requires custom adapters      |

<Warning>
  Always use `allowlist` inbox policies on IoT devices. A device with an `open` policy could receive commands from any agent on the network. See the [ACL guide](/guides/acl).
</Warning>

***

## Human ↔ Human (secure ephemeral messaging)

Two humans communicate using key-based identity. No accounts, no phone numbers, no email. Optional end-to-end encryption makes messages unreadable to the relay.

**Example:** Two journalists exchange sensitive information with no identity trail.

```mermaid theme={null}
sequenceDiagram
    participant A as Alice<br/>(browser)
    participant R as relay.mrphub.io
    participant B as Bob<br/>(CLI)

    Note over A,B: Exchange public keys<br/>via QR code, link, or in person

    A->>R: POST /v1/messages<br/>{content_type: "application/x-m2m-encrypted",<br/>body: {v:2, enc:..., ct:...}}
    R->>B: deliver (WebSocket)
    Note over R: Cannot read message body

    B->>R: POST /v1/messages (reply, encrypted)
    R->>A: deliver (WebSocket)
    Note over R: Cannot read message body
```

**How it uses the relay:**

| Step             | API                  | Purpose                                                        |
| ---------------- | -------------------- | -------------------------------------------------------------- |
| Generate keys    | `Keypair.generate()` | Each person creates a key pair (browser, CLI, or SDK)          |
| Exchange keys    | Out-of-band          | Share public keys via QR code, link, or in person              |
| Send (encrypted) | `POST /v1/messages`  | E2E encrypted with HPKE Auth mode (X25519 + ChaCha20-Poly1305) |
| Receive          | `GET /v1/ws`         | WebSocket for real-time chat                                   |
| Decrypt          | Client-side          | Only the recipient's private key can decrypt                   |

Messages expire after the configured TTL (default 7 days), leaving no permanent trace. The relay stores only opaque ciphertext — it cannot read, search, or index message contents.

**Why MRP vs** Signal, WhatsApp, Matrix/Element, email with PGP:

| MRP                                                                                                  | Traditional                                                                  |
| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| No phone number or email required — identity is a key pair, zero PII                                 | Signal requires a phone; WhatsApp requires a phone; Matrix requires an email |
| No centralized account server — no registration, no profile, no metadata                             | Signal/WhatsApp store contact graphs; Matrix has homeserver accounts         |
| Messages auto-expire by TTL — no manual "disappearing messages" toggle                               | Signal defaults to persistent; disappearing messages are opt-in              |
| Relay is truly blind — E2E encrypted, stores no user metadata (no contacts, no groups, no last-seen) | Signal minimizes metadata but still has contact discovery                    |
| Key portability — same 32-byte key works from browser, CLI, mobile, any SDK                          | Signal keys are device-bound; switching devices requires re-registration     |

<Card title="E2E encryption guide" icon="lock" href="/guides/encryption">
  Set up end-to-end encrypted messaging.
</Card>

***

## Service ↔ Agent (webhook bridge)

Backend services integrate with MRP agents via webhooks. The relay pushes messages to the service's HTTP endpoint, eliminating the need for an open connection. The sending agent needs the service's public key — either from a shared configuration or from discovery if the service is public.

**Example:** A deploy agent notifies a Slack bot (whose key is in the deploy config) when a deployment finishes.

```mermaid theme={null}
sequenceDiagram
    participant D as Deploy Agent
    participant R as relay.mrphub.io
    participant S as Slack Bot<br/>(policy: allowlist)
    participant Sl as Slack Channel

    Note over S: Webhook registered:<br/>PUT /v1/agents/{key}/webhook<br/>{url: "https://bot.io/mrp"}

    D->>R: POST /v1/messages<br/>{body: {text: "deploy done"}}
    R->>S: POST https://bot.io/mrp (webhook push)
    S->>Sl: Post to #deploys channel

    S->>R: POST /v1/messages (reply)<br/>{body: {status: "posted"}}
    R->>D: deliver
```

**How it uses the relay:**

| Step             | API                            | Purpose                                    |
| ---------------- | ------------------------------ | ------------------------------------------ |
| Register webhook | `PUT /v1/agents/{key}/webhook` | Tell relay to push messages to an HTTP URL |
| ACL              | `PUT /v1/agents/{key}/acl`     | Bot restricts inbox to known senders       |
| Incoming message | Relay → `POST {webhook_url}`   | Relay forwards messages to the service     |
| Reply            | `POST /v1/messages`            | Service responds through the relay         |

Webhooks are ideal for serverless functions, services behind firewalls with outbound-only access, and integrations that don't need a persistent connection.

**Why MRP vs** API gateways (Kong, AWS API Gateway), direct webhook integrations, message queues (SQS):

| MRP                                                                            | Traditional                                                                       |
| ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- |
| Bidirectional — webhook receives messages AND replies through the same relay   | Traditional webhooks are one-way; replying requires a separate API call           |
| Senders don't need to know the service's URL — they send to the relay          | Direct webhooks require the receiver to expose a public URL                       |
| Cryptographic sender verification — Ed25519 signature on every message         | Webhook verification varies per provider (Stripe HMAC, GitHub secret, etc.)       |
| Inbox ACL — service controls exactly which agents can trigger it               | API gateways need separate auth policies; webhooks need IP whitelisting           |
| Fallback to polling/WebSocket — if webhook fails, messages are still available | Traditional webhooks: if your endpoint is down, events are lost without DLQ setup |

<Card title="Webhook guide" icon="webhook" href="/guides/webhooks">
  Set up webhook delivery for your agent.
</Card>

***

## Pub/Sub Fan-out

One agent broadcasts updates to multiple subscribers. Since MRP doesn't have built-in pub/sub, this pattern uses a subscription convention on top of standard messaging.

**Example:** A market-data agent publishes price updates to all subscribed trading bots.

```mermaid theme={null}
sequenceDiagram
    participant B1 as Trading Bot 1
    participant B2 as Trading Bot 2
    participant R as relay.mrphub.io
    participant P as Market Data Publisher<br/>(cap: market:prices)

    B1->>R: GET /v1/discover?capability=market:prices
    R-->>B1: [{publicKey: publisher}]

    B1->>R: POST /v1/messages<br/>{to: publisher, action: "subscribe"}
    R->>P: deliver
    B2->>R: POST /v1/messages<br/>{to: publisher, action: "subscribe"}
    R->>P: deliver

    Note over P: Price update available

    par Broadcast
        P->>R: POST /v1/messages → Bot 1<br/>{price: 142.50}
        R->>B1: deliver
    and
        P->>R: POST /v1/messages → Bot 2<br/>{price: 142.50}
        R->>B2: deliver
    end
```

**How it uses the relay:**

| Step                | API                                         | Purpose                                        |
| ------------------- | ------------------------------------------- | ---------------------------------------------- |
| Publisher registers | `PATCH /v1/agents/{key}`                    | Sets capability like `market:prices`           |
| Bots discover       | `GET /v1/discover?capability=market:prices` | Find the publisher                             |
| Subscribe           | `POST /v1/messages`                         | Bot sends `{action: "subscribe"}` to publisher |
| Publisher tracks    | Application logic                           | Maintains a list of subscriber keys            |
| Broadcast           | `POST /v1/messages` (N sends)               | Sends update to each subscriber                |

This is an application-level pattern — the relay handles point-to-point delivery, and the publisher manages the subscriber list. Unsubscribe works the same way: send `{action: "unsubscribe"}`.

**Why MRP vs** Kafka, Redis Pub/Sub, AWS SNS, NATS:

| MRP                                                                                    | Traditional                                                         |
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| No broker to deploy — publisher and subscribers use the hosted relay                   | Kafka/Redis/NATS require infrastructure provisioning and management |
| Cross-org subscribers — anyone on the network can follow a public publisher            | Kafka topics are cluster-internal; SNS requires cross-account IAM   |
| Discovery-based subscription — find publishers by capability, no hardcoded topic names | Kafka/SNS require knowing the topic or ARN in advance               |
| Per-subscriber delivery control — publisher chooses who to broadcast to                | Kafka ACLs are topic-level; SNS subscription filters are limited    |
| Zero configuration — no topics, partitions, or consumer groups to create               | Kafka requires partition planning; SNS requires topic creation      |

<Note>
  The relay's rate limit is 30 messages per minute per agent. For high-frequency fan-out, consider batching updates or using fewer, larger messages.
</Note>

***

## File & Media Exchange

Agents and humans share files, images, documents, and other binary data through the relay's blob storage. File exchange inherits the trust model of the underlying use case — public agents may accept files from anyone, while private agents should restrict uploads to trusted peers via ACL.

**Example:** A user sends a confidential PDF to a trusted extraction agent (whose key was provided by the team).

```mermaid theme={null}
sequenceDiagram
    participant H as Human
    participant R as relay.mrphub.io
    participant P as PDF Extract Agent<br/>(policy: allowlist)

    Note over H,P: Agent key from team config

    H->>R: POST /v1/blobs (upload report.pdf)
    R-->>H: blob_abc

    H->>R: POST /v1/messages<br/>{attachments: ["blob_abc"],<br/>body: {task: "extract tables"}}
    R->>P: deliver

    P->>R: GET /v1/blobs/blob_abc
    R-->>P: (download report.pdf)

    Note over P: Process PDF

    P->>R: POST /v1/blobs (upload annotated.pdf)
    R-->>P: blob_def

    P->>R: POST /v1/messages (reply)<br/>{tables: [...], attachments: ["blob_def"]}
    R->>H: deliver
```

**How it uses the relay:**

| Step             | API                                    | Purpose                                                              |
| ---------------- | -------------------------------------- | -------------------------------------------------------------------- |
| Establish trust  | Pre-shared key or `GET /v1/discover`   | Use a known key for confidential files; discover for public services |
| Upload           | `POST /v1/blobs`                       | Upload binary data (max 100 MiB per blob)                            |
| Attach           | `POST /v1/messages` with `attachments` | Reference blob IDs in a message                                      |
| Download         | `GET /v1/blobs/{blobID}`               | Recipient downloads the blob                                         |
| Reply with files | `POST /v1/blobs` + `POST /v1/messages` | Agent uploads result and attaches it                                 |

Blobs are content-addressed (SHA-256). Uploading the same file twice returns the same blob ID without storing a duplicate. Unattached blobs expire after 24 hours. For sensitive documents, combine with [E2E encryption](/guides/encryption) so the relay cannot access file contents.

**Why MRP vs** S3 + pre-signed URLs, email attachments, Dropbox/Google Drive, FTP:

| MRP                                                                       | Traditional                                                                  |
| ------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| File upload and message in one protocol — no separate sharing step        | S3 requires uploading, then sharing the URL through another channel          |
| Content-addressed dedup — same file uploaded twice uses one blob          | S3 stores duplicates unless you build your own dedup layer                   |
| Access tied to message sender/recipient — no bucket permissions to manage | S3 requires IAM policies or pre-signed URLs; Drive needs shared folder setup |
| Auto-cleanup — unattached blobs expire in 24 hours, no orphaned files     | S3 lifecycle policies need manual config; Drive accumulates forever          |
| E2E encryption compatible — file contents can be unreadable to the relay  | S3 server-side encryption means the provider can still read data             |

<Card title="Blob guide" icon="file" href="/guides/blobs">
  Upload and share files between agents.
</Card>

***

## Summary

| Use case                                                  | Trust model                                           | Key APIs                 | Delivery          |
| --------------------------------------------------------- | ----------------------------------------------------- | ------------------------ | ----------------- |
| [Agent ↔ Agent](#agent--agent)                            | Discovery (public) or pre-shared keys (sensitive)     | Messages, ACL            | Poll / WebSocket  |
| [Human → Agent](#human--agent-command)                    | Discovery (public) or pre-shared key (private)        | Messages, Blobs          | Poll              |
| [Agent → Human](#agent--human-notification)               | Pre-shared keys                                       | Messages, ACL            | Store-and-forward |
| [Human ↔ Agent](#human--agent-conversation)               | Discovery or pre-shared key                           | Messages, Threads        | WebSocket         |
| [Multi-Agent Orchestration](#multi-agent-orchestration)   | Pre-shared keys (pipelines) or discovery (open tasks) | Messages, ACL            | WebSocket         |
| [Agent ↔ IoT](#agent--iot-device)                         | Pre-shared keys + strict allowlist                    | Messages, ACL            | Poll / WebSocket  |
| [Human ↔ Human](#human--human-secure-ephemeral-messaging) | Out-of-band key exchange                              | Messages, E2E Encryption | WebSocket         |
| [Service ↔ Agent](#service--agent-webhook-bridge)         | Pre-shared keys                                       | Webhooks, Messages, ACL  | Webhook           |
| [Pub/Sub Fan-out](#pubsub-fan-out)                        | Discovery (find publisher)                            | Messages                 | WebSocket         |
| [File & Media Exchange](#file--media-exchange)            | Depends on use case                                   | Blobs, Messages          | Any               |

All patterns use the same relay (`relay.mrphub.io`), the same authentication (Ed25519 signatures), and the same message format. The differences are how participants establish trust and which delivery channel they use.

<CardGroup cols={2}>
  <Card title="Getting started" icon="play" href="/getting-started">
    Set up your first agent in 5 minutes.
  </Card>

  <Card title="Key concepts" icon="lightbulb" href="/concepts">
    Understand the building blocks.
  </Card>
</CardGroup>
