mcpField
O
ovh-api-mcp

ovh-api-mcp

Local
github.com/davidlandaisCloud & Infra3Updated 33w ago

About ovh-api-mcp

ovh-api-mcp is an MCP server for LLM clients that need to explore and call OVH API v1 and v2 endpoints. It exposes JavaScript-based search and execution tools, running code in a constrained QuickJS sandbox and validating requests against the OpenAPI spec.

Key features

  1. 01Search OVH OpenAPI endpoints and schemas
  2. 02Call OVH API v1 and v2
  3. 03Run JavaScript in a bounded QuickJS sandbox
  4. 04Validate calls against the OpenAPI spec
  5. 05Support HTTP and stdio transports

Use cases

  1. 01Find an OVH endpoint and inspect its parameters
  2. 02Manage OVH resources through API requests
  3. 03Connect an MCP client to OVH APIs

MCP support

The MCP server exposes `search` and `execute` tools to MCP clients. It supports Streamable HTTP and stdio transports.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

mcp.json · Universal config
{
"mcpServers": {
"davidlandais-ovh-api": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"OVH_APPLICATION_KEY",
"-e",
"OVH_APPLICATION_SECRET",
"-e",
"OVH_CONSUMER_KEY",
"-e",
"OVH_ENDPOINT",
"-e",
"OVH_SERVICES",
"-e",
"OVH_CLIENT_ID",
"-e",
"OVH_CLIENT_SECRET",
"ghcr.io/davidlandais/ovh-api-mcp:0.3.0"
],
"env": {
"OVH_APPLICATION_KEY": "<OVH_APPLICATION_KEY>",
"OVH_APPLICATION_SECRET": "<OVH_APPLICATION_SECRET>",
"OVH_CONSUMER_KEY": "<OVH_CONSUMER_KEY>",
"OVH_ENDPOINT": "<OVH_ENDPOINT>",
"OVH_SERVICES": "<OVH_SERVICES>",
"OVH_CLIENT_ID": "<OVH_CLIENT_ID>",
"OVH_CLIENT_SECRET": "<OVH_CLIENT_SECRET>"
}
}
}
}
Run commanddocker run -i --rm -e OVH_APPLICATION_KEY -e OVH_APPLICATION_SECRET -e OVH_CONSUMER_KEY -e OVH_ENDPOINT -e OVH_SERVICES -e OVH_CLIENT_ID -e OVH_CLIENT_SECRET ghcr.io/davidlandais/ovh-api-mcp:0.3.0
Environment variables to set
OVH_APPLICATION_KEYSecretOVH API application key
OVH_APPLICATION_SECRETSecretOVH API application secret
OVH_CONSUMER_KEYSecretOVH API consumer key
OVH_ENDPOINTOVH API region: eu, ca, or us
OVH_SERVICESComma-separated OVH API services, or * for all
OVH_CLIENT_IDOVH OAuth2 client ID (service account, alternative to API keys)
OVH_CLIENT_SECRETSecretOVH OAuth2 client secret (service account)

Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.

Packages
ocighcr.io/davidlandais/ovh-api-mcp:0.3.0

Tools

No tool list yet

Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.

Details

From the project README

ovh-api-mcp

CI License: MIT Rust MCP Status

A native Model Context Protocol (MCP) server that gives LLMs full access to the OVH API (v1 and v2). Built in Rust for minimal footprint (~19 MB Docker image, ~1.2 MiB RAM).

Early Release — Designed for local development use. Security hardening has been applied (sandboxed execution, spec validation, secret protection), but the server has not been battle-tested at scale. Do not expose it to the public internet. Feedback and bug reports are welcome.

ovh-api-mcp MCP server

How it works

The server exposes two MCP tools:

ToolDescription
searchExplore the OVH OpenAPI spec using JavaScript — find endpoints, inspect schemas, read parameters
executeCall any OVH API endpoint using JavaScript — authentication is handled transparently

The LLM writes JavaScript that runs inside a sandboxed QuickJS engine with resource limits (memory, CPU timeout, stack size). Every API call is validated against the loaded OpenAPI spec before execution.

The server supports two transport modes:

  • HTTP (Streamable HTTP) — for web-based clients and Docker deployments
  • stdio — for direct integration with Claude Desktop, Cursor, and MCP inspectors

OVH credentials are optional at startup: the server starts and exposes its tools even without API keys. Tools return a clear error when called without credentials.

Quick start

With stdio (Claude Desktop / Cursor)

Add to your MCP client configuration:

