fix(mcp-server): do not expose server-monitor as an MCP tool (#25511)

server-monitor sends arbitrary QMP/HMP commands (pmemsave, migrate,
etc.) to a running guest, which exceeds the semantics of monitoring.
As an MCP tool it could be triggered without human awareness through
LLM prompt injection or the tool-request endpoint.

Remove the mcp-desc registration tag from ServerMonitorOptions so
climcgen no longer registers the tool, drop its mention from the MCP
instructions, and add a regression test asserting it is not exposed.
The climc command and the permission-gated region API are unchanged.

Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Jian Qiu
2026-09-03 19:22:19 +08:00
committed by GitHub
co-authored by Qiu Jian Claude
parent 1312d0d4cf
commit 742297e4a6
3 changed files with 42 additions and 4 deletions
+4 -3
View File
@@ -1027,12 +1027,13 @@ func (o *ServerKickstartCompleteOptions) Params() (jsonutils.JSONObject, error)
return options.StructToParams(o)
}
// ServerMonitorOptions 不注册为 MCP tool(无 mcp-desc tag):向虚机发送任意
// HMP/QMP 命令(如 pmemsave/migrate)超出"监控"语义,经 LLM 通道可被提示注入
// 无感知触发,禁止 AI 调用。仅保留 climc 命令行与受控 API 使用。
type ServerMonitorOptions struct {
_ struct{} `mcp-desc:"【QEMU Monitor,不是监控指标】向虚机发送 HMP/QMP。查 CPU/内存等指标请用 climc_monitor_unifiedmonitor_query"`
ServerIdOptions
Qmp bool `help:"Use qmp protocol, default is hmp" mcp:"true"`
Qmp bool `help:"Use qmp protocol, default is hmp"`
COMMAND string `help:"Qemu Monitor command to send"`
}
+1 -1
View File
@@ -41,7 +41,7 @@ const serverInstructionsTemplate = `%s MCPclimc tools)使用规则:
- net 可省略自动调度。工具会 forecast→创建并等待 running/ready;若返回 wait_pending,用 climc_server_show 续查,勿重复创建。
- 若 final_status 含 fail:结果中会带 fail_reason 与 fail_diagnostics.action_logs(平台操作日志);也可 climc_action_show type=server id=<id> fail=true。
3. 启停/重启/删除/重置密码/改配/挂盘/绑 EIPclimc_server_list 定位 id 后立刻调用对应操作工具。删除时若锁定会自动解锁。
4. 监控指标用 climc_monitor_unifiedmonitor_queryclimc_server_monitor 是 QEMU HMP/QMP,不是指标
4. 监控指标用 climc_monitor_unifiedmonitor_query。
5. 缺参只追问真正缺失项;已有 id 直接下一步。
`
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package climcgen
import (
"testing"
"yunion.io/x/onecloud/cmd/climc/shell"
)
// server-monitor sends arbitrary QMP/HMP commands to a running guest, which
// exceeds the semantics of monitoring and must never be callable by AI/MCP
// (e.g. via prompt injection or the tool-request endpoint)
func TestServerMonitorNotExposedToMcp(t *testing.T) {
for _, cmd := range shell.CommandTable {
if cmd.Command != "server-monitor" {
continue
}
if d := collectMcpDesc(cmd.Options); d != "" {
t.Fatalf("server-monitor must not be registered as MCP tool, got mcp-desc %q", d)
}
return
}
t.Fatalf("server-monitor command not found in CommandTable")
}