npm package: @iflow-mcp/tritlo-lsp-mcp
Description: MCP server for Language Server Protocol (LSP) integration, providing hover information, code completions, diagnostics, and code actions with resource-based access
Latest version: 0.2.0

# LSP MCP Server

An MCP (Model Context Protocol) server for interacting with LSP (Language Server Protocol) interface.
This server acts as a bridge that allows LLMs to query LSP Hover and Completion providers.

## Overview

The MCP Server works by:
1. Starting an LSP client that connects to a LSP server
2. Exposing MCP tools that send requests to the LSP server
3. Returning the results in a format that LLMs can understand and use

This enables LLMs to utilize LSPs for more accurate code suggestions.


## Configuration:

```json
{
  "mcpServers": {
    "lsp-mcp": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "tritlo/lsp-mcp",
        "<language-id>",
        "<path-to-lsp>",
        "<lsp-args>"
      ]
    }
  }
}
```


## Features

### MCP Tools
- `get_info_on_location`: Get hover information at a specific location in a file
- `get_completions`: Get completion suggestions at a specific location in a file
- `get_code_actions`: Get code actions for a specific range in a file
- `open_document`: Open a file in the LSP server for analysis
- `close_document`: Close a file in the LSP server
- `get_diagnostics`: Get diagnostic messages (errors, warnings) for open files
- `start_lsp`: Start the LSP server with a specified root directory
- `restart_lsp_server`: Restart the LSP server without restarting the MCP server
- `set_log_level`: Change the server's logging verbosity level at runtime

### MCP Resources
- `lsp-diagnostics://` resources for accessing diagnostic messages with real-time updates via subscriptions
- `lsp-hover://` resources for retrieving hover information at specific file locations
- `lsp-completions://` resources for getting code completion suggestions at specific positions

### Additional Features
- Comprehensive logging system with multiple severity levels
- Colorized console output for better readability
- Runtime-configurable log level
- Detailed error handling and reporting
- Simple command-line interface

## Prerequisites

- Node.js (v16 or later)
- npm

For the demo server:
- GHC (8.10 or later)
- Cabal (3.0 or later)

## Installation

### Building the MCP Server

1. Clone this repository:
   ```
   git clone https://github.com/your-username/lsp-mcp.git
   cd lsp-mcp
   ```

2. Install dependencies:
   ```
   npm install
   ```

3. Build the MCP server:
   ```
   npm run build
   ```

## Testing

The project includes integration tests for the TypeScript LSP support. These tests verify that the LSP-MCP server correctly handles LSP operations like hover information, completions, diagnostics, and code actions.

### Running Tests

To run the TypeScript LSP tests:

```
npm test
```

or specifically:

```
npm run test:typescript
```

### Test Coverage

The tests verify the following functionality:
- Initializing the TypeScript LSP with a mock project
- Opening TypeScript files for analysis
- Getting hover information for functions and types
- Getting code completion suggestions
- Getting diagnostic error messages
- Getting code actions for errors

The test project is located in `test/ts-project/` and contains TypeScript files with intentional errors to test diagnostic feedback.

## Usage

Run the MCP server by providing the path to the LSP executable and any arguments to pass to the LSP server:

```
npx tritlo/lsp-mcp <language> /path/to/lsp [lsp-args...]
```

For example:
```
npx tritlo/lsp-mcp haskell /usr/bin/haskell-language-server-wrapper lsp
```

### Important: Starting the LSP Server

With version 0.2.0 and later, you must explicitly start the LSP server by calling the `start_lsp` tool before using any LSP functionality. This ensures proper initialization with the correct root directory, which is especially important when using tools like npx:

```json
{
  "tool": "start_lsp",
  "arguments": {
    "root_dir": "/path/to/your/project"
  }
}
```

### Logging

The server includes a comprehensive logging system with 8 severity levels:
- `debug`: Detailed information for debugging purposes
- `info`: General informational messages about system operation
- `notice`: Significant operational events
- `warning`: Potential issues that might need attention
- `error`: Error conditions that affect operation but don't halt the system
- `critical`: Critical conditions requiring immediate attention
- `alert`: System is in an unstable state
- `emergency`: System is unusable

By default, logs are sent to:
1. Console output with color-coding for better readability
2. MCP notifications to the client (via the `notifications/message` method)

#### Viewing Debug Logs

For detailed debugging, you can:

1. Use the `claude --mcp-debug` flag when running Claude to see all MCP traffic between Claude and the server:
   ```
   claude --mcp-debug
   ```

2. Change the log level at runtime using the `set_log_level` tool:
   ```json
   {
     "tool": "set_log_level",
     "arguments": {
       "level": "debug"
     }
   }
   ```

The default log level is `info`, which shows moderate operational detail while filtering out verbose debug messages.

## API

The server provides the following MCP tools:

### get_info_on_location

Gets hover information at a specific location in a file.

Parameters:
- `file_path`: Path to the file
- `language_id`: The programming language the file is written in (e.g., "haskell")
- `line`: Line number
- `column`: Column position

Example:
```json
{
  "tool": "get_info_on_location",
  "arguments": {
    "file_path": "/path/to/your/file",
    "language_id": "haskell",
    "line": 3,
    "column": 5
  }
}
```

### get_completions

Gets completion suggestions at a specific location in a file.

Parameters:
- `file_path`: Path to the file
- `language_id`: The programming language the file is written in (e.g., "haskell")
- `line`: Line number
- `column`: Column position

Example:
```json
{
  "tool": "get_completions",
  "arguments": {
    "file_path": "/path/to/your/file",
    "language_id": "haskell",
    "line": 3,
    "column": 10
  }
}
```

### get_code_actions

Gets code actions for a specific range in a file.

Parameters:
- `file_path`: Path to the file
- `language_id`: The programming language the file is written in (e.g., "haskell")
- `start_line`: Start line number
- `start_column`: Start column position
- `end_line`: End line number
- `end_column`: End column position

Example:
```json
{
  "tool": "get_code_actions",
  "arguments": {
    "file_path": "/path/to/your/file",
    "language_id": "haskell",
    "start_line": 3,
    "start_column": 5,
    "end_line": 3,
    "end_column": 10
  }
}
```

### start_lsp

Starts the LSP server with a specified root directory. This must be called before using any other LSP-related tools.

Parameters:
- `root_dir`: The root directory for the LSP server (absolute path recommended)

Example:
```json
{
  "tool": "start_lsp",
  "arguments": {
    "root_dir": "/path/to/your/project"
  }
}
```

### restart_lsp_server

Restarts the LSP server process without restarting the MCP server. This is useful for recovering from LSP server issues or for applying changes to the LSP server configuration.

Parameters:
- `root_dir`: (Optional) The root directory for the LSP server. If provided, the server will be initialized with this directory after restart.

Example without root_dir (uses previously set root directory):
```json
{
  "tool": "restart_lsp_server",
  "arguments": {}
}
```

Example with root_dir:
```json
{
  "tool": "restart_lsp_server",
  "arguments": {
    "root_dir": "/path/to/your/project"
  }
}
```

### open_document

Opens a file in the LSP server for analysis. This must be called before accessing diagnostics or performing other operations on the file.

Parameters:
- `file_path`: Path to the file to open
- `language_id`: The programming language the file is written in (e.g., "haskell")

Example:
```json
{
  "tool": "open_document",
  "arguments": {
    "file_path": "/path/to/your/file",
    "language_id": "haskell"
  }
}
```

### close_document

Closes a file in the LSP server when you're done working with it. This helps manage resources and cleanup.

Parameters:
- `file_path`: Path to the file to close

Example:
```json
{
  "tool": "close_document",
  "arguments": {
    "file_path": "/path/to/your/file"
  }
}
```

### get_diagnostics

Gets diagnostic messages (errors, warnings) for one or all open files.

Parameters:
- `file_path`: (Optional) Path to the file to get diagnostics for. If not provided, returns diagnostics for all open files.

Example for a specific file:
```json
{
  "tool": "get_diagnostics",
  "arguments": {
    "file_path": "/path/to/your/file"
  }
}
```

Example for all open files:
```json
{
  "tool": "get_diagnostics",
  "arguments": {}
}
```

### set_log_level

Sets the server's logging level to control verbosity of log messages.

Parameters:
- `level`: The logging level to set. One of: `debug`, `info`, `notice`, `warning`, `error`, `critical`, `alert`, `emergency`.

Example:
```json
{
  "tool": "set_log_level",
  "arguments": {
    "level": "debug"
  }
}
```

## MCP Resources

In addition to tools, the server provides resources for accessing LSP features including diagnostics, hover information, and code completions:

