内容
# gigahost-mcp
一个小型的 [MCP](https://modelcontextprotocol.io) 服务器,暴露 [Gigahost](https://gigahost.no) API(`https://api.gigahost.no/api/v0`)给任何兼容 MCP 的客户端(Claude Code/Desktop, Cursor, Windsurf, Cline, 或您自己的)。
Gigahost API 是统一的 REST,因此整个接口(约 150 个端点:DNS 区域/记录,`.no` 域名,服务器,网络托管,BGP,DynDNS)被一个单独的直通工具封装,而不是每个端点一个工具。模型直接驱动路径。
## 工具
`gigahost_request(method, path, body=None, query=None, files=None)`
- `method` — `GET` / `POST` / `PUT` / `DELETE`
- `path` — 例如 `/dns/zones`,`/servers/123/reboot`
- `body` — `POST`/`PUT` 的 JSON 正文
- `query` — 查询字符串参数
- `files` — `{form_field: local_file_path}` 用于多部分上传(例如 `POST /webhosting/{id}/files/upload`)。设置后,`body` 作为多部分表单字段发送,而不是 JSON。
返回 `{"status": <http_status>, "data": <json|text>}`,或在网络/文件失败时返回 `{"error": ...}`。
这涵盖了整个 Gigahost REST 接口:所有 JSON 端点和多部分文件上传。唯一限制是 API 密钥的权限范围。
端点参考:<https://gigahost.no/en/api-dokumentasjon>
### 示例
以下调用显示为模型生成的工具参数。
列出 DNS 区域:
```json
{ "method": "GET", "path": "/dns/zones" }
```
向区域 4040 添加 A 记录:
```json
{
"method": "POST",
"path": "/dns/zones/4040/records",
"body": { "record_name": "@", "record_type": "A", "record_value": "203.0.113.10", "record_ttl": 3600 }
}
```
重启服务器:
```json
{ "method": "GET", "path": "/servers/123/reboot" }
```
上传文件到网络托管账户(多部分):
```json
{
"method": "POST",
"path": "/webhosting/55/files/upload",
"files": { "file": "/local/path/index.html" }
}
```
## 前提条件
- **Python 3.11+**
- 一个 **Gigahost API 密钥**(`flux_live_<hex>`),在 Flux 仪表板中创建,位于 **Konto → API keys**。将其范围限定为仅所需的权限(例如 DNS / 域名)。它是可以撤销的,并且仅在创建时显示一次。
- 密钥从环境变量 `GIGAHOST_API_KEY` 中读取。
## 安装
选择您已经使用的任意一种。
### 选项 A — uv(零安装)
依赖项内联声明(PEP 723),因此无需安装:
```sh
GIGAHOST_API_KEY=flux_live_xxxxxxxx uv run /path/to/server.py
```
### 选项 B — pip / venv
```sh
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
GIGAHOST_API_KEY=flux_live_xxxxxxxx python server.py
```
### 自检(离线,无密钥,无网络)
```sh
uv run server.py --selfcheck # 或:python server.py --selfcheck
# 输出:ok
```
## 配置您的 MCP 客户端
大多数客户端读取具有 `mcpServers` 映射的 JSON 配置。添加以下内容之一,使用 `server.py` 的**绝对路径**和 `env` 中的密钥。
使用 uv:
```json
{
"mcpServers": {
"gigahost": {
"command": "uv",
"args": ["run", "/absolute/path/to/server.py"],
"env": { "GIGAHOST_API_KEY": "flux_live_xxxxxxxx" }
}
}
}
```
使用 venv / 系统 Python:
```json
{
"mcpServers": {
"gigahost": {
"command": "python",
"args": ["/absolute/path/to/server.py"],
"env": { "GIGAHOST_API_KEY": "flux_live_xxxxxxxx" }
}
}
}
```
配置文件位置因客户端而异,例如:
- **Claude Desktop** — `claude_desktop_config.json`(设置 → 开发者 → 编辑配置)
- **Cursor** — `~/.cursor/mcp.json`
- **Windsurf / Cline / 其他** — 它们的 MCP 设置 JSON
### Claude Code(CLI 快捷方式)
```sh
claude mcp add -s user gigahost -e GIGAHOST_API_KEY=flux_live_xxxxxxxx \
-- uv run /absolute/path/to/server.py
```
配置后,客户端应列出带有 `gigahost_request` 工具的 `gigahost` 服务器。通过要求它 `GET /dns/zones` 进行烟雾测试。
## 密钥权限(范围)
创建 Flux API 密钥时,您为**每个区域**设置了一个访问级别。这限制了 `gigahost_request` 可以执行的操作,与代码无关:
- **Ingen** — 无访问权限,调用返回 `403`。
- **Les** — 只读,`GET` 有效,写入(`POST`/`PUT`/`DELETE`)返回 `403`。
- **Les/skriv** — 完全读取 + 写入。
区域映射到 API 路径前缀:
| Flux 区域 | 路径前缀 |
|------------------|--------------------------|
| DNS og domener | `/dns/...` |
| Servere | `/servers/...` |
| Webhotell | `/webhosting/...` |
| Deploy | `/deploy/...`, `/reinstall/...` |
| Rack | `/bgp/...` |
| Fakturering | `/my/invoices` |
| Min konto | `/account/...`, `/my/account` |
`403 "You do not have permission for this operation"` 表示密钥缺乏该区域的正确级别(例如,当调用需要 `Les/skriv` 时为 `Les`)。授予每个区域所需的最低权限,而不是 blanket `Les/skriv`。
## 安全
- API 密钥仅从 `GIGAHOST_API_KEY` 读取。密钥不会写入此存储库。
- 将密钥放入客户端配置文件(或通过 `claude mcp add -e` 放入 `~/.claude.json`)会以明文存储。对于您自己的机器上的个人作用域密钥,这是可以接受的。如果密钥泄露,请在 Flux 中撤销并轮换。
## 许可证
MIT