feat(plugin): MCP 服务器管理页 + 按 server 独立启停与状态快照

design/09 §5.2.1 / §5.6.1:补上「看不见连没连上 / 暴露了哪些工具 / 为什么挂了」的洞。

- runtimeconfig:PluginConfig 新增 `enabled`(*bool,缺省=启用 ⇒ 既有 plugins.json
  向后兼容);新增 RedactPluginSecrets(整把凭据 + 任意 ≥6 字符片段一并抹除)。
- mcp:新增 status.go 的只读状态读面(ToolSummaries:工具名 + 截断描述,取自能力
  注册表本身,因此与模型可见的工具集合同源)。
- plugin 管理器:
  · Install/Restore 尊重 enabled(停用=落盘不连接,重启后仍是停用,且一次都不连);
  · SetEnabled 落盘 enabled(停用先落盘再下线;启用失败时 enabled 保持 false);
  · 新增 Reconnect(对已停用者拒绝,不替用户启用);
  · 新增 Statuses(三态:connected 缺席=未知,工具数/明细/时间只在知道时给出,
    lastError 在记录那一刻即脱敏截断);
  · 内置「MCP 服务器」页声明 + 7 个已声明动作(list/install/reconnect/enable/
    disable/uninstall/transports),走既有通用动作端点(owner-admin + 审计);
  · 护栏:热装插件的生命周期不改动内置提供者(mcp)的目录条目。
- gateway:已安装列表与 install 响应加 enabled,install 支持 config.enabled。
This commit is contained in:
AskaEth committed 2026-10-24 19:31:31 +08:00
1 parent 4ed5925296
commit 9654ce8861
14 files changed
+1969 -115

No files matched your search

@@ -63,6 +63,9 @@ type pluginInstallConfig struct {
Args []string `json:"args"`
APIKey string `json:"apiKey"`
Env map[string]string `json:"env"`
// Enabled 是安装时的初始启用态。缺省(nil)=启用;显式 false =装上但先不连
// (配置落盘、工具不注册,之后可由面板「启用」)。
Enabled *bool `json:"enabled"`
}
// AdminInstalledPlugin 是管理列表中一个已安装插件的线上
@@ -78,6 +81,9 @@ type AdminInstalledPlugin struct {
APIKey string `json:"apiKey,omitempty"`
Env map[string]string `json:"env,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
// Enabled 是这一台的启用态(plugins.json 的 `enabled`,缺省视为 true)。
// 停用 ≠ 卸载:条目仍在列表里,只是没连、没注册工具。
Enabled bool `json:"enabled"`
// Live 报告 MCP server 是否已连接、其工具是否已注册。
Live bool `json:"live"`
// ToolCount 是活着的 server 已注册的工具数。
@@ -134,6 +140,7 @@ func (s *Server) adminInstallMCPPlugin(w http.ResponseWriter, r *http.Request, r
Args: req.Config.Args,
APIKey: req.Config.APIKey,
Env: req.Config.Env,
Enabled: req.Config.Enabled,
}.Normalize()
if err := cfg.Validate(); err != nil {
s.auditClaims(r, "plugin.install", "error")
@@ -160,6 +167,7 @@ func (s *Server) adminInstallMCPPlugin(w http.ResponseWriter, r *http.Request, r
"name": res.Config.Name,
"kind": res.Config.Kind,
"transport": res.Config.Transport,
"enabled": res.Config.IsEnabled(),
"toolCount": res.ToolCount,
})
}
@@ -240,6 +248,7 @@ func adminInstalledPluginOf(it pluginmgr.Installed) AdminInstalledPlugin {
APIKey: cfg.APIKey,
Env: cfg.Env,
CreatedAt: cfg.CreatedAt,
Enabled: cfg.IsEnabled(),
Live: it.Live,
ToolCount: it.ToolCount,
}