### Diagnostic Resources

The server exposes diagnostic information via the `lsp-diagnostics://` resource scheme. These resources can be subscribed to for real-time updates when diagnostics change.

Resource URIs:
- `lsp-diagnostics://` - Diagnostics for all open files
- `lsp-diagnostics:///path/to/file` - Diagnostics for a specific file

Important: Files must be opened using the `open_document` tool before diagnostics can be accessed.

### Hover Information Resources

The server exposes hover information via the `lsp-hover://` resource scheme. This allows you to get information about code elements at specific positions in files.

Resource URI format:
```
lsp-hover:///path/to/file?line={line}&column={column}&language_id={language_id}
```

Parameters:
- `line`: Line number (1-based)
- `column`: Column position (1-based)
- `language_id`: The programming language (e.g., "haskell")

Example:
```
lsp-hover:///home/user/project/src/Main.hs?line=42&column=10&language_id=haskell
```

### Code Completion Resources

The server exposes code completion suggestions via the `lsp-completions://` resource scheme. This allows you to get completion candidates at specific positions in files.

Resource URI format:
```
lsp-completions:///path/to/file?line={line}&column={column}&language_id={language_id}
```

Parameters:
- `line`: Line number (1-based)
- `column`: Column position (1-based)
- `language_id`: The programming language (e.g., "haskell")

Example:
```
lsp-completions:///home/user/project/src/Main.hs?line=42&column=10&language_id=haskell
```

### Listing Available Resources

To discover available resources, use the MCP `resources/list` endpoint. The response will include all available resources for currently open files, including:
- Diagnostics resources for all open files
- Hover information templates for all open files
- Code completion templates for all open files

### Subscribing to Resource Updates

Diagnostic resources support subscriptions to receive real-time updates when diagnostics change (e.g., when files are modified and new errors or warnings appear). Subscribe to diagnostic resources using the MCP `resources/subscribe` endpoint.

Note: Hover and completion resources don't support subscriptions as they represent point-in-time queries.

### Working with Resources vs. Tools

You can choose between two approaches for accessing LSP features:

1. Tool-based approach: Use the `get_diagnostics`, `get_info_on_location`, and `get_completions` tools for a simple, direct way to fetch information.
2. Resource-based approach: Use the `lsp-diagnostics://`, `lsp-hover://`, and `lsp-completions://` resources for a more RESTful approach.

Both approaches provide the same data in the same format and enforce the same requirement that files must be opened first.


## Troubleshooting

- If the server fails to start, make sure the path to the LSP executable is correct
- Check the log file (if configured) for detailed error messages

## License

MIT License



## Extensions

The LSP-MCP server supports language-specific extensions that enhance its capabilities for different programming languages. Extensions can provide:

- Custom LSP-specific tools and functionality
- Language-specific resource handlers and templates
- Specialized prompts for language-related tasks
- Custom subscription handlers for real-time data

### Available Extensions

Currently, the following extensions are available:

- **Haskell**: Provides specialized prompts for Haskell development, including typed-hole exploration guidance

### Using Extensions

Extensions are loaded automatically when you specify a language ID when starting the server:

```
npx tritlo/lsp-mcp haskell /path/to/haskell-language-server-wrapper lsp
```

### Extension Namespacing

All extension-provided features are namespaced with the language ID. For example, the Haskell extension's typed-hole prompt is available as `haskell.typed-hole-use`.

### Creating New Extensions

To create a new extension:

1. Create a new TypeScript file in `src/extensions/` named after your language (e.g., `typescript.ts`)
2. Implement the Extension interface with any of these optional functions:
   - `getToolHandlers()`: Provide custom tool implementations
   - `getToolDefinitions()`: Define custom tools in the MCP API
   - `getResourceHandlers()`: Implement custom resource handlers
   - `getSubscriptionHandlers()`: Implement custom subscription handlers
   - `getUnsubscriptionHandlers()`: Implement custom unsubscription handlers
   - `getResourceTemplates()`: Define custom resource templates
   - `getPromptDefinitions()`: Define custom prompts for language tasks
   - `getPromptHandlers()`: Implement custom prompt handlers

3. Export your implementation functions

The extension system will automatically load your extension when the matching language ID is specified.

## Acknowledgments

- HLS team for the Language Server Protocol implementation
- Anthropic for the Model Context Protocol specification