{
  "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"
      }
    }
  }
}
With Docker
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
From source
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
Pre-built binaries

Download from GitHub Releases — available for macOS (x86_64, aarch64) and Linux (x86_64 musl).

Claude Code configuration (HTTP mode)
{
  "mcpServers": {
    "ovh-api": {
      "type": "http",
      "url": "http://localhost:3104/mcp",
      "headers": {
        "Authorization": "Bearer local"
      }
    }
  }
}

The Authorization header is required to bypass Claude Code's OAuth discovery. See claude-code#2831.

OVH credentials

You need three values: an application key, an application secret, and a consumer key.

Go to the token creation page for your region, log in with your OVH account, set the permissions and validity, and you'll get all three keys at once:

RegionURL
Europehttps://auth.eu.ovhcloud.com/api/createToken
Canadahttps://auth.ca.ovhcloud.com/api/createToken
UShttps://auth.us.ovhcloud.com/api/createToken

For full API access, set all four methods (GET, POST, PUT, DELETE) with path /*.

OAuth2 authentication (service accounts)

As an alternative to API keys, you can use OVH service accounts with OAuth2 client credentials:

VariableDescription
OVH_CLIENT_IDService account ID
OVH_CLIENT_SECRETService account secret

Service accounts are created via the OVH API (POST /me/api/oauth2/client with flow: CLIENT_CREDENTIALS). You must then create an IAM policy (POST /v2/iam/policy) to grant API permissions to the service account. See the OVHcloud documentation for details.

The server auto-detects the auth mode from environment variables. Do not set both API keys and OAuth2 credentials at the same time.

CLI options

Options:
  --transport <TRANSPORT>        Transport mode: http, stdio [env: OVH_TRANSPORT] [default: http]
  --port <PORT>                  Port to listen on [env: PORT] [default: 3104]
  --host <HOST>                  Host to bind to [default: 127.0.0.1]
  --endpoint <ENDPOINT>          OVH API endpoint: eu, ca, us [env: OVH_ENDPOINT] [default: eu]
  --app-key <APP_KEY>            OVH application key [env: OVH_APPLICATION_KEY]
  --app-secret <APP_SECRET>      OVH application secret [env: OVH_APPLICATION_SECRET]
  --consumer-key <CONSUMER_KEY>  OVH consumer key [env: OVH_CONSUMER_KEY]
  --client-id <CLIENT_ID>        OVH OAuth2 client ID [env: OVH_CLIENT_ID]
  --client-secret <CLIENT_SECRET> OVH OAuth2 client secret [env: OVH_CLIENT_SECRET]
  --services <SERVICES>          Services to load, comma-separated or "*" [env: OVH_SERVICES] [default: *]
  --cache-dir <PATH>             Directory to cache the merged spec [env: OVH_CACHE_DIR]
  --cache-ttl <SECONDS>          Cache TTL in seconds, 0 to disable [env: OVH_CACHE_TTL] [default: 86400]
  --no-cache                     Disable spec caching entirely
  --max-code-size <BYTES>        Maximum code input size [env: OVH_MAX_CODE_SIZE] [default: 1048576]

Usage examples

Once connected, the LLM can use the tools like this:

Search for DNS endpoints:

// search tool
(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;
}

List your domain zones:

// execute tool
async () => await ovh.request({ method: "GET", path: "/v1/domain/zone" })

Get DNS records for a domain:

// execute tool
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;
}

Security

  • Sandboxed execution — JavaScript runs in QuickJS with memory limit (64 MiB), stack limit (1 MiB), and execution timeout (10s for search, 30s for execute)
  • Spec-validated API calls — every ovh.request() call is matched against the loaded OpenAPI spec; unknown endpoints or wrong HTTP methods are rejected
  • Path injection prevention — API paths containing ?, #, or .. are rejected
  • Secret protection — app_secret and consumer_key are stored using secrecy (zeroized on drop)
  • No HTTP redirects — prevents credential leakage to third-party domains
  • Non-root container — Docker image runs as unprivileged user

Architecture

src/
  main.rs      CLI, logging, transport selection (HTTP/stdio), graceful shutdown
  tools.rs     MCP tool definitions (search, execute) via rmcp macros
  sandbox.rs   QuickJS sandboxed JS execution with resource limits
  auth.rs      OVH API client with signature, clock sync, request handling
  spec.rs      OpenAPI spec fetching, caching, merging, and path validation
  types.rs     Input types for MCP tool parameters

License

MIT — David Landais

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.