Every serious protocol has, hidden in its plumbing, a compatibility promise. The promise says what kind of changes are allowed without breaking existing clients, and what kind of changes count as a breaking change that requires bumping the version. The shape of the promise is what lets ecosystems form around the protocol — it is what made HTTP, SQL, and MCP grow ecosystems in the first place.
The vocabulary comes from RFC 2119: MUST, SHOULD, and MAY. MUST is non-negotiable; if you do not do it, your implementation is non-conforming and will break. SHOULD is "you really ought to, and people will be unhappy if you don't, but it is not strictly fatal." MAY is "you can if you want, but no one is allowed to assume you did."
For protocols touching LLMs and agents, three patterns recur. First, fields tend to be added, not renamed: a new revision adds annotations next to content, but does not silently change what content means. Second, deprecation runs in long windows: a field is marked deprecated for at least one revision before it is removed, with the new field shipping in parallel so old clients still work. Third, capability negotiation moves the burden off versions: if both sides advertise what they support at handshake time, the protocol does not have to lock-step every detail to a global version number.
The compatibility promise is what you read when you ask "can I upgrade my server without breaking my clients?" If the answer is "look at the changelog and pray," you are not dealing with a real protocol; you are dealing with a moving target dressed up as one. Real protocols make the promise, write it down, and treat violations as bugs.