关于 Periscope
Periscope 是 MCP 服务,可为编码 Agent 接入运行中的 Neovim 及其现有配置。它提供 LSP、格式化器、检查器和 DAP 信息,无需维护重复配置。
主要功能
- 01托管或附加 Neovim 模式
- 02LSP 定义、引用与诊断
- 03发现并运行格式化器和检查器
- 04列出 DAP 模块与配置
- 05Agent 焦点与协作看板
适用场景
- 01查询项目语言服务器信息
- 02运行已配置格式化且不写入文件
- 03检查已配置的检查器与诊断
- 04协调多个 Agent 对共享目标的关注
MCP 相关
Periscope 通过 stdio 与客户端进行 MCP 通信,并通过 msgpack-RPC 与 Neovim 通信。其工具可访问编辑器配置和语言服务、运行已配置的格式化与检查流程,并提供进程内注意力看板。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Periscope
一个 MCP 服务,可代理到运行中且使用你实际 Neovim 配置的 Neovim 实例,让 MCP 客户端(Agent)查询与你编辑时相同的语言服务、格式化器注册表、检查器注册表和 DAP 模块树——配置只有一个可信来源,无需重复配置服务,也无需转换配置文件。
Periscope 是一个独立的 Rust 二进制程序。它通过 stdio(NDJSON JSON-RPC)与客户端通信,并通过 msgpack-RPC 与 Neovim 通信。
运行方式
- 托管模式(默认):启动自己的
nvim --headless --listen <tmp socket>,并将 cwd 设为 工作区。你的配置会按你平时使用时的方式加载;代理程序不会触碰你的交互式编辑器。拒绝执行项目本地配置 (--cmd "set noexrc")。 - 附加模式(
--attach <socket>):连接到你已在运行的 Neovim (任何使用--listen启动的实例)。代理程序绝不会向它未启动的编辑器发送信号或将其关闭。
工具是通过 nvim_exec_lua 在编辑器内执行的小型 Lua 程序。它们仅使用原生 API(vim.lsp、vim.diagnostic、运行时文件),并继承 lsp/*.lua
文件中的所有逐服务设置——包括有意做出的选择,例如禁用 rust-analyzer 的原生诊断,改用 bacon-ls。
工具
只读智能功能(broker_status、get_*、list_*),以及两个执行工具(run_format、run_lint),可在编辑器内运行配置自己的流水线。格式化会应用到代理编辑器的缓冲区,并以文本形式返回——绝不会写入磁盘文件(written 始终为 false;写入磁盘的工具将在后续阶段推出,并需通过显式启用标志开启)。Lint 仅进行读取。
四个 attention_* 工具用于由服务进程维护的联合注意力协调板(MATE 协议,vendored from phlow-attention):Agent 可发布有序关注列表、读取彼此的关注列表,并请求对齐评分或协调决策。协调板不会触碰编辑器或文件系统;发布内容会绑定到客户端在 initialize 时提供的身份。
| 工具 | 返回内容 |
|---|---|
attention_alignment | 你发布的关注焦点与合作 Agent 的关注焦点之间的匹配度,仅在同一显著性快照帧内测量(Jaccard 重叠度、共同目标、共同首要目标);跨帧时会拒绝请求 |
attention_decide | 针对合作 Agent 关注焦点的协调决策:parallel(无冲突)、serialize(首要目标相同——指定的持有者继续操作,你暂缓)或 reject(快照帧已过期或关注焦点无效——重新获取快照,绝不猜测) |
attention_focus | 从协调面板获取合作 Agent 当前公布的关注焦点(按顺序排列的显著目标,以及据此计算的快照哈希) |
attention_publish | 将你的关注焦点发布到协调面板:关注焦点文档 {agent_id, snapshot_hash, seq, targets[]}(最多 8 个目标);agent_id 必须与客户端身份一致,且序号必须严格递增 |
broker_status | 模式、Neovim 版本、当前工作目录、配置根目录 |
get_definition | 合并所有已连接客户端的定义位置 |
get_diagnostics | 来自 vim.diagnostic 的缓冲区诊断(LSP + linter 流程),每条记录都会注明生成它的 source |
get_document_symbols | 包含容器信息的扁平化符号大纲 |
get_hover | 指定位置的悬停文本 |
get_references | 合并所有已连接客户端的引用位置 |
list_dap | 配置树中的 DAP 模块,以及会话中注册的适配器/配置 |
list_formatters | 配置树中的 formatter 模块 |
list_linters | 配置树中的 linter 模块(以下划线开头的模块会标记为内部模块) |
list_servers | 树中配置的 LSP 服务,以及连接到任何已打开缓冲区的服务 |
run_format | 使用配置中的 formatter 流程(require('formatters'))格式化文件;可选指定 formatter 名称和 LSP 模式(fallback / never / only);返回状态、changed、运行过的步骤和格式化后的文本 |
run_lint | 使用配置中的 linter 运行器(require('linters'))检查文件;可选指定 linter 名称,否则使用文件类型对应的配置集合;返回每个 linter 的状态、退出代码和诊断(每条都会在 source 中注明对应的 linter) |
位置从 0 开始计数;character 按 UTF-16 代码单元计数(LSP 约定)。
LSP 请求工具会在编辑器中轮询,等待服务报告进行中的进度,因此冷启动的 rust-analyzer 会返回实际结果(小型项目约需 10 s),而不是快速返回空结果。
用法
periscope [--workspace <dir>] [--attach <socket>] [--nvim-bin <path>]
--workspace默认值为当前目录,也是托管编辑器的启动目录。- 在注册 MCP 服务的位置注册它;在 diver 中,这对应于
lua/ai/mcp/declared_servers.lua中的declared_servers条目:
periscope = {
args = { '--workspace', '/path/to/project' },
cmd = '/home/phaedrus/.local/bin/periscope',
kind = 'stdio',
name = 'periscope',
source = 'local',
timeout = 5000,
tools = 'all',
},
根据安装情况调整 cmd/args;删除 --workspace 参数项即可使用客户端的工作目录,或者使用 --attach <socket> 指向正在运行的编辑器。
预算与限制
所有等待和列表都有上限:编辑器连接 20 s,LSP 请求阶段 30 s(按进度门控轮询),诊断稳定等待 5 s,连接截止时间 10 s,VimEnter 就绪等待 20 s。结果上限:
每次调用最多 500 条诊断位置、1,000 个文档符号(深度 6)、500 个定义/引用位置;每行 MCP 输入最多 4 MiB。
编辑器返回的错误会转发,长度上限为 512 个字符。
工具失败会以内联 MCP isError 结果返回,而不是协议错误。
安全状况
仅使用 stdio 传输——不会监听网络端口。托管编辑器的套接字位于私有临时路径中,并会在关闭时删除;broker 会回收其子进程。没有工具会将文件写入磁盘、重命名文件或启动调试会话:格式化只会修改 broker 所管理的编辑器缓冲区,并以文本形式返回;attention 面板使用进程内存,服务退出时即会丢弃。
路线图
- P2(已完成):通过配置自身的管道执行格式化程序和代码检查工具(`run_format`、`run_lint`)。 - P3:在显式启用标志后提供写入工具(重命名、代码操作、格式化并写入)。 - P4:基于 `index.scip` 的 SCIP 查询工具(原生 Rust 读取器)。 - P5:驱动 DAP 会话。评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。