Aller au contenu
Développement medium

reShapr : transformer une API cloud en serveur MCP FinOps

23 min de lecture

reShapr transforme n’importe quelle API REST, GraphQL ou gRPC en serveur MCP sécurisé, sans écrire une ligne de code. Vous importez une spécification OpenAPI, vous filtrez les opérations exposées, vous attachez des Custom Tools et des Prompts, et vous obtenez un endpoint MCP que n’importe quel agent IA peut consommer.

Dans ce guide, vous allez construire un serveur MCP FinOps à partir de l’API 3DS Outscale (235 opérations). L’objectif : n’exposer que les opérations read-only nécessaires pour détecter les ressources cloud inutilisées — IPs publiques non attachées, volumes orphelins, snapshots anciens, VMs arrêtées — et laisser un agent IA produire un rapport d’audit automatisé.

  • Déployer reShapr localement avec Docker Compose et sa CLI
  • Importer une spécification OpenAPI et découvrir automatiquement un service
  • Filtrer les opérations exposées pour réduire la surface d’attaque (235 → 11 read-only)
  • Sécuriser l’endpoint MCP avec une API key
  • Créer des Custom Tools FinOps (détection IPs, volumes, snapshots inutilisés)
  • Attacher des Prompts d’audit FinOps pour guider l’agent IA
  • Connecter VS Code comme client MCP pour interroger l’API cloud

En environnement cloud, les ressources oubliées s’accumulent : une IP publique allouée après un test, un volume détaché après la suppression d’une VM, des snapshots de 6 mois que personne ne nettoie. Ces ressources fantômes génèrent des coûts silencieux.

Le Model Context Protocol (MCP) permet aux agents IA d’appeler des outils structurés. Plutôt que de coder un serveur MCP from scratch pour chaque API cloud, reShapr transforme la spec OpenAPI existante en endpoint MCP en quelques commandes CLI. Cas d’usage concrets :

  • Audit FinOps : un agent IA interroge l’API cloud pour lister les ressources orphelines
  • Conformité réseau : exposer uniquement ReadSecurityGroups pour auditer les règles firewall
  • Inventaire infra : créer un MCP read-only que les développeurs interrogent depuis leur IDE
  • Réduction de surface : sur 235 opérations, n’en exposer que 11 — zéro risque de mutation accidentelle
ComposantVersionVérification
Docker (avec Compose v2)24+docker --version
Node.js18+node --version
npm8+npm --version
curl + jqcurl --version && jq --version

reShapr repose sur une architecture control-plane / data-plane :

ComposantRôlePort local
Control PlaneStocke les services, configs, secrets, expositions5555
Gateway (Proxy)Expose les endpoints MCP, route le trafic7777
PostgreSQLPersistance des métadonnées54321

Le flux de travail suit cinq étapes :

  1. Import — reShapr ingère une spec OpenAPI et découvre un Service
  2. Configuration — vous créez un Configuration Plan avec le backend cible et les filtres d’opérations
  3. Sécurité — vous ajoutez une API key, un Secret backend, ou OAuth2
  4. Exposition — le plan est déployé sur les Gateways qui exposent l’endpoint MCP
  5. Enrichissement — vous attachez des Custom Tools et des Prompts pour affiner le contexte
  1. Installer la CLI reShapr

    Fenêtre de terminal
    npm install -g @reshapr/reshapr-cli

    Vérifiez l’installation :

    Fenêtre de terminal
    reshapr --version
    0.0.8
  2. Démarrer la plateforme en local

    Fenêtre de terminal
    reshapr run
    ℹ️ Resolved 'latest' to release '0.0.8'.
    ℹ️ Downloading compose file from
    https://raw.githubusercontent.com/reshaprio/reshapr/refs/tags/0.0.8/install/docker-compose-all-in-one.yml...
    ✅ Compose file saved to /home/bob/.reshapr/docker-compose-0.0.8.yml
    ℹ️ Starting Reshapr containers (release: 0.0.8)...
    ✅ Reshapr containers started successfully.
  3. Vérifier l’état des conteneurs

    Fenêtre de terminal
    reshapr status
    ℹ️ Reshapr containers (release: 0.0.8, started at: 2026-04-11T18:25:02.673Z)
    NAME IMAGE STATUS
    reshapr-control-plane registry.reshapr.io/reshapr/reshapr-ctrl:0.0.8 Up (healthy)
    reshapr-gateway-01 registry.reshapr.io/reshapr/reshapr-proxy:0.0.8 Up (healthy)
    reshapr-postgres library/postgres:17-alpine Up
  4. Se connecter au control-plane

    Fenêtre de terminal
    reshapr login -s http://localhost:5555 -u admin -p password
    ✅ Login successful!
    ℹ️ Welcome, admin!
    ✅ Configuration saved to /home/bob/.reshapr/config
  5. Vérifier la connexion

    Fenêtre de terminal
    reshapr info
    ℹ️ User Information
    User : admin
    Organization: reshapr
    Server : http://localhost:5555
    ℹ️ Server Information
    Version : 0.0.8
    Build time : 2026-04-03T09:59:28Z
    Mode : on-premises

