# RBS MCP Protocol

This file is published to <a href="https://mcp.g3nretailstack.com/rbs/PROTOCOL.md" target="_blank" rel="noopener noreferrer">https://mcp.g3nretailstack.com/rbs/PROTOCOL.md</a>.


## Usage patterns (headless)
- Stack-wide SOPs & operations catalog: <a href="https://doc.g3nretailstack.com/story/operations.html" target="_blank" rel="noopener noreferrer">/story/operations.html</a>.
- Super-usecase scenarios + QA status: <a href="https://doc.g3nretailstack.com/story/super-usecases.html" target="_blank" rel="noopener noreferrer">/story/super-usecases.html</a>.
- This protocol stays contract-only; use the catalogs for workflow expectations.

## Base URL
- API Gateway: `https://api.g3nretailstack.com/rbs`

## Auth + tenancy
- Auth placement: header auth is canonical for org-scoped APIs; body auth is accepted for compatibility where documented. Exceptions: USM and UTL require body auth. See [/common/headers-identity.html](https://doc.g3nretailstack.com/common/headers-identity.html).
- Auth headers (`x-session-guid` or `x-api-key`) are required for all API Gateway calls, including `/stat`.
- Tenant endpoints (non-`/stat`) require `x-orgcode`.
- Auth is either:
  - `x-session-guid` (user session), OR
  - `x-api-key` (org-bound service account)
- Role-based: read operations require `rbs_view` or `rbs_admin`; write operations require `rbs_admin`. Owner bypass applies (anti-enumeration still applies).
- Optional cost attribution: provide `x-cccode` (or request field `cccode`).
- Write operations require `request_context`; mismatches between `request_context` and headers (`orgcode`, `logical_guid`, `channel_code`, `cccode`, `context_source`, `roles`) return `invalid-input`.
- `session_guid` is never emitted in responses; use `stats.session_fingerprint` for correlation.
- Delivery auth: prefer `assume_role` with `external_id`; static access keys are supported for legacy use.
- Queue ownership verification: RBS calls `GetQueueAttributes` and validates the queue ARN/account before activation.

## Roles
- Read: `rbs_view`, `rbs_admin` (owner implied).
- Write: `rbs_admin` (owner implied).
- Health: `/stat` requires `requireSession` (any authenticated user).
Read operations: `subscription/get`, `subscription/list`, `notification/template/get`, `notification/template/list`, `notification/log/list`. All other operations are writes.

## Surfaces
- Subscriptions: `/subscription/register`, `/subscription/verify`, `/subscription/update`, `/subscription/status/set`, `/subscription/unregister`, `/subscription/get`, `/subscription/list`
- Test delivery: `/subscription/test`
- Notifications: `/notification/template/set`, `/notification/template/get`, `/notification/template/list`, `/notification/template/status/set`, `/notification/send`, `/notification/log/list`
- Health: `/stat`

## Endpoint inventory (OpenAPI parity)

| Method | Path | Request schema | Response schema |
| --- | --- | --- | --- |
| GET | /stat | — | Envelope |
| POST | /subscription/register | SubscriptionRegisterRequest | Envelope |
| POST | /subscription/verify | SubscriptionVerifyRequest | Envelope |
| POST | /subscription/update | SubscriptionUpdateRequest | Envelope |
| POST | /subscription/status/set | SubscriptionStatusSetRequest | Envelope |
| POST | /subscription/unregister | SubscriptionUnregisterRequest | Envelope |
| POST | /subscription/test | SubscriptionTestRequest | Envelope |
| POST | /subscription/get | SubscriptionGetRequest | Envelope |
| POST | /subscription/list | SubscriptionListRequest | Envelope |
| POST | /notification/template/set | NotificationTemplateSetRequest | Envelope |
| POST | /notification/template/get | NotificationTemplateGetRequest | Envelope |
| POST | /notification/template/list | NotificationTemplateListRequest | Envelope |
| POST | /notification/template/status/set | NotificationTemplateStatusSetRequest | Envelope |
| POST | /notification/send | NotificationSendRequest | Envelope |
| POST | /notification/log/list | NotificationLogListRequest | Envelope |

## Error tags
Common tags (see [/common/error-tags.html](https://doc.g3nretailstack.com/common/error-tags.html) for definitions): `invalid-input`, `unauthorized`, `invalid-session`, `forbidden`, `not-found`, `expected-revision-required`, `conflict`, `dependency-unavailable`, `payload-too-large`, `throttled`, `internal-error`.

## Delivery payloads
- Standard deliveries are a single JSON message containing `delivery_id`, `subscription_id`, `delivered_at`, `delivery_reason`, and `event`.
- `delivery_reason`: `live` (normal delivery), `retry` (automatic retry), `test` (manual test), or `verify` (subscription verification).
- Oversize deliveries are stored in S3 and sent as a signed pointer (`type: rbs_payload_pointer`) with a `payload_pointer` object and `event_summary.reason` for quick context.

## Example envelopes
Success:
```json
{
  "success": true,
  "data": { "subscription_id": "sub-abc", "status": "active" },
  "revision": "rev-1",
  "stats": { "service": "rbs", "call": "rbs_subscription_get", "timestamp_utc": "2026-01-01T00:00:00Z", "build": { "build_major": "MONDAY", "build_minor": "0000000000", "build_id": "MONDAY-0000000000" } }
}
```
Error:
```json
{
  "success": false,
  "error": {
    "error_code": "rbs.auth_invalid",
    "http_status": 401,
    "retryable": false,
    "major": { "tag": "invalid-session", "message": { "en_US": "session_guid required" } }
  },
  "stats": { "service": "rbs", "call": "rbsEntry", "timestamp_utc": "2026-01-01T00:00:00Z", "build": { "build_major": "MONDAY", "build_minor": "0000000000", "build_id": "MONDAY-0000000000" } }
}
```


## Idempotency & retries
- All **GET / list / resolve / search** calls are safe to retry with identical inputs (read-only, no side effects).
- **POST mutations** that accept `expected_revision` use optimistic concurrency: on `409 conflict` or `428 expected-revision-required`, re-read the record, obtain the current `revision`, and retry with the updated value.
- Creates are generally **not** idempotent. Prefer caller-provided `code` (where supported) and verify existence before retrying a failed create.
- Bulk or scheduled jobs that accept an `idempotency_key` will de-duplicate within the documented time window.

## Known pitfalls
- **Missing `expected_revision`**: most state-changing operations require it; omitting it returns `428` with the current revision in `error.details`.
- **Stale revision**: reading a record, waiting, then writing with an outdated `revision` triggers `409`. Always use the latest revision from the most recent read.
- **Pagination cursors**: `next_token` is opaque JSON. Do not modify, decode, or persist cursors across sessions — they may change format between deploys.
- **Anti-enumeration 404**: some org-scoped reads return `404` even when the record exists, if the caller is not associated with the org. Treat `404` as ambiguous; verify caller association before assuming "not found".

## OpenAPI
- `https://doc.g3nretailstack.com/rbs/openapi.yaml`

_Build MONDAY-1776194870 • 2026-04-14T19:27:50.000Z • [© 1999 Microhouse Systems Inc. All rights reserved.](https://doc.g3nretailstack.com/common/copyright-license.html)_
