mcpField
H
Hetzner Cloud (unofficial)

Hetzner Cloud (unofficial)

本地服务
github.com云与基础设施02 天前更新

关于 Hetzner Cloud (unofficial)

Hetzner Cloud (unofficial) 是通过 stdio 提供 Hetzner Cloud API 操作的本地 MCP 服务,面向需要以 MCP 客户端管理云资源的用户。它为 API 操作生成类型化工具,并提供常用服务器操作封装和写入保护。

主要功能

  1. 01覆盖 Hetzner Cloud API 操作
  2. 02常见服务器操作封装
  3. 03原始请求通用入口
  4. 04自动分页与限流重试
  5. 05写入确认和只读开关

适用场景

  1. 01查询或管理 Hetzner Cloud 资源
  2. 02通过分页读取大型列表
  3. 03限制 MCP 调用中的写操作

MCP 相关

通过 stdio 向 MCP 客户端提供 Hetzner Cloud API 工具;工具涵盖读取和写入操作。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"mguttmann-the-real-hetzner": {
"command": "npx",
"args": [
"-y",
"@mguttmann/hetzner-cloud-mcp"
],
"env": {
"HETZNER_API_TOKEN": "<HETZNER_API_TOKEN>",
"HETZNER_READ_ONLY": "<HETZNER_READ_ONLY>",
"HETZNER_CONFIRM_WRITES": "<HETZNER_CONFIRM_WRITES>",
"HETZNER_DENY_TOOLS": "<HETZNER_DENY_TOOLS>",
"LOG_LEVEL": "<LOG_LEVEL>"
}
}
}
}
启动命令npx -y @mguttmann/hetzner-cloud-mcp
需要配置的环境变量
HETZNER_API_TOKEN密钥Hetzner Cloud API token from the Cloud Console (project > Security > API tokens). The server can do exactly what this token allows; use a Read token if the client only needs to read.
HETZNER_READ_ONLYtrue: every tool that is not read-only, and hcloud_raw_request with a method other than GET, returns an error without sending a request. Any value other than true, 1, yes, false, 0, no or empty stops the server at startup.
HETZNER_CONFIRM_WRITEStrue: every tool that is not read-only returns a preview unless the call carries confirm "YES". Friction against mistakes, not a security boundary.
HETZNER_DENY_TOOLSComma-separated tool name globs (for example hcloud_delete_*,hcloud_raw_request) that always return an error. Deny hcloud_raw_request as well, otherwise denied endpoints stay reachable through it. A pattern that matches no tool stops the server at startup.
LOG_LEVELLog level of the JSON logs on stderr.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@mguttmann/hetzner-cloud-mcp0.2.0

工具

202

收录的工具列表 · 更新于 2 天前

参数类型必填说明
server_idinteger是
firewall_idinteger否
firewall_namestring否

详细介绍

the-real-hetzner-mcp

一个非官方的本地 Model Context Protocol (MCP) 服务 (stdio),用于 Hetzner Cloud API:将其随附的 Hetzner Cloud API 规范中的每项操作都作为有类型的工具提供,支持读写;此外还针对常见的服务器操作提供了经过精细调整的封装。npm 包:@mguttmann/hetzner-cloud-mcp。

非官方项目。 此服务与 Hetzner Online GmbH 无关联,也未获得其认可、赞助或支持。“Hetzner”是 Hetzner Online GmbH 的商标。随附的 API 规范(specs/cloud.spec.json)归 Hetzner 所有,不受本项目 MIT License 的约束。请参阅 NOTICE。

维护状态

  • 由一位维护者(@mguttmann)利用业余时间尽力维护,不保证持续投入。没有支持合同,也不保证响应时间。
  • 安全修复优先于功能开发。请通过 GitHub 私密漏洞报告渠道私下报告漏洞,切勿在公开 issue 中披露;请参阅 SECURITY.md。
  • 仅为最新的次要版本提供修复(SECURITY.md 列出了受支持的版本)。
  • 依赖项更新来自 Dependabot;如果运行时依赖项存在已知的高危或严重安全公告,CI 将失败。
  • 版本由 GitHub Actions 从 main 分支上的标签构建并发布,同时提供 CycloneDX SBOM、SHA256SUMS 和构建出处证明(CHANGELOG.md 列出了变更)。
  • 欢迎提交 issue 和拉取请求。工具名称、参数和环境变量在不同版本之间保持稳定;有关契约规则,请参阅 AGENTS.md。

功能

  • 通过基于 specs/cloud.spec.json 的代码生成,全面覆盖 Hetzner Cloud API(每项操作生成一个工具),并针对常见的服务器操作提供经过精细调整的封装。确切的工具列表及数量由 tests/tools-contract.test.ts 根据 tests/snapshots/tools-contract.json 固定。
  • 提供 hcloud_raw_request,作为调用任意端点的通用后备方式。
  • 限制 429 退避重试次数、自动分页并设软上限、轮询操作并设定墙钟时间预算(请参阅超时与重试)。
  • 可选的写入保护 HETZNER_CONFIRM_WRITES=true:除非调用中包含 confirm: "YES",否则所有非只读工具都会返回预览(工具名称和输入)。
  • 可选的运维开关 HETZNER_READ_ONLY=true(仅运行只读工具,以及通过 hcloud_raw_request 发出的 GET 请求)和 HETZNER_DENY_TOOLS(始终返回错误的工具名称 glob 模式)。这两者都不会改变工具列表和架构。

不在范围内

不包括: Hetzner Robot(专用服务器 API)、Hetzner DNS(独立的 DNS 产品,与 Cloud DNS 是不同的 API)和 Hetzner Storage Boxes。它们不属于 Cloud API,代码生成也没有相应的规范。

包括: Cloud DNS 区域和 RRSet(/v1/zones)属于 Cloud API 规范,因此可通过生成的工具使用。

安装

需要 Node.js 22.12 或更高版本(package.json 中的 engines;.github/workflows/ci.yml 中的 CI 矩阵会测试最低版本及当前的 Node.js 版本线)。

请勿安装 0.1.x。 低于 0.2.0 的 npm 版本(0.1.0 和 0.1.1)存在路径注入漏洞,该漏洞已在 0.2.0 中修复,请参阅 SECURITY.md。

从 npm 安装(0.2.0 或更高版本)

包名准确为 @mguttmann/hetzner-cloud-mcp;名称相似的包并非来自本项目。

npm install -g "@mguttmann/hetzner-cloud-mcp@>=0.2.0"

版本范围会使 npm 拒绝安装存在漏洞的 0.1.x 版本。如果 npm 提示找不到匹配的版本,则表示 0.2.0 尚未发布:请改为从固定的 git 提交安装。在 MCP 客户端配置中,command 只需填写 hetzner-cloud-mcp(无需路径)。

使用 npx(无需全局安装)
npx -y "@mguttmann/hetzner-cloud-mcp@>=0.2.0"

MCP 客户端以相同方式启动它,请参阅变体 C:使用 npx。请保留版本范围:如果不指定,npx 会获取 npm 提供的任意 latest 版本。

来自 MCP Registry

列入后,该服务将进入官方 MCP Registry,名称为 io.github.mguttmann/the-real-hetzner-mcp,并使用上文的 npm 包。通过 Registry 安装的客户端使用同一个 npm 包。

使用固定的 git 提交
git clone https://github.com/mguttmann/the-real-hetzner-mcp.git
cd the-real-hetzner-mcp
git checkout <full commit sha>
npm ci
npm run build

请固定完整的提交 SHA,而不是分支名称:可以使用 v0.2.0 标签的提交(git rev-list -n 1 v0.2.0),或 main 上更晚的提交。npm ci 会严格按照已提交的锁定文件安装。

设置

