One major point as yet unaddressed by topics so far is negotiating how to enter the new protocol's mode. And then additionally, the client might want to inform the server of some things it can do, which again lowers the minimum requirements for what a client should support.
After a long discussion with Talvo/Mike (the Potato guy, as well as a Penn dev, and an invaluable source of feedback so far), I've become pretty convinced that telnet negotiation is the preferred method.
I've taken to tentatively calling the protocol IYFL (pronounced something like ee-f'l I imagine), which stands for 'If You Feel Like', which is a large part of the protocol's feel: Once you get the minimalistic set of basics implemented you can gradually add support for other stuff. You know, if you feel like. Anyway, I bring it up here because it'll be useful as a symbolic representation in telnet negotiation examples.
Near as I can tell, MSP and MXP use bytes 90 and 91, respectively, and the next one is free, so unless I come across a conflicting use of the byte, I'm tentatively assigning IYFL byte 92. In that case, true to telnet protocol in general, the MUSH would send IAC WILL IYFL to denote its support. The client would acknowledge with IAC DO IYFL. The server would then respond by a request for subnegotiation. Subnegotiation should be used to indicate client capabilities. In our case, the server asks IAC SB IYFL SEND IAC SE, and the client answers with something like IAC SB IYFL IS 'colortag withsprinkles' IAC SE. This indicates the client has both the 'colortag' and the 'withsprinkles' capabilities. (I tentatively propose the server always send the request for subnegotiation, as this is an implicit acknowledgement of the protocol, and from that point on the client is certain any future data will be in IYFL mode.)
There is an alternative (with precedent), to instead send one item at a time, letting the server query the client until the client runs out of options. So far, however, I am not convinced this is preferable. For one, this process seems both harder to implement and more error-prone, both of which are properties I'd like to avoid. In addition, this sort of querying seems primarily geared to fallback situations. For example, when subnegotiating term type, the server will query the client again if it doesn't feel it understands the client's first answer, and the client will send increasingly generic replies until it runs out of answers. I don't particularly feel as though this applies here, because a server should always be informed of all the client's capabilities, so why would you ever want to do it piecemeal or, worse, have the possibility to stop prematurely? Of course, I'm not dead set on this yet, so I'm open to good arguments for using this method.
As for specific capabilities, I have one fairly definite one so far: colortag. This indicates to the server that the client would prefer to have its color data sent as color tags rather than ansi colors. A client that doesn't implement the color tag will therefore incur no loss of information.
In less related news, I've started a list of tags the protocol will offer. At 3 required and 1 strongly suggested (hopefully the final list as far as reasonably critical tags goes), I feel the absolute minimum amount of stuff a client needs to support is pretty light, especially since all four tags should be pretty easy to implement at the lowest requirements.