Skip to main content
Glama
mgcrea

mcp-ovh-api

by mgcrea

@mgcrea/mcp-ovh-api

npm version GHCR

Сервер Model Context Protocol для OVHcloud API, ориентированный на Object Storage: бакеты, объекты, пользователей проекта, S3-учётные данные и политики хранения, которые связывают их воедино.

Сервер по умолчанию работает только на чтение. Изменяющие состояние инструменты не просто отклоняются, когда запись выключена, — они вообще не регистрируются, так что агент не может их вызвать.

Возможности

  • Подобранные инструменты для /1.0 API OVHcloud с описаниями, которые явно указывают на его ловушки (см. Ловушки, о которых стоит знать).

  • Только чтение по умолчанию. OVH_ALLOW_WRITES=1 добавляет инструменты записи; разрушительные из них дополнительно требуют явного confirm: true при каждом вызове.

  • Все три метода аутентификации OVH автоматически выбираются по присутствующим переменным окружения: сервисный аккаунт OAuth2 (рекомендуется), application key + consumer key (подпись SHA1 с автоматической коррекцией смещения часов) или статический токен доступа.

  • Пресеты политик — включая write-only, которого нет в быстрых ролях OVH.

  • Результаты списков выдаются в сводном виде, а устаревший массив objects[] в расчёте на бакет (который встраивает каждый объект бакета) подавляется на обоих концах.

  • X-Ovh-QueryID выводится при каждой ошибке, потому что это первое, о чём спрашивает поддержка OVH.

  • Запасной выход ovh_request для остальной части API (только GET, если запись не включена).

  • Нативный fetch, без зависимостей времени выполнения, кроме MCP SDK и Zod.

Related MCP server: saveformedearai

Установка

pnpm install
pnpm build

Настройка

Выберите один метод аутентификации.

(A) Сервисный аккаунт OAuth2 — рекомендуется

  1. Создайте сервисный аккаунт IAM на https://www.ovh.com/manager/#/iam/service-account.

  2. Прикрепите IAM-политику, предоставляющую ему ваш проект public cloud (для object storage: publicCloudProject:apiovh:* на ресурсе проекта).

  3. Скопируйте client id и secret в .env.

Токены действуют час, кэшируются и обновляются до истечения срока действия.

(B) Ключ приложения + потребительский ключ

Создайте тройку одним разом на https://eu.api.ovh.com/createToken/. Указанные там правила доступа зафиксированы навсегда — потребительский ключ впоследствии нельзя расширить, поэтому сразу выдайте всё, что нужно:

GET    /cloud/project/*
POST   /cloud/project/*
PUT    /cloud/project/*
DELETE /cloud/project/*
GET    /me

Запросы подписываются по SHA1 над secret+consumerKey+METHOD+URL+BODY+TIMESTAMP. Если часы расходятся с часами OVH более чем на ~30 секунд, каждый вызов завершается ошибкой с вводящим в заблуждение Invalid signature, поэтому при запуске сервер один раз опрашивает /auth/time и корректирует разницу.

(C) Статический токен доступа

Установите OVH_ACCESS_TOKEN, и он будет отправлен как Authorization: Bearer.

cp .env.example .env

Переменная

Требуется

Описание

OVH_ENDPOINT

нет

ovh-eu (по умолчанию), ovh-ca, ovh-us, kimsufi-*, soyoustart-*.

OVH_CLIENT_ID / OVH_CLIENT_SECRET

(A)

Сервисный аккаунт IAM. Их наличие выбирает OAuth2.

OVH_APPLICATION_KEY / _SECRET

(B)

Пара ключей приложения.

OVH_CONSUMER_KEY

(B)

Потребительский ключ, выпущенный вместе с ними.

OVH_ACCESS_TOKEN

(C)

Предварительно выпущенный bearer-токен.

OVH_AUTH_METHOD

нет

Принудительно задаёт oauth2, signature или accessToken. В противном случае метод определяется автоматически.

OVH_CLOUD_PROJECT

нет

Проект по умолчанию — 32-значный шестнадцатеричный serviceName, а не отображаемое имя.

OVH_REGION

нет

Регион хранения по умолчанию, в верхнем регистре (GRA, SBG, DE, UK).

OVH_ALLOW_WRITES

нет

Установите 1, чтобы зарегистрировать инструменты записи. По умолчанию выключено.

OVH_API_URL

нет

Полностью переопределяет базовый URL API.

OVH_MAX_RETRIES

нет

Лимит повторов для 401 / 429 / 5xx. По умолчанию 3.

OVH_REFRESH_SKEW_SECONDS

нет

Обновлять токен OAuth2 за это время до истечения срока. По умолчанию 60.

OVH_DEBUG

нет

Установите 1, чтобы выводить отладочные данные в stderr.

Запуск

pnpm start   # speaks JSON-RPC over stdio

Подключение к Claude Code

Добавьте в .mcp.json (проект) или ~/.claude.json (глобально):

{
  "mcpServers": {
    "ovh": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-ovh-api/dist/cli.js"],
      "env": {
        "OVH_CLIENT_ID": "...",
        "OVH_CLIENT_SECRET": "...",
        "OVH_CLOUD_PROJECT": "abcdef0123456789abcdef0123456789",
        "OVH_REGION": "UK"
      }
    }
  }
}

Просмотр инструментов

npx @modelcontextprotocol/inspector node dist/cli.js

Ловушки, о которых стоит знать

Все они вшиты в описания инструментов, но именно они объясняют устройство этого сервера:

  1. В OVH нет политик бакетов — только пользовательские политики. Один «сырой» JSON-документ на каждого пользователя проекта, и этот документ — вся поверхность контроля доступа. Установка политики заменяет всё, что этот пользователь мог делать раньше, во всех бакетах.

  2. Политика не может ограничить владельца бакета. OVH откатывается к ACL, и владелец обладает FULL_CONTROL: «если пользователь является владельцем бакета, он будет авторизован, даже если в файле политики нет явного разрешения». Поэтому ограниченный ключ должен принадлежать новому пользователю проекта, который не создавал бакет. ovh_provision_s3_user проверяет ownerId бакета и отказывает, если вы нацелили его на владельца.

  3. То же самое касается каждого объекта. Кто загружает объект, тот владеет им и получает FULL_CONTROL через ACL объекта. Поэтому простое отсутствие s3:GetObject не мешает ключу, предназначенному только для загрузки, считывать всё, что он записал, — проверено на живом API: голая политика-разрешение охотно отдавала ключу его собственные загрузки и при этом корректно запрещала все объекты, загруженные кем-то другим. Требуется явный Deny, и он действительно перебивает ACL. Именно поэтому пресет write-only содержит оператор Deny, а не просто список разрешений.

Ещё две, поменьше. Один лишь s3:PutObject по-прежнему разрешает слепую перезапись существующих ключей внутри разрешённого префикса — ключ «write-only» не является ключом «только для добавления», что является веской причиной включить версионирование на бакете. А изменения политики распространяются до ~30 секунд: проверка, выполненная через пять секунд после ovh_set_storage_policy, всё ещё показывает старое поведение, что выглядит в точности как политика, которая молча не сработала.

Инструменты

Каждый инструмент уровня проекта принимает необязательный параметр project, а каждый инструмент хранилища — необязательный region, переопределяя OVH_CLOUD_PROJECT / OVH_REGION в рамках вызова. Инструменты, помеченные W, существуют только при OVH_ALLOW_WRITES=1; помеченные ⚠️ являются разрушительными и дополнительно требуют confirm: true.

Начните с ovh_whoami. Он показывает, какой метод аутентификации активен, под какой учётной записью вы работаете и какая разница часов с OVH — а именно об этом почти всегда говорит 401 при методе подписи.

Область

Инструменты

Мета

ovh_whoami, ovh_list_projects, ovh_get_project, ovh_list_regions, ovh_get_region

Бакеты

ovh_list_buckets, ovh_get_bucket, ovh_get_bucket_lifecycle · W ovh_create_bucket, ovh_update_bucket, ovh_set_bucket_lifecycle, ⚠️ ovh_delete_bucket_lifecycle, ⚠️ ovh_delete_bucket

Объекты

ovh_list_objects, ovh_get_object, ovh_list_object_versions, ovh_presign_object · W ovh_copy_object, ⚠️ ovh_delete_object, ⚠️ ovh_delete_object_version, ⚠️ ovh_bulk_delete_objects

Пользователи и ключи

ovh_list_project_users, ovh_get_project_user, ovh_list_s3_credentials · W ovh_create_project_user, ovh_create_s3_credentials, ovh_reveal_s3_secret, ⚠️ ovh_delete_s3_credentials, ⚠️ ovh_delete_project_user

Политики

ovh_get_storage_policy, ovh_preview_policy · W ⚠️ ovh_set_storage_policy, ⚠️ ovh_grant_bucket_access, ⚠️ ovh_provision_s3_user

Запасной выход

ovh_request — любой путь /1.0, только GET, если запись не включена

ovh_presign_object — единственный способ перемещения данных: сервер никогда не проксирует содержимое объектов, а вместо этого выпускает ограниченную по времени предварительно подписанную S3-ссылку. При выключенной записи он подписывает только GET.

Пресеты политик

ovh_preview_policy, ovh_set_storage_policy и ovh_provision_s3_user используют три общих пресета, каждый из которых можно ограничить префиксом ключа:

Пресет

Разрешения

write-only

Разрешает s3:PutObject, s3:AbortMultipartUpload, s3:ListMultipartUploadParts для префикса — плюс явный Deny на s3:GetObject / s3:GetObjectAcl на весь бакет

read-only

s3:ListBucket + s3:GetBucketLocation для бакета, s3:GetObject для объектов

read-write

и то и другое, плюс s3:DeleteObject

Встроенные роли OVH (admin, deny, readOnly, readWrite, через ovh_grant_bucket_access) не имеют эквивалента write-only — именно поэтому существует путь через «сырую» политику. Пара multipart включена намеренно: любой S3 SDK автоматически переключается на multipart при размерах выше ~8-16 МБ, а без abort/list неудачная загрузка осиротит части, которые владелец ключа не может удалить и за хранение которых продолжает платить.

OVH проверяет действия политики по фиксированному перечислению и отклоняет весь документ с кодом 400, если какое-то действие неизвестно, — s3:GetObjectVersion и s3:DeleteObjectVersion существуют в AWS, но не здесь. В пресетах используются только принимаемые действия, и тест это закрепляет.

Выдача ключа для загрузки только на запись

Мотивирующий случай: приложение встраивает S3-ключ в поставляемый бинарный файл, поэтому ключ должен уметь только загружать, а ключ чтения/записи остаётся у разработчика.

ovh_get_bucket           bucket=dev-rgis-ar          → note ownerId
ovh_preview_policy       bucket=dev-rgis-ar preset=write-only prefix=uploads/
ovh_provision_s3_user    bucket=dev-rgis-ar preset=write-only prefix=uploads/ \
                         description=ar-app-uploader confirm=true

Это создаёт нового пользователя проекта (никогда не владельца бакета), применяет политику и только затем выпускает учётные данные — ключ, существовавший до своей политики, это ключ, который недолго имел всё, что разрешено по умолчанию. Секрет возвращается только один раз.

Проверьте на реальном S3 API, прежде чем передавать ключ, — политика, которая выглядит корректной, всё ещё может быть перекрыта владельцем, а подождите ~30 секунд после её установки, иначе вы будете проверять предыдущую политику:

export AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=...
# An array, not a string: zsh does not word-split an unquoted $var, so the
# `S3='aws ...'` form you would write in bash silently becomes "command not found".
S3=(aws --endpoint-url https://s3.uk.io.cloud.ovh.net --region uk s3api)
"${S3[@]}" put-object      --bucket dev-rgis-ar --key uploads/probe.txt --body /dev/null   # 200
"${S3[@]}" get-object      --bucket dev-rgis-ar --key uploads/probe.txt /dev/null          # 403
"${S3[@]}" list-objects-v2 --bucket dev-rgis-ar                                            # 403
"${S3[@]}" delete-object   --bucket dev-rgis-ar --key uploads/probe.txt                    # 403
"${S3[@]}" put-object      --bucket dev-rgis-ar --key elsewhere/probe.txt --body /dev/null # 403

Строка get-object — вот что важно: это проверка, которая ловит ловушку № 3, и она проходит только благодаря Deny из пресета.

Разработка

pnpm dev            # tsdown --watch
pnpm test           # vitest
pnpm typecheck
pnpm lint
pnpm format

Лицензия

MIT

Available Tools

1 tool
ovh_auth_statusOVHcloud: Auth StatusA
Read-only

Report whether this server has working OVHcloud credentials, which auth method and endpoint it uses, the default project and region, whether writes are enabled, the OVH_SECRET_DIR that secretFile paths are confined to, and — when something is missing — exactly what to set. Call this first when a tool you expected is not listed: an absent tool here means missing configuration, not a bug.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say readOnlyHint=true; the description adds real substance on top: the full set of reported facts, the confinement of `secretFile` paths to OVH_SECRET_DIR, the write-enabled flag, and prescriptive remediation ("exactly what to set") when something is missing. That is behavior an agent could not infer from the annotation alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler, with the diagnostic use case front-loaded after the enumeration. The first sentence is dense with comma-separated items but every item is a distinct reported fact that earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description carries the return-value burden — and it does so by enumerating every reported field plus the remediation behavior for missing config. For a zero-parameter, read-only diagnostic tool this is complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is no parameter semantics to explain; baseline applies. The description correctly spends none of its length on inputs and instead covers what the no-arg call reports.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Uses a specific verb ("report") with a precisely enumerated payload: credential validity, auth method, endpoint, default project/region, write-enablement, and the OVH_SECRET_DIR constraint. An agent knows exactly what this tool returns and why it exists without consulting other fields.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit trigger — "Call this first when a tool you expected is not listed" — plus the interpretation rule that an absent tool means missing configuration, not a bug. It stops short of stating when *not* to call it (e.g., routine polling), so it lands just under a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev0.1.0
    • First observedovh_auth_status

TDQS

A4.1/5.0

Scored across 1 tool

Disambiguation5/5

There is only one tool, so there is no possibility of confusing it with another. Its purpose is clearly stated as an authentication/configuration diagnostic.

Naming Consistency5/5

The single tool name `ovh_auth_status` follows a clear snake_case domain-action pattern. With only one tool, there is no inconsistency to assess.

Tool Count1/5

The server claims to be an OVHcloud API server but exposes only a single diagnostic tool. This is an extreme mismatch between the broad implied domain and the one available operation.

Completeness1/5

The surface contains only an auth-status check and no OVHcloud resource operations such as listing projects, managing instances, or any CRUD lifecycle. It is effectively a diagnostic stub rather than a usable API toolset.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    MCP server for uploading, listing, and retrieving files on S3-compatible storage (AWS S3, DigitalOcean Spaces) with public/private access and temporary URLs.
    4
    0
    MIT