L’API 3DS Outscale est décrite par une spécification OpenAPI 3.x hébergée sur GitHub. La commande import la récupère, découvre le service et crée automatiquement une exposition sur la gateway par défaut.

Fenêtre de terminal
reshapr import \
-u https://raw.githubusercontent.com/outscale/osc-api/master/outscale.yaml \
--backendEndpoint https://api.eu-west-2.outscale.com/api/v1
✅ Import successful!
ℹ️ Discovered Service 3DS OUTSCALE API with ID: 0Q1YS09DAWPPW
✅ Exposition done!
✅ Exposition is now active!
Exposition ID : 0Q1YS0A5PWPXR
Organization : reshapr
Service Name : 3DS OUTSCALE API
Service Version: 1.40.1
Service Type : REST -> https://api.eu-west-2.outscale.com/api/v1
Endpoints : localhost:7777/mcp/reshapr/3DS+OUTSCALE+API/1.40.1

reShapr a découvert 235 opérations automatiquement :

Fenêtre de terminal
reshapr service get 0Q1YS09DAWPPW -o json | \
jq '{name: .name, version: .version, type: .type, operationCount: (.operations | length)}'
{
"name": "3DS OUTSCALE API",
"version": "1.40.1",
"type": "REST",
"operationCount": 235
}

Le Configuration Plan définit quelles opérations sont exposées et comment l’endpoint est sécurisé. Ici, on restreint à 11 opérations de lecture pertinentes pour l’audit FinOps :

Fenêtre de terminal
reshapr config create 'outscale-finops-audit' \
--description 'FinOps read-only plan: detect unused Outscale resources' \
--serviceId 0Q1YS09DAWPPW \
--backendEndpoint https://api.eu-west-2.outscale.com/api/v1 \
--io '["POST /ReadPublicIps", "POST /ReadVolumes", "POST /ReadSnapshots",
"POST /ReadImages", "POST /ReadVms", "POST /ReadNics",
"POST /ReadLoadBalancers", "POST /ReadNatServices",
"POST /ReadSecurityGroups", "POST /ReadNets",
"POST /ReadInternetServices"]' \
--apiKey
✅ Configuration plan 'outscale-finops-audit' created successfully with ID: 0Q1YW7G3JWMXY
⚠️ The API Key to access future expositions is: 91a9189b-a842-41c5-9b5b-56751d1797c6
⚠️ Make sure to store it securely, as it will not be shown again.
OptionRôle
--ioIncluded Operations — seules ces 11 opérations seront exposées
--apiKeyGénère une clé API que le client MCP devra fournir via x-reshapr-key
--backendEndpointURL du backend Outscale réel
Fenêtre de terminal
reshapr expo create --configuration 0Q1YW7G3JWMXY --gateway-group 1
✅ Exposition created successfully with ID: 0Q1YW8R92WMZR
ℹ️ Exposition details
ID : 0Q1YW8R92WMZR
Service:
Name : 3DS OUTSCALE API
Version: 1.40.1
Type : REST
Configuration Plan
Name : outscale-finops-audit
BackendEndpoint: https://api.eu-west-2.outscale.com/api/v1
Included Ops. : ["POST /ReadPublicIps","POST /ReadVolumes","POST /ReadSnapshots",
"POST /ReadImages","POST /ReadVms","POST /ReadNics",
"POST /ReadLoadBalancers","POST /ReadNatServices",
"POST /ReadSecurityGroups","POST /ReadNets",
"POST /ReadInternetServices"]
Gateway Endpoints
- Endpoints: localhost:7777/mcp/reshapr/3DS+OUTSCALE+API/1.40.1

