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é.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- 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
Dans quel contexte ?
Section intitulée « Dans quel contexte ? »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
ReadSecurityGroupspour 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
Prérequis
Section intitulée « Prérequis »| Composant | Version | Vérification |
|---|---|---|
| Docker (avec Compose v2) | 24+ | docker --version |
| Node.js | 18+ | node --version |
| npm | 8+ | npm --version |
| curl + jq | — | curl --version && jq --version |
Architecture reShapr
Section intitulée « Architecture reShapr »reShapr repose sur une architecture control-plane / data-plane :
| Composant | Rôle | Port local |
|---|---|---|
| Control Plane | Stocke les services, configs, secrets, expositions | 5555 |
| Gateway (Proxy) | Expose les endpoints MCP, route le trafic | 7777 |
| PostgreSQL | Persistance des métadonnées | 54321 |
Le flux de travail suit cinq étapes :
- Import — reShapr ingère une spec OpenAPI et découvre un Service
- Configuration — vous créez un Configuration Plan avec le backend cible et les filtres d’opérations
- Sécurité — vous ajoutez une API key, un Secret backend, ou OAuth2
- Exposition — le plan est déployé sur les Gateways qui exposent l’endpoint MCP
- Enrichissement — vous attachez des Custom Tools et des Prompts pour affiner le contexte
Installation
Section intitulée « Installation »-
Installer la CLI reShapr
Fenêtre de terminal npm install -g @reshapr/reshapr-cliVérifiez l’installation :
Fenêtre de terminal reshapr --version0.0.8 -
Démarrer la plateforme en local
Fenêtre de terminal reshapr runℹ️ Resolved 'latest' to release '0.0.8'.ℹ️ Downloading compose file fromhttps://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. -
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 STATUSreshapr-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 -
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 -
Vérifier la connexion
Fenêtre de terminal reshapr infoℹ️ User InformationUser : adminOrganization: reshaprServer : http://localhost:5555ℹ️ Server InformationVersion : 0.0.8Build time : 2026-04-03T09:59:28ZMode : on-premises
Importer l’API Outscale
Section intitulée « Importer l’API Outscale »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.
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 : 0Q1YS0A5PWPXROrganization : reshaprService Name : 3DS OUTSCALE APIService Version: 1.40.1Service Type : REST -> https://api.eu-west-2.outscale.com/api/v1Endpoints : localhost:7777/mcp/reshapr/3DS+OUTSCALE+API/1.40.1reShapr a découvert 235 opérations automatiquement :
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}Créer un plan FinOps read-only
Section intitulée « Créer un plan FinOps read-only »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 :
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.| Option | Rôle |
|---|---|
--io | Included Operations — seules ces 11 opérations seront exposées |
--apiKey | Génère une clé API que le client MCP devra fournir via x-reshapr-key |
--backendEndpoint | URL du backend Outscale réel |
Exposer le plan sur la gateway
Section intitulée « Exposer le plan sur la gateway »reshapr expo create --configuration 0Q1YW7G3JWMXY --gateway-group 1✅ Exposition created successfully with ID: 0Q1YW8R92WMZRℹ️ Exposition detailsID : 0Q1YW8R92WMZRService: Name : 3DS OUTSCALE API Version: 1.40.1 Type : RESTConfiguration 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.1Résultat : 235 opérations ramenées à 11, toutes en lecture seule, protégées par une API key.
Créer un secret backend
Section intitulée « Créer un secret backend »Pour que la gateway puisse s’authentifier auprès de l’API Outscale, créez un Secret de type backend :
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: 0Q1YSB1KPWQFTreshapr secret listID NAME TYPE DESCRIPTION0Q1YSB1KPWQFT outscale-credentials ENDPOINT Outscale API Access Key / Secret Key| Option | Rôle |
|---|---|
-B | Tagge le secret comme backend (pour l’endpoint cible) |
-t | Token ou clé d’API à transmettre |
-h | Header HTTP utilisé pour envoyer le token |
Attacher des Custom Tools FinOps
Section intitulée « Attacher des Custom Tools FinOps »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/v1alpha1kind: CustomToolsservice: 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 :
reshapr attach -f outscale-finops-custom-tools.yaml✅ Attachment successful!ℹ️ Discovered Artifact file with ID: 0Q1YWD15AWN1JAttacher des Prompts FinOps
Section intitulée « Attacher des Prompts FinOps »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/v1alpha1kind: Promptsservice: 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.reshapr attach -f outscale-finops-prompts.yaml✅ Attachment successful!ℹ️ Discovered Artifact file with ID: 0Q1YWE1M6WNDJVérifier l’endpoint MCP
Section intitulée « Vérifier l’endpoint MCP »L’endpoint est maintenant prêt. Testons-le avec curl pour valider que les tools et prompts sont bien exposés.
Initialiser une session MCP
Section intitulée « Initialiser une session MCP »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" } }}Lister les outils MCP exposés
Section intitulée « Lister les outils MCP exposés »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.
Lister les prompts MCP
Section intitulée « Lister les prompts MCP »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"}Sortie structurée
Section intitulée « Sortie structurée »La CLI supporte les formats JSON et YAML pour l’automatisation :
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"}reshapr expo list -o yaml- id: 0Q1YW8R92WMZR organizationId: reshapr service: name: 3DS OUTSCALE API version: 1.40.1 type: REST configurationPlan: backendEndpoint: https://api.eu-west-2.outscale.com/api/v1 gateways: - fqdns: - localhost:7777Connecter VS Code comme client MCP
Section intitulée « Connecter VS Code comme client MCP »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.”
Gérer les quotas et tokens
Section intitulée « Gérer les quotas et tokens »Quotas de la plateforme
Section intitulée « Quotas de la plateforme »reshapr quotasORG METRIC ENABLED LIMIT REMAININGreshapr exposition.count Y 1000 998reshapr gateway-group.count Y 1000 999reshapr gateway.count Y 1000 999Renouveler une API key
Section intitulée « Renouveler une API key »Si une clé est compromise, renouvelez-la immédiatement :
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.
Référence CLI
Section intitulée « Référence CLI »| Commande | Rôle |
|---|---|
reshapr run | Démarrer la plateforme en local (Docker Compose) |
reshapr status | Vérifier l’état des conteneurs |
reshapr login | S’authentifier auprès du control-plane |
reshapr info | Afficher les informations de connexion |
reshapr import | Importer un artefact OpenAPI/GraphQL/gRPC |
reshapr attach | Attacher un artefact complémentaire (Prompts, Custom Tools) |
reshapr service list/get/delete | Gérer les services découverts |
reshapr config create | Créer un Configuration Plan (filtrage + sécurité) |
reshapr config renew-api-key | Renouveler une API key |
reshapr expo create/list/get/delete | Gérer les expositions MCP |
reshapr secret create/list | Gérer les secrets backend |
reshapr api-token create/list/delete | Gérer les tokens d’API gateway |
reshapr quotas | Afficher les quotas de la plateforme |
reshapr stop | Arrêter les conteneurs |
Dépannage
Section intitulée « Dépannage »| Problème | Cause | Solution |
|---|---|---|
reshapr run échoue | Docker non démarré | systemctl start docker |
401 Unauthorized sur l’endpoint MCP | API key manquante ou invalide | Ajouter x-reshapr-key dans les headers |
reshapr login timeout | Control-plane pas encore prêt | Attendre 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 visibles | Mauvais service.name ou version | Vérifier avec reshapr service list et corriger le YAML |
| Gateway unhealthy | Port 7777 déjà occupé | lsof -i :7777 puis arrêter le processus concurrent |
Sécurité
Section intitulée « Sécurité »| Mesure | Détail |
|---|---|
| Filtrage d’opérations | N’exposer que les opérations strictement nécessaires (--io) |
| API key | Chaque Configuration Plan peut avoir sa propre clé |
| Secret backend | Les credentials Outscale ne transitent jamais côté client |
| OAuth2 | Supporté via --internalOAuth2 ou config create-oauth avec serveur externe |
| TLS | En production, terminer TLS devant la gateway |
| Rotation | renew-api-key révoque instantanément l’ancienne clé |
| Multi-tenant | Isolation stricte entre organisations |
À retenir
Section intitulée « À retenir »- 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|yamlpermet l’intégration GitOps et l’automatisation - La plateforme se déploie en local (Docker), en hybride ou on-premises