Generic LSP Proxy for VS Code

A flexible Language Server Protocol (LSP) proxy extension for VS Code that dynamically forwards requests to any LSP server based on configuration files. No more installing separate extensions for each language!
🌟 Features
- 🔄 Dynamic LSP Loading - Automatically detect and load language servers based on file type
- 📝 Configuration-Driven - Simple JSON configuration for any LSP server
- 🚀 Multiple Transport Support - stdio, TCP, and WebSocket connections
- 📊 Status Bar Integration - Monitor active servers at a glance
- 🎯 Per-Workspace Configuration - Different settings for different projects
- 🛠️ Built-in Commands - Restart, reload, and manage servers easily
- 🛡️ Manual Server Management - Enable/disable servers as needed
📦 Installation
From VS Code Marketplace
- Open VS Code
- Press
Ctrl+P
/ Cmd+P
- Type
ext install generic-lsp-proxy
- Press Enter
From Source
# Clone the repository
git clone https://github.com/mjmorales/vscode-generic-lsp-proxy.git
cd vscode-generic-lsp-proxy
# Install dependencies
npm install
# Build and package
npm run compile
npx vsce package
# Install the VSIX
code --install-extension generic-lsp-proxy-*.vsix
🚀 Quick Start
1. Initialize Configuration
Option A: Use the Init Command (Recommended)
- Press
Ctrl+Shift+P
/ Cmd+Shift+P
- Run
LSP Proxy: Initialize LSP Configuration
- Choose
Custom Configuration
:
- Enter language ID (e.g.,
python
, rust
, custom
)
- Enter LSP command (e.g.,
pylsp
, rust-analyzer
)
- Enter file extensions (e.g.,
.py, .pyw
)
- Select transport type (stdio, tcp, or websocket)
- Add optional arguments if needed
- Your
.vscode/lsp-proxy.json
will be created automatically!
Option B: Create Manually
[
{
"languageId": "python",
"command": "pylsp",
"fileExtensions": [".py"]
}
]
2. Install Language Server
# Python
pip install python-lsp-server
# TypeScript
npm install -g typescript-language-server typescript
# Rust
rustup component add rust-analyzer
3. Open a File
Open any file matching your configured extensions. The LSP will start automatically!
📋 Configuration
Configuration File Locations
The extension looks for configuration in the following order:
.vscode/lsp-proxy.json
(workspace-specific)
.lsp-proxy.json
(project root)
- Global configuration in VS Code settings
Configuration Schema
interface LSPServerConfig {
// Required fields
languageId: string; // Unique identifier for the language
command: string; // Command to start the LSP server
fileExtensions: string[]; // File extensions to activate this server
// Optional fields
args?: string[]; // Command line arguments
filePatterns?: string[]; // Glob patterns for file matching
workspacePattern?: string; // Restrict to specific workspace folders
initializationOptions?: {}; // LSP initialization options
settings?: {}; // Language-specific settings
env?: {}; // Environment variables
transport?: 'stdio' | 'tcp' | 'websocket'; // Connection type
tcpPort?: number; // Port for TCP transport
websocketUrl?: string; // URL for WebSocket transport
}
Example Configurations
TypeScript/JavaScript
{
"languageId": "typescript",
"command": "typescript-language-server",
"args": ["--stdio"],
"fileExtensions": [".ts", ".tsx", ".js", ".jsx"],
"initializationOptions": {
"preferences": {
"includeCompletionsForModuleExports": true,
"includeInlayParameterNameHints": "all"
}
}
}
Python
{
"languageId": "python",
"command": "pylsp",
"fileExtensions": [".py", ".pyw"],
"settings": {
"pylsp": {
"plugins": {
"pycodestyle": {
"enabled": true,
"maxLineLength": 120
},
"pylint": {
"enabled": true
}
}
}
}
}
Rust
{
"languageId": "rust",
"command": "rust-analyzer",
"fileExtensions": [".rs"],
"initializationOptions": {
"cargo": {
"buildScripts": {
"enable": true
},
"features": "all"
},
"procMacro": {
"enable": true
}
}
}
Go
{
"languageId": "go",
"command": "gopls",
"fileExtensions": [".go"],
"initializationOptions": {
"usePlaceholders": true,
"completeUnimported": true,
"staticcheck": true
}
}
Remote Server (TCP)
{
"languageId": "gdscript",
"command": "nc",
"args": ["localhost", "6005"],
"transport": "tcp",
"tcpPort": 6005,
"fileExtensions": [".gd", ".tres", ".tscn"]
}
⚙️ Extension Settings
Configure the extension behavior in VS Code settings (Ctrl+,
/ Cmd+,
):
Setting |
Type |
Default |
Description |
genericLspProxy.configPath |
string |
.vscode/lsp-proxy.json |
Path to configuration file |
genericLspProxy.enableDebugLogging |
boolean |
false |
Enable detailed logging |
📟 Commands
Access commands via Command Palette (Ctrl+Shift+P
/ Cmd+Shift+P
):
- LSP Proxy: Initialize LSP Configuration - Create a new LSP configuration with guided setup
- LSP Proxy: Restart LSP Server - Restart the server for the current file
- LSP Proxy: Show Active LSP Servers - Display and manage running servers
- LSP Proxy: Reload LSP Configuration - Reload config and restart servers
- LSP Proxy: Show Disabled Servers - View and re-enable servers that failed to start
🔧 Development
This project uses Task for development workflows.
Prerequisites
# Install Task
brew install go-task/tap/go-task # macOS
# or see https://taskfile.dev/installation/
# Install dependencies
task install
Common Tasks
task # Show all available tasks
task dev # Start development mode
task test # Run all tests
task lint # Run linter
task build # Build the extension
task package # Create VSIX file
Project Structure
vscode-generic-lsp-proxy/
├── src/
│ ├── extension.ts # Extension entry point
│ ├── lspProxyManager.ts # LSP client lifecycle management
│ ├── configurationManager.ts # Configuration loading and validation
│ ├── logger.ts # Logging utilities
│ └── test/ # Test suites
├── examples/ # Example configurations
├── package.json # Extension manifest
├── Taskfile.yml # Task runner configuration
└── README.md # This file
Testing
# Run all tests
task test
# Run with coverage
task test:coverage
# Run specific test suite
npm test -- --grep "ConfigurationManager"
Code Quality
# Run all checks
task check
# Auto-fix issues
task fix
# Format code
task format
🐛 Troubleshooting
Server Not Starting
- Check Output Panel: View → Output → "Generic LSP Proxy"
- Verify Installation:
which <command>
should return the path
- Test Manually: Run
<command> --version
in terminal
- Check Configuration: Ensure JSON is valid and paths are correct
No IntelliSense/Completions
- File Extension: Verify file extension matches configuration
- Language Server Features: Not all servers support all features
- Initialization: Check
initializationOptions
in config
- Debug Logging: Enable in settings to see LSP communication
- Reduce File Watchers: Limit
filePatterns
scope
- Server Performance: Some servers are resource-intensive
- Check Output: Look for errors in the output panel
Common Error Messages
Error |
Solution |
"Command not found" |
Install the language server or check PATH |
"Connection refused" |
For TCP, ensure server is running on specified port |
"Invalid configuration" |
Check JSON syntax and required fields |
"Server stopped" |
Check server logs and restart manually |
🤝 Contributing
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Make your changes and add tests
- Run checks:
task ready
- Commit:
git commit -m 'Add amazing feature'
- Push:
git push origin feature/amazing-feature
- Open a Pull Request
Development Guidelines
- Write tests for new features
- Follow existing code style
- Update documentation
- Add example configurations
- Run
task check
before committing
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Built with vscode-languageclient
- Inspired by the need for a unified LSP experience
- Thanks to all contributors and users
🔗 Links
Made with ❤️ for the VS Code community