1. 项目概述:当LSP遇上MCP,一场开发工具链的“协议融合”
如果你是一名长期与IDE打交道的开发者,无论是写Java、TypeScript还是其他语言,大概率都听说过或者用过语言服务器协议。它让VS Code、IntelliJ IDEA这些编辑器能理解代码、提供智能提示,背后就是LSP在默默工作。而MCP,可能对很多人来说还是个新面孔,它全称是Model Context Protocol,是Anthropic提出的一套旨在让大语言模型能安全、结构化地访问外部工具和数据的协议。那么,当这两个分别服务于“机器理解代码”和“模型理解世界”的协议,通过stephanj/LSP4J-MCP这个项目碰撞在一起时,会发生什么?
简单来说,这个项目构建了一座桥梁。它允许一个实现了LSP的语言服务器,摇身一变,成为一个MCP服务器。这意味着,任何支持MCP的客户端(比如Claude Desktop、Cursor编辑器,或者其他集成了MCP SDK的应用),现在可以直接“询问”这个语言服务器关于代码的问题,或者调用它提供的代码分析、重构等能力。想象一下,你在与AI助手对话时,可以直接说“帮我把这个Java类里的所有public方法文档补全”,AI助手通过MCP调用背后的Java语言服务器,精准地完成操作,而不是自己“瞎猜”代码结构——这就是LSP4J-MCP带来的可能性。
它的核心价值在于能力复用与生态连接。全球有上百个活跃的LSP实现,覆盖了几乎所有主流和小众编程语言,它们经过了多年实战打磨,对代码的语法、语义分析能力极其强大且准确。LSP4J-MCP没有重新发明轮子,而是巧妙地将这些现成的、可靠的能力,暴露给了方兴未艾的AI应用生态。对于工具开发者,可以用一套代码(基于LSP4J)同时服务传统IDE和AI智能体;对于AI应用开发者,则获得了一个庞大、高质量的工具箱,无需从零开始为每种语言构建分析器。
2. 核心架构与设计思路拆解
2.1 协议桥梁:LSP与MCP的异同与映射
要理解这个项目,首先得看清LSP和MCP在设计目标上的根本差异,以及LSP4J-MCP是如何在它们之间进行“翻译”的。
LSP的核心是编辑器与语言服务器之间的双向通信。它定义了一套标准的JSON-RPC消息,用于代码补全、跳转到定义、查找引用、重命名、诊断错误等。通信模型是“请求-响应”和“通知”。例如,编辑器发送textDocument/completion请求,语言服务器返回补全项列表;语言服务器可以主动发送textDocument/publishDiagnostics通知,告诉编辑器哪些行有错误或警告。它的上下文高度依赖于一个或多个已经打开的文件。
MCP的核心是大语言模型与工具之间的安全交互。它定义了一套让模型发现、调用工具的协议。一个MCP服务器会向客户端宣告自己提供了哪些“工具”(可以理解为函数),每个工具有什么参数。模型(或AI应用)根据需要,选择调用某个工具,并传入参数,然后获取结构化的结果。MCP更强调工具的“描述性”和“安全性”,工具的参数和返回值都有明确的模式定义。
LSP4J-MCP项目的设计智慧,就在于它没有尝试把整个LSP协议机械地翻译成MCP。那样会过于复杂且低效。它采取了一种更实用的策略:将LSP的某些核心能力,封装成一个个独立的、描述清晰的MCP工具。
例如:
textDocument/completion这个LSP请求,可以被映射为一个名为get_completions的MCP工具。调用时需要传入文件路径、文件内容、光标位置等参数。textDocument/definition可以被映射为goto_definition工具。textDocument/references可以被映射为find_references工具。
项目内部维护了一个LSP客户端,连接到目标语言服务器。当MCP客户端调用某个工具时,LSP4J-MCP桥接器就将参数转换为LSP请求发送给语言服务器,再将LSP的响应转换为MCP工具的结果返回。这相当于为语言服务器套上了一个MCP兼容的“外壳”。
2.2 技术选型:为什么是LSP4J?
Java生态中有多个LSP实现库,比如Eclipse LSP4J和微软的lsp4j(该项目似乎基于后者)。选择LSP4J作为基础是经过考量的:
- 成熟度与生态:LSP4J是Eclipse基金会下的项目,历史悠久,被广泛应用于Eclipse IDE、Eclipse Che、Microsoft的Java语言服务器等众多重量级产品中,其稳定性和协议覆盖完整性经过充分验证。
- 协议完整性:它完整实现了LSP协议规范,包括所有主流请求、通知和数据类型,为桥接器提供了坚实的功能基础。
- 异步与并发模型:LSP4J基于
CompletableFuture等现代Java并发构建,天生支持异步非阻塞IO,这对于需要同时处理多个MCP工具请求的场景至关重要,能有效避免阻塞,提升吞吐量。 - 可扩展性:其模块化设计使得桥接器可以相对容易地选择需要暴露的LSP能力,而不是必须暴露全部。这对于构建一个轻量、专注的MCP服务器很有帮助。
注意:这里存在一个潜在的命名混淆。Eclipse的项目叫
Eclipse LSP4J,而GitHub上有一个lsp4j的组织。根据项目名stephanj/LSP4J-MCP,它很可能直接使用了lsp4j这个库。在实际使用或贡献代码前,需要仔细查看其pom.xml或build.gradle文件来确认具体的依赖。
2.3 桥接器的核心职责
这个项目的核心是一个“桥接器”(Bridge)或“适配器”(Adapter)。它的主要职责可以分解为:
- MCP服务器实现:实现MCP协议规定的服务器端,能够响应客户端的
initialize、tools/list、tools/call等请求。 - LSP客户端实现:作为一个LSP客户端,能够连接到指定的语言服务器(例如Java语言服务器、Python的
pylsp等),并管理连接的生命周期。 - 协议转换器:
- 工具发现:将语言服务器支持的能力(通过LSP的
initialize响应和client/registerCapability得知),动态或静态地转换为一组MCP工具描述。例如,如果语言服务器声明支持completionProvider,桥接器就注册一个get_completions的MCP工具。 - 请求转发:将MCP工具调用(包含文件URI、位置、查询文本等参数)转换为对应的LSP请求消息。
- 响应适配:将LSP的响应(可能是复杂的嵌套对象)转换为MCP工具要求的、更适合LLM理解的结构化数据(通常是更扁平化的JSON)。
- 工具发现:将语言服务器支持的能力(通过LSP的
- 会话与状态管理:管理MCP会话和LSP会话的对应关系,可能还需要维护文件的虚拟文档状态(因为MCP调用可能不基于一个已打开的IDE文档)。
3. 实操部署与核心配置解析
3.1 环境准备与项目构建
假设我们要将一个现成的Java语言服务器通过LSP4J-MCP暴露为MCP服务。以下是详细的步骤:
第一步:获取与构建桥接器
# 克隆项目 git clone https://github.com/stephanj/LSP4J-MCP.git cd LSP4J-MCP # 项目很可能使用Maven或Gradle构建,以Maven为例 mvn clean package构建成功后,你会在target目录下得到一个可执行的JAR文件,例如lsp4j-mcp-bridge-1.0.0-SNAPSHOT.jar。这个JAR包包含了桥接器所有依赖,可以直接运行。
第二步:准备目标语言服务器你需要一个实现了LSP的语言服务器。以Eclipse JDT Language Server为例,你可以直接下载其发行版,或者如果你有Eclipse IDE,它内部就集成了。为了简单,我们假设你有一个可以独立启动的JAR,比如jdt-language-server-xxx.jar,它启动后会监听某个端口(如8080)或通过stdio通信。
第三步:配置桥接器桥接器需要一个配置文件来知道如何连接语言服务器。通常,这会是一个JSON或YAML文件。我们需要创建一个config.json:
{ "lspServer": { "command": "java", "args": [ "-jar", "/path/to/your/jdt-language-server-xxx.jar", "-configuration", "/path/to/configuration_dir", "-data", "/path/to/workspace_dir" ], "transport": "stdio" // 也可以是 "socket",如果语言服务器监听端口 }, "mcp": { "serverName": "Java Language Server (via LSP4J-MCP)", "serverVersion": "1.0.0", "tools": [ { "name": "get_completions", "description": "Get code completion items at a given position in a Java file.", "inputSchema": { "type": "object", "properties": { "fileUri": { "type": "string", "description": "The URI of the Java file." }, "fileContent": { "type": "string", "description": "The full content of the file." }, "line": { "type": "integer", "description": "0-based line number." }, "character": { "type": "integer", "description": "0-based character offset in line." } }, "required": ["fileUri", "fileContent", "line", "character"] } }, { "name": "goto_definition", "description": "Go to the definition of the symbol at the given position.", "inputSchema": { ... } // 类似定义 } // ... 可以暴露更多工具,如 find_references, format_document, rename_symbol 等 ] } }在这个配置中:
lspServer部分定义了如何启动和与语言服务器通信。stdio是最常见的方式,桥接器会启动这个命令行进程,并通过标准输入输出与其通信。mcp部分定义了MCP服务器的元信息和要暴露的工具列表。每个工具都需要明确定义其输入参数的JSON Schema,这对于MCP客户端(如AI)安全、正确地调用工具至关重要。
实操心得:配置
args时,务必查阅目标语言服务器的文档,了解其正确的启动参数。特别是-configuration和-data目录,它们分别用于存放服务器配置和工作空间数据,如果路径不正确或权限不足,语言服务器可能无法正常启动或工作。
3.2 启动桥接器与MCP客户端连接
启动桥接器:
java -jar /path/to/lsp4j-mcp-bridge-xxx.jar --config /path/to/config.json如果一切正常,桥接器会启动,同时它会根据配置启动Java语言服务器进程。桥接器本身会作为一个MCP服务器,默认可能监听在某个端口(例如8081),或者通过stdio等待MCP客户端连接。
连接MCP客户端(以Claude Desktop为例):
- 找到Claude Desktop的MCP服务器配置目录。通常在
~/Library/Application Support/Claude/claude_desktop_config.json(macOS) 或%APPDATA%\Claude\claude_desktop_config.json(Windows)。 - 编辑该JSON文件,添加你的桥接器作为MCP服务器。配置方式取决于桥接器提供的连接方式(stdio或socket)。假设是stdio:
{ "mcpServers": { "java-lsp": { "command": "java", "args": [ "-jar", "/absolute/path/to/lsp4j-mcp-bridge-xxx.jar", "--config", "/absolute/path/to/config.json" ] } } }- 重启Claude Desktop。在对话中,你应该能通过特定的命令(如
/tools)看到新注册的get_completions、goto_definition等工具。
测试工具调用:你可以在Claude Desktop中尝试这样的对话:
“我有一个Java文件,内容如下:
public class Test { public static void main(String[] args) { List<String> list = new ArrayList<>(); list. } }光标在
list.后面(第4行,第14个字符)。请调用get_completions工具,看看能补全哪些方法。”
理论上,AI助手会理解你的请求,构造正确的参数调用MCP工具,并将返回的补全列表(如add,get,size等)呈现给你。
3.3 关键配置参数深度解析
要让桥接器稳定高效地工作,以下几个配置项需要特别关注:
LSP传输层 (
transport):stdio:最常用,桥接器以子进程方式启动语言服务器,通过管道通信。好处是部署简单,无需管理网络端口。但要注意:需要确保语言服务器的日志输出不会污染通信通道(有些服务器会向stderr打印日志,需要被妥善处理或重定向)。socket:语言服务器独立运行并监听端口,桥接器以网络客户端方式连接。好处是语言服务器进程生命周期独立,便于调试。需要额外配置host和port。
工具暴露策略:在
config.json的mcp.tools数组里,你不需要暴露语言服务器所有的LSP能力。只暴露那些对AI助手最有用的、最稳定的。例如,代码补全(completion)、跳转定义(definition)、查找引用(references)、文档符号(documentSymbol)是非常有用的。而像代码格式化(formatting)、重构(rename)等可能涉及更复杂的上下文和副作用,需要谨慎评估。输入参数映射:MCP工具的输入参数需要精心设计。LSP请求通常需要
TextDocumentIdentifier和Position。在MCP工具中,我们将其拆解为fileUri、fileContent、line、character。这里有一个关键决策点:是传递fileContent还是让桥接器/语言服务器自己去读取文件?- 传递
fileContent:更安全、更符合无状态服务的设计。MCP客户端负责提供文件的最新内容。这对于AI助手正在编辑但尚未保存的代码片段场景非常合适。 - 基于
fileUri读取:要求桥接器能访问到实际文件系统路径。这在某些受控环境(如容器内)可能可行,但限制了灵活性,且可能引发路径安全和一致性问题。推荐使用传递fileContent的方式,它更通用,也是大多数类似桥接器的选择。
- 传递
超时与错误处理:需要在配置或代码中为LSP请求设置合理的超时时间。语言服务器分析大型项目时可能较慢,超时设置过短会导致工具调用频繁失败;设置过长则会让AI助手等待太久。建议初始设置为10-15秒,并根据实际性能调整。
4. 核心功能实现与协议转换细节
4.1 工具动态注册与能力协商
一个高级的实现不会在配置文件中静态写死所有工具,而是根据实际连接的语言服务器能力进行动态注册。这是更健壮和灵活的方式。
桥接器启动并连接到语言服务器后,第一件事是发送LSP的initialize请求。语言服务器的响应中会包含一个capabilities字段,详细说明了它支持哪些功能(如completionProvider、definitionProvider为true)。
桥接器可以解析这个capabilities对象,然后动态地向MCP客户端注册对应的工具。例如:
- 检测到
capabilities.completionProvider存在,则注册get_completions工具。 - 检测到
capabilities.definitionProvider为true,则注册goto_definition工具。 - 检测到
capabilities.referencesProvider为true,则注册find_references工具。
这种动态方式的好处是:
- 适应性:同一个桥接器可以用于不同的语言服务器,无需修改配置。
- 准确性:暴露的工具集与后端能力完全匹配,避免调用不支持的功能导致错误。
- 可维护性:当语言服务器升级,新增能力时,桥接器能自动发现并暴露新工具。
实现动态注册的关键在于,桥接器在实现MCP的initialize握手阶段,需要根据已获取的LSP能力信息,构造并返回完整的工具列表。
4.2 请求参数转换与上下文管理
当MCP客户端调用get_completions工具时,桥接器收到如下的调用请求:
{ "tool": "get_completions", "arguments": { "fileUri": "file:///project/src/Test.java", "fileContent": "public class Test {... list. }", "line": 3, "character": 14 } }桥接器需要将其转换为LSP的textDocument/completion请求。转换过程涉及几个关键步骤:
- 构建TextDocumentIdentifier:LSP请求需要
textDocument.uri。这里直接使用传入的fileUri。 - 构建Position对象:LSP使用0-based的
line和character,这与传入的参数一致。 - 处理文档状态:这是最复杂的部分。LSP协议通常假设编辑器维护着文档的打开状态,并通过
textDocument/didOpen、textDocument/didChange等通知来同步内容。但在MCP调用场景,我们每次调用可能对应一个“瞬态”的文档内容。- 简单策略:每次工具调用都视为一个全新的文档。桥接器在发送
completion请求前,先模拟发送一个textDocument/didOpen通知,将fileContent作为文档内容发送给语言服务器。收到结果后,再发送textDocument/didClose。这种方式逻辑简单,但每次调用都有开销,且语言服务器无法利用之前的分析缓存。 - 优化策略:桥接器在内部维护一个虚拟的文档集合(
VirtualDocumentManager)。对于同一个fileUri,如果fileContent发生了变化,则发送textDocument/didChange通知进行更新;如果内容没变,则复用已有的文档状态。这能显著提升性能,尤其是对同一文件的连续操作(如多次补全请求)。但实现更复杂,需要管理文档版本和生命周期。
- 简单策略:每次工具调用都视为一个全新的文档。桥接器在发送
对于LSP4J-MCP这样的项目,采用简单策略作为起点是合理的,因为它实现起来更直接,且保证了每次调用的独立性,避免了状态残留导致的潜在问题。在性能成为瓶颈时,再考虑引入虚拟文档管理。
4.3 响应结果适配与标准化
语言服务器返回的补全结果可能非常丰富。一个LSP的CompletionItem可能包含label、kind、detail、documentation、insertText、textEdit等字段。其中documentation可能是Markdown字符串,textEdit是一个复杂的编辑指令。
直接将这些原始数据扔给AI助手可能信息过载或格式不适配。因此,桥接器需要做结果适配:
信息筛选与扁平化:提取对AI最有用的核心信息。例如,对于补全结果,可以构造一个更简单的列表:
[ { "label": "add(E e)", "detail": "boolean - java.util.List", "documentation": "Appends the specified element to the end of this list." }, ... ]去掉了
kind(图标类型)、textEdit(编辑细节)等对纯文本对话模型不那么关键的字段。文档格式化:将
documentation从可能的Markdown转换为纯文本,或者保留Markdown但确保其格式在AI助手的回复中能正确渲染。错误处理标准化:将LSP通信错误、语言服务器内部错误,统一转换为MCP协议定义的标准错误格式,包含清晰的错误码和消息,方便MCP客户端处理。
这个适配层是提升AI助手使用体验的关键。它决定了AI看到的工具返回结果是清晰易懂的“答案”,还是一堆需要它再次解析的“原始数据”。
5. 性能优化与高级应用场景
5.1 连接池与会话复用
在真实的生产或高频使用场景下,为每一个MCP工具调用都创建新的LSP连接(即启动一个新的语言服务器进程)是灾难性的,因为语言服务器启动和初始化项目通常很慢。
因此,桥接器必须实现LSP连接池或长连接会话复用。
- 连接池:维护一个固定数量的、已初始化好的LSP连接。当MCP工具调用到来时,从池中取出一个空闲连接使用,用完归还。这适用于无状态或轻状态的语言服务器。
- 会话复用:对于一个MCP客户端(例如一个长期的Claude对话会话),维持一个持久的LSP连接和会话状态。在这个会话中,所有针对同一工作空间(workspace)的工具调用都共享同一个语言服务器实例,从而能充分利用其缓存和索引,性能最优。这需要桥接器能关联MCP客户端ID和LSP会话。
LSP4J-MCP项目如果面向重度使用,采用会话复用模式是更优的。这需要在MCP的initialize请求中携带某种工作空间标识,桥接器根据该标识查找或创建对应的LSP连接。
5.2 支持复杂LSP操作:代码操作与重构
除了查询类操作(补全、跳转),LSP还支持有副作用的操作,如textDocument/rename(重命名符号)、textDocument/codeAction(代码操作,如生成getter/setter)、workspace/executeCommand(执行自定义命令)。
将这些暴露为MCP工具需要格外小心,因为它们会修改代码。
安全执行模式:
- 预览与确认:工具调用不直接执行修改,而是返回一个“编辑预览”(一个
WorkspaceEdit对象,描述将要进行的更改)。MCP客户端(AI助手)将这个预览呈现给用户,由用户确认后再执行。 - 沙盒环境:在独立的、临时的工作空间副本中执行修改操作,确保不会影响用户的原始代码。
例如,可以设计一个get_rename_preview工具,它返回重命名的影响范围和新的代码片段,而不是直接重命名。
实现挑战:这类操作往往需要更精确的上下文,比如codeAction通常是在某个诊断错误(Diagnostic)的上下文中触发。桥接器需要将更丰富的上下文信息通过MCP工具参数传递下去。
5.3 多语言服务器路由
一个更强大的桥接器可以同时连接多个不同类型的语言服务器(Java、Python、Go等),并充当一个智能路由器。
当MCP客户端调用工具时,桥接器需要根据fileUri的后缀(.java,.py,.go)或者文件内容,将请求路由到对应的语言服务器。
这要求桥接器:
- 维护一个从“文件模式/语言ID”到“LSP连接”的映射表。
- 在工具调用时,根据输入参数中的
fileUri或fileContent推断目标语言。 - 实现一个通用的、与语言无关的MCP工具集(如
get_completions),在内部进行路由和协议转换。
这样,对于AI助手来说,它只需要知道一套统一的工具接口(get_completions),就可以对多种编程语言进行代码智能操作,体验是无缝的。这是LSP4J-MCP项目一个非常诱人的演进方向。
6. 常见问题、排查技巧与实战心得
在实际部署和使用LSP4J-MCP这类桥接器时,你会遇到各种问题。下面是我在类似集成项目中踩过的一些坑和总结的技巧。
6.1 连接与启动故障排查
问题1:桥接器启动失败,报错“无法启动语言服务器进程”。
- 排查步骤:
- 检查命令路径:确认
config.json中lspServer.command的路径是否正确。在服务器环境下,java可能不在默认PATH中,需要使用绝对路径,如/usr/bin/java。 - 检查参数:手动在终端执行配置中的完整命令,看语言服务器是否能独立启动。例如:
java -jar /path/to/language-server.jar -arg1 val1 ...。观察是否有缺失依赖、权限错误或端口冲突。 - 检查工作目录:桥接器启动子进程时的工作目录可能影响语言服务器寻找配置文件或依赖。尝试在
lspServer配置中增加"cwd": "/path/to/working/directory"。 - 查看日志:桥接器应该提供日志输出,查看更详细的错误信息。确保语言服务器的错误输出(stderr)没有被忽略,它通常包含关键的启动失败原因。
- 检查命令路径:确认
问题2:MCP客户端(如Claude Desktop)连接桥接器成功,但看不到任何工具。
- 排查步骤:
- 检查MCP握手:确认桥接器是否正确实现了MCP的
initialize和tools/list协议。可以使用一个简单的MCP客户端测试工具(如mcp-clientCLI)直接连接桥接器,查看原始协议消息。 - 检查工具注册逻辑:如果使用动态注册,确认桥接器是否成功从语言服务器获取了
capabilities,并正确解析和转换成了MCP工具描述。 - 检查配置:如果使用静态配置,确认
config.json中mcp.tools数组的格式完全符合MCP协议对工具定义的规范,特别是inputSchema部分。
- 检查MCP握手:确认桥接器是否正确实现了MCP的
6.2 工具调用错误与性能问题
问题3:调用get_completions工具超时或无结果。
- 排查步骤:
- 参数验证:首先确认传入的
line和character参数是0-based的,并且没有越界。检查fileContent是否包含了光标所在行的完整内容。 - 语言服务器状态:确认语言服务器进程是否还活着,是否因为分析大型项目而卡死。查看桥接器和语言服务器的日志,看是否有错误或警告。
- 模拟LSP请求:使用LSP客户端工具(如
lsp-cli或VS Code的LSP日志)直接向语言服务器发送相同的textDocument/completion请求,看是否能正常返回。这可以隔离出是桥接器转换的问题,还是语言服务器本身的问题。 - 虚拟文档问题:如果你实现了虚拟文档管理,检查是否为本次调用正确打开了文档或同步了最新内容。一个常见的错误是文档URI不匹配或版本未更新。
- 参数验证:首先确认传入的
问题4:工具调用响应慢,尤其是第一次调用。
- 原因与优化:
- 语言服务器冷启动:这是最大的延迟来源。解决方案就是前面提到的连接池或会话复用,避免每次调用都重启语言服务器。
- 项目初始化:Java/Python等语言服务器在打开工作空间时需要构建索引,这可能耗时几分钟。考虑让桥接器在启动后预初始化一个“就绪”的连接。
- 网络延迟:如果使用
socket传输,确保桥接器与语言服务器在同一低延迟网络内。 - 结果处理过载:如果语言服务器返回了成千上万个补全项,桥接器的结果适配和序列化可能成为瓶颈。可以考虑在桥接器层面进行结果截断(例如,只返回前50个最相关的项)。
6.3 安全与稳定性考量
安全建议:
- 输入消毒:对MCP客户端传入的
fileUri和fileContent进行严格的验证和消毒,防止路径遍历攻击或恶意代码内容导致语言服务器异常。 - 资源限制:为每个LSP连接设置内存和CPU使用上限,防止语言服务器分析超大型文件时耗尽资源。
- 超时控制:为所有LSP请求设置严格的超时,并在超时后能安全地终止请求,释放资源。
稳定性心得:
- 实现健康检查:桥接器应定期对LSP连接进行健康检查(例如发送一个简单的
shutdown请求?不,shutdown会关闭连接。更好的方法是发送workspace/symbol等轻量级请求),发现僵死连接及时重建。 - 完善的日志:在关键步骤(连接建立、工具调用、协议转换、错误发生)记录结构化日志,这是线上排查问题的生命线。日志中应包含请求ID,以便串联整个调用链。
- 优雅降级:如果某个语言服务器暂时不可用,桥接器应能优雅地处理,向MCP客户端返回明确的错误,而不是整体崩溃。对于多语言路由器,某个语言的失败不应影响其他语言。
6.4 对项目stephanj/LSP4J-MCP的实践展望
目前(根据项目名和描述推断),stephanj/LSP4J-MCP可能还是一个处于早期阶段的概念验证或基础实现。要将其用于生产环境,可能需要社区或使用者自己贡献以下关键特性:
- 动态工具注册:基于LSP能力发现,而非静态配置。
- 虚拟文档管理:实现简单的文档状态维护,提升连续操作性能。
- 连接管理:实现LSP连接池,支持配置连接数、超时和重试。
- 更丰富的工具集:逐步支持
codeAction、rename、formatting等高级操作,并设计好其安全调用模式。 - 配置化:提供更灵活的配置文件,允许用户指定语言服务器路径、启用的工具列表、超时时间、日志级别等。
这个项目的真正价值在于提供了一个清晰的架构蓝图和起点。通过它,开发者可以快速理解LSP与MCP协议转换的核心问题,并在此基础上构建出功能强大、稳定可靠的AI代码助手基础设施。随着MCP生态的成熟,这类桥接器很可能成为连接传统IDE智能与新一代AI应用的关键中间件。