Ask HN: LSP Reverse Proxy Server – Practical Use?
Hi everyone in the HN community, I am new here, but I was hoping to get your opinions on a use case for LSP before I start a new FOSS project. Thanks in advance!

I was thinking about the current capabilities of LSP and how it might be used to add only certain IDE features to a text editor without the config burden that usually comes with editor plugins, but currently, there isn't really a way to do this in a modular way that works with arbitrary LSP-capable editors. Editors can implement the logic for handling multiple servers for the same language, but it doesn't seem to be the norm (please correct me if I'm wrong).

The Language Server Protocol states that one server can only connect to one client, and one client connecting to multiple servers for the same language requires implementing the logic for handling multiple LSP servers in the client's connection code, which adds friction to adoption.

I think it would be better if FOSS devs could implement LSP servers that handle one specific tooling objective and allow users to compose their editors with the features that they like from various server implementations while leaving out anything they don't need (good old Unix Philosophy).

In theory, this could be achieved without any changes to the protocol or most servers and clients by just creating a reverse proxy LSP server. Basically, the client would see it as a server, the server would see it as a client, and it would simply relay the JSON-RPC calls to the appropriate client/server while keeping track of connections with some kind of reference counting-like mechanism so that it would only pass on the shutdown and exit calls from the client to the server if all other clients of that server are disconnected from the proxy and the initialize call only if the server has not been started yet. Otherwise, it would give the appropriate response to the client telling it that the server was initialized, shutdown, exited, etc... even if it actually wasn't due to other connected clients.

The proxy would only need knowledge of the initialize, shutdown, and exit requests, as well as the capabilities feature of LSP, and it would allow using multiple servers by creating a mapping or some other kind of registry of their capabilities and then routing connections from the client to the appropriate server for the client's capabilities. The initialize request would be used to match clients with appropriate servers, so servers would still only be started when needed by an active client, and they would be closed once no more clients need them.

The implementation details would of course be more complicated than this, but at a high level this should work okay, and as long as the language the proxy is implemented in has good support for io-bound concurrency such as Node.js, Elixir, or Python with asyncio, I think it would be able to handle everyday use.

Ideally, the benefits of this wouldn't depend on buy-in from tooling devs since current clients and servers could still communicate through the proxy without any changes, so users that want modular editor features can run the proxy server, and devs that want to build modular servers can do so without interfering with the current ecosystem, and editor developers don't have to do anything. The proxy is just another piece of tooling users can include to allow modular LSP features.

This would also enable a web-based language server that any editor could connect to, which is likely impractical due to latency, but it is a use case that is not possible without allowing a single server to connect to multiple clients, so it opens up possibilities, I guess.

I am interested in building something like this, but I am very busy these days, and I don't really want to invest the time and energy into a new project if it is ultimately a pointless endeavor, so does this sound useful or interesting to you, or is this use case simply not something LSP should bother trying to handle?