Résultat : 235 opérations ramenées à 11, toutes en lecture seule, protégées par une API key.

Pour que la gateway puisse s’authentifier auprès de l’API Outscale, créez un Secret de type backend :

Fenêtre de terminal
reshapr secret create outscale-credentials \
--description 'Outscale API Access Key / Secret Key' \
-B \
-t "VOTRE_ACCESS_KEY" \
-h "Authorization"
✅ Secret outscale-credentials created successfully with ID: 0Q1YSB1KPWQFT
Fenêtre de terminal
reshapr secret list
ID NAME TYPE DESCRIPTION
0Q1YSB1KPWQFT outscale-credentials ENDPOINT Outscale API Access Key / Secret Key
OptionRôle
-BTagge le secret comme backend (pour l’endpoint cible)
-tToken ou clé d’API à transmettre
-hHeader HTTP utilisé pour envoyer le token

Les Custom Tools permettent de renommer, condenser et pré-paramétrer les outils MCP. Au lieu de laisser l’agent deviner les paramètres de ReadVolumes, vous créez un outil find_unattached_volumes avec une description FinOps explicite.

Créez le fichier outscale-finops-custom-tools.yaml :

apiVersion: reshapr.io/v1alpha1
kind: CustomTools
service:
name: 3DS OUTSCALE API
version: '1.40.1'
customTools:
find_unattached_public_ips:
tool: POST /ReadPublicIps
title: find unattached public ips
description: >
List all Elastic IPs that are NOT linked to any VM or NIC.
These IPs are billed but unused — prime FinOps waste.
input:
type: object
properties: {}
arguments: {}
find_unattached_volumes:
tool: POST /ReadVolumes
title: find unattached volumes
description: >
List all volumes in 'available' state (not attached to any VM).
These volumes are billed but unused — typical FinOps waste.
input:
type: object
properties: {}
arguments: {}
find_stopped_vms:
tool: POST /ReadVms
title: find stopped vms
description: >
List VMs in 'stopped' state. Stopped VMs still incur storage
costs for their root volumes and any attached EBS.
input:
type: object
properties: {}
arguments:
Filters:
VmStates:
- stopped
find_old_snapshots:
tool: POST /ReadSnapshots
title: find old snapshots
description: >
List all snapshots. An agent should identify snapshots
older than 90 days that may no longer be needed.
input:
type: object
properties: {}
arguments: {}
find_unused_nics:
tool: POST /ReadNics
title: find unused network interfaces
description: >
List all NICs in 'available' state (not attached to a VM).
Unused NICs with associated Public IPs waste money.
input:
type: object
properties: {}
arguments: {}
list_load_balancers:
tool: POST /ReadLoadBalancers
title: list load balancers
description: >
List all load balancers. An agent should flag LBs
with zero backend VMs registered.
input:
type: object
properties: {}
arguments: {}

Attachez-le au service :

Fenêtre de terminal
reshapr attach -f outscale-finops-custom-tools.yaml
✅ Attachment successful!
ℹ️ Discovered Artifact file with ID: 0Q1YWD15AWN1J

Les Prompts MCP fournissent des instructions pré-rédigées que l’agent peut invoquer pour exécuter un scénario complet.

Créez le fichier outscale-finops-prompts.yaml :

