{"id":13895092,"url":"https://github.com/sourcegraph/lsp-adapter","last_synced_at":"2025-07-17T10:32:31.888Z","repository":{"id":31937147,"uuid":"130127321","full_name":"sourcegraph/lsp-adapter","owner":"sourcegraph","description":"lsp-adapter provides a proxy which adapts Sourcegraph LSP requests to vanilla LSP requests","archived":true,"fork":false,"pushed_at":"2022-06-23T22:21:49.000Z","size":323,"stargazers_count":29,"open_issues_count":16,"forks_count":8,"subscribers_count":65,"default_branch":"master","last_synced_at":"2024-08-07T18:32:37.010Z","etag":null,"topics":["language-server","language-server-protocol","lsp","lsp-server","repo-type-codeintel"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sourcegraph.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-18T22:07:44.000Z","updated_at":"2024-05-09T04:12:36.000Z","dependencies_parsed_at":"2022-08-07T17:01:01.440Z","dependency_job_id":null,"html_url":"https://github.com/sourcegraph/lsp-adapter","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sourcegraph%2Flsp-adapter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sourcegraph%2Flsp-adapter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sourcegraph%2Flsp-adapter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sourcegraph%2Flsp-adapter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sourcegraph","download_url":"https://codeload.github.com/sourcegraph/lsp-adapter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226255327,"owners_count":17595859,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["language-server","language-server-protocol","lsp","lsp-server","repo-type-codeintel"],"created_at":"2024-08-06T18:01:59.222Z","updated_at":"2024-11-25T00:30:50.233Z","avatar_url":"https://github.com/sourcegraph.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# lsp-adapter [![Travis-CI](https://travis-ci.org/sourcegraph/lsp-adapter.svg)](https://travis-ci.org/sourcegraph/lsp-adapter) [![AppVeyor](https://ci.appveyor.com/api/projects/status/vfdftcqh0ekb881u/branch/master?svg=true)](https://ci.appveyor.com/project/sourcegraph/lsp-adapter/branch/master) [![GoDoc](https://godoc.org/github.com/sourcegraph/lsp-adapter?status.svg)](http://godoc.org/github.com/sourcegraph/lsp-adapter) [![Go Report Card](https://goreportcard.com/badge/github.com/sourcegraph/lsp-adapter)](https://goreportcard.com/report/github.com/sourcegraph/lsp-adapter)\n\nCommand `lsp-adapter` provides a proxy which adapts Sourcegraph LSP requests to\nvanilla LSP requests.\n\n## Background\n\n[Code Intelligence on Sourcegraph](https://about.sourcegraph.com/docs/code-intelligence/) is powered by the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/).\n\nPreviously, language servers that were used on sourcegraph.com were additionally required to support our\ncustom LSP [files extensions](https://github.com/sourcegraph/language-server-protocol/blob/master/extension-files.md). These extensions allowed language servers to operate without sharing a physical file system with the client. While it's preferable for language servers to implement these extensions for performance reasons, implementing this functionality is a large undertaking.\n\n`lsp-adapter` eliminates the need for this requirement, which allows off-the-shelf language servers to be able to provide basic functionality (hovers, local definitions) to Sourcegraph.\n\n## How to Install\n\nYou can download the latest binary on the [releases page](https://github.com/sourcegraph/lsp-adapter/releases).\n\nAlternatively, install it with `go get`:\n\n```shell\ngo get -u -v github.com/sourcegraph/lsp-adapter\n```\n\nRunning `lsp-adapter --help` shows you some of its options:\n\n```shell\n\u003e lsp-adapter --help\nUsage: lsp-adapter [OPTIONS] LSP_COMMAND_ARGS...\n\nOptions:\n  -beforeInitializeHook string\n    \tA program to run after cloning the repository, but before the 'initialize' call is forwarded to the language server. (For example, you can use this to run a script to install dependencies for the project). The program's cwd will be the workspace's cache directory, and it will also be passed the cache directory as an argument.\n  -cacheDirectory string\n    \tcache directory location (default \"/var/folders/qq/1q_cmsmx6qv7bs_m6g_2pt1r0000gn/T/proxy-cache\")\n  -didOpenLanguage string\n    \t(HACK) If non-empty, send 'textDocument/didOpen' notifications with the specified language field (e.x. 'python') to the language server for every file.\n  -glob string\n    \tA colon (:) separated list of file globs to sync locally. By default we place all files into the workspace, but some language servers may only look at a subset of files. Specifying this allows us to avoid syncing all files. Note: This is done by basename only.\n  -jsonrpc2IDRewrite string\n    \t(HACK) Rewrite jsonrpc2 ID. none (default) is no rewriting. string will use a string ID. number will use number ID. Useful for language servers with non-spec complaint JSONRPC2 implementations. (default \"none\")\n  -pprofAddr string\n    \tserver listen address for pprof\n  -proxyAddress string\n    \tproxy server listen address (tcp) (default \"127.0.0.1:8080\")\n  -trace\n    \ttrace logs to stderr (default true)\n```\n\n## How to Use `lsp-adapter`\n\n`lsp-adapter` proxies requests between your Sourcegraph instance and the language server, and modifies them in such a way that allows for the two to communicate correctly. In order to do this, we need to know\n\n- How to connect `lsp-adapter` to the language server\n- How to connect to your Sourcegraph instance to `lsp-adapter`\n\n### Connect `lsp-adapter` to the Language Server\n\n`lsp-adapter` can talk to language servers over standard I/O.\n\n`lsp-adapter` interprets any positional arguments after the flags as the necessary command (+ arguments) to start the language server binary. It uses this command to communicate to the language server inside of a subprocess.\n\nFor example, if I am trying to use Rust’s language server, the command to start it up is just `rls`. `lsp-adapter` can be told to start the start the same server via:\n\n```shell\nlsp-adapter rls\n```\n\nAny stderr output from the binary will also appear in `lsp-adapter`'s logs.\n\n### Connect Sourcegraph to `lsp-adapter`\n\n1.  Use the `-proxyAddress` flag to tell `lsp-adapter` what address to listen for connections from Sourcegraph on. For example, I can tell `lsp-adapter` to listen on my local `8080` port with `-proxyAddress=127.0.0.1:8080`.\n\n2.  We then need to add a new entry to the `\"langservers\"` field in the site configuration in order to point Sourcegraph at `lsp-adapter` (similar to the steps in [this document](https://about.sourcegraph.com/docs/code-intelligence/install-manual)). For example, if `lsp-adapter` is connected to the Rust language server, and the `lsp-adapter` itself is listening on `127.0.0.1:8080`:\n\n```json\n{\n  \"language\": \"rust\",\n  \"address\": \"tcp://127.0.0.1:8080\"\n}\n```\n\nwould be the new entry that needs to be added to the `\"langservers\"` field.\n\n## Example Commands\n\nConnect via standard I/O to a language server whose command can be run with `rls`, and listen for connections from Sourcegraph from any address on port `1234`.\n\n```shell\n\u003e lsp-adapter -proxyAddresss=0.0.0.0:1234 rls\n\n2018/04/04 15:27:04 proxy.go:71: CloneProxy: accepting connections at [::]:8080\n```\n\nConnect via standard I/O to a language server whose command can be run with `rls`, change the location of the cache directory (used for cloning the repo locally) to `/tmpDir`, and enable tracing for every request to/from the language server.\n\n```shell\n\u003e lsp-adapter -cacheDir='/tmpDir' -trace rls\n```\n\n## Docker\n\nThere is a [skeleton Dockerfile](./Dockerfile) that shows how to package `lsp-adapter` along with your desired language server inside of a docker container. There are fully working examples in [dockerfiles](./dockerfiles). For example [dockerfiles/rust/Dockerfile](./dockerfiles/rust/Dockerfile), which can be built with:\n\n```shell\n\u003e docker build -f dockerfiles/rust/Dockerfile .\n```\n\n## Glob\n\nMost language servers will only ever look at files that match a set of known patterns. On initialize lsp-adapter copies a full work-tree to disk for a repository, but by specifying `-glob` we can avoid copying over files that will not be looked at. For example, if a python language server only looks at `py` and `pyc` files you can specify `-glob=*.py:*.pyc`. The matching is done on the basename of the path using [path.Match](https://godoc.org/path#Match).\n\n## Did Open Hack\n\nSome language servers do not follow the LSP spec correctly and refuse to work unless the `textDocument/didOpen` notification has been sent. See [this commit](https://github.com/sourcegraph/lsp-adapter/commit/1228a1fbaf102aa44575cec6802a5a211d117ee1) for more context. If the language server that you’re trying to use has this issue, try setting the `didOpenLanguage` flag (example: if a python language server had this issue - use `./lsp-adapter -didOpenLanguage=python ...`) to work around it.\n\n## JSONRPC2 ID Rewrite Hack\n\nSome language servers do not follow the JSONRPC2 spec correctly and fail if the Request ID is not a number of string. If the language server that you’re trying to use has this issue, try setting the `jsonrpc2IDRewrite` flag (example: if a rust language server had this issue - use `./lsp-adapter -jsonrpc2IDRewrite=number ...`) to work around it.\n\n## Before Initialization Hook\n\nSome language servers need to run setup scripts (to install dependencies, for example) in order to provide code intelligence. By using the `-beforeInitializeHook` flag, you can specify a program/script that will run after the repository is cloned to workspace's cache directory, but before the language server receives the `initalize` request. The program's `cwd` will be the cache directory (which will also be passed as an argument for convenience).\n\nFor example, if you have the following script named `hook.sh`:\n\n```shell\n#!/bin/sh\nset -x\necho $(pwd)\n```\n\nAfter specifying the hook via `lsp-adapter -beforeInitializeHook='/test.sh'` You will see output like\n\n```shell\n2018/06/20 21:11:45 uris.go:25: Cloned workspace to /tmp/proxy-cache/3bb76102-a73b-4442-a03e-930c59e1fdcb\n2018/06/20 21:11:45 hook.go:26: Running pre-init hook: '/test.sh /tmp/proxy-cache/3bb76102-a73b-4442-a03e-930c59e1fdcb'\n++ pwd\n+ echo /Users/ggilmore/dev/go/src/github.com/sourcegraph/lsp-adapter\n/Users/ggilmore/dev/go/src/github.com/sourcegraph/lsp-adapter\n```\n\nevery time the language sever receives an `initialize` request. Obviously, you should replace this script with something meaningful.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsourcegraph%2Flsp-adapter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsourcegraph%2Flsp-adapter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsourcegraph%2Flsp-adapter/lists"}