内容
# ovh-api-mcp
[](https://github.com/davidlandais/ovh-api-mcp/actions/workflows/ci.yml)
[](LICENSE)
[](https://www.rust-lang.org/)
[](https://modelcontextprotocol.io/)
[](#status)
一个原生的 **模型上下文协议(MCP)** 服务器,为 LLMs 提供对 **OVH API(v1 和 v2)** 的完全访问权限。采用 Rust 构建,占用空间极小(约 19 MB Docker 镜像,约 1.2 MiB RAM)。
> **早期发布** — 设计用于 **本地开发使用**。已应用安全强化(沙箱执行、规范验证、机密保护),但服务器尚未在大规模上经过实战测试。请勿将其暴露在公共互联网上。欢迎反馈和错误报告。
<a href="https://glama.ai/mcp/servers/davidlandais/ovh-api-mcp">
<img width="380" height="200" src="https://glama.ai/mcp/servers/davidlandais/ovh-api-mcp/badge" alt="ovh-api-mcp MCP 服务器" />
</a>
## 工作原理
服务器暴露了两个 MCP 工具:
| 工具 | 描述 |
|------|-------------|
| `search` | 使用 JavaScript 探索 OVH OpenAPI 规范 — 查找端点、检查模式、读取参数 |
| `execute` | 使用 JavaScript 调用任何 OVH API 端点 — 认证处理透明 |
LLM 编写的 JavaScript 在 **沙箱 QuickJS 引擎** 中运行,带有资源限制(内存、CPU 超时、堆大小)。每个 API 调用在执行前都会根据加载的 OpenAPI 规范进行验证。
服务器支持两种传输模式:
- **HTTP** (可流式 HTTP)— 适用于基于 Web 的客户端和 Docker 部署
- **stdio** — 适用于与 Claude Desktop、Cursor 和 MCP 检查器的直接集成
OVH 凭证在启动时是可选的:服务器启动并暴露其工具,即使没有 API 密钥。工具在调用时如果没有凭证会返回明确的错误。
## 快速入门
### 使用 stdio(Claude Desktop / Cursor)
在您的 MCP 客户端配置中添加:
```json
{
"mcpServers": {
"ovh-api": {
"command": "ovh-api-mcp",
"args": ["--transport", "stdio"],
"env": {
"OVH_APPLICATION_KEY": "your_app_key",
"OVH_APPLICATION_SECRET": "your_app_secret",
"OVH_CONSUMER_KEY": "your_consumer_key"
}
}
}
}
```
### 使用 Docker
```bash
docker run -d --name ovh-api \
-e OVH_APPLICATION_KEY=your_app_key \
-e OVH_APPLICATION_SECRET=your_app_secret \
-e OVH_CONSUMER_KEY=your_consumer_key \
-p 3104:3104 \
ghcr.io/davidlandais/ovh-api-mcp:latest
```
### 从源代码构建
```bash
cargo install --git https://github.com/davidlandais/ovh-api-mcp
export OVH_APPLICATION_KEY=your_app_key
export OVH_APPLICATION_SECRET=your_app_secret
export OVH_CONSUMER_KEY=your_consumer_key
ovh-api-mcp --port 3104
```
### 预编译二进制文件
从 [GitHub Releases](https://github.com/davidlandais/ovh-api-mcp/releases) 下载 — 适用于 macOS(x86_64,aarch64)和 Linux(x86_64 musl)。
### Claude Code 配置(HTTP 模式)
```json
{
"mcpServers": {
"ovh-api": {
"type": "http",
"url": "http://localhost:3104/mcp",
"headers": {
"Authorization": "Bearer local"
}
}
}
}
```
> `Authorization` 头部是必需的,用于绕过 Claude Code 的 OAuth 发现。参见 [claude-code#2831](https://github.com/anthropics/claude-code/issues/2831)。
## OVH 凭证
您需要三个值:一个 **应用程序密钥**,一个 **应用程序机密**,和一个 **消费者密钥**。
前往您所在区域的令牌创建页面,登录您的 OVH 账户,设置权限和有效期,您将一次性获得这三个密钥:
| 区域 | URL |
|--------|-----|
| 欧洲 | https://auth.eu.ovhcloud.com/api/createToken |
| 加拿大 | https://auth.ca.ovhcloud.com/api/createToken |
| 美国 | https://auth.us.ovhcloud.com/api/createToken |
对于完全的 API 访问权限,请设置所有四种方法(`GET`,`POST`,`PUT`,`DELETE`)和路径 `/*`。
### OAuth2 认证(服务账户)
作为 API 密钥的替代方案,您可以使用带有 OAuth2 客户端凭证的 OVH 服务账户:
| 变量 | 描述 |
|----------|-------------|
| `OVH_CLIENT_ID` | 服务账户 ID |
| `OVH_CLIENT_SECRET` | 服务账户机密 |
服务账户通过 OVH API 创建(`POST /me/api/oauth2/client` 带有 `flow: CLIENT_CREDENTIALS`)。然后,您必须创建一个 IAM 策略(`POST /v2/iam/policy`)以向服务账户授予 API 权限。有关详细信息,请参见 [OVHcloud 文档](https://help.ovhcloud.com/csm/en-manage-service-account)。
服务器从环境变量中自动检测身份验证模式。请勿同时设置 API 密钥和 OAuth2 凭证。
## CLI 选项
```
选项:
--transport <TRANSPORT> 传输模式:http,stdio [env: OVH_TRANSPORT] [默认值:http]
--port <PORT> 监听端口 [env: PORT] [默认值:3104]
--host <HOST> 绑定主机 [默认值:127.0.0.1]
--endpoint <ENDPOINT> OVH API 端点:eu,ca,us [env: OVH_ENDPOINT] [默认值:eu]
--app-key <APP_KEY> OVH 应用程序密钥 [env: OVH_APPLICATION_KEY]
--app-secret <APP_SECRET> OVH 应用程序机密 [env: OVH_APPLICATION_SECRET]
--consumer-key <CONSUMER_KEY> OVH 消费者密钥 [env: OVH_CONSUMER_KEY]
--client-id <CLIENT_ID> OVH OAuth2 客户端 ID [env: OVH_CLIENT_ID]
--client-secret <CLIENT_SECRET> OVH OAuth2 客户端机密 [env: OVH_CLIENT_SECRET]
--services <SERVICES> 加载的服务,逗号分隔或 "*" [env: OVH_SERVICES] [默认值:*]
--cache-dir <PATH> 缓存合并规范的目录 [env: OVH_CACHE_DIR]
--cache-ttl <SECONDS> 缓存 TTL(秒),0 表示禁用 [env: OVH_CACHE_TTL] [默认值:86400]
--no-cache 完全禁用规范缓存
--max-code-size <BYTES> 最大代码输入大小 [env: OVH_MAX_CODE_SIZE] [默认值:1048576]
```
## 使用示例
连接后,LLM 可以像这样使用工具:
**搜索 DNS 端点:**
```javascript
// 搜索工具
(spec) => {
const results = [];
for (const [path, methods] of Object.entries(spec.paths)) {
if (path.includes("/domain/zone")) {
for (const [method, op] of Object.entries(methods)) {
results.push({ method: method.toUpperCase(), path, summary: op.summary });
}
}
}
return results;
}
```
**列出您的域名区域:**
```javascript
// 执行工具
async () => await ovh.request({ method: "GET", path: "/v1/domain/zone" })
```
**获取域名的 DNS 记录:**
```javascript
// 执行工具
async () => {
const records = await ovh.request({
method: "GET",
path: "/v1/domain/zone/example.com/record"
});
const details = [];
for (const id of records.slice(0, 10)) {
details.push(await ovh.request({
method: "GET",
path: `/v1/domain/zone/example.com/record/${id}`
}));
}
return details;
}
```
## 安全
- **沙箱执行** — JavaScript 在 QuickJS 中运行,带有内存限制(64 MiB)、堆栈限制(1 MiB)和执行超时(搜索 10 秒,执行 30 秒)
- **规范验证的 API 调用** — 每个 `ovh.request()` 调用都与加载的 OpenAPI 规范进行匹配;未知端点或错误 HTTP 方法会被拒绝
- **路径注入预防** — 包含 `?`、`#` 或 `..` 的 API 路径会被拒绝
- **机密保护** — `app_secret` 和 `consumer_key` 使用 `secrecy` 存储(在删除时归零)
- **无 HTTP 重定向** — 防止凭证泄露到第三方域
- **非 root 容器** — Docker 镜像以非特权用户运行
## 架构
```
src/
main.rs CLI、日志记录、传输选择(HTTP/stdio)、优雅关闭
tools.rs MCP 工具定义(搜索、执行)通过 rmcp 宏
sandbox.rs QuickJS 沙箱 JavaScript 执行,带有资源限制
auth.rs OVH API 客户端,带有签名、时钟同步、请求处理
spec.rs OpenAPI 规范获取、缓存、合并和路径验证
types.rs MCP 工具参数的输入类型
```
## 许可证
[MIT](LICENSE) — David Landais