apiVersion: reshapr.io/v1alpha1
kind: Prompts
service:
name: 3DS OUTSCALE API
version: '1.40.1'
prompts:
finops_full_audit:
title: FinOps full audit
description: Run a complete FinOps waste detection audit
result: |
Perform a complete FinOps audit of this Outscale account.
Step 1: Find all unattached Public IPs (billed but not linked to a VM).
Step 2: Find all unattached volumes (state = available).
Step 3: Find all stopped VMs and their attached volumes.
Step 4: Find all snapshots and flag those older than 90 days.
Step 5: Find unused NICs (state = available).
Step 6: Find load balancers with no registered backend VMs.
Present a summary table with: resource type, count, estimated waste level.
finops_quick_ips:
title: Quick IP waste check
description: Find Elastic IPs allocated but not attached to any resource
result: |
Find all Public IPs that are not linked to any VM or NIC.
Each unlinked Elastic IP costs money for nothing.
Present the list with IP address, allocation ID, and age.
finops_storage_waste:
title: Storage waste check
description: Find unattached volumes and old snapshots
result: |
Step 1: Find all volumes in 'available' state (not attached).
Step 2: Find all snapshots older than 90 days.
Present a combined report with volume ID, size, snapshot ID, age.
Fenêtre de terminal
reshapr attach -f outscale-finops-prompts.yaml
✅ Attachment successful!
ℹ️ Discovered Artifact file with ID: 0Q1YWE1M6WNDJ

L’endpoint est maintenant prêt. Testons-le avec curl pour valider que les tools et prompts sont bien exposés.

Fenêtre de terminal
curl -s http://localhost:7777/mcp/reshapr/3DS+OUTSCALE+API/1.40.1 \
-H "Content-Type: application/json" \
-H "x-reshapr-key: 91a9189b-a842-41c5-9b5b-56751d1797c6" \
-d '{
"jsonrpc": "2.0", "id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {"name": "finops-lab", "version": "1.0"}
}
}' | jq .
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-06-18",
"capabilities": {
"prompts": { "listChanged": false },
"resources": { "subscribe": false, "listChanged": false },
"tools": { "listChanged": false }
},
"serverInfo": {
"name": "3DS OUTSCALE API MCP server",
"version": "1.40.1"
}
}
}
Fenêtre de terminal
curl -s http://localhost:7777/mcp/reshapr/3DS+OUTSCALE+API/1.40.1 \
-H "Content-Type: application/json" \
-H "x-reshapr-key: 91a9189b-a842-41c5-9b5b-56751d1797c6" \
-H "MCP-Session-Id: <session-id>" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | jq '.result.tools[] | .name'
"post_readimages"
"post_readinternetservices"
"post_readloadbalancers"
"post_readnatservices"
"post_readnets"
"post_readnics"
"post_readpublicips"
"post_readsecuritygroups"
"post_readsnapshots"
"post_readvms"
"post_readvolumes"

11 outils au lieu de 235 — exactement le périmètre FinOps défini.

Fenêtre de terminal
curl -s http://localhost:7777/mcp/reshapr/3DS+OUTSCALE+API/1.40.1 \
-H "Content-Type: application/json" \
-H "x-reshapr-key: 91a9189b-a842-41c5-9b5b-56751d1797c6" \
-H "MCP-Session-Id: <session-id>" \
-d '{"jsonrpc":"2.0","id":3,"method":"prompts/list"}' | jq '.result.prompts[] | {name, description}'
{
"name": "finops_full_audit",
"description": "Run a complete FinOps waste detection audit on the Outscale account"
}
{
"name": "finops_quick_ips",
"description": "Find Elastic IPs that are allocated but not attached to any resource"
}
{
"name": "finops_storage_waste",
"description": "Find unattached volumes and old snapshots that waste storage budget"
}

La CLI supporte les formats JSON et YAML pour l’automatisation :

Fenêtre de terminal
reshapr expo list -o json | jq '.[0] | {service: .service.name, backend: .configurationPlan.backendEndpoint}'
{
"service": "3DS OUTSCALE API",
"backend": "https://api.eu-west-2.outscale.com/api/v1"
}

L’endpoint MCP exposé par reShapr est compatible avec tout client MCP. Pour l’utiliser depuis VS Code avec GitHub Copilot, ajoutez cette configuration dans votre fichier .vscode/mcp.json :

