Protols - Protobuf Language Server
May 23, 2026 · View on GitHub
Protols is an open-source, feature-rich Language Server Protocol (LSP) for Protocol Buffers (proto) files. Powered by the efficient tree-sitter parser, Protols offers intelligent code assistance for protobuf development, including features like auto-completion, diagnostics, formatting, and more.
✨ Features
- ✅ Code Completion: Auto-complete messages, enums, and keywords in your
.protofiles. - ✅ Diagnostics: Syntax errors, import error with tree-sitter and advanced diagnostics from
protoc. - ✅ Workspace Symbols: Search and view all symbols across workspaces.
- ✅ Document Symbols: Navigate and view all symbols, including nested messages and enums.
- ✅ Code Formatting: Format
.protofiles usingclang-formatfor a consistent style. - ✅ Go to Definition: Jump to the definition of symbols like messages or enums and imports.
- ✅ Hover Information: Get detailed information and documentation on hover.
- ✅ Rename Symbols: Rename protobuf symbols and propagate changes across the codebase.
- ✅ Find References: Find where messages, enums, and fields are used throughout the codebase.
Table of Contents
🚀 Installation
For Neovim
You can install Protols via mason.nvim, or install it directly from crates.io:
cargo install protols
Then, configure it in your init.lua using nvim-lspconfig:
require'lspconfig'.protols.setup{}
Setting Include Paths in Neovim
For dynamic configuration of include paths, you can use the before_init callback to set them via initializationParams:
require'lspconfig'.protols.setup{
before_init = function(_, config)
config.init_options = {
include_paths = {
"/usr/local/include/protobuf",
"vendor/protos",
"../shared-protos"
}
}
end
}
Command Line Options
Protols supports various command line options to customize its behavior:
Usage: protols [OPTIONS]
Options:
-i, --include-paths <INCLUDE_PATHS> Include paths for proto files, comma-separated (can be used multiple times)
-h, --help Print help
-V, --version Print version
Transport:
--stdio Use stdin/stdout for communication (default)
--socket <ADDR> Use TCP communication with a specific address and port. Examples: "192.168.1.10:5005" or "0.0.0.0:5005"
--port <PORT> Use TCP communication on localhost with a specific port. Example: "5005"
--pipe <PATH> Use Unix domain socket (Linux/macOS) or Named Pipe (Windows). Examples: "/tmp/protols.sock" or "protols-pipe" (Windows)
Examples
Specify include paths
You can provide include paths using a comma-separated list or by repeating the flag:
protols --include-paths=/path/to/protos,/another/path/to/protos
# or
protols -i /path/to/protos -i /another/path/to/protos
Communication via TCP
TCP transport is useful when the language server and the IDE run in different environments.
- Localhost only: Connect within the same machine.
protols --port 7301 - Container/Docker mode: Listen on all interfaces to allow access from the
host machine to the container.
protols --socket 0.0.0.0:7301 - Specific interface: Listen on a specific network IP.
protols --socket 192.168.1.10:7301
Communication via Unix Domain Socket
On Linux or macOS, you can use a socket file for communication:
protols --pipe /tmp/protols.sock
Communication via Named Pipes (Windows)
On Windows, you can specify a pipe name. protols handles the \\.\pipe\ prefix automatically:
protols --pipe protols-pipe
For Visual Studio Code
If you're using Visual Studio Code, you can install the Protobuf Language Support extension, which uses this LSP under the hood.
Note: This extension is open source, but is not officially maintained by us.
⚙️Configuration
Protols can be configured using a protols.toml file, which you can place in root of your project directory.
Sample protols.toml
[config]
include_paths = ["foobar", "bazbaaz"] # Include paths to look for protofiles during parsing
[config.path]
clang_format = "clang-format"
protoc = "protoc"
[config.rename]
chain_rpc_request_response = false # Also rename <Rpc>Request/<Rpc>Response messages when renaming an rpc
Configuration Sections
Basic Configuration
The [config] section contains stable settings that should generally remain unchanged.
-
include_paths: These are directories where.protofiles are searched. Paths can be absolute or relative to the LSP workspace root, which is already included in theinclude_paths. You can also specify include paths using:- Configuration file: Workspace-specific paths defined in
protols.toml - Command line: Global paths using
--include-pathsflag that apply to all workspaces - Initialization parameters: Dynamic paths set via LSP
initializationParams(useful for editors like Neovim)
When a file is not found in any of the paths above, the following directories are searched:
- Protobuf Include Path: the path containing the Protocol Buffers Well-Known Types as detected by
pkg-config(requirespkg-configpresent in environment and capable of finding the installation ofprotobuf) - Fallback Include Path: the fallback include path configured at compile time
All include paths from these sources are combined when resolving proto imports.
- Configuration file: Workspace-specific paths defined in
Path Configuration
The [config.path] section contains path for various tools used by LSP.
clang_format: Uses clang_format from this path for formattingprotoc: Uses protoc from this path for diagnostics
Rename Configuration
The [config.rename] section tunes rename behaviour.
chain_rpc_request_response(defaultfalse): when enabled, renaming anrpcalso renames its convention-named<Rpc>Requestand<Rpc>Responsemessages — and renaming such a message renames therpcand its sibling message. The chain only fires when the names follow the Google API design guide convention and the messages are used by exactly onerpc.
🛠 Usage
Protols offers a rich set of features to enhance your .proto file editing experience.
Code Completion
Protols offers intelligent autocompletion for messages, enums, and proto3 keywords within the current package. Simply start typing, and Protols will suggest valid completions.
Diagnostics
Syntax errors are caught by the tree-sitter parser, which highlights issues directly in your editor. More advanced error reporting, is done by protoc which runs after a file saved. You must have protoc installed and added to your path or you can specify its path in the configuration above
Code Formatting
Format your .proto files using clang-format. To customize the formatting style, add a .clang-format file to the root of your project. Both document and range formatting are supported.
Workspace Symbols
Protols implements workspace symbol capabilities allowing you to search for symbols across workspace or list them, including nested symbols such as messages and enums. This allows for easy navigation and reference across workspace.
Document Symbols
Protols provides a list of symbols in the current document, including nested symbols such as messages and enums. This allows for easy navigation and reference.
Go to Definition
Jump directly to the definition of any custom symbol or imports, including those in other files or packages. This feature works across package boundaries.
Hover Information
Hover over any symbol or imports to get detailed documentation and comments associated with it. This works seamlessly across different packages and namespaces.
Rename Symbols
Rename symbols like messages, enums, services and RPC methods, and propagate the changes throughout the codebase. Rename also works when invoked on a type reference (e.g. the request or response type of an rpc) — the LSP pivots to the declaration and applies the rename from there. Field names, oneof names, and enum values can also be renamed at their declaration site (single-site rename, since they aren't referenced as types from other .proto files).
When an rpc follows the rpc <Name>(<Name>Request) returns (<Name>Response) convention from the Google API design guide (AIPs 131–136), renaming any one of the three triggers a chained rename of the other two — but only when (a) the matching message name follows the convention exactly, (b) the request/response is used by exactly one rpc in the workspace, and (c) the user's new name preserves the convention. If any check fails, only the symbol the user invoked rename on is renamed.
Find References
Find all references to user-defined types like messages or enums. Nested fields are fully supported, making it easier to track symbol usage across your project.
Protocol Buffers Well-Known Types
Protols does not ship with the Protocol Buffers Well-Known Types unless configured to do so by a distribution.
In order for features above to work for the well-known types, the well-known imports must either resolve against one of the configured import paths or the environment must contain in PATH a pkg-config executable capable of resolving the package protobuf.
You can verify this by running
pkg-config --modversion protobuf
in protols' environment.
📦 Packaging
Distributions may set an absolute include path which contains the Protocol Buffers Well-Known Types,
for example pointing to the files provided by the protobuf package, by compiling protols with the
environment variable FALLBACK_INCLUDE_PATH set to the desired path. This path will be used by the
compiled executable for resolution of any proto files that could not be resolved otherwise.
🤝 Contributing
We welcome contributions from developers of all experience levels! To get started:
- Fork the repository and clone it to your local machine.
- Create a new branch for your feature or fix.
- Run the tests to ensure everything works as expected.
- Open a pull request with a detailed description of your changes.
Setting Up Locally
Option 1: Using Dev Containers (Easiest)
The project includes a pre-configured Dev Container, which sets up Rust, Neovim, and all dependencies automatically.
Prerequisites:
- Docker installed and running.
- (Windows users) WSL2 must be enabled.
- An IDE that supports Dev Containers (e.g., Visual Studio Code with the Dev Containers extension).
Steps:
- Open the project folder in your IDE.
- If using Visual Studio Code, click "Reopen in Container" in the pop-up
notification or via the Command Palette (
F1->Dev Containers: Reopen in Container). - The environment will be built automatically. Once finished, you can start developing immediately.
Tip
A pre-configured Neovim is included in the container for instant LSP testing.
Option 2: Manual Setup
-
Clone the repository:
git clone https://github.com/coder3101/protols.git cd protols -
Build and test the project:
cargo build cargo test
🐞 Debugging
If you want to contribute or debug the server logic, please refer to the Debugging Guide for instructions on setting up a TCP-based debug session with VS Code and Neovim.
📄 License
This project is licensed under the MIT License. See the LICENSE file for more details.