使用 npm 包时,请在 MCP 客户端配置的 env 块中设置变量(参见 MCP Connector Setup(Claude Desktop 和 Claude Code));该包不附带 .env 文件。在 git 检出目录中:

cp .env.example .env
# Add HETZNER_API_TOKEN to .env (Read & Write token from the Hetzner Cloud Console)

npm run refresh-spec 和 npm run generate 不属于设置步骤:它们会更改工具接口(参见 规范更新)。

服务从环境中读取配置。启动时,它还会加载包目录中的 .env 文件(与 package.json 位于同一目录,使用 dotenv),绝不会加载当前工作目录中的文件;已设置的变量优先。部署时也可以从任意工作目录显式传入该文件:node --env-file=/path/to/.env dist/index.js。

可选:针对真实 API 进行冒烟测试(四次只读调用):

npm run test:live
配置

只需设置 HETZNER_API_TOKEN。下表中的默认值由 tests/config.test.ts 固定。非正数的数值、未知的布尔值或日志级别都会回退到默认值。但以下异常会导致服务在启动时停止:无效的 HETZNER_API_BASE 和未知的 HETZNER_READ_ONLY 值。

变量默认值含义
HETZNER_API_TOKEN(必填)Hetzner Cloud API 令牌,每个请求都会将其作为 bearer 令牌发送。服务可以执行此令牌所允许的所有操作。
HETZNER_API_BASEhttps://api.hetzner.cloud/v1API 基础 URL。必须使用 https;仅当地址为 localhost、127.0.0.1 或 ::1 时,才允许使用普通 http。其他任何值都会导致服务在启动时停止。仅在测试或使用本地模拟上游时覆盖此值。
HETZNER_CONFIRM_WRITESfalsetrue、1 或 yes:所有非只读工具都会返回预览,除非调用中包含 confirm: "YES"。
HETZNER_READ_ONLYfalsetrue、1 或 yes:所有未标注为只读的工具,以及使用 GET 以外方法的 hcloud_raw_request,都会返回 isError,且不发送请求。此项会在确认防护之前检查。工具列表和架构不会改变。除 true、1、yes、false、0、no 或空值以外的任何值都会导致服务在启动时停止。
HETZNER_DENY_TOOLS(空)以逗号分隔的工具名称 glob 模式(* 匹配任意字符,? 匹配一个字符;匹配整个名称,区分大小写),例如 hcloud_delete_*,hcloud_raw_request。匹配的工具会返回 isError,且不发送请求,包括只读工具。工具列表和架构不会改变。模式使用服务自身的 hcloud_* 名称,而不是带网关前缀的名称;如果某个模式未匹配任何工具,服务会在启动时停止。禁止某个工具不会阻止通过 hcloud_raw_request 访问其端点,因此还必须禁止 hcloud_raw_request,否则所有被禁止的端点仍可通过它访问。
LOG_LEVELwarndebug、info、warn 或 error。日志以 JSON 格式写入 stderr;stdout 用于承载 MCP 协议。
HTTP_TIMEOUT_MS30000单个 API 请求的墙钟时间预算,包括所有尝试和重试延迟。
HTTP_MAX_RETRY_DELAY_MS10000单次重试延迟的最长时间。如果 429 响应的 Retry-After 要求等待更久,则会立即将其作为错误返回。
ACTION_POLL_TIMEOUT_MS45000wait: true 调用的墙钟时间预算,从调用开始时计时(包括写请求、轮询请求及其重试)。同时也是 hcloud_wait_action 的 timeout_ms 参数上限。
ACTION_POLL_INTERVAL_MS2000两次轮询之间的间隔。hcloud_wait_action 的 interval_ms 参数不能低于 1000 或此值,以较低者为准。
PAGINATION_MAX_ITEMS500自动分页列表收集项目数的软上限;达到上限的列表会报告 truncated: true。
PAGINATION_MAX_PAGES10自动分页列表请求页数的软上限。
MAX_OUTPUT_BYTES8388608工具结果文本的最大字节数,按发送时的字节数计算(JSON 转义后)。超出长度的结果会被截断,并以 [output truncated by MAX_OUTPUT_BYTES=...] 结尾。高于默认值的设置会被调低至默认值,以确保单条结果低于 10 MiB 的标准输入输出限制。
PAGINATION_TIMEOUT_MS45000单个自动分页列表的墙钟时间预算。超时后,已读取的页面会连同 truncated: true 和 note 一起返回。
MCP_SERVE_MODERN_PROTOCOLfalsetrue、1 或 yes:还会通过 stdio 提供 MCP 2026-07-28 修订版(参见 MCP 协议)。使用 initialize 打开的客户端会获得与值为 false 时相同的 2025 年时代会话。

仅用于开发:RUN_LIVE_TESTS=1 会启用 tests/live-smoke.test.ts(由 npm run test:live 设置);HETZNER_LIVE_SMOKE_ANCHORS 可选用于指定测试预期能找到的服务器。

超时和重试

重试:收到 429 后,会在 Retry-After 指定的时间后重试;如果缺少该标头,则会在短暂退避后重试(Hetzner 每秒补充一个请求;RateLimit-Reset 表示令牌桶再次满载的时间,不会用作延迟时间)。收到 5xx 后会进行退避重试,但 POST 除外,因为请求可能已经处理。使用默认值时,一次工具调用会在约 max(HTTP_TIMEOUT_MS, ACTION_POLL_TIMEOUT_MS) 时间内返回结果(tests/call-budget.test.ts 会测量这一点),因此不会超过 60 秒的客户端调用超时;这也是 MCP 客户端和网关中常见的超时值。提高这些值时,请保持这种关系。自动分页的列表会在 PAGINATION_TIMEOUT_MS 时间预算内每页发送一个请求;预算用尽时,已读取的页面会连同 truncated: true 和 note 一起返回,不会返回看起来完整的列表。

成功写入后,如果轮询失败或预算用尽,工具会返回写入响应(例如新资源 ID 和一次性 root_password),并附带 polling_timed_out: true;如果轮询失败,还会附带 polling_error。

MCP 协议

该服务仅通过 stdio 使用 MCP,不会开放网络端口。

  • **协议修订版本:**客户端请求 2024-11-05、2025-03-26、2025-06-18 或 2025-11-25 时,会收到相应的修订版本;客户端在 initialize 中请求较新的版本(例如 2026-07-28)时,会收到 2025-11-25(tests/server.test.ts)。
  • **2026-07-28 为可选启用:**设置 MCP_SERVE_MODERN_PROTOCOL=true 后,服务也会响应通过 server/discover 建立连接的客户端,并为其提供 2026-07-28 修订版本和相同的工具。通过 initialize 建立连接的客户端仍会收到上述 2025 年时代的会话(tests/serve-protocol.test.ts)。默认值为 false:自动模式下的客户端(例如 python mcp 客户端)一旦发现新修订版本可用,就会切换到该版本,因此只有在确认客户端支持后才启用。请参阅 docs/adr/0001-mcp-sdk-v2.md。
  • **消息大小限制:**单条传入的 JSON-RPC 消息(即一行 stdin)最大为 10 MiB,这是 MCP SDK 的 stdio 限制(tests/transport-lifecycle.test.ts)。超长行会关闭传输:服务会在 stderr 上记录 mcp transport error,并以代码 1 退出。较大的参数(例如 user_data)应远小于此大小。对于传出消息,工具结果会截断至 MAX_OUTPUT_BYTES(最多 8 MiB,tests/output-cap.test.ts),并以 [output truncated by MAX_OUTPUT_BYTES=...] 标记结尾。

MCP Connector 设置(Claude Desktop / Claude Code)

将以下内容追加到客户端的 MCP 配置中(Claude Desktop 使用 ~/Library/Application Support/Claude/claude_desktop_config.json,Claude Code 则使用相应的配置文件)。

方案 A:通过 npm 安装
{
  "mcpServers": {
    "hetzner-cloud": {
      "command": "hetzner-cloud-mcp",
      "env": {
        "HETZNER_API_TOKEN": "...",
        "HETZNER_CONFIRM_WRITES": "false",
        "LOG_LEVEL": "warn"
      }
    }
  }
}
方案 B:从 git 检出
{
  "mcpServers": {
    "hetzner-cloud": {
      "command": "node",
      "args": ["/absolute/path/to/the-real-hetzner-mcp/dist/index.js"],
      "env": {
        "HETZNER_API_TOKEN": "...",
        "HETZNER_CONFIRM_WRITES": "false",
        "LOG_LEVEL": "warn"
      }
    }
  }
}
方案 C:使用 npx
{
  "mcpServers": {
    "hetzner-cloud": {
      "command": "npx",
      "args": ["-y", "@mguttmann/hetzner-cloud-mcp@>=0.2.0"],
      "env": {
        "HETZNER_API_TOKEN": "...",
        "HETZNER_CONFIRM_WRITES": "false",
        "LOG_LEVEL": "warn"
      }
    }
  }
}

重启客户端以应用更改。tools/list 应显示 tests/snapshots/tools-contract.json 中固定的工具,名称均为 hcloud_*。

工具:概览

手工封装的工具
工具功能说明
hcloud_list_servers列出服务器,支持 name_contains 筛选,并默认按 name 排序。
hcloud_get_server通过 id 或 name 获取服务器。
hcloud_server_power使用单个工具执行 poweron / poweroff / reboot / shutdown / reset。
hcloud_server_rebuild重建服务器,接受 image_id 或 image_name。
hcloud_server_snapshot使用默认 type=snapshot 执行 create_image。
hcloud_server_backup开启或关闭自动备份。
hcloud_server_rescue开启或关闭救援模式,默认 type=linux64。
hcloud_server_change_type更改服务器类型,默认 upgrade_disk=false。
hcloud_get_server_metrics获取服务器指标,接受 id 或 name,默认时间范围为“过去 1 小时”。
hcloud_apply_firewall_to_server通过 ID 或名称为服务器应用防火墙。
hcloud_raw_request向 API 发送任意请求。查询参数放在 query 中;如果 path 会被 URL 规范化处理更改,或包含 %2F、%5C 或 %2E,则会被拒绝。
hcloud_wait_action轮询操作,直到成功、出错或超时。
生成的工具

每个 OpenAPI 操作对应一个工具,命名规则为 hcloud_<verb>_<resource> 或 hcloud_<resource>_<action>_action。如果与封装工具名称冲突,生成的工具会添加后缀 _raw(hcloud_list_servers_raw、hcloud_get_server_raw、hcloud_get_server_metrics_raw)。

在 Inspector 中运行 tools/list 查看完整列表。

输入验证

在处理程序运行前,参数会根据工具声明的 inputSchema 进行检查。底层 MCP SDK 服务只验证 tools/call 请求的结构,因此这项检查负责确保参数符合所公布的架构。违反要求时会返回一个 isError 结果,其中注明不符合要求的属性;处理程序不会被调用,也不会向 Hetzner API 发送请求。

验证内容如下:

  • 资源 ID 必须是大于等于 1 的 JSON 整数。 字符串形式的数字(例如 "42")会被拒绝,而不会强制转换为数字。API 声明为字符串的路径参数 (id_or_name、rr_name、rr_type)仍保持为字符串,但用作路径的字符串 必须对应单个路径段,详见下文。
  • 顶层类型、enum、minimum/maximum、minLength/maxLength、扁平数组元素 (元素类型、items.enum、items.minimum/maximum),以及 required。对于声明为标量数组的参数,也接受裸标量,并按照元素架构进行 检查:对于 sort 或 status 这类可重复的 查询 参数,它序列化后恰好是 相同的单个参数,因此拒绝它会破坏一直以来都能正常工作的调用。唯一会放入 请求 正文 的数组类型参数 hcloud_server_rescue.ssh_keys 会将标量规范化为 含一个元素的数组,因此调用者发送的值始终会被使用或拒绝,而不会被静默丢弃。 对错误数组的逐元素错误消息最多显示前 10 条,外加错误数量 (tests/validate-input.test.ts),因此大型输入不会被扩增到结果或日志中。
  • 未知的顶层属性,适用于架构声明了 additionalProperties: false 的工具 (所有包装器和所有生成的工具)。带外键 confirm、wait 和 auto_paginate 始终会被容忍,因此,即使 HETZNER_CONFIRM_WRITES 已禁用仍 发送 confirm,或将 wait / auto_paginate 发送给未声明这些参数的工具, 都不会报错;这些键会在构建请求前被丢弃。
  • 路径参数必须恰好对应一个路径段。 对于 API 声明为字符串的参数 (id_or_name、rr_name),如果值为空、为 . 或 ..、包含 / 或 \, 或包含百分号编码的分隔符或点(任意大小写的 %2f、%5c、%2e),则会被拒绝。 原因:百分号编码只能在本地 URL 解析器看来将这样的值保留在一个路径段中。 解析路径的主体是 源站,它会解码编码后的分隔符,并在路由前解析点路径段, 因此若没有此检查,精心构造的值可能会指向与工具自身不同的资源。合法值不会 被改动:IDN 区域名(原始形式或 punycode)、末尾的点、@、*、*.sub、 _dmarc 等都能通过,并会像以前一样进行百分号编码。
  • 每个插值位置的路径段都会进行百分号编码,且 HTTP 客户端会拒绝任何会被 URL 规范化改变的路径。以下内容会被拒绝:? 和 #(会将路径截断为查询或 片段)、\(对 URL 解析器来说是路径分隔符)、RFC 3986 pchar 之外的字符 (例如控制字符,解析器会将其剥离,因此否则它们可能会形成点路径段)、空路径段, 以及所有形式的 . / .. 路径段,包括百分号编码形式。随后会将拼装后的 URL 与预期目标进行比较:其源站必须是已配置的源站,路径必须与基础路径加上请求路径 完全一致。因此,任何残留的规范化都会中止请求,而不是触发重定向。此客户端检查 只能识别本地 URL 解析器会重写的内容,因此它是最后一道防线,而非完整保障: 上述逐参数规则用于覆盖 源站 会重写的内容。
  • 被拒绝的输入不会发出任何 HTTP 请求,而不是发送经过清理的请求。

刻意不强制执行的内容:请求 body 的内容。这些树状结构遵循 Hetzner Cloud API 自身的契约:API 会对其进行验证,并将其 400 响应原样返回给调用者。也不会评估 format、pattern 和 nullable。

验证失败会记录有问题的属性名称和有问题值的 类型;值本身只会反馈给调用者, 因此,包含私钥或密码的格式错误 body 不会进入日志。 关于 hcloud_raw_request 的说明:它是有意保留的逃生通道,按设计接受任意路径,因此不受资源白名单限制。它固定使用配置的 API 基础 URL(源和路径前缀),但获得此工具授权的调用方可以访问 Hetzner Cloud API 的任意端点。与其他工具一样,如果其 path 中包含百分号编码的分隔符或点(任意大小写的 %2F、%5C、%2E),它会拒绝该请求,因为编码分隔符的含义由源决定,而不是由本地 URL 解析器决定。请据此授予 hcloud_raw_request 的使用权限。

规范更新

当 Hetzner 更新 OpenAPI 时:

npm run refresh-spec       # re-downloads specs/cloud.spec.json
# update the fetch date and the SHA-256 in specs/SOURCE.md
npm run generate           # rebuilds src/tools/generated/operations.ts
npm test                   # codegen and contract snapshots show the diff
npm run refresh-snapshot   # rewrite the snapshots deliberately (after review)
git add specs/cloud.spec.json specs/SOURCE.md src/tools/generated/operations.ts tests/snapshots/tool-registry.json tests/snapshots/tools-contract.json
git commit -m "chore(spec): refresh from Hetzner"

刷新会更改工具输入模式,也可能添加工具,MCP 客户端和网关会将其视为契约变更。请在 CHANGELOG.md 的“行为变更”下列出。如果新规范要求现有工具的 body 字段必填,请在 scripts/generate.ts 中保留旧列表 PINNED_BODY_REQUIRED,以免收紧工具契约;缺少该字段的调用仍会被 API 拒绝。新工具会改变网关基线中的工具数量和名称哈希值,这两项保存在一个文件 tests/gateway-baseline.json 中,tests/tools-contract.test.ts 以及 CI 和发布冒烟测试都会读取该文件。

开发

工具契约快照

tests/tools-contract.test.ts 会按照 stdio 服务的方式构建注册表(src/build-registry.ts),并将每个工具与 tests/snapshots/tools-contract.json 进行比较:名称、inputSchema.required、inputSchema 规范化(按键排序)JSON 的 sha256(分别在启用和未启用 HETZNER_CONFIRM_WRITES=true 时计算)、描述的 sha256,以及注解。它还会将工具数量和已排序工具名称的 sha256 固定为网关基线;这两个值保存在 tests/gateway-baseline.json 中,不会被任何脚本改写。

npm run refresh-snapshot 会重新生成 tests/snapshots/tool-registry.json 和 tests/snapshots/tools-contract.json。仅在有意更改契约时运行,并检查差异:required、模式或描述哈希发生变化,都会改变 MCP 客户端看到的内容。

Stdio 冒烟测试

npm run smoke 会启动 dist/index.js(请先运行 npm run build),通过 stdio 发送 initialize、notifications/initialized 和 tools/list,并以 JSON 格式输出协商的协议版本、serverInfo、工具数量以及已排序工具名称的 sha256。此测试无需网络:

HETZNER_API_TOKEN=dummy HETZNER_API_BASE=http://127.0.0.1:1 npm run smoke -- \
  --min-tools <n> --expect-names-sha256 <sha256>
# or with an env file, passed to node as --env-file:
npm run smoke -- --env-file ./smoke.env

选项:--protocol-version <v>、--min-tools <n>、--expect-names-sha256 <hex>、--baseline <file>(从包含 toolCount 和 namesSha256 的 JSON 文件中同时设置这两个值)、--server <path>(默认为 dist/index.js)和 --timeout-ms <ms>;默认值位于 scripts/smoke-stdio.mjs 顶部。退出码为 0 表示所有检查均通过,1 表示检查失败,2 表示服务未能启动或响应。CI 使用 --baseline tests/gateway-baseline.json 运行该测试;tests/tools-contract.test.ts 也会读取此文件。

手动验证步骤

在确认发布就绪之前运行:

  1. npm run inspector 会打开 MCP Inspector 并连接此服务。
  2. tools/list:确认工具数量与 tests/snapshots/tools-contract.json 中的 toolCount 相同,并确认上表中的每个封装器都已出现。
  3. hcloud_list_servers(不带参数):至少与账户中一台已知服务器的信息核对。
  4. 使用 name: "<one of your server names>" 调用 hcloud_get_server:应返回 id、type、ip。
  5. 使用 { name: "mcp-smoke", public_key: "<your test key>" } 调用 hcloud_create_ssh_key:记下返回的 id。
  6. 使用该 id 调用 hcloud_delete_ssh_key:确认已彻底删除。

冒烟测试中不要对生产服务器执行电源、重建或快照操作。

安全

请参阅 SECURITY.md,了解受支持的版本、如何私下报告漏洞,以及威胁模型(令牌权限、确认保护、按工具名称授予权限)。

许可证

MIT,详见 LICENSE;但 vendored Hetzner Cloud API 规范 (specs/cloud.spec.json)归 Hetzner 所有;详见 NOTICE 和 specs/SOURCE.md。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。