Skip to content

docs(rfd): propose LSP proxy methods - #2154

Open
ojkelly wants to merge 1 commit into
agentclientprotocol:mainfrom
ojkelly:rfd/lsp-proxy
Open

docs(rfd): propose LSP proxy methods#2154
ojkelly wants to merge 1 commit into
agentclientprotocol:mainfrom
ojkelly:rfd/lsp-proxy

Conversation

@ojkelly

@ojkelly ojkelly commented Sep 14, 2026

Copy link
Copy Markdown

Summary

Adds a draft RFD proposing two Client methods, lsp/servers and lsp/request,
that let an Agent discover configured language servers and send LSP requests to
them, gated on an lsp Client capability.

The Client remains the only LSP client. It owns the server processes, document
synchronisation, and buffer state. The Agent supplies an LSP method name and
params and receives the server's raw result.

Motivation

There is no standard way for an Agent to reach the language servers a Client is
already running. The idea was raised in #1292 in May 2026 without a concrete
design.

An agent integrating with an editor over ACP is more valuable when it shares the editors running LSP language servers, than duplicating them and running them itself.

I have a working patch to Zed that implements this on the _meta key.

ojkelly/zed@2dc1c62

If this RFD is open to being considered I'd also like to raise a PR for that
change, either into _meta or proper as per the RFD itself.

The LSP specification is defined well enough that, in using this with an in-development agent runtime in the patched Zed, I haven't found any need for this RFD to be any more specific or to specify transforming any of the responses.

A simple direct proxy is enough.

What the RFD covers

  • lsp/servers: the servers running for a session, each with an opaque
    serverId that is stable across restarts, workspace root, language id, file
    extensions, state, and the server's verbatim initialize capabilities, plus
    the set of methods the Client will forward.
  • lsp/request: one client-to-server LSP request. Method and params are
    carried through unread and the server's result is returned in lspResult.
  • Refused categories: notifications, connection lifecycle, document lifecycle,
    and server-to-client requests.
  • Document state: the Client's servers track the files under the session's
    roots whatever process changed them, so the Agent opens and synchronises
    nothing.
  • Errors, cancellation, and position encoding.

Out of scope

Server-to-client notifications, including textDocument/publishDiagnostics.
Pull-model diagnostics are reachable through textDocument/diagnostic and
workspace/diagnostic.

Notes

  • Targets v1 and v2. The capability is clientCapabilities.lsp in v1 and
    capabilities.lsp in v2.

Editor File Sync

I also want to highlight that I think the removal of fs_write for v2 should be reconsidered. I appreciate many agents never implemented it, but there's real value when combined with this RFD for LSP integration, and I think it should be kept as optional for v2. At least, something that allows an agent to pass the file edits it wants over ACP so that they are applied via the Client/editor and thus stay in sync with all the editors tooling.

I've spent the last few years working on an unreleaseed programming language,
and have spent a long time learning how to write a good performant LSP server. The key thing I've learned that's relevant to this RFD is that:

LSP is not multi-client, and the LSP server is expected to stay in sync with
the editors file buffers as a priority over changes to the file system.

This means any change to a file not made via the editor, or LSP server itself
will be delayed until the editor has a chance to sync with the LSP server.

If the LSP server loads changes from the file system itself, it needs to reconcile that with what the editor has told it about those files.

To me, having the editor as the central authority for file buffers is becoming
the primary value proposition of an editor when running with agents as opposed to only running the agent itself.

A big frusteration I have with the current state of Claude and Codex is that
they often obscure the changes they are making, and it's harder to keep track
of what they are writing. Visibility here, means we can steer the agent back
on track earlier.

This also means the diagnostics that we see in editor, and the agent queries are
in sync with changes. This speeds up the feedback loop.

One workflow that I've watched Claude and Codex struggle their way through for
an hour, that is trivial with LSP is renaming a symbol. With LSP this becomes
a single request, who's response can be programatically converted from the LSP WorkspaceEdit to a batch of fs/write_text_file. I've implemented this in an agent runtime I've working on, and it's works really well.

This RFD isn't useless without editor file sync, but it does mean the agents
will often make queries and then be confused about the results, until they work
out that the LSP server has not yet seen the changes they made.

Related

@ojkelly
ojkelly requested a review from a team as a code owner September 14, 2026 10:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant