One of my favorite aspects of LSP being 'good enough' is that barebones support is incredibly simple to understand and implement. Old link since it was factored out at some point, but here is the entire LSP implementation for the Micro editor, in ~700 lines of Lua (+ utility functions): https://github.com/AndCake/micro-plugin-lsp/blob/dde90295f09...
Admittedly my proposal to build everything off more powerful state synchronization primitives does raise the bar for getting _something_ working. Ideally you make it so you can progressively support more features, still. But sometimes you do have to choose between "easy at first, then gets progressively harder" vs "hard at first, then stays manageable".
It's also not enough to send the versions: you need to actually say what to do with them!