{
"servers": {
"outscale-finops": {
"type": "http",
"url": "http://localhost:7777/mcp/reshapr/3DS+OUTSCALE+API/1.40.1",
"headers": {
"x-reshapr-key": "91a9189b-a842-41c5-9b5b-56751d1797c6"
}
}
}
}

Une fois configuré, l’agent Copilot peut utiliser les 11 outils FinOps et les 3 prompts directement depuis l’éditeur. Demandez-lui par exemple :

“Lance un audit FinOps complet de mon compte Outscale. Trouve les IPs non utilisées, les volumes détachés et les snapshots de plus de 90 jours.”

Fenêtre de terminal
reshapr quotas
ORG METRIC ENABLED LIMIT REMAINING
reshapr exposition.count Y 1000 998
reshapr gateway-group.count Y 1000 999
reshapr gateway.count Y 1000 999

Si une clé est compromise, renouvelez-la immédiatement :

Fenêtre de terminal
reshapr config renew-api-key 0Q1YW7G3JWMXY
⚠️ The API Key to access future expositions is: 2c8b1608-e8c2-4dfa-85ae-55da0caf6c50
⚠️ Make sure to store it securely, as it will not be shown again.

La clé précédente est immédiatement révoquée. Tous les clients MCP doivent être mis à jour.

CommandeRôle
reshapr runDémarrer la plateforme en local (Docker Compose)
reshapr statusVérifier l’état des conteneurs
reshapr loginS’authentifier auprès du control-plane
reshapr infoAfficher les informations de connexion
reshapr importImporter un artefact OpenAPI/GraphQL/gRPC
reshapr attachAttacher un artefact complémentaire (Prompts, Custom Tools)
reshapr service list/get/deleteGérer les services découverts
reshapr config createCréer un Configuration Plan (filtrage + sécurité)
reshapr config renew-api-keyRenouveler une API key
reshapr expo create/list/get/deleteGérer les expositions MCP
reshapr secret create/listGérer les secrets backend
reshapr api-token create/list/deleteGérer les tokens d’API gateway
reshapr quotasAfficher les quotas de la plateforme
reshapr stopArrêter les conteneurs
ProblèmeCauseSolution
reshapr run échoueDocker non démarrésystemctl start docker
401 Unauthorized sur l’endpoint MCPAPI key manquante ou invalideAjouter x-reshapr-key dans les headers
reshapr login timeoutControl-plane pas encore prêtAttendre 10–15 s après reshapr run, vérifier reshapr status
Import échoue avec « invalid spec »Spec OpenAPI 2.0 (Swagger)reShapr supporte OpenAPI 3.x uniquement — convertir avec swagger2openapi
Custom Tools non visiblesMauvais service.name ou versionVérifier avec reshapr service list et corriger le YAML
Gateway unhealthyPort 7777 déjà occupélsof -i :7777 puis arrêter le processus concurrent
MesureDétail
Filtrage d’opérationsN’exposer que les opérations strictement nécessaires (--io)
API keyChaque Configuration Plan peut avoir sa propre clé
Secret backendLes credentials Outscale ne transitent jamais côté client
OAuth2Supporté via --internalOAuth2 ou config create-oauth avec serveur externe
TLSEn production, terminer TLS devant la gateway
Rotationrenew-api-key révoque instantanément l’ancienne clé
Multi-tenantIsolation stricte entre organisations
  • reShapr transforme une spec OpenAPI, GraphQL ou gRPC en serveur MCP sans code
  • Le filtrage d’opérations (--io / --eo) réduit la surface d’attaque et optimise les tokens LLM
  • Les Custom Tools permettent de pré-paramétrer et renommer les outils pour un contexte métier (FinOps)
  • Les Prompts guident l’agent IA vers des scénarios d’audit structurés
  • L’API key protège l’accès à l’endpoint MCP — renouvelez-la avec renew-api-key
  • Les Secrets stockent les credentials backend de façon sécurisée côté serveur
  • La sortie --output json|yaml permet l’intégration GitOps et l’automatisation
  • La plateforme se déploie en local (Docker), en hybride ou on-premises

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn