news 2026/10/23 14:54:54

Cloudpods MCP Server 深度解析:用 MCP 协议把 climc 能力暴露给 AI 客户端

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cloudpods MCP Server 深度解析:用 MCP 协议把 climc 能力暴露给 AI 客户端
  • 后端
  • 云原生
  • 运维
  • 虚拟化
  • 人工智能
  • AI 应用

【免费下载链接】cloudpods

开源、云原生的多云管理及混合云融合平台

项目地址:https://gitcode.com/yunionio/cloudpods
点击查看免费下载

Cloudpods MCP Server 是 Cloudpods 多云管理平台提供的 AI 能力网关:它通过 MCP(Model Context Protocol)协议,把平台命令行工具 climc 的命令能力自动转换、注册为 MCP tools,供 Cursor、Cline、Claude 等 AI 客户端直接调用,从而实现"用自然语言查询镜像/网络/虚拟机、创建和启停服务器"等操作。读完本文,你可以掌握 mcp-server 的目录结构与运行机制、SSE/stdio 两种模式的部署配置、AK/SK 与 Header 的认证方式、工具如何从 climc 命令表自动生成,以及如何通过mcp-desc/mcp:"true"标签快速扩展新的 MCP 工具。

一、MCP Server 定位与整体架构

docs/mcp-server/README.md 对模块的定位一句话概括:

Cloudpods MCP Server:通过 MCP 协议把 climc 能力暴露给 AI 客户端(Cursor / Claude 等)。

从源码结构看,整个模块由 cmd/mcp-server/main.go 作为进程入口,实际逻辑全部位于pkg/mcp-server/下,各目录职责如下:

目录职责关键文件
adapters/Cloudpods 认证与 ClientSession 创建adapter.go、credentials.go
climcgen/从 climc CommandTable + Options tag 生成 MCP toolsregister.go、schema.go、exec.go、tool.go
options/服务配置项定义options.go
registry/MCP tool 注册中心registry.go
server/SSE / stdio 服务实现server.go
service/进程入口装配service.go

启动装配流程在 service.go 中完成:解析mcpserver.conf配置 → 若配置了auth_url+admin_user等则初始化全局认证 → 创建CloudpodsMCPServer(内部构建 ServerInstructions、扫描并生成全部 tools)→ 启动 SSE 服务。

二、运行机制:从 climc 命令表到 MCP tools 的三步

README 中描述的三步运行机制,在源码中都能找到精确对应。

2.1 第一步:blank-import climc shell 包,填充 CommandTable

climc 的每条命令(server-create、image-list、cloud-region-list……)都以shell.CMD结构体注册在shell.CommandTable中。MCP Server 通过 imports.go 以空白导入方式引入 climc 各业务子包,触发其init()完成注册:

// 导入 climc shell 子包以填充 shell.CommandTable import ( _ "yunion.io/x/onecloud/cmd/climc/shell/compute" _ "yunion.io/x/onecloud/cmd/climc/shell/identity" _ "yunion.io/x/onecloud/cmd/climc/shell/image" _ "yunion.io/x/onecloud/cmd/climc/shell/logger" _ "yunion.io/x/onecloud/cmd/climc/shell/monitor" _ "yunion.io/x/onecloud/cmd/climc/shell/scheduler" )

这意味着:只要 climc 支持某命令,MCP Server 就有能力将其暴露为工具,无需在 MCP 侧重复实现任何 API 调用逻辑。

2.2 第二步:扫描mcp-desc命令,用 struct tag 生成 schema

并非所有 climc 命令都会被注册为 MCP tool。register.go 中的BuildTools只会挑选 Options 结构体上带有mcp-desc标签的命令:

// discoverMcpDescCommands 扫描 CommandTable,收集 Options 带 mcp-desc 的命令。 // server-create /「最终动作」优先排前,便于模型在创建意图下选中。 func discoverMcpDescCommands() []string { ... for i, cmd := range shell.CommandTable { desc := collectMcpDesc(cmd.Options) if desc == "" { continue } ... } ... }

标签约定定义在 mcp_tags.go 中:

  • mcp-desc写在 Options 结构体的_ struct{}字段上,作为该 MCP tool 的描述,直接面向 AI 模型书写(中文即可)。例如 cloudregions.go 中:
_ struct{} `mcp-desc:"【创建流程中的中间步骤】本工具不能完成创建。指定云厂商时必须传 provider,例如创建阿里云:provider=[\"Aliyun\"]。..."`
  • mcp:"true"表示该可选参数要暴露给 AI;mcp:"required"表示建议必填。例如 snapshots.go:
Disk string `help:"Disk snapshots" json:"disk_id" mcp:"true"` Server string `help:"Filter by server" json:"server_id" mcp:"true"` DiskType string `help:"Filter by disk type" choices:"sys|data" mcp:"true"`

schema 的构建在 schema.go 的buildInputSchema中完成,几个值得注意的工程细节:

  1. 参数精简:常量maxSchemaProperties = 48限制了单工具生成的参数数量,"避免 BaseListOptions 等过大 schema 淹没模型";没有mcp:"true"标记的可选参数一律不暴露(见mcpKeepArg函数)。
  2. 类型推断:布尔型参数生成boolean,IsMulti()参数生成array,有Choices()的参数自动带上enum,其余为string。
  3. 面向模型的"手把手"描述增强:针对关键命令,源码会覆写参数描述,降低模型调用门槛。例如:
    • server-create的disk参数被重写为:系统盘描述,数组。公有云:["size=40g,image=<镜像ID>,backend=cloud_essd"];CAS/UIS/SangFor:["size=40g,backend=dir"]...;
    • *-list命令强制注入scope参数说明:"resource scope;省略时 MCP 默认注入 max";
    • cloud-region-list的usable参数说明:"创建虚拟机时必须为 true,只返回网络可用区域;省略时 MCP 默认注入 true"。
  4. 工具命名:schema.go 的toolNameFromCommand将 climc 命令名转为 MCP 工具名——当前版本前缀为climc_,例如server-create→climc_server_create;使用文档 中给出的cloudpods_list_images、cloudpods_create_server等名称则是文档示例时期的命名风格,工具语义一一对应。

注册完成后,registry.go 负责把每个Tool(含 schema 与 Handle 回调)挂载到 mcp-go 的MCPServer实例上;Initialize失败会以"初始化工具注册中心失败"报错退出。

2.3 第三步:工具调用时用凭据建 session,执行 climc callback,JSON 返回

工具调用入口是 tool.go 的Handle方法,流程为:

  1. 从请求参数中取ak/sk(兼容从连接 Header 注入的凭据,二者缺一即返回authentication required: provide X-Auth-Token, AK/SK headers, or X-API-Key on tools/call);
  2. 调用 adapters/adapter.go 的GetSession:AuthenticateByAccessKey换取 Token,经 apigateway endpoint 创建mcclient.ClientSession;
  3. 将 MCP 的 JSON 参数转成 climc 的 argv 执行(exec.go的mcpArgsToArgv,自动处理-/_命名、布尔值true/1/yes/on等转换);
  4. 通过shell.PushOutput(&buf, shell.OUTPUT_FORMAT_JSON)把该 goroutine 的输出重定向为 JSON,调用命令回调后取出结果,compactJSON压缩空白降低模型上下文占用,再拼上"下一步提示"(见下文)返回给客户端。

两个特殊的流程化命令不走通用invokeCommand:server-create由 create_flow.go 处理,会先调用调度器 forecast、创建后每 5 秒轮询直至 running/ready(最长等待时间由server_create_wait_seconds控制,默认 180 秒,超时仍返回 server_id 供继续查询);server-delete同理有 delete_flow.go 处理。

多步任务引导:nextStepHint

为防止模型"只查完区域就停止",tool.go 在每次工具结果末尾追加[MCP下一步]提示,例如:

[MCP下一步] 创建虚拟机尚未完成。请用区域 id 调 climc_cloud_region_capability,再 climc_cached_image_list + climc_server_sku_list(可并行),最后 climc_server_create。

配套的 instructions.go 还会生成一份全局 ServerInstructions,明确告诉模型完整规则:"严禁空口编造:未实际调用 climc_* 并拿到返回前,禁止声称'已查到/已创建成功'"、创建虚拟机的标准顺序"区域→能力→规格→镜像→创建"、监控查询的 measurement/field 写法等。这份说明可通过mcp_server_name等配置间接影响,也可经climcgen.RegisterExtraInstructions追加。

三、部署与配置

3.1 编译与配置文件

按 安装文档 的步骤部署:

# 编译 mcp-server $ cd /root/cloudpods && make cmd/mcp-server # 编写配置文件,注意根据实际情况修改 Cloudpods API 的认证信息 # 需要在系统内先创建 mcp-server-admin 用户,并以 admin 角色加入到 system 项目 $ mkdir -p /etc/yunion/mcp-server $ cat<<EOF >/etc/yunion/mcp-server/mcp-server.conf # ==================== 服务器基础配置 ==================== address = '127.0.0.1' port = 12001 admin_domain = Default admin_password = <admin密码> admin_project = system admin_project_domain = Default admin_user = mcp-server-admin auth_url = https://<apigateway_ip_or_domain>:30500/v3 session_endpoint_type = public # ==================== MCP 服务配置 ==================== mcp_server_name = cloudpods-mcp-server # MCP 服务名称 mcp_server_version = 1.0.0 # MCP 服务版本 mcp_server_description = the mcp server of the cloudpods server EOF

配置项与 options.go 的对应关系如下(前缀mcp_对应结构体字段MCPServer*):

配置项说明默认值
address/port服务监听地址与端口安装示例用127.0.0.1:12001
auth_url平台 apigateway 的认证地址(v3)必填
admin_user/admin_password/admin_project/admin_project_domain/admin_domain服务自身的平台用户身份需预先创建
mcp_server_name上报给客户端的 MCP 服务名;为空时回退为PlatformName(默认Cloudpods,见options.ResolvedPlatformName)Cloudpods
mcp_server_versionMCP 服务版本1.0.0(文档示例)
mcp_server_descriptionMCP 服务描述-
timeout到平台 API 的 SDK 连接超时(秒)30
server_create_wait_seconds创建虚拟机后等待 running/ready 的最长时间,超时仍返回 server_id180

其中timeout与server_create_wait_seconds支持热更新;platform_name因写入 ServerInstructions 需要重启进程(见 options.go 的OnOptionsChange注释)。

3.2 启动与验证

# 默认从以下路径查找配置文件: /etc/yunion/mcp-server/mcp-server.yaml, ./config/mcp-server.yaml, ./mcp-server.yaml $ /root/cloudpods/bin/mcp-server --log-level debug # 或使用 --conf 参数指定配置文件路径 $ /root/cloudpods/bin/mcp-server --log-level debug --conf /etc/yunion/mcp-server/mcp-server.yaml # 启动成功后检查 SSE 端点 $ curl http://localhost:12001/sse

服务在 server.go 的Start中启动,除/sse外还挂载了/version、/stats、/ping、/worker_stats、/process_stats等运维端点,可用curl逐个探活。启动日志会打印Start mcp server successfully on <addr>,工具注册时逐一打印climcgen: registered MCP tool <name> (<climc命令>),可作为工具是否成功注册的核对依据。

四、MCP 客户端接入:SSE 与 stdio 两种模式

按 使用文档,主流 MCP 客户端(Cline、Cursor 等)均可接入,两种模式的配置方式如下。

SSE 模式(源码默认):/sse为长连接端点,消息 POST 到/message端点:

{ "mcpServers": { "cloudpods-sse": { "url": "http://localhost:12001/sse" } } }

stdio 模式:直接拉起本地mcp-server进程:

{ "mcpServers": { "mcp-server": { "disabled": false, "timeout": 60, "type": "stdio", "command": "/path/to/mcp-server", "args": [ "config", "/path/to/mcp-server.yaml" ] } } }

源码对两种协议做了兼容:server.go 在同一个/sse路径上按 HTTP method 分流——GET 走传统 SSE(Cursor 等旧客户端),POST/DELETE 走 Streamable HTTP(部分新客户端把/sse当作 Streamable HTTP 使用),避免405报错;SSE 心跳间隔 15 秒(WithKeepAliveInterval),用于在长耗时的tools/call(如公有云创建)期间防止中间代理空闲断连。

4.1 认证:Header 优先,参数兜底

凭据传递有两条路径,server.go 的authenticateRequest支持三种 Header 形态:

  • X-Auth-Token:平台签发的 token(服务配置了全局认证时先auth.Verify);
  • AK+SK两个 Header;
  • X-API-Key:值为base64("ak:sk")。

Header 中未携带时,才允许在工具参数里传ak/sk(使用文档的方式:对话中向模型提供 Access Key / Secret Key,例如先用climc credential-create-aksk创建)。credentials.go 中ErrAuthenticationRequired明确了这一优先级:provide X-Auth-Token, AK/SK headers, or X-API-Key on tools/call。initialize/tools/list允许匿名,只有tools/call强制鉴权,因此客户端"已连接"并不代表可以立即执行操作。

五、工具清单与使用示例

使用文档 梳理了 15 类典型能力(文档示例以cloudpods_前缀命名,当前代码生成climc_前缀,语义相同):

资源查询

工具(文档命名)功能
cloudpods_list_images查询镜像列表
cloudpods_list_networks查询网络列表(支持vpc_id过滤)
cloudpods_list_regions查询区域列表(支持provider过滤)
cloudpods_list_servers查询虚拟机实例列表(支持status过滤)
cloudpods_list_serverskus查询服务器规格列表(支持cpu_core_count、memory_size_mb、cpu_arch、providers等)
cloudpods_list_storages查询存储列表(支持storage_types、host_id等)
cloudpods_list_vpcs查询 VPC 列表

资源操作

工具(文档命名)功能
cloudpods_create_server创建虚拟机实例(name/vcpu_count/vmem_size/image_id/network_id/auto_start/billing_type等)
cloudpods_delete_server删除实例(delete_disks/delete_eip/purge等)
cloudpods_start_server启动实例(qemu_version等)
cloudpods_stop_server停止实例(is_force/stop_charging/timeout_secs)
cloudpods_reset_server_password重置密码(auto_start/username)
cloudpods_get_server_monitor历史监控指标(metrics/start_time/end_time)
cloudpods_get_server_stats实时统计信息

查询类工具的返回统一带query_info(limit/offset/total 与已生效的过滤条件)和summary(has_more/next_offset/total_*),便于模型做分页续查。例如 使用文档 中cloudpods_list_images的交互示例:

提示词:"帮我查询云平台的镜像列表,要求显示前10条(从第1条开始),筛选条件为操作系统类型是Linux或Windows,关键词包含'centos'。" 模型转换为:

{ "limit": "10", "offset": "0", "search": "", "os_types": "Linux,Windows" }

返回:

{ "images": [], "query_info": { "count": 0, "limit": 10, "offset": 0, "os_types": ["Linux", "Windows"], "search": "", "total": 0 }, "summary": { "has_more": false, "next_offset": 0, "returned_count": 0, "total_images": 0 } }

当前源码中已带mcp-desc注册的命令远不止这 15 个,还包括域/项目/用户的增删查(identity)、操作日志查询(actions.go)、资源用量汇总(usages.go)、磁盘挂载/卸载(serverdisks.go)、快照列表(snapshots.go)等,实际数量以启动日志中registered MCP tool为准。

六、扩展新工具

README 给出的扩展方式非常轻量——在对应 climc 命令的 Options 上打标,重启 mcp-server 即可注册:

type ImageListOptions struct { cloudcommon.ListOptions OsTypes string `help:"Filter by OS types" mcp:"true"` // 按需给要暴露的字段加 mcp tag _ struct{} `mcp-desc:"查询镜像列表。可用 os-types/limit/offset 过滤"` // 作为 MCP tool 描述 }

两条规则来自 mcp_tags.go 的实现细节:

  1. mcp-desc只读取本结构体的非嵌入字段、不递归匿名嵌入(collectMcpDescFromType中if f.Anonymous { continue })。这是刻意设计:避免复用 Options(如 statistics 嵌入 List)时被误注册。servers.go 中的注释也印证了这一点:"与 server-start 复用参数时单独包一层,避免继承 mcp-desc 被注册为 MCP tool"。
  2. 字段 token 的推导与 structarg 完全一致:优先token标签,其次json名,再次alias,最后字段名,统一CamelSplit为 kebab-case(如MemSpec→mem-spec),并额外登记字段名与 json 名的变体,保证模型传任一写法都能落到正确的 CLI 参数。

除了 tag 方式,源码还预留了两个 Go 层面的扩展点(extra.go):

  • climcgen.RegisterExtraTools(fn):注册额外工具构建回调,返回自定义[]Tool,应在init()中调用;
  • climcgen.RegisterExtraInstructions(fn):向全局 ServerInstructions 追加自定义说明。

两者在 server.go 的NewServerWithOptions中被合并进最终的 instructions 与工具列表(extra tools 排在自动生成的 climc tools 之前)。

七、小结

Cloudpods MCP Server 的设计核心是"零手写工具代码":它不逐条实现 API 客户端,而是站在 climc 命令表之上,用mcp-desc/mcp两个 struct tag 声明式地挑选命令、裁剪参数、生成 schema,再用统一的 session 建立、argv 转换、JSON 压缩输出和"下一步提示"把命令执行封装成对 LLM 友好的多步任务流。对使用者而言,部署只需一份mcp-server.conf(核心是auth_url+admin_*+ 端口),客户端接入只需一段 SSE 或 stdio 配置;对开发者而言,暴露一个新能力只需在既有 climc 命令上补两行标签后重启服务。相关入口与关键实现可沿 README、安装文档、使用文档 以及pkg/mcp-server/目录继续深入。

  • 后端
  • 云原生
  • 运维
  • 虚拟化
  • 人工智能
  • AI 应用

【免费下载链接】cloudpods

开源、云原生的多云管理及混合云融合平台

项目地址:https://gitcode.com/yunionio/cloudpods
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 14:37:27

0基础学网安,先学网络还是Linux?

不少零基础想要入行网络安全的同学&#xff0c;心中都存在这样的疑问&#xff1a;零基础学网安&#xff0c;先学Linux还是计算机网络?答案是&#xff1a;优先务实计算机网络基础&#xff0c;同步入门Linux基础&#xff0c;不建议学完一门再开启另外一门。计算机网络是网络安全…

作者头像 李华
网站建设 2026/10/22 18:27:56

Ptrade量化交易核心函数解析与实战技巧

1. 项目概述Ptrade作为券商常用的量化交易平台&#xff0c;其内置函数库是量化策略实现的基础工具。本文将系统梳理Ptrade平台最核心的交易函数&#xff0c;涵盖下单、打新、持仓管理三大模块&#xff0c;帮助零基础用户快速掌握函数调用逻辑与实战技巧。在量化交易中&#xff…

作者头像 李华
网站建设 2026/10/22 15:13:24

FPGA脉冲拨号课设实战:状态机、按键消抖与Verilog实现

简介&#xff1a;南京邮电大学课程设计中的脉冲按键拨号电路FPGA设计工程包&#xff0c;主要面向FPGA初学者与数字逻辑课程设计学生&#xff0c;解决按键脉冲串行码生成与动态显示需求。工程实现0~9按键对应脉冲序列输出&#xff0c;并将所按键值实时显示&#xff0c;支持基本技…

作者头像 李华
网站建设 2026/10/19 7:05:38

OpenFive平台:面向HPC与AI混合负载的SoC系统集成加速器

1. 这不是“又一个HPC平台”&#xff1a;OpenFive平台的真实定位与设计原点很多人第一次看到“OpenFive’s Platform for HPC and AI SoCs in Data Center”这个标题&#xff0c;下意识会把它归类为“某家初创公司推出的新型服务器芯片平台”——就像过去五年里冒出的几十个类似…

作者头像 李华
网站建设 2026/10/17 11:05:18

C语言200例源码包深度拆解:从编译调试到代码优化

简介&#xff1a;《C语言精彩编程200例》是一套面向初学者与进阶开发者的C语言实践代码合集&#xff0c;以编程实例串联变量、运算符、流程控制、函数、数组、指针等基础知识点&#xff0c;并延伸到结构体、位运算、文件操作及链表、栈、队列、树、图等数据结构练习&#xff0c…

作者头像 李华