Go语言语义分析服务

gopls-mcp是一个基于Go语言服务器的语义分析工具,提供符号解析、引用跟踪和类型感知导航等功能,适用于Go代码的深度理解和重构。

  • by averycrespi
  • Go
  • 本地部署
  • 更新于
在 GitHub 查看 averycrespi/gopls-mcp

使用说明

gopls mcp

一个MCP(模型上下文协议)服务器,它公开了 gopls 语言服务器。


⚠️ 警告:此项目正在积极开发中。重大变更可能会发布,恕不另行通知。

⚠️ 警告:MCP服务器以完全文件系统访问权限执行,可以运行任意命令。仅使用受信任的服务器,并在安装前检查代码。此服务器执行gopls并读取指定工作区内的Go源文件。

目的

使用Go代码需要理解其语义结构,而不仅仅是文本模式。传统的基于文本的操作,如grep和find,不足以用于Go开发,因为:

  • 语义理解:Go符号具有上下文相关的含义。函数名称 Add 可以跨包引用不同的函数、不同类型的方法,甚至变量。
  • 精确度:文本搜索返回误报,并忽略了语义关系,如接口实现、类型别名和嵌入式字段。
  • 范围意识:Go的作用域规则(包、函数、块)决定了文本搜索无法理解的符号可见性和含义。
  • 类型信息Go的类型系统提供了丰富的元数据(方法、字段、接口),这对代码导航和理解至关重要。

gopls-mcp通过利用Go语言服务器的语义分析功能弥合了这一差距:

  • 符号分辨率:查找精确的符号定义,而不仅仅是文本匹配
  • 参考跟踪:标识对符号的所有实际引用,不包括误报
  • 层次结构:了解Go的包/类型/方法层次结构
  • 类型感知导航:遵循Go符号之间的语义关系

这使得LLM能够像IDE一样处理Go代码——具有完全的语义理解,而不是模式匹配。

工具

工具 目的 输入 输出
list_symbols_in_file 列出Go文件中具有层次结构的所有符号 file_path, limit, include_hover 文件符号的分层列表
find_symbol_definitions_by_name 使用模糊搜索按名称查找符号定义 symbol_name, limit, include_hover 与名称模糊匹配的符号定义列表
find_symbol_references_by_anchor 查找特定符号实例的所有引用 symbol_anchor, limit 锚的符号参考列表
(WIP) rename_symbol_by_anchor 在整个工作区重命名符号 symbol_anchor, new_name 每个文件的名称更改列表(旧→新

所有工具都返回结构化的JSON响应,其中包含精确的位置信息和用于消歧的符号锚点。

安装

先决条件

  • 转到1.23或更高版本
  • gopls(Go语言服务器)-通常与 go install golang.org/x/tools/gopls@latest

直接运行(推荐)

go run github.com/averycrespi/gopls-mcp@latest

从源代码构建

git clone https://github.com/averycrespi/gopls-mcp
cd gopls-mcp
make build

用法

命令行选项

./bin/gopls-mcp [flags]

Flags:
      --gopls-path string       Path to the gopls binary (default "gopls")
      --log-level string        Log level (debug, info, warn, error) (default "info")
      --workspace-root string   Root directory of the Go workspace (default ".")
  -h, --help                    help for gopls-mcp

MCP客户端集成

服务器使用MCP协议通过stdin/stdout进行通信。它可以与任何兼容MCP的客户端集成。

Claude代码集成

将服务器添加到Claude Code:

claude mcp add gopls-mcp go run github.com/averycrespi/gopls-mcp@latest

手动配置

配置示例:

{
  "mcpServers": {
    "gopls-mcp": {
      "command": "go run github.com/averycrespi/gopls-mcp@latest",
      "args": []
    }
  }
}

可用的MCP工具

所有工具都返回结构化的JSON响应,便于编程使用。

注:符号锚

符号锚点提供了一种精确的方法来识别Go代码中的特定符号实例。他们使用以下格式:

go://FILE#LINE:CHAR

哪里:

  • FILE:从工作区根目录到文件的相对路径
  • LINE:显示行号(从1开始,匹配编辑器显示)
  • CHAR:显示字符位置(从1开始,匹配编辑器显示)

例子: go://calculator.go#6:6

锚点使用与您在编辑器中看到的内容匹配的显示坐标。它们包含在所有符号结果中,当多个符号共享同一名称时,可以无歧义地进行精确的参考查找。

工具:查找_符号_定义_名称

在Go工作区中按名称查找符号的定义,通过模糊搜索返回符号定义列表。

参数:

  • symbol_name (字符串,必填):用于查找定义的符号名称,具有模糊匹配
  • limit (number,可选):要返回的最大符号定义数(默认值:50)
  • include_hover (布尔值,可选):是否包含符号的悬停信息(默认值:false)

答复: JSON对象包含:

  • message:关于结果的摘要消息(例如,“在Go工作区中找到3个符号定义。”或“在Go工作区中找不到符号定义”。)
  • arguments:输入参数回显为:
    • symbol_name:搜索到的符号名称
    • limit:最大结果数(如果指定)
    • include_hover:是否包括悬停信息(如果指定)
  • definitions:符号定义对象数组(可能为空),每个对象包含:
    • name:符号名称
    • kind:符号类型(函数、结构、方法等)
    • location:文件路径、行和字符位置
    • anchor:格式中的符号锚点 go://FILE#LINE:CHAR (显示坐标)
    • hover_info:从语言服务器悬停信息(仅在以下情况下包含 include_hover 是真的)

工具:列表_符号_文件

列出Go文件中的所有符号,返回具有层次结构的符号列表。

参数:

  • file_path (string,必填):Go文件的路径
  • limit (数字,可选):返回的最大符号数(默认值:100)
  • include_hover (布尔值,可选):是否包含符号的悬停信息(默认值:false)

答复: JSON对象包含:

  • message:关于结果的摘要消息(例如,“在文件中找到8个符号。”或“在文件里找不到符号。”)
  • arguments:输入参数回显为:
    • file_path:分析文件的路径
    • limit:最大结果数(如果指定)
    • include_hover:是否包括悬停信息(如果指定)
  • file_symbols:文件符号对象数组(可能为空),每个对象包含:
    • name:符号名称
    • kind:符号类型(函数、结构、方法等)
    • location:文件路径、行和字符位置
    • anchor:格式中的符号锚点 go://FILE#LINE:CHAR (显示坐标)
    • hover_info:从语言服务器悬停信息(仅在以下情况下包含 include_hover 是真的)
    • children:子符号数组(用于具有字段、方法等的结构等层次符号)

该工具为Go符号提供了完整的层次结构支持。例如:

  • 结构符号包括它们的子字段和方法
  • 接口符号包括它们作为子对象的方法签名
  • 函数符号可能包含嵌套函数声明作为子函数

这种层次结构由LSP客户端启用 hierarchicalDocumentSymbolSupport 能力。

工具:find_symbol_references_by_anchor

通过符号在Go工作区中的精确锚点位置查找对符号的所有引用。

参数:

  • symbol_anchor (字符串,必填):格式中的符号锚点 go://FILE#LINE:CHAR (显示坐标)
  • limit (number,可选):要返回的最大符号引用数(默认值:100)

答复: JSON对象包含:

  • message:关于结果的摘要消息(例如,“找到了符号锚点的8个引用。”或“没有找到符号锚点的引用。”)
  • arguments:输入参数回显为:
    • symbol_anchor:用于搜索的输入符号锚点
    • limit:最大结果数(如果指定)
  • references:引用对象数组,每个对象包含:
    • location:参考位置:
      • file:工作区根目录的相对文件路径
      • line:显示行号(从1开始,匹配编辑器显示)
      • character:显示字符位置(从1开始,匹配编辑器显示)
    • anchor:此特定参考位置的符号锚点格式 go://FILE#LINE:CHAR

注: 该工具需要从输出中精确定位 find_symbol_definitions_by_name 或 list_symbols_in_file 用于识别确切符号实例的工具。

工具:重命名_符号_by_anchor

通过符号在整个Go工作空间中的精确锚点位置重命名符号。

参数:

  • symbol_anchor (string):格式中的符号锚点 go://FILE#LINE:CHAR (显示坐标)
  • new_name (string):符号的新名称(必须是有效的Go标识符)

答复: JSON对象包含:

  • message:关于结果的摘要消息(例如,“已成功将符号重命名为'NewName',在3个文件中进行了5次编辑。”)
  • arguments:输入参数回显为:
    • symbol_anchor:用于重命名的输入符号锚点
    • new_name:符号的新名称
  • file_edits:文件编辑对象数组(可能为空),每个对象包含:
    • file:工作区根目录的相对文件路径
    • edits:编辑对象数组,每个对象具有:
      • start_line:显示编辑开始处的行号(1-索引)
      • start_character:显示编辑开始的字符位置(1-索引)
      • end_line:显示编辑结束处的行号(1-索引)
      • end_character:显示编辑结束的字符位置(1-索引)
      • old_text:文本被替换
      • new_text:替换文本

笔记:

  • 此工具使用gopls的重命名功能,其中包括验证以防止破坏更改
  • 如果重命名会引入编译错误,则重命名将失败
  • Go关键字不能用作新名称
  • 该工具首先执行prepareName检查,以确保重命名有效

发展

有关架构、设计模式和开发指南的详细信息,请参阅 开发商.md.

相关项目

许可证

麻省理工学院