Manageable Messaging Protocol (MMP): Core

Source file (imported manually from Hedgedoc)

This is a rough draft specification.

The Micro Messaging Protocol aims to enable secure, unencumbered, and interoperable instant messaging, built on top of and alongside existing standards. Existing standards in this space fail to accomplish their goals for various reasons: Matrix is encumbered by its event graph, making self-hosting prohibitively expensive, and a confusingly large and growing single specification with no extension standardization framework, and the Extensible Messaging and Presence Protocol (XMPP) is encumbered by years of rotting code, reliance on dated technology, and contradicting extensions in crucial areas.

MMP endeavors to avoid these shortcomings by providing extensibility governed by a standards body, and by considering features in the base protocol which enable more advanced features, while keeping those advanced features separate.

Concepts and Terminology

Frame

: A packet of data which contains the information in transit. This corresponds to a Protobuf message. It's a metaphor: a frame _contains_ a message. It also can contain other information about the message, including delivery information, sender, recipients, and what type of content is contained in the message.

Conversation

: A conceptual unit, determined by its participants (to and from) and its conversation ID which acts as a disambiguator; it can include messages and state. Most conversations have an ID of 0, as multiple conversations between the same group of people is not always useful but it can be.

: **Note:** Group chats could end up with a large conversation ID as a consequence of adding and removing participants. This practice is not recommended and a chat room, to be defined in a companion specification, should be used instead.

Message

: A single, user-specified, sequential element of a conversation. It may be a text message such as "Hello!", or a group of images. One cognitive unit should be represented per message: an album of images or a single image, a text message, or a captioned location are good examples.

General Rules of Handling MMP Protobuf

In both the client-server and server-server (federation) APIs, Protobuf is used as the wire format for frames. The following rules apply to all Protobuf "messages" as used in MMP:

* Tip: to parse this, use `message MMP_Ping` first to determine the type, then if the type is known, re-parse the frame with that type.

* Frame type URIs which refer to frames specified in this document are in the URN namespace `urn:mmp:mmp1:*`; for example, the "ping" message is `urn:mmp:mmp1:ping`.

* Extensions and specifications related to MMP **MUST NOT** use `911` as anything other than as specified here!

* Error messages MUST be generated and interpreted as plain text. They MAY, however, contain URLs which clients SHOULD make clickable.

* While error codes are specified, error messages are not. They may be in any language and include server or situation specific information. However, when in doubt: use English and be specific about the problem without giving away sensitive details.

Client to Server Protocol

MMP data is to be accepted by servers and sent to clients as Protocol Buffers (Protobuf) messages, specified below, over a secure WebSocket at a server-specified endpoint on the domain. This endpoint is specified relative to the given login domain as plain text at the well-known path `/.well-known/mmp-client-socket` over HTTPS. This is done to allow alternate APIs to be added on top.

Ping

An authenticated client MUST send a ping at least as often as once per 30 seconds. Clients SHOULD send pings as often as every 10 seconds. Servers SHOULD disconnect clients that do not send a heartbeat for 30 seconds. It's your loss if you decide not to do that.

The Protobuf message for a ping looks like this.

Every frame type is based on this frame type; or, in other words, this is the most minimal frame type MMP allows.

Authentication

Servers are expected to authenticate clients via an HTTP header, typically either the Cookie or Authorization headers, when a client attempts to establish the WebSocket connection.

If a client is not authenticated and wishes to be (so that they can use the Client-Server API), it is to send an empty, unauthenticated HTTP POST request to the Client-Server websocket endpoint. The appropriate response is a Protobuf message according to the following:

Password-based login

If a client wishes to log in with a password (assuming the server listed and allows it), the client is to send a POST request over valid HTTPS (with any content type, as it should be ignored) with a frame conforming to the following format:

The HTTP response, with a server-selected appropriate status code, will obey the following format:

The value of `accessToken`, if set, should be considered a Bearer token, and when connecting to the WebSocket, a header like this is to be set:

Error codes that may be used here:

In-Band Account Registration

Registration, when done "in-band," occurs via the same HTTPS endpoint used for password-based login, if it is accepted (see `message MMP_Auth#registrationEndpoint` above).

At least one of email-and-password or username-and-password based login MUST be enabled to facilitate logging in after registration.

The POST body should contain the following frame:

The HTTP response, with appropriate status code, should conform to this frame:

Assuming the response is `message MMP_Success` and no error code was given, the client should then attempt to log in with their credentials.

Error codes that may be used here include:

Sending messages

To send a message, send a Message frame to the server.

Servers MUST send a [`message MMP_Success`](#MMP_Success) response, indicating whether the message was sent and, if it wasn't, why not (via an error code and optional message).

HTML messages are NOT RECOMMENED due to the complexity of HTML. Instead, prefer Markdown.

Error codes that may be returned here:

Retrieving messages

By message ID

If you have a message or event ID, you can try to find that message by sending this frame:

The response will be a [`message MMP_Message`](#MMP_Message) frame, which, if necessary, may contain an error.

Such errors may include:

By conversation

To retrieve a message by conversation, send a frame with this format:

This returns a message list frame:

User IDs

TODO

Appendix A: Errors

Errors may be under any namespace, but generic errors defined in this document use the `urn:mmp:mmp1:error#*` namespace.

General errors

`urn:mmp:mmp1:error#missing`

: The requested resource could not be found.

`urn:mmp:mmp1:error#delivery-failed`

: The remote server could not be reached or delivery failed for another reason.

`urn:mmp:mmp1:error#disabled`

: The requested feature is supported, but the server administrator has disabled it.

`urn:mmp:mmp1:error#unimplemented`

: The requested feature, frame type, or other action has not been implemented.

Auth errors

`urn:mmp:mmp1:auth#incorrect`

: The supplied credentials are in the correct format but do not match any records available to the server.

`urn:mmp:mmp1:auth#invalid`

: The supplied credentials are malformed. Reasons may include:

`urn:mmp:mmp1:auth#banned`

: The user was banned from the server.

: The IP address, IP address range, internet service provider, or location was banned from the server; typically, this is a rate limit or a spam protection, but may also be enacted for legal reasons.

: A remote server being interacted with has banned the user from participating in conversations on that server.

`urn:mmp:mmp1:auth#badname`

: The requested username includes a banned word. Servers may return this to refuse names including certain words such as slurs, curse words, or reserved system terms, which should be accompanied by a (temporary) IP block, during registration.

`urn:mmp:mmp1:auth#exists`

: The requested username is already in use.

: The email address given is already associated with an account.

Message errors

`urn:mmp:mmp1:message#invalid`

: TODO: this should be a generic error

: Required fields were missing.

: Fields excluded from certain requests were set.

`urn:mmp:mmp1:message#toobig`

: The message submitted exceeds the maximum size allowed by the server.

`urn:mmp:mmp1:message#ambiguous`

: The message requested matches more than one message.

Profile errors

`urn:mmp:mmp1:profile#missing`

: The user exists but does not have profile information.

: Profile information for the user is not known to the server.

: The user is missing (especially when other things can be missing).

The original Gemtext version of this page can be accessed with a Gemini client: gemini://blakes.dev/hdoc/yQCRixlTQsGFtTPayGpdoQ.gmi

Gemini request details:

Original URL
gemini://blakes.dev/hdoc/yQCRixlTQsGFtTPayGpdoQ.gmi
Status code
Success
Meta
text/gemini
Proxied by
A modified version of kineto

Be advised that no attempt was made to verify the remote SSL certificate.