🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

MCP 状态灯 lobichshev-ops/dsh-mcp-status

DeepSeek Harness
lobichshev-ops6 天前有提交已提供中文文档扫描:含敏感能力

在聊天头部查看 MCP 服务器是否在线及工具数量

32.1/100
综合分
3
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/30 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add lobichshev-ops/dsh-mcp-status
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
dsh 原生插件 · ui
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 6 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 8 处,展示前 8 条)
  • 写入本地文件
    index.js:33
    appendFileSync(join(HERE, '.activation.log'), `${new Date().toISOString()} import\n`)
  • 写入本地文件
    index.js:44
    appendFileSync(join(HERE, '.activation.log'), `${new Date().toISOString()} ${note}\n`)
  • 读取本地文件
    index.js:59
    error: existsSync(scriptPath) ? null : `скрипт не найден: ${scriptPath}`,
  • 读取本地文件
    index.js:81
    if (!existsSync(scriptPath)) {
  • 读取本地文件
    index.js:101
    text = await readFile(outFile, 'utf8')
  • 删除本地文件
    index.js:106
    await rm(outFile, { force: true })
  • 执行外部命令来自配置/变量
    index.js:130
    child = spawn(pythonPath, [scriptPath, '--json', '--out', outFile], {
  • 发起网络请求
    client.js:246
    const response = await fetch(force ? `${ENDPOINT}?refresh=1` : ENDPOINT, { cache: 'no-store' })
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DeepSeek Harness 插件:聊天顶栏的 MCP 状态按钮,实时显示哪些 MCP 服务器正在响应

README

由 DeepSeek 最新模型翻译生成
dsh-mcp-status English · Русский 一个 DeepSeek Harness 插件,在聊天头部放一个 MCP 按钮。 点一下就能看到哪些 MCP 服务器已连接,以及其中哪些服务器此刻能应答,还会显示每个服务器实际暴露的工具数量。 MCP 状态面板 截图中的示例服务器、地址和名称均为占位符。 目录 - 为什么需要它 - 你会得到什么 - 工作原理 - 通信格式 - 状态 - 配置 - 安装 - 独立探测 - 故障排查 - 限制 - 许可证 为什么需要它 DSH 只在启动时连接一次 MCP 服务器。当其中某个服务器挂掉时,症状很间接:原本在模型工具集里的工具直接消失了,或者调用时返回传输错误。配置文件只能告诉你应该连上什么,而不是实际连上了什么。 一个占着 TCP 端口、却从不完成 MCP 握手的端点,在任何端口检查器看来都是「在线」。这个插件回答一个更严格的问题:服务器此刻能否完成 initialize + tools/list,返回了多少个工具? 这正是 Harness 本身为了把这些工具交给模型所需要的东西。
展开完整文档(README 剩余 1 节)
dsh-mcp-status

English · Русский

一个 DeepSeek Harness 插件,在聊天头部放一个 MCP 按钮。
点一下就能看到哪些 MCP 服务器已连接,以及其中哪些服务器此刻能应答,还会显示每个服务器实际暴露的工具数量。

MCP 状态面板

截图中的示例服务器、地址和名称均为占位符。

目录

- 为什么需要它
- 你会得到什么
- 工作原理
- 通信格式
- 状态
- 配置
- 安装
- 独立探测
- 故障排查
- 限制
- 许可证

为什么需要它

DSH 只在启动时连接一次 MCP 服务器。当其中某个服务器挂掉时,症状很间接:原本在模型工具集里的工具直接消失了,或者调用时返回传输错误。配置文件只能告诉你应该连上什么,而不是实际连上了什么。

一个占着 TCP 端口、却从不完成 MCP 握手的端点,在任何端口检查器看来都是「在线」。这个插件回答一个更严格的问题:服务器此刻能否完成 initialize + tools/list,返回了多少个工具? 这正是 Harness 本身为了把这些工具交给模型所需要的东西。

你会得到什么

| 元素 | 位置 | 显示内容 |
| 状态胶囊 | 聊天头部,conversation.session.header.utilities | 一个圆点:全部应答时绿色,有服务器挂掉时红色 |
| 服务器列表 | 弹出面板内 | 名称、端点、状态、响应时间、工具数量 |
| EDT 区块 | 弹出面板内 | 当前有哪些 1C:EDT 项目在提供 MCP 服务,从各项目的 .mcp.json 中发现 |
| 刷新按钮 | 弹出面板头部 | 强制探测;新结果到达时时间戳会变化 |

结果会缓存,所以打开面板是瞬时的,尽管完整探测要花约 15 秒。

工作原理

一个包里分两半——这是带 UI 的 DSH 插件的常见形态。

flowchart LR
subgraph host["Host · Node"]
A["apply(ctx)"] --> B["webServer.registerGET /plugin/mcp-status"]
A --> C["refresh()startup + every 5 min"]
C --> D["spawn pythonmcp_status.py --json --out file"]
D --> E[("cachedata · fetchedAt")]
E --> B
end
subgraph client["Client · browser"]mermaid
F["McpStatusButton"] -->|"fetch, every 20 s"| B
F --> G["popoverservers + EDT"]
end

宿主端 —— index.js

声明 export const inject = ['webServer'],在 ctx.effect 里注册路由,启动时跑一次探测,之后每五分钟跑一次。探测是一个子进程:它把 JSON 写进文件,插件读这个文件,缓存起来再对外提供。

客户端 —— client.js

一个经典脚本,通过 window.__ModuleLoader__.load 注册自己,导出 { inject: ['slots'], apply(ctx) }。它把一个 React 组件放进 conversation.session.header.utilities 插槽 —— 和语言、Markdown 控件同一条带。组件挂载时轮询路由,之后每 20 秒一次;宿主报告 refreshing: true 期间改为每 1.5 秒一次,这样结果一就绪时间戳立刻变化,不用再等半分钟。

做握手,不做端口检查

对每个配置过的服务器,探测都执行一次真正的 MCP 握手:

1. POST initialize,带上 Accept: application/json, text/event-stream,并跟随 307 重定向 —— 有些服务器在 /mcp 上会先这样应答,再转到 /mcp/。
2. 记下 Mcp-Session-Id,发送 notifications/initialized —— 好几个基于 FastMCP 的服务器少了这一步,会用 "Invalid request parameters" 拒绝 tools/list。
3. 带上该会话头 POST tools/list;解析普通 JSON 响应体或 SSE 流(data: {...} 块)都行。
4. stdio 服务器:启动配置的命令,通过 stdin/stdout 收发换行分隔的 JSON-RPC,每个阶段单独设超时 —— 路由器在 tools/list 上可能耗 12 秒,因为它要先重扫端口范围。

为什么用 Python 子进程

这套逻辑已经有一个测过的 Python 脚本(scripts/mcp_status.py,只用标准库)。用 JavaScript 重写传输层的各种边界情况,等于造出第二个事实来源,所以宿主端干脆直接跑这个脚本,缓存它的 JSON。脚本随包发布 —— 没有外部依赖。

有个后果值得知道:子进程的 stdout 不走管道捕获。脚本把结果写进文件(--out),插件读取后删除。管道在沙箱化的 shell 里很脆弱;文件交接到哪都能用。

传输格式

GET /plugin/mcp-status 返回缓存信封: json { "ok": true, "fetchedAt": 1793269934399, "durationMs": 14984, "refreshing": false, "error": null,
"data": {
"generatedAt": "2026-10-29T13:32:14",
"config": "C:\\Users\\me\\.dsh\\profiles\\desktop\\cordis.patch.yml",
"servers": [
{
"name": "edt-router",
"transport": "stdio",
"endpoint": "python edt-mcp-router.py",
"state": "ok",
"ms": 12293,
"tools": 52,
"detail": ""
},
{
"name": "postgres",
"transport": "http",
"endpoint": "http://10.20.30.40:8000/mcp",
"state": "dead",
"ms": 2041,
"tools": null,
"detail": "порт закрыт (connection refused)"
}
],
"commentedOut": ["mcp-metadata"],
"edt": [
{
"project": "My project",
"url": "http://10.20.30.41:8765/mcp",
"state": "ok",
"tools": 50,
"detail": ""
}
],
"orphanPorts": []
}
}

上面这些地址只是示例,不属于任何真实网络。

?refresh=1 会启动后台探测,并立刻返回上一次的缓存,同时带上 refreshing: true。UI 会持续轮询,直到 refreshing 翻回原值。

状态

| 状态 | 含义 |
| ok | 握手成功;tools 是服务端返回的数量。 |
| warn | initialize 成功,tools/list 失败:服务活着,但有问题。detail 里写明原因。 |
| dead | 连接被拒、超时、HTTP 错误,或返回的不是 MCP 响应。 |
| off | 配置行里写了 disabled: true。 |
| skipped | 没有探测(比如 EDT 项目没配 URL)。 |

配置

所有键都是可选的,写在加载器行里:

| 键 | 默认值 | 含义 |
| pythonPath | DSH 运行时的 Python | 探测脚本用的解释器。 |
| scriptPath | 包内的 scripts/mcp_status.py | 改过探测脚本的话,指向你自己的副本。 |
| intervalMs | 300000(5 分钟) | 后台刷新周期;最小 15 秒。 |

- insert:
- id: mcp-status
name: '@local/dsh-mcp-status'
config:
intervalMs: 60000

安装

这个包是个 bundle:自带一份 dsh.bundle.patch,会插入它自己的加载器行。

1. 链接到配置档里:

cd ~\.dsh\profiles\desktop
pnpm add "link:<absolute path to this package>"

2. 把包名加进 ~/.dsh/profiles/desktop/package.json 的 bundle 列表:

"dsh": {
"profile": {
"bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "@local/dsh-mcp-status"]
}
}

3. 重启 DSH。宿主端随配置档一起激活;客户端在下次页面加载时出现。

要卸载,把包名从 bundles 里删掉,再跑一次 pnpm install。

[!NOTE]
@local/dsh-mcp-status 这个名字是随便起的:一个私有包,从不发布到 npm。改名时要同时改 package.json 和 cordis.patch.yml,还有配置档的依赖键和 bundle 列表。

独立探测

scripts/mcp_status.py 不依赖 UI 也能跑:

python scripts/mcp_status.py # human-readable table
python scripts/mcp_status.py --json # machine-readable
python scripts/mcp_status.py --json --out result.json # write to a file
python scripts/mcp_status.py --no-edt # skip the 1C:EDT block
python scripts/mcp_status.py --edt-roots 'D:\projects' # EDT roots, when the router row carries none

退出码 1 表示至少有一台服务挂了,0 表示全部有响应——适合放进 cron。

故障排查

| 现象 | 原因 / 修复 |
| 安装后没有按钮 | 客户端那一半在页面加载时注册。刷新页面(F5),只刷新应用不够。 |
| 路由返回 404 | 宿主那一半没有激活。到 DSH 的 stderr 里找 [mcp-status] 警告;检查加载器那一行,确认包能从配置档里解析到。 |
| cannot get property "webServer" without inject | Cordis 禁止读取未声明的服务。插件声明了 inject = ['webServer']。 |
| 「Checking…」持续约 15 s | 正常现象:stdio 路由器每次 tools/list 都会重新扫描端口范围。只有 HTTP 服务器时约 200 ms 就能返回。 |
| EDT 项目显示 dead | 那个 EDT 实例没在运行。.mcp.json 保留了它上次运行时的端口——这不是错误。 |
| 全部显示 dead | 什么都连不上:先检查 MCP 进程/容器,再按 Refresh。 |

模块被导入时、以及 apply 抛错时,包会在自己旁边追加 .activation.log。该文件已被 git 忽略。

限制

- 这条路由是普通的 webServer 路由,不是带鉴权的 /api 路由。它只在回环地址上暴露名称、端点和状态,但如果你把 DSH 绑定到非回环地址,这条路由也能被访问到。
- EDT 区块是 1C 专用的;在其他环境里它只是找不到项目。
- 客户端那一半收不到配置(DSH 创建客户端条目时不带配置),所以所有调优都放在宿主那一行。

许可证

MIT
预览分享卡片长什么样 ↓lobichshev-ops/dsh-mcp-status
分享 · DeepSeek Harness Hub
lobichshev-ops/dsh-mcp-status

在聊天头部查看 MCP 服务器是否在线及工具数量

这是你的仓库?认领条目

回到顶部